R.1: the record contract, and the six enums the review gates froze - #5
Merged
Conversation
R.1 is the packet everything in areas A, B, D, O and X is written against. Its
scope grew after it was written: IMPLEMENTATION-PLAN.md section 6 makes it the
single point where all shared cross-area vocabulary is fixed, because ten
confirmed defects came from four areas each defining that vocabulary from their
own side. Every one was a produce/consume break -- one area writing literals
another area's NOT NULL column could not accept, with `dast_status` sharing
ZERO values between two areas that each claimed authority over it.
What landed: internal/record/contract.go (the Go contract and its validators),
CONTRACT.md (the human-readable version other areas get pointed at, naming a
producer and a consumer for every field), and schemas/anvil-record-v1.schema.json
(SARIF 2.1.0 plus the anvil/* extension, Draft 2020-12).
Four distinctions carry comments explaining why, because they look like
redundancy and someone will otherwise simplify them away:
- dast_sealed and both_sealed exist because S1 requires two INDEPENDENTLY
sealed halves. A machine that can only seal SAST-then-DAST cannot express a
DAST-first seal, which is what area O's four-state version got wrong.
- skipped_no_manifest is deliberately distinct from not_run: no manifest
declared, versus the DAST tier not installed. S6 requires a target that
failed to be distinguishable from one scanned clean.
- target.provenance (boot outcome) and target.provisioning (which path) were
one field with two meanings in two areas. dastStatus derives from the
former; merging them loses information S6 requires.
- insufficient_context is a verdict, not a low confidence score.
Tests added by the orchestrator, because R.1 shipped without any
The packet validated itself through a scratchpad harness -- 17 negative Go
fixtures and 20 negative JSON-schema fixtures, all correctly rejected -- but
none of it landed in the repository, so nothing would ever run it again. That
is the same defect fixed for the experiment register two commits ago: a schema
nobody runs is a comment.
contract_test.go now pins, in-tree:
- all six frozen enums as literal strings, compared against the accessors
other packages consume. Not circular: the table is what the ruling says,
the accessors are what the code does, and a "tidy" edit has to defeat both.
- every pre-ruling literal the four areas were actually using -- `open`,
`complete`, `clean`, `partial`, `failed_to_boot`, `EXHIBITS`, and the rest
-- asserted to be REJECTED. If one starts validating, the ruling has been
quietly undone.
- the four handoff dispositions that existed only in area 60's deleted
anvil_ledger table, without which area X's exit criterion 14 is
unsatisfiable.
- that a repo source snippet is `untrusted` and not `anvil_generated`. Area B
was found stamping the latter on a struct whose field is verbatim
target-repo source, which would disable area X's containment check on
exactly the string that most needs it.
- that a CWE match alone never qualifies a correlation as verified (S7).
- that the empty string is rejected everywhere, so a zero-valued Go string
cannot pass as "unset but fine".
Evidence: gofmt clean; go vet clean; go build clean; go test -count=1 ./...
passes; schema self-checks as valid Draft 2020-12.
R.2 is NOT in this commit. It wrote fingerprint.go and fingerprint_test.go
before the session cap killed it, but the artifact is not structurally complete:
it had a compile error (string concatenation with the + leading the
continuation line, which semicolon insertion breaks), it never wrote its
testdata/fingerprint_corpus/ fixtures, and two of its own tests disagree with
its implementation. Fingerprint drift fails silently and permanently, so it gets
a clean re-run rather than a repair by guesswork. The work-in-progress is
preserved outside the tree.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
R.1 — the packet everything in areas A, B, D, O and X is written against. Its scope grew after it was written: the review gates made it the single point where all shared cross-area vocabulary is fixed.
Ten confirmed defects came from four areas each defining that vocabulary from their own side. Every one was a produce/consume break — one area writing literals another area's
NOT NULLcolumn could not accept.dast_statusshared zero values between two areas that each claimed authority over it.What landed
internal/record/contract.go— the Go contract and its validatorsinternal/record/CONTRACT.md— the human-readable version other areas get pointed at, naming a producer and a consumer for every fieldschemas/anvil-record-v1.schema.json— SARIF 2.1.0 + theanvil/*extension, Draft 2020-12Four distinctions carry comments explaining why, because they look like redundancy and someone will otherwise simplify them away:
dast_sealed/both_sealedskipped_no_manifestvsnot_runtarget.provenancevstarget.provisioningdastStatusderives from the former; merging loses information S6 requires.insufficient_contextTests added by me, because R.1 shipped without any
The packet validated itself through a scratchpad harness — 17 negative Go fixtures and 20 negative JSON-schema fixtures, all correctly rejected — but none of it landed in the repo, so nothing would ever run it again. That's the same defect fixed for the experiment register two commits ago: a schema nobody runs is a comment.
contract_test.gonow pins, in-tree:open,complete,clean,partial,failed_to_boot,EXHIBITSand the rest — asserted to be rejected. If one starts validating, the ruling has been quietly undone.anvil_ledger, without which area X's exit criterion 14 is unsatisfiable.untrusted, notanvil_generated. Area B was found stamping the latter on a struct whose field is verbatim target-repo source — which would disable area X's containment check on exactly the string that most needs it.What is deliberately NOT here
R.2 (the fingerprint). It wrote
fingerprint.goandfingerprint_test.gobefore the session cap killed it, and the plan's own §0.3 rule says to check the filesystem before concluding a step failed — so I did. But §0.3 requires the artifact be structurally complete, and this one is not:+leading the continuation line, which semicolon insertion breaks)testdata/fingerprint_corpus/was never written — 5 of its 8 test failures are just the missing fixturesFingerprint drift fails silently and permanently — two producers emitting different digests means regression matching breaks forever with nothing surfacing it. That earns a clean re-run, not a repair by guesswork. The WIP is preserved outside the tree.
Testing