joulecontract: the published negative vectors were never actually run #94
Loading…
Reference in a new issue
No description provided.
Delete branch "joulecontract/run-negative-vectors"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The pack had two tests: every file's content address against
MANIFEST.json, and the positive DSSE envelope. Neither executed a negative vector. All elevennegative-*.jsonwere published, digest-pinned, and never read by a verifier — so the vectors written to catch a verifier that stops demoting were exactly the ones that could not catch it.This replays each through
validate_sealedunder the context they were generated in, comparing all four recorded fields: the demotion list, the maximum profile, the rendered §15 claim string, and whether the claimed profile is permitted.Equality, not "it demoted"
These are degradation vectors, not accept/reject ones. Each records the verdict a conformant verifier must produce —
metered_unattesteddemotes Energy toModelBased,generator_unattestedcaps Governance atdeclared. Asserting merely that something was demoted would pass a verifier that demoted the wrong axis, or by the wrong amount, or that refused the receipt outright — and refusing isn't the specified behaviour either, so the replay also asserts each vector still validates structurally.A wrong assumption the vectors corrected
My first version asserted every negative vector must leave its claimed profile impermissible. Two do not.
recourse_undeclaredandstatic_only_framerecord a disclosure demotion rather than a cap, andstatic_onlyis prohibited only at JR-4 while these vectors claim JR-3 — so the honest verdict is "permitted, and here is what you are trusting". Asserting!permitswould have pressured two published vectors toward a stricter reading than the spec takes. The invariant is the demotion list instead.Falsified, not assumed
Removing the
EngagementUndiscloseddemotion rule from the verifier leaves the entire pre-existing workspace suite green, and fails this replay naming the vector and the axis.StaticOnly,EngagementUndisclosedandIndependentKeyOnlyappear in no unit test injoulecontract-receiptat all — the published pack was their only coverage, and it was not running.Worth stating precisely: a probe against
MeteredUnattestedis not silent — two unit tests catch that one. The gap is uneven, which is itself worth knowing, and this PR does not claim more than it closes.Anti-vacuity
The replay asserts it saw at least eleven vectors, so a wrong path, a renamed prefix or an empty glob fails rather than passing having checked nothing — the same vacuity that let the original gap hide. It also pins the three context scalars it replays under, so a pack regenerated under a different context fails rather than silently comparing two different questions.
joulecontract-rsis already in the CI matrix, so these vectors now run on every change.Verification
15 test binaries green across the workspace, 1 new. The verifier crate is byte-identical to
main— the falsification probes were reverted and the revert checked withgit diff --quiet.🤖 Generated with Claude Code
5350ed3c49d5aa3635d7d5aa3635d77eee267a06