10 / 14 · certificates

Spectral Constraint Oracle

A decision procedure for cross-illuminant appearance: witness reflectance when feasible, named conflicts when not.

figure generated by the instrument itself. hover to let the light in.

The problem

Multi-condition metamer generation, the Metameric line from SIGGRAPH 2023 and Finlayson's work before it, can produce a spectrum hitting several appearance targets when one exists. What that line never provides is the decision: a verified yes, or a no that names which requirements conflict. The no is the valuable half. It answers whether any coating can look brick red under daylight and olive under tungsten, and its forensic corollary, whether two photographed observations could be the same physical surface at all.

The method

Each appearance requirement becomes a convex constraint in spectral space, the set of reflectances whose response under the stated illuminant lands within a ΔE_OK tolerance of the target, and physical realizability is the box [0,1] on the canonical 38-sample grid. Projections onto convex sets (POCS) iterates across all constraints and the box; when the intersection is nonempty the iterates converge into it, and the witness spectrum is re-verified through the forward colorimetric path before it is returned with its achieved error per constraint. When the residual stalls, the tool declares infeasibility and runs a pairwise pass that names the smallest constraint subsets already in conflict. The forensic mode, could_be_same_surface, is the two-constraint case: feasible means one physical reflectance accounts for both observations; infeasible means a different surface, a wrong illuminant assumption, or a surface that is not a plain diffuse reflector.

What it promises

  • Every witness is verified before it ships: a reflectance in [0,1] on the canonical grid, pushed back through the forward colorimetric path, with achieved ΔE_OK per constraint in the response.
  • Infeasibility is localized, not just announced: the conflict list names the smallest constraint subsets that are jointly unsatisfiable, so you know exactly what to relax.
  • The forensic answer states its alternatives: a no from could_be_same_surface means a different surface, a wrong illuminant assumption, or a non-diffuse material, and the response says so in those words.

Calling it

{
  "tool": "solve_spectral_constraints",
  "arguments": {
    "constraints": [
      {
        "illuminant": "D65",
        "target": {
          "space": "srgb",
          "value": [
            0.62,
            0.26,
            0.18
          ]
        },
        "tolerance_delta_e_ok": 0.01
      },
      {
        "illuminant": "A",
        "target": {
          "space": "srgb",
          "value": [
            0.45,
            0.43,
            0.2
          ]
        },
        "tolerance_delta_e_ok": 0.01
      }
    ]
  }
}

Clone the maryslab repo, run cd mcp && npm install && npm run build, then claude mcp add maryslab -- node mcp/dist/server.js

A worked example

Could one physical surface look like this under D65 and like that under tungsten?

what was asked

{
  "constraints": [
    {
      "illuminant": "D65",
      "target": {
        "space": "srgb",
        "value": [
          0.62,
          0.24,
          0.18
        ]
      },
      "tolerance_delta_e_ok": 0.03
    },
    {
      "illuminant": "A",
      "target": {
        "space": "srgb",
        "value": [
          0.45,
          0.42,
          0.16
        ]
      },
      "tolerance_delta_e_ok": 0.03
    }
  ]
}

what the engine answered

{
  "feasible": false,
  "witness_spectrum": null,
  "achieved_delta_e_ok": null,
  "conflicting_constraint_sets": [
    [
      0,
      1
    ]
  ],
  "method": "POCS failed to reach the intersection within budget; the conflict list names the smallest constraint subsets that are already jointly unsatisfiable. Treat infeasibility as strong evidence, not proof: POCS has no dual certificate.",
  "meta": {
    "engine_version": "0.4.1",
    "engine_backend": "reference-ts",
    "dataset_snapshot": "usgs-splib07a-1",
    "compute_device": "cpu"
  }
}

how to read it

A witness is a real reflectance, re-verified through the forward path. Infeasibility is strong evidence rather than proof — POCS carries no dual certificate, and the conflict list names which requirements clash.

Produced by running solve_spectral_constraints at build time (9 ms). Long arrays are truncated for reading; nothing else is edited.

Known limits

  • Infeasibility is strong evidence, not proof: POCS carries no dual certificate, so a stalled residual means no witness was found within the iteration budget, not a theorem that none exists.
  • The forensic mode is decision support: it rules on colorimetric consistency for plain diffuse reflectors, fluorescence breaks the bound, and a feasible witness proves possibility, never identity.
  • The oracle accepts at most six constraints over the four named illuminants (D65, D50, A, E), with appearance judged through the standard observer; very tight ΔE_OK tolerances can stall convergence and read as infeasible within the budget.