From 6b93739126dbdf1575a9a5d5e69c4463300b5c03 Mon Sep 17 00:00:00 2001 From: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Date: Fri, 31 Jul 2026 12:36:41 +0800 Subject: [PATCH] chore(spec): the field-file collection proof stops being an orphan tag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `packages/qa/dogfood/test/field-file-collection.dogfood.test.ts` declares `@proof: adr0104-field-file-collection`, but the ADR-0054 registry never learned about it — so the liveness gate has been warning on every run since #4285 landed the test: ⚠ 1 unregistered dogfood proof tag(s) — add to proof-registry.mts That warning is the registry's reverse-integrity leg doing exactly its job: an orphan tag means a proof was written but never wired into the high-risk class list, so nothing connects the test to the surface it guards. Registered as **honestly unbound**, not bound. The collection contract the proof exercises is the `lifecycle` ttl declared on the SYSTEM object `sys_file` (service-storage), not an authorable per-type property — and `object.lifecycle` is already bound to `data-lifecycle`, which carries one `proof` ref. The rest of the route (exclusive ownership, release-on-write, the per-deployment migration gate) is service code with no authorable surface to govern, so there is no other entry to bind instead. Faking a binding would misrepresent both what the proof covers and what that entry is proven by; `blockedReason` records the reason instead, the same shape as `flow-runas-userless` and `scope-depth-cli-fallback`. Enforcement is therefore unchanged: `BOUND_PROOF_PATHS` skips unbound classes, so the bound-class list and the pinned path map are byte-identical. The only behavioural change is that the gate now runs clean. Verification: `check:liveness` green with the warning gone; liveness script suite 98/98; spec suite 277 files / 7128 tests; `tsc --noEmit` clean. Gate-only change under `packages/spec/scripts/`, which is not in the package's published `files` — empty changeset. Co-Authored-By: Claude Opus 5 --- .../register-field-file-collection-proof.md | 4 ++++ .../spec/scripts/liveness/proof-registry.mts | 24 +++++++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 .changeset/register-field-file-collection-proof.md diff --git a/.changeset/register-field-file-collection-proof.md b/.changeset/register-field-file-collection-proof.md new file mode 100644 index 0000000000..81e1f0b54c --- /dev/null +++ b/.changeset/register-field-file-collection-proof.md @@ -0,0 +1,4 @@ +--- +--- + +chore(spec): register the `adr0104-field-file-collection` dogfood proof tag in the ADR-0054 registry, honestly unbound — the collection contract it guards is `lifecycle` on the system `sys_file` object, already bound to `data-lifecycle`. Gate-only (`packages/spec/scripts/`, not published), so this releases nothing. diff --git a/packages/spec/scripts/liveness/proof-registry.mts b/packages/spec/scripts/liveness/proof-registry.mts index 1a6416cc7c..2d63492a9a 100644 --- a/packages/spec/scripts/liveness/proof-registry.mts +++ b/packages/spec/scripts/liveness/proof-registry.mts @@ -482,6 +482,30 @@ export const HIGH_RISK_CLASSES: HighRiskClass[] = [ + 'one entry would misrepresent both what it covers and what that entry is proven by. The ' + 'per-property bindings above carve out the parts that do have a single owner.', }, + { + id: 'field-file-collection', + label: 'Field-file collection (ADR-0104 PR-5b)', + summary: + 'a field file released by its ONE owning record is tombstoned, and the sweep reclaims the row AND ' + + 'the storage bytes once the declared window passes — with both vetoes intact: a tombstone that ' + + 'regained an owner is un-tombstoned rather than reaped, and a REGRESSED migration flag stops ' + + 'collection immediately (the guard re-reads the flag at sweep time instead of trusting the ' + + 'memoized read the release path uses). This is the only code on the platform that deletes a ' + + "user's bytes, and its sibling lineage — attachments — has had an end-to-end proof since #2755 " + + 'while field files, which reach collection by a different route (exclusive ownership, released ' + + 'by the write path, gated per deployment), had none.', + proofId: 'adr0104-field-file-collection', + proofRef: 'packages/qa/dogfood/test/field-file-collection.dogfood.test.ts#adr0104-field-file-collection', + bound: false, + ledgerBindings: [], + blockedReason: + 'the collection contract it guards is the `lifecycle` ttl declared on the SYSTEM object `sys_file` ' + + '(service-storage), not an authorable per-type property — and `object.lifecycle` is already bound ' + + 'to `data-lifecycle`, which carries one `proof` ref. The rest of the route (exclusive ownership, ' + + 'release-on-write, the per-deployment migration gate) is service code with no authorable surface ' + + 'to govern, so there is no other entry to bind instead. It runs unconditionally in the dogfood ' + + 'suite.', + }, ]; /** Bound ledger paths → the class that binds them. Key: `/`. */