Skip to content

R.11-R.16: queue re-cut, correlation, read path, GitHub projection, conformance harness - #8

Merged
tom-snyder merged 1 commit into
mainfrom
feat/phase1-queue-readpath
Aug 9, 2026
Merged

R.11-R.16: queue re-cut, correlation, read path, GitHub projection, conformance harness#8
tom-snyder merged 1 commit into
mainfrom
feat/phase1-queue-readpath

Conversation

@tom-snyder

Copy link
Copy Markdown
Member

Summary

R.11 queue re-cut, R.12 correlation, R.13 three-tier read path, R.14 GitHub SARIF projection, R.15 critic, R.16 the spine-mandated conformance harness — completing Phase 1's record area except the R.17 freeze, which is deliberately held until M0.18.

R.15 returned FAIL: 1 blocker, 4 majors, 4 minors, each reproduced with a probe. All fixed, none by weakening a test.

The pattern mattered more than any single defect

Two of R.15's findings were read-gate bypasses. That makes four bypasses found by two different criticsCRITIQUE-02 caught ReadPacket checking nothing and Sealer.Inspect skipping the expiry arm; CRITIQUE-03 caught the GitHub projection ignoring the seal gate entirely, and the read path ignoring audit state so an expired audit stayed fully readable.

Five independent authors each re-derived "is this half readable?" locally, and all five got it wrong differently. So the gate was consolidated rather than patched a fourth time: one halfReadRefusal body, one exported HalfReadGate, and every consumer routed through it. The GitHub projection — the most externally-visible consumer, and the one publishing results from unsealed halves — now ledgers each withheld result under half_not_readable, named that way because the gate also refuses an expired audit holding a cleanly sealed half, where not_sealed would be a lie.

Three rounds of being wrong about the guard

The test meant to stop bypass number five was defeated twice on its first outing — it whitelisted ten return type names, and Result, Run, SARIFLog, []string, []byte weren't among them. Rewritten to walk the call graph with go/ast, it was attacked 16 ways and lost 8, including one needing only a local variable named readOrder, because obedience was matched on an identifier mention rather than a call.

Six holes now closed with a RED proof each: a call is required rather than a mention; the returned error must be used; package-level func values, exported func-typed vars and exported methods on unexported receivers are enumerated; and an allowlist entry carries a hash of the function body, so rewriting an exempted body invalidates the exemption. The allowlist survived every attempt to make it stale or collide.

Attacks 14 and 15 are deliberately not fixed. Whether the seal passed to the gate is the right seal for the results returned is a dataflow question, not a reachability one — and an AST walk pretending to answer it would give exactly the false confidence this exercise exists to prevent.

The limits section is now honest about being incomplete

A second adversary re-ran all 16 (14 caught) and found three more, then judged the KNOWN LIMITS section "adequate for 14 and 15 specifically, but FALSE AS A CENSUS."

That's the criticism worth acting on. The section now says plainly it is not a census, records the three new holes, and states what the guard is — a check against accidental bypass, which is not a small thing given five authors made exactly that mistake — and what it is not: a security boundary. Obedience is matched by name and therefore spoofable. A green run is not evidence that no exported function can leak.

Other work

R.11 demonstrated the priority inversion rather than asserting the constant: with no reserve, the first cut spends all 200,000 tokens on unconfirmed static findings and all five DAST-confirmed findings land in skipped_budget; with the default, they all fit. It also decided CRITIQUE-02 §7 — it does not dispose stale leased rows, because handoff already makes a stale lease inert at the write boundary, and internal/store cannot import internal/handoff (the dependency runs the other way), so doing it there would mean a raw-SQL back door into the lease protocol — the exact defect class G9/G10 closed.

R.16 improved on its brief. The oracle parses the 193-entry reserved-word list and the constants out of FINGERPRINT-SPEC.md at runtime instead of transcribing them, so spec and oracle cannot drift. It closed Appendix Z4 with fixtures whose ordinals must be derived from a batch. All eight existing digests unchanged; fingerprint.go is additions only.

Tier 0 went from 22% to 98% budget utilisation, measured at nine sizes.

Testing

gofmt / vet / build   clean
go test -count=1      green: cmd/anvil, internal/handoff, internal/record, internal/store

-race can't run on this Windows host; CI runs it on Linux and has already caught one real bug there that passed locally.

…onformance

R.11 queue re-cut, R.12 correlation, R.13 three-tier read path, R.14 the GitHub
SARIF projection, R.15 the critic, R.16 the spine-mandated conformance harness.
Plus the fix round for everything R.15 raised, and three rounds of hardening on
the guard that came out of it.

R.15 returned FAIL: one blocker, four majors, four minors, each reproduced with
a probe. All are fixed and none was fixed by weakening a test.

The pattern mattered more than any single defect

Two of R.15's findings were read-gate bypasses. That made FOUR bypasses found by
two different critics: CRITIQUE-02 caught ReadPacket checking nothing and
Sealer.Inspect skipping the expiry arm; CRITIQUE-03 caught the GitHub projection
ignoring the seal gate entirely, and the read path ignoring audit state so an
EXPIRED audit stayed fully readable. Five independent authors each re-derived
"is this half readable?" locally and all five got it wrong differently.

So the gate was consolidated rather than patched a fourth time. halfReadRefusal
is now the single body combining both arms; HalfReadGate is the exported typed
predicate; readpath, taskcard, sarif_github and the sealer all route through it.
The GitHub projection -- the most externally visible consumer in the system, and
the one that was publishing results from unsealed halves -- now ledgers every
withheld result under half_not_readable, a reason named that way because the
gate also refuses an expired audit holding a cleanly sealed half, and
"not_sealed" would have been a lie in that arm.

The guard, and three rounds of being wrong about it

The test meant to stop bypass number five was DEFEATED TWICE on its first
outing: it whitelisted ten return TYPE names, and Result, Run, SARIFLog, []string
and []byte were not among them. Adding LeakResults handed out nine results from
a never-sealed half with the suite green.

Rewritten to reason about the call graph with go/ast, it was then attacked 16
ways and lost 8, including one that needed only a local variable NAMED readOrder,
because obedience was matched on an identifier MENTION rather than a call.

Six of those holes are now closed with a RED proof each: a call is required
rather than a mention; the returned error must actually be used; package-level
func values, exported func-typed vars and exported methods on unexported
receivers are enumerated; and an allowlist entry now carries a hash of the
function BODY, so rewriting an exempted body invalidates the exemption. The
allowlist survived every attempt to make it stale or collide.

Attacks 14 and 15 -- calling the gate against a fabricated seal, and obeying it
for one half then returning both -- are deliberately NOT fixed. Whether the seal
passed to the gate is the RIGHT seal for the results returned is a dataflow
question, not a reachability one, and an AST walk pretending to answer it would
give exactly the false confidence this whole exercise exists to prevent.

And the limits section is now honest about being incomplete

A second adversary re-ran all 16 (14 caught) and found THREE MORE: an error that
is checked but not obeyed, a method promoted from an embedded unexported type,
and minting your own obedience by naming a local func after the gate -- one pair
of parentheses over the attack the previous fix was written against.

It also judged the KNOWN LIMITS section "adequate for 14 and 15 specifically,
but FALSE AS A CENSUS." That was correct, and it is the criticism worth acting
on. The section now says plainly that it is not a census, records the three new
holes, and states what the guard IS -- a check against ACCIDENTAL bypass, which
is not a small thing given five authors made exactly that mistake -- and what it
is NOT: a security boundary. Obedience is matched by name and therefore
spoofable. A green run is not evidence that no exported function can leak.

Other work in this batch

R.11 demonstrated the priority inversion rather than asserting the constant: with
no reserve the first cut spends all 200,000 tokens on unconfirmed static findings
and all five DAST-confirmed findings land in skipped_budget; with the default
they all fit. It also decided CRITIQUE-02 section 7 -- it does NOT dispose stale
leased rows, because handoff already makes a stale lease inert at the write
boundary, and internal/store CANNOT import internal/handoff (the dependency runs
the other way), so doing it here would mean a raw-SQL back door into the lease
protocol: the exact defect class G9/G10 closed.

R.16 improved on its brief. The oracle PARSES the 193-entry reserved-word list
and the constants out of FINGERPRINT-SPEC.md at run time instead of transcribing
them, so spec and oracle cannot drift. It closed Appendix Z4 with fixtures whose
ordinals must be DERIVED from a batch rather than supplied. Every one of the
eight existing digests is unchanged; fingerprint.go is additions only.

Tier 0 went from 22% to 98% budget utilisation, measured at nine sizes.

Evidence: gofmt, vet, build clean; go test -count=1 ./... green across
cmd/anvil, internal/handoff, internal/record, internal/store. -race cannot run
on this Windows host; CI runs it on Linux and has already caught one real bug
there that passed locally.
@tom-snyder
tom-snyder merged commit 19ca758 into main Aug 9, 2026
4 checks passed
@tom-snyder
tom-snyder deleted the feat/phase1-queue-readpath branch August 9, 2026 03:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant