Illuminant Robustness Certificate
A guaranteed lower bound on palette discriminability across an entire illuminant family.
The problem
A palette that reads clearly under daylight can collapse under a warm bulb or a narrowband LED, and checking a handful of lamps only tells you about those lamps. Certified-robustness machinery from machine learning is mature, but it is built for L_p balls in pixel space, and physically plausible lighting work such as FLARE generates worst-case attacks rather than certificates. Neither line of work certifies a palette against the set of physically realizable illuminant spectra between your test points.
The method
For a fixed reflectance, XYZ is linear in the illuminant SPD, so over the convex hull of the basis illuminants the reachable XYZ set of each surface is exactly the convex hull of its basis responses, with no relaxation at that stage. The tool samples the mixture simplex on a barycentric grid, takes the minimum pairwise Oklab ΔE across the sampled mixtures, and subtracts a conservative correction: a numerically estimated Lipschitz constant of the XYZ to Oklab map, taken over the reachable set rather than its bounding box (the box's unreachable near-zero corners meet Oklab's cube root, whose gradient is unbounded at zero, and inflate the constant roughly tenfold), times the grid step, times two because both surfaces in a pair can move. The result is a guaranteed lower bound rather than a sampled estimate. This adapts the certified-robustness framework from the neural network literature to illuminant spectra instead of pixel perturbations.
What it promises
- guaranteedMinDeltaEOk is a true lower bound on minimum pairwise ΔE_OK under every illuminant in the convex hull of the basis, not only the sampled mixtures.
- The XYZ stage is exact: linearity in the illuminant means the reachable response set is the convex hull of basis responses, no relaxation.
- The nonlinear Oklab step is covered by a conservative Lipschitz correction; when that correction dominates the colors themselves, the certificate reports grid_sufficient: false plus a recommended division count instead of a hollow zero.
- Unknown basis names fail loudly with INVALID_ARG; accepted bases are D65, D50, A, E, BB<kelvin>, and LED<nm>.
Calling it
{
"tool": "certify_illuminant_robustness",
"arguments": {
"surfaces": [
{
"space": "srgb",
"value": [
0.9,
0.62,
0.04
]
},
{
"space": "srgb",
"value": [
0.16,
0.47,
0.85
]
},
{
"space": "srgb",
"value": [
0.55,
0.55,
0.55
]
}
],
"basis": [
"D65",
"A",
"LED450"
],
"threshold_delta_e_ok": 0.02,
"divisions": 8
}
} Clone the maryslab repo, run cd mcp && npm install && npm run build, then claude mcp add maryslab -- node mcp/dist/server.js
Known limits
- The Lipschitz constant is estimated numerically over sampled reachable points and their midpoints, not derived in closed form; the bound is conservative but rests on that empirical constant.
- With a coarse grid the correction, not the colors, can dominate; the tool then says so via grid_sufficient: false and recommended_divisions rather than pretending the bound is informative.
- The illuminant family is convex mixtures of at most four named bases; the Gaussian LED<nm> band is a crude but realizable stand-in for real LED primaries.