Skip to content

Pin why an inclusion receipt was refused - #354

Open
jasonodoom wants to merge 1 commit into
mainfrom
gates-reject-reasons
Open

Pin why an inclusion receipt was refused#354
jasonodoom wants to merge 1 commit into
mainfrom
gates-reject-reasons

Conversation

@jasonodoom

Copy link
Copy Markdown
Contributor

First slice of the gates stream. It resets no soak window: no runtime decision
changes, only what the corpus asserts and what the runners check.

The problem

The pre-1.0 audit measured 397 of 655 reject vectors asserting a verdict and
nothing else. A vector that pins only "reject" is satisfied by a refusal from
any check, so a verifier that never reaches the proof walk passes every proof
case. That is the same weakness that let schema-invalid-non-array-signing-reject
sit green while a real authentication bypass was live in #352: it rejected, for
an unrelated reason.

This does one surface end to end as the pattern for the rest.

What changed

All 33 inclusion-receipt reject vectors now name the check that must refuse
them: structure 13, signature 8, proof 8, checkpoint 4. Both runners assert it.
The step was derived from the reference and reviewed case by case against the
vector names, then confirmed against Go.

Go gained VerifyInclusionReceiptStep beside the existing verdict, using the
reference's step vocabulary. VerifyInclusionReceipt keeps its signature.

The generator throws if a reject vector has no declared step, so this cannot
regress by adding a vector.

Two gate defects found while doing it

The Go test cache does not track the corpus files the tests read. Mutating an
expected step and re-running reported ok in 0.004 seconds with nothing caught;
the same run with -count=1 caught it. Every conformance invocation now passes
-count=1, and check:facts fails any that does not, so a corpus edit cannot
be validated against a cached pass.

A reject vector whose input the Go parser refused at the boundary skipped every
assertion, verdict included, so a parser that refused everything satisfied it.
A boundary refusal is a structural rejection and is asserted as one now.

A divergence this surfaced

Three cases refuse at the parse boundary in Go and at a later step in the
reference: surrogate-in-event-rejects and null-event-rejects reach proof,
and surrogate-in-event-id-rejects reaches signature. The enforcement order in
ink-signed-string-safety.md requires the raw-text checks, unpaired surrogates
among them, to run before the JSON is parsed. The Go runner hands its verifier
raw bytes so they do; the reference verifier takes an already-parsed object, so
the same input travels further before being refused. Both reject, so this is a
question of where rather than whether, and it is independent evidence for the
existing raw-gate finding. The three are listed by name in the runner so the
set cannot widen quietly.

Verification

Mutating one expected step fails both runners. 2405 TypeScript tests, the Go
suite with -count=1, typecheck and check:facts all pass.

Not in this change

The other surfaces the audit names, fetch, encryption and key-rotation, need a
reason from the library before their vectors can assert one. Same pattern,
separate changes.

All 33 reject vectors on this surface asserted a verdict and nothing else, so a
verifier that refused for an unrelated reason satisfied every one of them. Each
now names the check that must refuse it, both runners assert it, and the
generator will not emit a reject vector without one.

Two gate defects surfaced while doing it. The Go test cache does not track the
corpus files the tests read, so a mutated expectation reported ok in 0.004
seconds and caught nothing, where the same run with -count=1 caught it. And a
reject vector whose input the Go parser refused at the boundary skipped every
assertion, so a parser that refused everything satisfied it.

Three cases refuse at the boundary in Go and at a later step in the reference,
because the raw-text checks required before the parse run there and not in the
reference, which is handed an already-parsed object. They are listed by name
rather than hidden.

Signed-off-by: Jason Odoom <jason@adastracomputing.com>
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