Skip to content

Commit cf684c9

Browse files
docs(dogfood): re-anchor the dead tracker citations in packages/qa/dogfood's files outside src to the commits and ADR that decided them (#20898)
Part of #20594 Clause-②: no ## What changed This is stage 15 of the `domain:cli` lane's dead-citation sweep: **`packages/qa/dogfood`'s dead citations in files outside `src/**`**, the largest package left after stage 14 (claim `5914651671`). The package has no `src/` at all, so the surface is its `test/**`, `README.md`, `tsconfig.json` and `vitest.config.ts`. Every comment site on that surface whose tracker number answers 404 now cites the object that decided what the line describes, in ruling C+D's form C (comment `5749154545` on #19123): the ADR clause when one records the ruling, otherwise the commit in this repository's history. Stages 1 to 14 of this card are the precedents; the latest is PR #20883. - **94 sites on 93 lines in 27 files**, covering **24 numbers**, now cite **24 distinct commits and one ADR clause** (ADR-0029 D9.2a). - The 27 files are `vitest.config.ts` and 26 under `test/**`: 21 test files, 4 helper modules and 1 fixture. - **Comments only.** 93 lines out and 93 in, and every file keeps its line count. A token guard (below) shows zero non-comment tokens changed. - **String literals, `describe` / `it` titles and messages are untouched.** They belong to #20752 (form D, fold `5911936313`); 28 such sites stay on this file list, listed in the acceptance notes. - **No tracker number is added.** The live numbers that share a changed line stay as they were: #4757, #6915, #7987, #8074, #8284, #8408, #9719, #11373 and #17978 all answer 200. - **Sites left without a deciding commit: none.** Every one of the 24 numbers has one. - Where an earlier stage anchored a number and the line here describes the same decision, the same anchor is reused: 16 of the 24 numbers. The other 8 anchors are new (marked below). - A trailing box rule (`── … ─────`) is shortened by the characters its heading gained, never below one dash. Three of the five section headers keep their width; `admin-route-nonadmin-refusal:339` grows by 2 characters and `two-doors-permission:81`, which already ended in one dash, by 11. ## Census **Instrument.** The card's gate does not read these files: its declared surface is `packages/**/src/**`, and `surfaceFor` answers null for all 27 touched paths (the control `packages/cli/src/commands/init.ts` answers `package-docblocks`). So the census is taken by hand, with the gate's own grammar, as stage 14 took it: - **Files:** every tracked file of `packages/qa/dogfood` outside `src/**`, with `CHANGELOG.md` (claim) and `package.json` (not on the claim's list) left out. That is 178 files. - **Extraction:** `extractCitations` from `scripts/check-issue-citations.mjs`, with its comment-prose projection for code and JSONC files and the whole file for `README.md`. The whole-file extraction minus the comment projection gives the string sites. - **Numbers kept:** only those naming this repository (`namesThisRepository`). - **Probe:** each distinct number, `GET /repos/objectstack-ai/objectstack/issues/N`; 404 means dead. | | tree | probe window (UTC) | numbers | answer 200 | answer 404 | dead comment sites | comment sites | dead string sites | |---|---|---|---|---|---|---|---|---| | before | base `4edb61449b` | 2026-09-30 15:46:43 to 15:49:29 | 386 | 359 | 27 | **94** (24 numbers, 27 files) | 1,145 | 28 (13 files) | | after | head `57ffb83b00` | 2026-09-30 15:59:37 to 16:02:15 | 375 | 359 | 16 | **0** | 1,051 | 28 (13 files) | - The before count matches stage 14's census at `660a9b247`: 94 comment sites and 28 string sites in 13 files. - No number present in both probes changed its answer. The 11 numbers that left the census were only on the rewritten lines. - Comment sites fell by exactly 94, the rewritten sites. String sites did not move. - `README.md` cites #2018 and #1994, and `package.json`'s description cites #2018, #1994 and #2004. All answer 200. ## Per-number anchors Each anchor was checked by blame on the site, and in the anchor's own message or diff. "Reused" names an earlier stage that gave the number the same anchor. | number | sites | anchor | what it decided | | |---|---|---|---|---| | `#6293` | 9 | `c39a911ae` | the build stand-in: `build-shaped-artifact.ts` runs the real lowering, and no published surface grows (its subject names the card) | reused (cli `src`) | | `#6483` | 15 | `ee58392e1` | the ADR-0005 rollback of `permission` (and eight more types) to `allowOrgOverride: false`; `allowRuntimeCreate` stays open | reused (spec, plugin-security, runtime) | | `#8460` | 4 | ADR-0029 D9.2a | the ruling itself, 2026-08-13, option A "tenant wins"; implemented in `01a7337fc`, which amends the ADR | reused (spec stage 6) | | `#8676` | 9 | `d6e80b28b` | flags `sys_account.password` and `previous_password_hashes` `internal` | reused (plugin-auth) | | `#8711` | 3 | `2ce1eb41b` | half (2): the ruled narrowing of the matrix's completeness claim to routes (its message records the maintainer ruling) | **new** | | `#8711` | 1 | `60ade586e` | half (1): the two `active` rows with no `covers`, and why (`matrix.ts:393`) | **new** | | `#8811` | 1 | `d6e793507` | adds the `grant-validity-window` matrix row (its subject names the card) | **new** | | `#8839` | 7 | `c25b2d52a` | comment moderation stops being dead behind the delete floor; ruling of 2026-08-15, reading 1 | reused (plugin-security) | | `#8919` | 1 | `b5378550e` | gates `/meta` publish and rollback on `manage_metadata`, with the enumeration pin | reused (rest, runtime, cloud-connection) | | `#9797` | 7 | `1258dcaee` | the PR itself: the opt-in whole-operation dispatch that restores the unscoped multi-delete refusal | **new** | | `#9934` | 2 | `79c46da90` | the producer-side `userMessage` marking, including the QuickJS side-channel | reused (types, rest, client, runtime, plugin-hono-server, spec) | | `#10243` | 1 | `266436a7f` | the toggle ruling: `POST /automation/:name/toggle` joins the `manage_metadata` write set (`automation-toggle-tenant-scope:4`) | reused (runtime, service-automation) | | `#10243` | 1 | `02b41232d` | the measured cross-organization toggle leak ADR-0126 §7.2 retires (`packaged-activation-ledger-reach:291`) | reused (runtime, service-automation) | | `#10943` | 1 | `46d34ab7c` | `fallbackImport` becomes a caller-supplied parameter | reused (types, cli, verify) | | `#10996` | 1 | `02b41232d` | the PR itself, the first landing of this file as a measurement | **new** | | `#11477` | 7 | `6dd3e6968` | `/admin/remove-user` authorizes before the break-glass guard (its message records "Ruled option A on" the card) | reused (plugin-auth, verify) | | `#11530` | 1 | `033a34c7c` | the PR itself: retires the `set_user_role` console action | **new** | | `#11686` | 1 | `7131f12bf` | the PR itself: `hasPlatformAdminStanding` as the one authority | **new** | | `#12176` | 3 | `7986d973f` | stage 3 of the ruled retirement: un-mounts the compound arities, `PUT /meta/:type/:section/:name` among them. The ruling's `D3` ordinal is kept beside it | reused (rest, client, runtime, spec) | | `#12194` | 1 | `311433f6b` | declares the metadata item-name grammar | reused (rest, client, runtime, spec) | | `#13214` | 4 | `cc837dbfe` | the ruled ownership gate at `GET /ui/view/:object/:type`; its diff writes these census lines and its message the 2026-08-30 ruling | reused (rest) | | `#16589` | 4 | `555a89cbd` | `driver-memory` refuses a tenant-scoped call; its diff names the card at every seam | reused (trigger-schedule) | | `#16659` | 6 | `ecdfc9411` | a time-triggered flow declares its acting organization; its diff adds these pins and the fixture. The `F2` ordinal is kept, as the trigger-schedule stage kept it | reused (trigger-schedule, service-automation, spec, lint) | | `#16687` | 1 | `779710213` | the PR itself; its squash carries the contract-review patch round the line describes | **new** | | `#17853` | 1 | `08f5f0e5a` | a vitest filter that selects nothing says so (the same sentence stage 14 rewrote in cli's config) | reused (qa, cli) | | `#19306` | 2 | `f9e16d856` | a packaged permission set's DELETE stops reporting a deletion; its diff adds both pins | **new** | **ADR and ruling records.** A grep of `docs/adr` and `scripts/adr-anchors` for the 24 numbers finds three: #8460, #6483 and #10243. ADR-0029 D9.2a is the ruling for #8460 (it carries the number in its heading), so it is cited. The #6483 hits (ADR-0086, ADR-0094, ADR-0126 and two adr-anchors entries) and the #10243 hits (ADR-0126, ADR-0131) mention those landings as history; none records the ruling itself, so those two stay on the commit every earlier stage anchored them to. The control number `7329` finds 1 file in the same tree. **Anchor checks:** - **Each sha is unambiguous:** `git rev-parse --disambiguate` gives count 1 for each of the 24. - **Each is a plain commit** with one parent. - **Each is on the base:** `merge-base --is-ancestor` against `4edb61449b` exits 0 for all 24. - **The history is complete:** the checkout is not shallow. Control leg: `255588bd36`, the parent of the oldest anchor `ee58392e1` (2026-08-09), exits 0. Negative control: the base as an ancestor of `ee58392e1` exits 1. ## Verification All at head `57ffb83b00`. Heavy runs went through `scripts/pm/os-verify-lock.sh` with `OS_VERIFY_LOCK_SLOT=issue-20594-dogfood`. - **Build (dependency closure):** `pnpm exec turbo run build --filter='@objectstack/dogfood^...' --concurrency=2` → 63 successful, 63 total (32 cached), lock verdict exit 0. - **Every touched test file ran, by name.** Dogfood has two vitest projects (`shared-showcase` and `isolated`) and no tier split, so one run named all 21 touched test files plus the unit tests of the two touched helpers no touched test imports (`authz-probe-blind-spot.test.ts`, the census module's only importer, and `enterprise-organizations.test.ts`): `pnpm --filter @objectstack/dogfood exec vitest run --maxWorkers=2 FILES` → **Test Files 23 passed (23), Tests 317 passed (317)**, lock verdict command-exit 0. `vitest.config.ts` is loaded by that run. - **Typecheck:** `pnpm --filter @objectstack/dogfood typecheck` (`tsc --noEmit`) → lock verdict command-exit 0. `--listFilesOnly` shows 26 of the 27 touched files in the program; the 27th is `vitest.config.ts`. - **Token guard** (TypeScript leaf tokens via `getChildren`, JSDoc nodes skipped), base `4edb61449b` against head, 27 files, 52,502 base tokens: **0 files differ**. Controls, in memory only: a comment inserted into each file, 0 of 27 differ; a statement appended, 27 of 27; one character flipped inside each file's first `StringLiteral`, 27 of 27. - **Control bytes:** a scan of the 27 files finds 0 (positive control, a scratch file holding U+0001: 1). `pnpm check:nul-bytes` exits 0. - **Derived gates and lint:** listed under "Gates". ## Gates All at head `57ffb83b00`, exit codes captured before any pipe. - **Derivation:** `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands`, no paths, derives **53 commands** for this change set (27 paths against merge base `4edb61449b`). Re-derived after two fetches of `origin/main` (to `00a92e18da`, then `33b6e8bece`): the same 53, and none of the upstream commits touches a derivation input or a file here. - **All 53 exit 0.** One needed a second run for a reason outside the diff: `pnpm check:dual-build-cjs-loads` first exited 3 (`PREREQUISITE NOT MET`, no `dist/` for 8 packages outside dogfood's build closure); after `pnpm exec turbo run build --filter='./packages/*' --filter='./packages/*/*' --concurrency=2` (71 of 71, all cached) it exits 0. - **Reconciliation:** `dispatch-gates --ran` over the recorded `COMMAND :: exit CODE` list → "53 derived, 53 run, 0 NOT-MEASURED, 0 UNRUN", exit 0. - **`pnpm lint`** (repo-wide `eslint . --no-inline-config`, the family the derivation does not name) → exit 0, 2026-09-30T16:13:49Z to 16:18:00Z. - `node scripts/check-issue-citations.mjs` (diff mode, in the 53) reads 0 files, because none of these paths is on its declared surface; the hand census above is the measurement for this surface. - A local `git merge-tree --write-tree` of this head against `origin/main` `33b6e8bece` is clean. **The 53 derived commands:** - `node scripts/check-ci-filter-parity.mjs` - `node scripts/check-closing-keyword-parity.mjs` - `node scripts/check-closing-keyword-parity.mjs --self-test` - `node scripts/check-comment-mask-adoption.mjs` - `node scripts/check-comment-mask-adoption.mjs --self-test` - `node scripts/check-comment-mask-corpus.mjs` - `node scripts/check-issue-citations.mjs` - `node scripts/check-keyed-text-bounds.mjs` - `node scripts/check-keyed-text-bounds.mjs --self-test` - `node scripts/check-platform-object-tenancy-census.mjs` - `node scripts/check-platform-object-tenancy-census.mjs --self-test` - `node scripts/check-plugin-teardown-shape.mjs` - `node scripts/check-plugin-teardown-shape.mjs --self-test` - `node scripts/check-registry-log-declared.mjs` - `node scripts/check-registry-log-declared.mjs --self-test` - `node scripts/check-rest-log-spy-declared.mjs` - `node scripts/check-rest-log-spy-declared.mjs --self-test` - `node scripts/check-system-context-census.mjs` - `node scripts/check-system-context-census.mjs --self-test` - `node scripts/check-undeclared-dep-imports.mjs` - `node scripts/check-undeclared-dep-imports.mjs --self-test` - `node scripts/docs-audit/check-affected-docs.mjs` - `node scripts/docs-audit/check-drift-comment.mjs` - `pnpm --filter @objectstack/spec run check:empty-state` - `pnpm --filter @objectstack/spec run check:liveness` - `pnpm --filter @objectstack/spec run check:strictness-ledger` - `pnpm --filter @objectstack/spec run check:variant-docs` - `pnpm check:cross-package-test-inputs` - `pnpm check:dispatcher-error-vocabulary` - `pnpm check:doc-authoring` - `pnpm check:driver-memory-census` - `pnpm check:dts-closure` - `pnpm check:dual-build-cjs-loads` - `pnpm check:engine-double-contract` - `pnpm check:gitlink-declared` - `pnpm check:issue-citations` - `pnpm check:lean-entry-closure` - `pnpm check:logger-receiver-detach` - `pnpm check:nul-bytes` - `pnpm check:objectql-double-limit` - `pnpm check:org-identifier` - `pnpm check:page-declaration-shape` - `pnpm check:published-files` - `pnpm check:query-options-erasure` - `pnpm check:refd-timer-probe` - `pnpm check:slot-lookup` - `pnpm check:sourcemap-no-sources-content` - `pnpm check:test-source-alias` - `pnpm check:tier-file-adoption` - `pnpm check:type-check-coverage` - `pnpm check:type-check-debt` - `pnpm check:watch-hint-literal` - `pnpm check:where-matcher` ## Acceptance notes - **Changeset:** none. `@objectstack/dogfood` is `private: true`, so nothing here publishes; the PR carries `skip-changeset`. - **28 dead string sites stay on this file list** (16 numbers in 13 files: #6293, #6483, #8676, #8710, #8711, #8811, #9934, #10243, #11477, #11530, #11686, #11757, #12176, #13260, #16589, #16659). They are `describe` / `it` titles and string values such as the matrix rows' `note:` text. They belong to #20752 (form D). - **What remains on this card after this stage** (stage 14's census at `660a9b247`, report `5914100460`): 17 comment sites in the other lane packages outside `src/**` (`plugin-hono-server` 4; `plugin-dev`, `client` and `qa/vitest-filter-preflight` 2 each; `cloud-connection`, `mcp`, `qa/downstream-contract`, `rest`, `runtime`, `types` and `verify` 1 each), the five `cli` sites with no deciding commit, and the 55 off-list sites stage 14 listed. None of them is touched here. - **No open PR touches `packages/qa/dogfood`** (all 10 open PRs' file lists read at 2026-09-30T15:56:00Z). The in-flight branch for #20862 adds one new file there, `automation-authoring-doors-durable.dogfood.test.ts`, which is not among these 27. --- _Generated by [Claude Code](https://claude.ai/code/session_01VvcEokUG1tvVxkceYfR5XB)_ Co-authored-by: Claude <noreply@anthropic.com>
1 parent 8fec76a commit cf684c9

27 files changed

Lines changed: 93 additions & 93 deletions

‎packages/qa/dogfood/test/account-oauth-tokens-not-serialized.dogfood.test.ts‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.
22

33
/**
4-
* #7987 (+ #8676) — `sys_account`'s credential columns must not come back on
4+
* #7987 (+ commit d6e80b28b) — `sys_account`'s credential columns must not come back on
55
* the generic data path.
66
*
7-
* [#8676] The file was #7987's three OAuth columns; it now covers the object's
7+
* [commit d6e80b28b] The file was #7987's three OAuth columns; it now covers the object's
88
* other two credential columns as well — `password` and
99
* `previous_password_hashes`, the one-way hashes of ADR-0100's third channel.
1010
* They belong here rather than in a fixture of their own because they are the
@@ -88,9 +88,9 @@ const PLANTED = {
8888
const TOKEN_COLUMNS = ['access_token', 'refresh_token', 'id_token'] as const;
8989

9090
/**
91-
* [#8676] The two one-way password hashes on the same object — ADR-0100's third
91+
* [commit d6e80b28b] The two one-way password hashes on the same object — ADR-0100's third
9292
* channel. They serialized on this very read path alongside the OAuth columns
93-
* (the #8676 key list was captured on this fixture's own ablation run), through
93+
* (commit d6e80b28b's key list was captured on this fixture's own ablation run), through
9494
* the same two barriers that miss them: `collectMaskedReadFields` keys on the
9595
* field TYPE and exempts `managedBy: 'better-auth'`, while these are
9696
* `text` / `textarea`. Asserted through the SAME persona matrix below, because
@@ -277,7 +277,7 @@ describe('#7987: sys_account OAuth tokens never serialize on the generic data pa
277277
assertNoCredentialColumns(row);
278278
}
279279

280-
// [#8676] The same spelling attack aimed at the password hashes, from both
280+
// [commit d6e80b28b] The same spelling attack aimed at the password hashes, from both
281281
// personas. The member's own row is the one that matters most here: the
282282
// `sys_account_self` policy grants the read, so this is a LEGAL request for
283283
// their own record that must still come back without the hash.
@@ -334,11 +334,11 @@ describe('#7987: sys_account OAuth tokens never serialize on the generic data pa
334334
// exactly one predicate — `internal === true` — so a column without the
335335
// flag is refused (ADR-0112 code + status).
336336
//
337-
// ⚠️ Its instance changed with #8676, and only its instance. This test used
337+
// ⚠️ Its instance changed with commit d6e80b28b, and only its instance. This test used
338338
// to spell the predicate with `password`, because #7987 deliberately left
339339
// that column unflagged and the test marked THAT card's scope boundary
340340
// ("a column that is **not flagged** … are deliberately NOT `internal`").
341-
// #8676 flags it, so the premise of `password`-as-example disappears while
341+
// Commit d6e80b28b flags it, so the premise of `password`-as-example disappears while
342342
// the proposition itself is untouched: `scope` is an ordinary unflagged
343343
// `sys_account` column and stands in as the example. What is NOT weakened
344344
// is the guard — no ADR-0100 carve-out was added, and the positive arm
@@ -361,7 +361,7 @@ describe('#7987: sys_account OAuth tokens never serialize on the generic data pa
361361
it('[#8676] `password` and `previous_password_hashes` are stripped, and reachable only through the accessor', async () => {
362362
// The card's own assertions, both directions. These are one-way password
363363
// hashes — ADR-0100's third channel — and they serialized on the generic
364-
// data API before #8676: to an admin for every user's row, and to a member
364+
// data API before commit d6e80b28b: to an admin for every user's row, and to a member
365365
// for their own.
366366
const rows: any[] = await ql.find('sys_account', {
367367
where: { id: memberAccountId },

‎packages/qa/dogfood/test/admin-platform-admin-standing.dogfood.test.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
// hand-roll better-auth's signed-cookie contract with
3131
// `/admin/stop-impersonating` and silently detach the #8243 bearer-rotation
3232
// hook. It is a better-auth PLUGIN endpoint with only the authorization
33-
// predicate replaced, and since #11686 that predicate is the consolidated
33+
// predicate replaced, and since commit 7131f12bf that predicate is the consolidated
3434
// authority `hasPlatformAdminStanding`. `has-permission` (#11900, ruled
3535
// 2026-08-25) is a third shape: a permission QUERY, raw-mounted WITHOUT
3636
// the refusing judge — the platform admin's query is answered from the
@@ -59,7 +59,7 @@
5959
// then folds back into `positions[]`. A working "Set Platform Role"
6060
// button would be a supported, gated, one-user-at-a-time channel for
6161
// resurrecting the dual identity representation the 2026-08-18 Option-3
62-
// veto killed. So the maintainer retired the CONSOLE ACTION (PR #11530)
62+
// veto killed. So the maintainer retired the CONSOLE ACTION (commit 033a34c7c)
6363
// and left the vendor ROUTE mounted and vendor-gated, byte for byte.
6464
//
6565
// ⛔ THEREFORE: a `403` from any of those eight is the system working. Do not

‎packages/qa/dogfood/test/admin-route-nonadmin-refusal.dogfood.test.ts‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@
7676
// gate verdict and not a payload the server rejects for everyone.
7777
//
7878
// `shaded-vendor-gate` (1 route: `remove-user`) — the two halves belong to
79-
// DIFFERENT layers, which is why it is neither of its neighbours. #11477
79+
// DIFFERENT layers, which is why it is neither of its neighbours. Commit 6dd3e6968
8080
// gave the route the raw-mount shading `ban-user` already had, so an
8181
// ObjectStack gate answers the refusal (member 403 PERMISSION_DENIED, anon
8282
// 401 UNAUTHENTICATED) — but the mount DELEGATES rather than
@@ -88,7 +88,7 @@
8888
// The both-sides contrast is therefore not a 2xx but a DIFFERENCE: the
8989
// member and the admin hear two different refusals, which is what proves
9090
// the member's 403 is an authorization verdict and not a blanket refusal.
91-
// The bucket also carries the #11477 negative — a member must never again
91+
// The bucket also carries commit 6dd3e6968's negative — a member must never again
9292
// see the break-glass guard's `409 LAST_LOCAL_CREDENTIAL`, which before the
9393
// shading was answered ahead of every authorization layer and VARIED WITH
9494
// THE TARGET, disclosing per-record state to a caller entitled to none.
@@ -336,7 +336,7 @@ function expectationsFor(targetUserId: string): Record<string, RouteExpectation>
336336
body: { userId: targetUserId },
337337
},
338338

339-
// ── #11477 — shaded for ORDERING, still admitted by the vendor ─────────
339+
// ── Commit 6dd3e6968 — shaded for ORDERING, still admitted by the vendor ─
340340
//
341341
// The only member of its bucket, and the bucket exists because this route
342342
// genuinely has a third shape rather than because the other two did not
@@ -345,7 +345,7 @@ function expectationsFor(targetUserId: string): Record<string, RouteExpectation>
345345
// owned by different layers:
346346
//
347347
// refusal → ObjectStack's gate (403 PERMISSION_DENIED), because the
348-
// mount answers first. That is #11477's whole point: the
348+
// mount answers first. That is commit 6dd3e6968's whole point: the
349349
// break-glass `hooks.before` guard used to answer an
350350
// authenticated non-admin BEFORE any authorization ran, and
351351
// its 409 differed per target — a per-record disclosure.
@@ -634,7 +634,7 @@ describe('#9482 C9: every derived /admin/ route refuses a non-admin', () => {
634634
}, 600_000);
635635

636636
it('the shaded vendor route refuses a non-admin from the ObjectStack gate, before the break-glass guard', async () => {
637-
// #11477. The both-sides contrast here is NOT a 2xx — it is that the two
637+
// Commit 6dd3e6968. The both-sides contrast here is NOT a 2xx — it is that the two
638638
// callers hear DIFFERENT refusals. A member is turned away by ObjectStack's
639639
// gate (`PERMISSION_DENIED`) and a platform admin gets past it only to be
640640
// turned away by the vendor's (`YOU_ARE_NOT_ALLOWED_*`, #9969). Two
@@ -653,7 +653,7 @@ describe('#9482 C9: every derived /admin/ route refuses a non-admin', () => {
653653
expect(member.status, `${route} member: ${member.body}`).toBe(403);
654654
expect(member.code, `${route} member code: ${member.body}`).toBe('PERMISSION_DENIED');
655655

656-
// ⛔ The load-bearing negative. Before #11477 the break-glass
656+
// ⛔ The load-bearing negative. Before commit 6dd3e6968 the break-glass
657657
// `hooks.before` guard answered an authenticated non-admin ahead of every
658658
// authorization layer, and its answer varied with the TARGET — a
659659
// per-record disclosure to a caller entitled to nothing. A member must
@@ -720,7 +720,7 @@ describe('#9482 C9: every derived /admin/ route refuses a non-admin', () => {
720720
// transaction, so this route answers the authorization question like
721721
// every other member of the bucket and needs no exception.
722722
//
723-
// ⚠️ #11477 moved `remove-user` OUT of this bucket entirely — its raw
723+
// ⚠️ Commit 6dd3e6968 moved `remove-user` OUT of this bucket entirely — its raw
724724
// mount now answers a member from ObjectStack's gate
725725
// (`403 PERMISSION_DENIED`) before better-auth is reached at all, so the
726726
// vendor-vocabulary rule below no longer describes it. It lives in

‎packages/qa/dogfood/test/attachments-unscoped-delete-gate.dogfood.test.ts‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
// "refused outright (#4757)", on the reasoning that "nothing was ever queried"
1010
// must not read as "nothing to authorize". `attachment-access-hooks.ts` carries
1111
// exactly that refusal, and `attachment-access-hooks.test.ts` pins it against a
12-
// wired engine (#9797). This file pins it END TO END, on the real stack, where
12+
// wired engine (commit 1258dcaee). This file pins it END TO END, on the real stack, where
1313
// RBAC and plugin-sharing are in the path and the session is a real one.
1414
//
1515
// ## History — this file's original verdict has been OVERTAKEN, twice
@@ -20,7 +20,7 @@
2020
// the `where === undefined` check. That was a PRODUCT gap (#9719), and this
2121
// file deliberately declined to pin the behaviour of the day.
2222
//
23-
// It has since been fixed. #9719/PR #9797 added an opt-in whole-operation
23+
// It has since been fixed. #9719/commit 1258dcaee added an opt-in whole-operation
2424
// dispatch to the engine, which #9974 renamed `dispatchUnscopedMultiWrite` when
2525
// it was ruled onto `beforeUpdate` as well. `attachment-access-hooks.ts`
2626
// declares it on both sys_attachment write registrations, so the #4757 refusal
@@ -35,7 +35,7 @@
3535
// properties that look identical on a fixture whose rows split entitled/not —
3636
// which is exactly the fixture the first block below uses. Measured on this
3737
// suite: with `dispatchUnscopedMultiWrite` removed from BOTH registrations and
38-
// service-storage rebuilt (the pre-#9797 world), the first block stays 5/5
38+
// service-storage rebuilt (the world before commit 1258dcaee), the first block stays 5/5
3939
// GREEN. It cannot see the refusal it is named for.
4040
//
4141
// So the second block seeds the ONE fixture that separates them: a caller who
@@ -163,7 +163,7 @@ describe('sys_attachment delete gate under an unscoped multi-delete (#9483)', ()
163163

164164
it('an unscoped multi-delete is refused OUTRIGHT — on its shape — and deletes NOTHING', async () => {
165165
// `{ multi: true }` with neither id nor where composes an AST over the whole
166-
// table. Since #9797 the refusal that answers is #4757's whole-operation
166+
// table. Since commit 1258dcaee the refusal that answers is #4757's whole-operation
167167
// one, dispatched BEFORE any row is resolved — not the per-row gate, which
168168
// on this fixture would also have refused (the member is the uploader of
169169
// one row and neither uploader nor parent-editor of the other).
@@ -193,7 +193,7 @@ describe('sys_attachment delete gate under an unscoped multi-delete (#9483)', ()
193193

194194
it('an empty `where: {}` reaches the same verdict by a DIFFERENT rule — the per-row gate', async () => {
195195
// ⚠️ Same outcome, deliberately different mechanism, and the difference is
196-
// load-bearing. #9797 scoped the whole-operation dispatch to a delete with
196+
// load-bearing. Commit 1258dcaee scoped the whole-operation dispatch to a delete with
197197
// NO `where` at all; a match-all `where: {}` is a real query, so it is NOT
198198
// refused on shape — it is refused here only because this caller cannot
199199
// have the foreign row. Asserting the per-row message is what keeps that
@@ -259,7 +259,7 @@ describe('sys_attachment delete gate under an unscoped multi-delete (#9483)', ()
259259
// whole-operation rule or from the per-row gate, because that fixture holds one
260260
// row the caller may not touch. Here the caller uploaded BOTH rows, so the
261261
// per-row gate has nothing to refuse — anything that still refuses is refusing
262-
// the SHAPE. Pre-#9797 this exact call resolved and emptied the table.
262+
// the SHAPE. Before commit 1258dcaee this exact call resolved and emptied the table.
263263
// ─────────────────────────────────────────────────────────────────────────────
264264

265265
describe('sys_attachment unscoped multi-delete is refused on its SHAPE, not on entitlement (#9483)', () => {
@@ -352,7 +352,7 @@ describe('sys_attachment unscoped multi-delete is refused on its SHAPE, not on e
352352
});
353353

354354
it('refuses `{ multi: true }` with no id and no where — even though the caller may delete every matched row', async () => {
355-
// #9719's measured wipe, end to end: before PR #9797 this call RESOLVED and
355+
// #9719's measured wipe, end to end: before commit 1258dcaee this call RESOLVED and
356356
// took both rows (2 -> 0). The per-row gate licenses each row individually,
357357
// so nothing but the whole-operation #4757 rule can refuse here — which is
358358
// what makes this the case that detects its removal.

‎packages/qa/dogfood/test/authz-conformance.matrix.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@
9393
// silencing that particular red costs an enforcement site rather than a
9494
// `covers` append on a row that records an absence.
9595
//
96-
// [#8711] That completeness is over ROUTES, not over primitives: a primitive
96+
// [commit 2ce1eb41b] That completeness is over ROUTES, not over primitives: a primitive
9797
// enforced by a predicate inside an existing resolver adds no entry point, so
9898
// it can be neither UNCLASSIFIED nor STALE. Measured against the rows below:
9999
// 44 of 51 carry no `covers` key at all (7 rows, 15 keys, every one an
@@ -390,12 +390,12 @@ export const AUTHZ_CONFORMANCE: AuthzPrimitive[] = [
390390
// mass-revoked) and the 0/1 storage shape the primary driver returns is
391391
// judged as well as a literal `false`.
392392
//
393-
// [#8711] Both rows carry NO `covers`, and that is a statement about the
393+
// [commit 60ade586e] Both rows carry NO `covers`, and that is a statement about the
394394
// RATCHET, not an omission: `discover()` enumerates HTTP entry points from a
395395
// curated per-file probe table, and a predicate inside an existing resolver
396396
// adds no entry point — so neither flag could ever have surfaced as
397397
// UNCLASSIFIED during the whole period it was inert. These two rows restore
398-
// the ledger's stated invariant. [Resolved — maintainer ruling on #8711,
398+
// the ledger's stated invariant. [Resolved — maintainer ruling (commit 2ce1eb41b),
399399
// 2026-08-15] The invariant's advertised SCOPE is narrowed to what the
400400
// ratchet can check, not the ratchet widened to reach in-resolver
401401
// predicates like this one — widening was measured unachievable in general
@@ -408,7 +408,7 @@ export const AUTHZ_CONFORMANCE: AuthzPrimitive[] = [
408408
enforcement: 'core/security/resolve-authz-context.ts step 6a — isRowActive gates BOTH halves, and only both hold it: (i) only ACTIVE position ids collect their `sys_position_permission_set` linkage, so a deactivated position carries no bound set; (ii) the deactivated NAME is dropped from `grants.positions`, because resolvePermissionSetsForContext requests positions as permission-set NAMES and a name left standing resolves the same grant one layer down',
409409
note: 'Only a name whose `sys_position` row is EXPLICITLY deactivated is dropped — a name with no row at all (`org_owner`, a membership-derived role, the built-in `everyone` audience anchor) has no flag to read and is untouched. Deliberately NOT a blanket revocation of the sets themselves: a set held via BOTH a deactivated position AND a direct user grant still resolves, since the direct grant is a different grant (resolve-authz-context.test.ts pins exactly that case). Symmetrically, the WRITE gates and blast-radius reads in plugin-security (assertAudienceAnchorBindingGate, setsBoundToPosition, the delegated-admin surfaces) stay UNFILTERED on purpose — dropping a deactivated row there would make a refused binding permitted, narrow a delegate\'s boundary, and make a deactivated position unmanageable. Unit-proven in core/security/resolve-authz-context.test.ts (a deactivated position stops granting its sets; an active one still grants; an absent column grants; the 0/1 shape deactivates; deactivating ONE position leaves the others granting) + core/security/row-active.test.ts. Not HIGH_RISK for the same reason as `permission-set-active`.' },
410410

411-
// ── ADR-0091 D1/D2 — grant validity windows (#8811) ───────────────────
411+
// ── ADR-0091 D1/D2 — grant validity windows (commit d6e793507) ────────
412412
//
413413
// The sibling of the `active` switch above, and enforced at the same seam
414414
// for the same stated reason: a grant that is supposed to lapse on a date,

‎packages/qa/dogfood/test/authz-conformance.test.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// ADR-0056 D10 — the authorization conformance matrix is a CHECKED artifact,
44
// within the scope the mechanism can see: routes are ratcheted, primitives are
55
// hand-maintained (see the matrix's own header for the narrowed claim and the
6-
// measured numbers — #8711). Refactored onto the reusable ADR-0060
6+
// measured numbers — commit 2ce1eb41b). Refactored onto the reusable ADR-0060
77
// `checkLedger` helper: one call asserts every shared invariant (valid state,
88
// enforced-has-site, experimental/removed-has-note, proof-file-exists,
99
// high-risk-has-proof). A row that regresses one of THOSE invariants, or a

‎packages/qa/dogfood/test/authz-probe-blind-spot.census.ts‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -431,9 +431,9 @@ export const PROBE_FILE_CENSUS: readonly ProbeFileReading[] = [
431431
// `this.routeManager.register(` reads 73 because the helper's forwarder is
432432
// one of them, and it is sliced out before counting.
433433
//
434-
// [#13214] `enforceAuth` 61 -> 64. ⛔ RE-ANCHORED, not relaxed: the control
434+
// [commit cc837dbfe] `enforceAuth` 61 -> 64. ⛔ RE-ANCHORED, not relaxed: the control
435435
// exists to prove this census is still reading the file it thinks it is, and
436-
// a rising `enforceAuth` is precisely what the 2026-08-30 ruling on #13214
436+
// a rising `enforceAuth` is precisely what the 2026-08-30 ruling (commit cc837dbfe)
437437
// was supposed to cause — `registerUiEndpoints` was the ONE route in this
438438
// file that resolved no identity, and it is now guarded. The move is +3 over
439439
// the whole file (`occurrences` counts the bare term, comments included):
@@ -445,9 +445,9 @@ export const PROBE_FILE_CENSUS: readonly ProbeFileReading[] = [
445445
// ⚠️ The three sibling numbers were re-derived and did NOT move, which is
446446
// what says this is a guard change and not a surface change: `population`
447447
// 80, `reachable` 19, `private register*Endpoints(` 17 and
448-
// `this.routeManager.register(` 80 are all unchanged — #13214 added no route
448+
// `this.routeManager.register(` 80 are all unchanged — commit cc837dbfe added no route
449449
// and no registrar. `blindSpot` therefore stays 61 as well.
450-
// ⚠️ That last figure is the reading AS OF #13214 and is left as written:
450+
// ⚠️ That last figure is the reading AS OF commit cc837dbfe and is left as written:
451451
// the control is 73 today for the spelling reason recorded above, and the
452452
// population it feeds is still 80. Do not "correct" the paragraph — it is a
453453
// dated measurement, not a live claim.

0 commit comments

Comments
 (0)