12 / 14 · audits
Dataset Diff
A forensic diff for spectral datasets: names what kind of change each record underwent and gates the release on it.
The problem
Version control tells you bytes changed; nothing tells you what kind of change a spectral record underwent. A re-measurement carries fresh noise on the same shape, a recalibration is a systematic gain and offset, and silent smoothing of a claimed measurement is a provenance violation wearing the same record id. A curator staring at two 38-number arrays cannot tell these apart by eye, and the distinction is exactly what decides whether the new version of a dataset should ship.
The method
Records are matched by id and each changed pair is classified by its numerical signature. A least-squares gain and offset fit that absorbs nearly all of the change reads as recalibration. Noise-band energy is measured as the residual against a Savitzky-Golay quadratic fit, which passes local curvature exactly while keeping per-sample noise, so a collapse in that band reads as smoothing while preserved noise energy on a near-identical shape reads as renoising, a re-measurement; everything beyond these signatures is a replacement. Every matched record also carries its perceptual impact as ΔE_OK under D65, because a change can be numerically large and perceptually nothing, or the reverse. The corpus verdict is a CI gate: it fails on smoothed records unless smoothing was explicitly allowed, and on records whose appearance moved beyond the stated ΔE budget without being declared replacements.
What it promises
- Every matched record gets a named verdict, identical, renoised, smoothed, rescaled, or replaced, together with the RMS change, a written justification, and its ΔE_OK under D65.
- The gate states its reasons: silent smoothing of claimed measurements and undeclared appearance changes each fail it with counts attached, and added or removed record ids are listed in full.
- Perceptual and numerical change are kept separate on purpose, so a loud edit nobody can see and a quiet edit everybody will see are both caught for what they are.
Calling it
{
"tool": "diff_spectral_datasets",
"arguments": {
"before": [
{
"id": "munsell-5R-4-14",
"values": "<38 samples>"
}
],
"after": [
{
"id": "munsell-5R-4-14",
"values": "<38 samples>"
}
],
"allow_smoothed": false,
"max_perceptual_delta": 0.05
}
} Clone the maryslab repo, run cd mcp && npm install && npm run build, then claude mcp add maryslab -- node mcp/dist/server.js
Known limits
- Classification is a signature match, not a chain of custody: the verdicts come from thresholded numerical fingerprints, and a smoothed curve with realistic synthetic noise added back can read as a re-measurement.
- Perceptual impact is judged under D65 for the standard observer only; a change that is invisible there can still matter under another light.
- Both versions must already sit on the canonical 38-sample grid and matching is by record id alone, so a renamed record shows up as one removal plus one addition, not a tracked change.