Skip to content

[finding] The authz conformance ledger checks only that a cited proof FILE EXISTS, never that it proves the row #7976

Description

@hotlong

Symptom

AUTHZ_CONFORMANCE (packages/qa/dogfood/test/authz-conformance.matrix.ts) is the durable encoding of the ADR-0056 D10 audit: one row per authorization primitive, enforced rows naming their runtime site, high-risk rows additionally citing an end-to-end dogfood proof. Its own file header states the contract:

The companion test (authz-conformance.test.ts) asserts the matrix is complete and that every referenced proof file exists

That is exactly what it does, and no more. checkLedger (packages/verify/src/conformance.ts:77):

if(r.proof&&!existsSync(join(opts.proofRoot,r.proof)))problems.push(`${r.id}: proof missing on disk: ${r.proof}`);

Existence — not that the proof proves the row. So a row may cite a file that exercises a neighbouring primitive and stay green forever. The shape is not hypothetical bookkeeping: rls-read (:37) and rls-by-id-write (:39) cite the same file, rls-fixture.dogfood.test.ts, and nothing in CI distinguishes "this file proves both" from "this row is borrowing the other's credibility".

Why it matters

This is the ADR-0049 declared ≠ enforced shape one layer up: the record of enforcement is gated, but the gate cannot see whether the record is true. A false enforced survives a green CI indefinitely, and the matrix is the artifact ADR-0056 D10 exists so that reviewers do not have to re-derive the audit by hand.

Evidence it is the live mechanism, not a theoretical one

Investigated under #7685 / PR #7975. Both rows the card accused (rls-by-id-write, controlled-by-parent) turned out to be correctlyenforced — each cited proof was checked line by line and both genuinely exercise their primitive with a persona holding full object CRUD, so refusals are the record gate. The point is that establishing that took a manual read of two proof files and a live ablation; no gate could have told the reviewer either way, which is precisely the gap.

That review did surface one thing the gate would also not have caught: rls-by-id-write's enforcement field named only the #1994 pre-image re-read, which the ablation proved is a no-op on its own under select-only authoring (16 of 20 probed showcase objects became rls-hole with that re-read fully present). Corrected in PR #7975 — by hand, by eye.

Repro

  1. packages/qa/dogfood/test/authz-conformance.matrix.ts:37,39 — two rows, one proof file.
  2. packages/verify/src/conformance.ts:77 — the only assertion made about proof.
  3. Point any enforced row's proof at an unrelated but existing dogfood test file → authz-conformance.test.ts stays green.

Suggested direction (not prescriptive)

Bind row → proof by name, not just by path. Several dogfood proofs already carry a @proof: <id> tag in their header for the spec liveness registry (packages/spec/scripts/liveness/proof-registry.mts), e.g. rls-fixture.dogfood.test.ts carries @proof: rls-by-id-write. Reusing that channel would make a row's citation checkable.

⚠️ It is not a drop-in: the liveness ids and the matrix row ids are different vocabularies today (controlled-by-parent.dogfood.test.ts is tagged @proof: cbp-controlled-by-parent while its matrix row id is controlled-by-parent), and most cited proofs carry no tag at all. So this needs a deliberate reconciliation across ~30 rows — a ratchet with a measured starting ledger, not a flag flip. Sizing that is the first task, not the fix.

Source

Found while executing #7685 items (i)/(ii) (PR #7975). Filed unassigned — recording a finding, not claiming it.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions