From 846750da14b65d6ae6c1076706db8a0a1dd755c3 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 26 Aug 2026 09:43:46 +0000 Subject: [PATCH 1/2] chore(spec): register the dogfood proof tag `admin-platform-admin-standing` --- .../spec/scripts/liveness/proof-registry.mts | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/packages/spec/scripts/liveness/proof-registry.mts b/packages/spec/scripts/liveness/proof-registry.mts index 11f63680f9..51066bfc84 100644 --- a/packages/spec/scripts/liveness/proof-registry.mts +++ b/packages/spec/scripts/liveness/proof-registry.mts @@ -791,6 +791,54 @@ export const HIGH_RISK_CLASSES: HighRiskClass[] = [ // for a property it does not exercise. ledgerBindings: [{ type: 'permission', path: 'fields.readable' }], }, + + // ───────────────────────────────────────────────────────────────────────── + // 2026-08-26 round — ONE tag, and the reason it is worth a paragraph is that + // it is a RECURRENCE of the block above: the 2026-08-21 round registered the + // eleven tags that existed then, and a twelfth arrived with the next dogfood + // proof. Registering instances one round at a time never closes the class, + // because the drift signal was a ⚠ that nothing failed on — so the gate is + // switched to red in the same PR (check-liveness.mts), which is the half + // that stops a thirteenth. + // + // Direction of drift, decided by reading both sides rather than assuming: + // the REGISTRY lagged. `admin-platform-admin-standing` is not a misspelling + // of an already-registered tag — the file names itself, its tag and its + // sibling (`admin-route-nonadmin-refusal`, registered above) distinctly, and + // no registered id is within a typo of it. + // ───────────────────────────────────────────────────────────────────────── + + { + id: 'admin-platform-admin-standing', + label: 'Platform-admin standing across the /admin/ route surface', + summary: + 'the DUAL of `admin-route-nonadmin-refusal`, over the same derived `/admin/` route population: ' + + 'no route refuses a genuine ADR-0068 platform admin unless the refusal is a RECORDED by-design ' + + 'ruling (#9969\'s seven consumer-less vendor routes, #9968\'s `set-role`). better-auth\'s stock ' + + 'admin plugin authorizes on the legacy `user.role === \'admin\'` scalar that ADR-0068 D2 stopped ' + + 'synthesizing, so the vendor\'s own endpoints refuse a real platform admin — and this file is ' + + 'what keeps that answer a ruled outcome instead of an unread gap. Two anti-vacuity pins carry ' + + 'it: the subject\'s standing is asserted as a CONTROL before any route answer is read ' + + '(`positions[]` contains `platform_admin`, `isPlatformAdmin` true, `sys_user.role` NOT ' + + '`\'admin\'` — the fixture a real deployment has, not the `role = \'admin\'` scalar the unit ' + + 'tests write), and every route is fired with a payload valid enough to REACH the gate, because ' + + 'better-auth validates the body BEFORE the admin check and an empty-body sweep draws a ' + + '`400 VALIDATION_ERROR` byte-identical for member and admin while looking exactly like a ' + + 'passing security suite.', + proofId: 'admin-platform-admin-standing', + proofRef: + 'packages/qa/dogfood/test/admin-platform-admin-standing.dogfood.test.ts#admin-platform-admin-standing', + bound: false, + ledgerBindings: [], + blockedReason: + 'platform-admin standing is the ADR-0068 D2 identity resolution (`positions[]` / ' + + '`isPlatformAdmin`, consolidated since #11686 as `hasPlatformAdminStanding`) evaluated inside ' + + 'the auth plugin\'s route gate — runtime principal resolution, not an authorable per-type ' + + 'property, so there is no metadata key whose `live` status it gates. It is also a BREADTH guard ' + + 'over a DERIVED route population, the `admin-route-nonadmin-refusal` / `permission-model-zoo` ' + + 'shape: binding it to any single entry would misrepresent both what it covers and what that ' + + 'entry is proven by. It runs unconditionally in the dogfood suite.', + }, ]; /** Bound ledger paths → the class that binds them. Key: `/`. */ From b884d562277038c191f99aa5aa092a75713b1bc4 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 26 Aug 2026 09:44:56 +0000 Subject: [PATCH 2/2] feat(spec): fail check:liveness on an unregistered dogfood proof tag --- .../spec/scripts/liveness/check-liveness.mts | 42 +++++++++++++++++-- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/packages/spec/scripts/liveness/check-liveness.mts b/packages/spec/scripts/liveness/check-liveness.mts index b8fc0a0399..5e9931e0cc 100644 --- a/packages/spec/scripts/liveness/check-liveness.mts +++ b/packages/spec/scripts/liveness/check-liveness.mts @@ -582,7 +582,17 @@ function classify(type: string, path: string, status: string, led: any, cat: any // Reverse integrity: every `@proof:` tag declared under the dogfood proof tree // must be registered in proof-registry.mts. An orphan tag means a proof was -// written but never wired into the high-risk-class list — flag it (warning). +// written but never wired into the high-risk-class list. +// +// RED since 2026-08-26, having been a ⚠ before. The warning was calibrated for +// a backlog era — it reported 13 orphan tags at once, then 11 — and a signal +// that never fails the build cannot close the class it names: the 11 were +// registered in one round, a 12th arrived with the next dogfood proof, and the +// second card was written from the same ⚠ line as the first. The census that +// licenses the flip is that round's own arithmetic: the list is at ZERO on the +// commit this changes, so the gate starts green and only a NEW unregistered tag +// can red it — the same "a check that starts at zero can be red" reasoning the +// key-mention half was switched on under. function scanOrphanProofs() { const proofDir = join(repoRoot, 'packages/qa/dogfood/test'); if (!existsSync(proofDir)) return; // spec may be consumed standalone (published) @@ -820,6 +830,10 @@ const failed = // be red; that is the whole reason the census came first. report.keyMentionUnanchored.length > 0 || report.keyMentionStale.length > 0 || + // A dogfood `@proof:` tag the registry never learned about. Red rather than ⚠ + // since 2026-08-26 — see scanOrphanProofs for why the warning could not close + // the class, and for the zero-census that lets this start green. + report.orphanProofs.length > 0 || report.orphanEntries.length > 0 || report.verification.errors.length > 0 || report.producers.errors.length > 0 || @@ -937,8 +951,29 @@ if (asJson) { ); } if (report.orphanProofs.length) { - console.log(`\n⚠ ${report.orphanProofs.length} unregistered dogfood proof tag(s) — add to proof-registry.mts:`); + console.log(`\n✗ ${report.orphanProofs.length} unregistered dogfood proof tag(s) — add to proof-registry.mts:`); report.orphanProofs.forEach((s: string) => console.log(` ${s}`)); + console.log( + '\n A `@proof:` tag on disk that the registry does not know is a proof no ledger entry\n' + + ' can cite: `BOUND_PROOF_PATHS` is built from HIGH_RISK_CLASSES, so an unregistered\n' + + ' proof cannot bind a `live` verdict however thoroughly it runs.\n\n' + + ' Add a HIGH_RISK_CLASSES entry in proof-registry.mts. Registering is mechanical;\n' + + ' the judgment half is `bound`. Read the proof file and ask: is there an AUTHORABLE\n' + + ' property whose `live` status it actually gates?\n' + + ' • yes → `bound: true` + the `ledgerBindings` entry, and put the same `proof` ref\n' + + ' on that ledger row (the wiring test in proof-registry.test.ts holds both ends);\n' + + ' • no → `bound: false` + a `blockedReason` naming what it guards INSTEAD (a\n' + + ' runtime/service invariant, a breadth sweep, or an entry already spoken for —\n' + + ' a ledger row carries one `proof` ref). Registered-and-honestly-unbound is a\n' + + ' first-class outcome; most of the registry is exactly that.\n' + + ' ⛔ Do not bind a proof to a property it does not AUTHOR just to reach `bound: true`\n' + + ' — a citation for a property the proof never exercises is the false comfort the\n' + + ' whole ledger exists to end.\n\n' + + ' This was a ⚠ until 2026-08-26. It reported 13 tags, then 11, and a warning nothing\n' + + ' fails on cannot close a class: the 11 were registered in one round and a 12th\n' + + ' arrived with the next dogfood proof, its card written off the same ⚠ line. The list\n' + + ' was at zero when this became red, so a hit here is a NEW tag, not a backlog.', + ); } if (report.proofMissing.length) { console.log(`\n✗ ${report.proofMissing.length} high-risk 'live' propert(ies) missing a runtime proof:`); @@ -1168,7 +1203,8 @@ if (asJson) { 'every container inheritance is declared, every `live` entry\'s repo-local evidence path ' + 'resolves, every `path:NNN` citation names a line that file actually has and every cited ' + 'file names the property it is evidence for (or is a recorded exemption), all bound ' + - 'high-risk proofs resolve, and the README state table carries a row ' + + 'high-risk proofs resolve, every dogfood `@proof:` tag on disk is registered in ' + + 'proof-registry.mts, and the README state table carries a row ' + `for each of the ${report.readmeRowCount} governed type(s) it claims to index.`, ); console.log(