Skip to content

Commit 9a4b2bb

Browse files
docs(plugin-security): re-anchor the dead tracker citations to the commits and ADRs that decided them (#20658)
Part of #20596 Clause-②: no ## What changed This is the fourth stage of the `domain:services` lane of the dead-citation sweep. It covers `packages/plugins/plugin-security/src/**` and nothing else. By census it is the largest package in the lane; it waited while its own fixes were in flight, and the claim (`5890784382`) records that they have all landed. Later stages cover the other packages, so this PR says `Part of` and the card stays open. Every comment or docblock site in scope that cited a tracker number answering 404 has been rewritten in ruling C+D's form C (comment 5749154545 on #19123), by the method of stages 1 to 3 (PR #20609 as `422db788a`, PR #20626 as `b80ab579d`, PR #20634 as `4d04b6be3`). That is **266 sites on 258 lines in 51 files, covering 40 numbers**: - 140 census sites (all of this package's census sites except the 3 generated headers, see below); - 123 sites in test comments, which the census defers; - 3 sites in comment prose that the gate's extractor does not match at all: one hyphen-joined (`#8919-era`) and two slash-joined second numbers (`#6483/#6608`, `#11184/#11343`), see Acceptance notes. Each rewritten line now cites the record in this repository that decided what the line describes, and says in its own words what was decided. Two numbers have an in-repo decision record, and it is preferred: `#11082` cites **ADR-0055's amendment** (2026-09-07, transitive chains compose), and `#6609` cites **ADR-0094 D5-R**, which records that conflict ruling (option A, accept the tightening). Every other number cites the commit in `origin/main` history that decided it: **36 distinct shas**. Three pairs share one anchor because one number was the pull request that settled the other (`#6483` and `#6608`, `#16607` and `#16722`, `#16608` and `#16805`); `#12143` was itself a pull request, and its squash commit `f64668d3c` is also where route A (`#11374`) reached this plugin's key columns. No number was dropped. Only comments changed. Every touched source file keeps its line count (266 lines out, 266 in, over 51 files), so no line citation into these files moves. 8 of those 266 lines hold no dead citation; they are reflow, listed under Wordings below. No code token moves (see the guard below). **No citation number is added.** Every tracker number on an added line was already on the line it replaces. Over the whole diff, added minus removed is 0 or negative for every number (the gate's own `extractCitations` over the diff: 277 citations removed, 14 added, all 14 kept resolving numbers on the lines they already stood on), and no number is new to the diff. No PR number stands on an added line. Sixty-five dead sites are left on purpose: 60 test strings, 2 operator log strings and 3 generated headers (see the list below). One more file: a `patch` changeset for `@objectstack/plugin-security`, because the rewritten docblocks ship (see Changeset below). ## Census: `plugin-security`, before and after **Instrument (A1).** The gate's own `node scripts/check-issue-citations.mjs --census --json`, read-only and unchanged. The count below is its `allocated-but-absent` findings under `packages/plugins/plugin-security/`. Each run counts as a reading only because its board frontier equals the newest issue number, read by a separate request just before and just after the run. | reading | tree | board | whole-repo `allocated-but-absent` | plugin-security sites | lines | files | numbers | |---|---|---|---|---|---|---|---| | before | base `cd901d7a5`, run 2026-09-29T13:00:53Z to 13:04:37Z | enumerated, 185 pages, frontier #20647 (newest #20646 before, #20647 after), 18,474 numbers | 1,707 | **143** | 140 | 22 | 28 | | after | head `aa067dad3`, run 13:29:02Z to 13:32:37Z | enumerated, 185 pages, frontier #20649 (newest #20649 before and after), 18,476 numbers | 1,567 | **3** | 3 | 3 | 1 | The before count matches the 143 that census `5884031174` read at `f11b5f20`. The 3 left are the generated `#11671` headers. The whole-repo drop is 140, exactly this diff's census sites. The `resolves` tally is 32,878 in both runs, and `resolves-as-pull-request` (1,984) and `cross-repo-unjudged` (995) did not move either. The after run was taken on `aa067dad3`; the head `f90c9b123` adds only the changeset. No run was truncated or discarded: all three enumerations in this stage (two census runs and the supplementary board below) read 185 pages at the newest frontier. **Supplementary instrument, the whole scope.** The census does not read test files or strings, and this stage's scope includes test comments. So a second reading runs the gate's own exported `extractCitations` (whole-file and comment-prose projections) and `classifyCitation` over every `.ts` file under `plugin-security/src` (216 files). It uses one board, enumerated by the gate's own `enumerateBoard` at 13:08:21Z (185 pages, frontier #20647, equal to the newest). | reading | citations | dead | src comment | test comment | src string | test string | |---|---|---|---|---|---|---| | before, `cd901d7a5` | 2,746 | **327** | 143 | 123 | 2 | 59 | | after, `aa067dad3` | 2,483 | **64** | 3 | 0 | 2 | 59 | Its src-comment column equals the census's 143, which is the control on the second instrument. The 2,307 resolving, 88 pull-request and 24 cross-repo citations are the same in both readings. A third, raw reading (every `#` followed by digits, judged against the same board, whatever surrounds it) finds 331 dead occurrences before and 65 after: the 4 it sees beyond the gate are the three prose sites above and one more second number inside a kept test title. ## Per-number table Sites and files count every dead occurrence in scope at the base (comments and strings, tests included, gate-invisible spellings included). `rewritten / left` counts the sites rewritten and the sites left. Each anchor was read in its message and diff, not only its subject. | number | sites / files | rewritten / left | anchor: what it decided | |---|---|---|---| | `#6206` | 2/1 | 1/1 | `8e13ca876`: share-link enforcement takes the whole authz envelope (option-A ruling); it adds this package's `group`-posture repro. Stage 2's anchor | | `#6216` | 1/1 | 1/0 | `f586f1a89`: one `ExecutionContext` assembler, with the closed-field-set pin. The anchor the spec, runtime and rest stages gave it | | `#6483` | 14/5 | 14/0 | `ee58392e1`: ADR-0005's allow-list enforced, nine unapproved types (`permission` among them) rolled back to `allowOrgOverride: false`. Its message records the zero-row measurement, the `allowRuntimeCreate` boundary and this suite's stub blind spot. The spec stages' anchor | | `#6564` | 1/1 | 1/0 | `54299caad`: the per-row `ISharingService` write verdict becomes tri-state (allow / abstain / deny); `#6564` was that pull request | | `#6608` | 11/5 | 11/0 | `ee58392e1`: `#6608` was the pull request itself; this is its squash commit | | `#6609` | 3/2 | 3/0 | ADR-0094 D5-R: the record of that conflict ruling (option A, accept the tightening), executed by #6858 | | `#8692` | 10/3 | 9/1 | `712e185db`: the 2026-08-15 ruling, option A: the seed insert stamps `managed_by: 'platform'` explicitly, forward only, and the resync skip warn stops claiming intent | | `#8714` | 15/2 | 10/5 | `42b05af89`: explain reports a deactivated permission set or position through the shared held-state vocabulary. The anchor the spec stage gave it | | `#8757` | 14/3 | 10/4 | `6feac910b`: the 2026-08-15 ruling: the master gate is the sole row-write authority for a `controlled_by_parent` detail; delegated writes keep both floors | | `#8772` | 5/2 | 5/0 | `8abada3ba`: the freeze note, Direction 4 of the 2026-08-16 master-reference ruling; it names the two ramp legs and the three shapes this guard alone refuses | | `#8778` | 2/1 | 1/1 | `7901b2dd2`: option A, a stamp-only, read-neutral `tenancy.organizationField`. The spec stage's anchor | | `#8804` | 2/1 | 2/0 | `db923a3a8`: `#8804` was the measurement pull request: a seeder-created row is stored `'admin'`, and resync reports resynced 0 / resyncSkipped 8 | | `#8839` | 7/3 | 6/1 | `c25b2d52a`: the 2026-08-15 ruling, reading 1: one per-object `sys_comment` delete policy, so moderation stops being dead behind the floor | | `#8865` | 14/2 | 12/2 | `498f4e884`: the 2026-08-15 ruling, direction 1: leg 1 of the master gate drops the platform ownership floor on a sharing `allow` | | `#8919` | 1/1 | 1/0 | `b5378550e`: `/meta` publish and rollback gated on `manage_metadata`; it created the write-door census whose count rule the line applies. The rest stage's anchor | | `#11082` | 18/2 | 13/5 | ADR-0055's amendment (2026-09-07): `controlled_by_parent` composes across a chain, bounded, failing closed. One implementation-only line (the factory split) cites `61713314e`, the commit that landed it | | `#11343` | 13/6 | 12/1 | `c0714eb5d`: walled elevation requires a VERIFIED owner-email match, and the bootstrap replays on the verifying `sys_user` update. Stage 3's anchor | | `#11374` | 3/2 | 2/1 | `3954fb7df`: route A, the 2026-08-24 ruling to declare a sourced `maxLength` on every keyed text column; the object-file line cites `f64668d3c`, which applied it to this plugin's key columns | | `#11451` | 20/4 | 18/2 | `c33f18592`: the curated half's existence read becomes one batched `$in` carrying the `#8470` predicate; the reconcile is equality-gated; the derived half's batching is filed, not decided | | `#11518` | 35/7 | 31/4 | `e1d773eb7`: the unscoped existence page cap is measured, not trusted: one row more than the budget, and an overflowing page degrades loudly to the per-item read | | `#11520` | 17/2 | 15/2 | `1a6855226`: the derived half is batched too, unnarrowed, on its own index; a derived name whose read cannot answer is declined | | `#11671` | 4/4 | 1/3 | `09b4f4e4e`: generated translation leaves record the source revision they were filled from. Stages 1 and 2's anchor | | `#11702` | 1/1 | 0/1 | a test title only; nothing to rewrite | | `#11703` | 15/3 | 13/2 | `5cb62d88b`: `clone_permission_set` carries all five copied facets; the params list is the payload. The runtime stage's anchor | | `#11725` | 3/1 | 2/1 | `1e79aa4f8`: the probe of the trash and restore door, which pinned its unreachability and measured the residual | | `#11753` | 2/2 | 2/0 | `0e4e51b0a`: `ActionParamSchema.carryOver`, the carry-over ruling's schema half. The spec stage's anchor | | `#11843` | 5/4 | 4/1 | `5619aace3`: the 2026-08-25 ruling, option B: the packaged-permission-set lock registered at the metadata door. The verbatim quotation 「11843 同意」 is kept as written | | `#12020` | 7/2 | 7/0 | `9cfc1f7e9`: the lock extended to the restore leg, refusing on the durability channel; the residual tripwire inverted in the same change | | `#12143` | 2/1 | 2/0 | `f64668d3c`: `#12143` was the pull request itself: each plugin's keyed-text-bounds pin reads the widths off its own registration path | | `#12144` | 11/1 | 6/5 | `3a04b0125`: the shared identifier schemas pinned to the storage columns that bound them; the ceiling is storage-owned | | `#12147` | 1/1 | 1/0 | `945e91a13`: the class-level keyed-text-bounds gate over every `*.object.ts`, superseding the per-package pins | | `#13176` | 6/5 | 6/0 | `a68c61267`: this package's test files put in front of tsc through the sibling `tsconfig.test.json` | | `#14484` | 2/1 | 1/1 | `3f64fe6c6`: `organization_id` stamped on every `sys_record_share` write, with the backfill and the tenancy-ledger admission; it adds this test file. Stage 2's anchor | | `#16518` | 7/2 | 3/4 | `470746ae4`: `current_user.accessible_org_ids` resolved into the RLS variable bag | | `#16607` | 8/3 | 4/4 | `1d73d45c1`: RLS membership staged on the write `check` path, so a membership-keyed check resolves on a bare insert | | `#16608` | 13/4 | 6/7 | `a016f08b8`: the insert-side RLS `check` judges the row that will be stored, after `beforeInsert` | | `#16682` | 22/4 | 18/4 | `9b9581b11`: the `single`-posture promotion target is chosen, not sampled: the order stated to the driver, the declared owner preferred and required verified, bounded pages with a loud ceiling | | `#16722` | 1/1 | 1/0 | `1d73d45c1`: `#16722` was the pull request itself | | `#16805` | 1/1 | 1/0 | `a016f08b8`: `#16805` was the pull request itself; its message records the contract review's findings | | `#16861` | 7/2 | 6/1 | `1c83ca226`: the `already_have_admin` guard stops letting the org-admin row count decide: two ordered, bounded legs that warn with the number examined | | `#19307` | 5/3 | 4/1 | `8f6d83147`: the duplicate-name refusal on `sys_permission_set` carries `UNIQUE_VIOLATION`, and the packaged-set lock answers first. The spec stage's anchor | Every cited sha matches exactly one commit (`git rev-parse --disambiguate`, count 1 for each of the 36), and every one is an ancestor of the base (`merge-base --is-ancestor`, exit 0 for all 36; the history is complete, `--is-shallow-repository` false, 15,092 commits). Where an earlier stage already anchored a number, this stage reuses that anchor after checking it against this package's lines. ## Wordings to check - **Two ADR anchors.** `#11082`: ADR-0055's only amendment (2026-09-07) is the in-repo record of the chain decision, so the tags read `[ADR-0055 amendment]`; `security-plugin.ts:8027` (the thrower split into a factory) is an implementation detail the ADR does not record, so it cites `61713314e`. `#6609`: the lines already named ADR-0094 D5-R, and now say it records ruling A (`permission-set-projection.ts:32`, `:535`, `permission-set-projection.test.ts:498`). - **A stale claim corrected, `errors.ts:184-185`.** The line said the publish-time lint was 「open and unruled」. The ruling of 2026-08-16 made that false; `8abada3ba` corrected the sibling paragraph in `security-plugin.ts` and missed this one. It now says the ruling (commit `8abada3ba`) orders the lint ramp and that the ramp has not landed, which matches the `security-plugin.ts` paragraph (1 reflow line). - **A vanished pull-request body, `permission-set-projection.test.ts:14-16`.** The lines quoted the body of the pull request, which answers 404. They now state what `ee58392e1`'s own message records about the same blind spot: this suite stubs `saveMetaItem`, and the real gate is pinned by the dogfood cases and a dedicated 403 suite (2 reflow lines). - **The same, `packaged-permission-set-restore-leg.test.ts:47`.** 「recorded on #12020's PR」 became 「was measured for commit 9cfc1f7」; the line itself already states the measurement. - **A referent, `bootstrap-system-capabilities.test.ts:1148`.** 「this file's own #8919-era rule」: the count rule it applies lives in the write-door census that `b5378550e` created (the rule's text is `bb920ee08`'s), not in this file. The line now says so. - **Dead comment ids dropped with their issues.** `comment 5306089973` (`security-plugin.ts:8093`) and `comment 5587754690` (`bootstrap-platform-admin-walled-owner.test.ts:482`). The verbatim maintainer quotation under the second is untouched. - **Words where the anchor is one line away.** `bootstrap-platform-admin.ts:630` (「a pre-ruling install」, anchor on `:628`), `bootstrap-platform-admin-walled-owner.test.ts:493` (「the TRIAGE seat's」, anchors on `:463` and `:482`), `security-plugin.ts:8137` (「that ruling」, anchor on `:8132`), `identifier-storage-ceiling-pin.test.ts:51` (「the triage fence at the top of this file」, anchors on `:13` and `:25`), `packaged-permission-set-lock.test.ts:94` (anchor on `:95`). - **Reflow, 8 lines with no dead site** (every file keeps its line count): `bootstrap-platform-admin.ts:267-268`, `errors.ts:185`, `identifier-storage-ceiling-pin.test.ts:26` (「dispatch」 became 「scope」, because the dispatch was the card's), `packaged-permission-set-lock.test.ts:95`, `permission-set-projection.test.ts:15-16`, `security-plugin.ts:8094`. - **Box-drawing rulers.** `security-plugin.ts:3078` and `bootstrap-platform-admin.ts:715`, `:1110`, `:1149` gave up as many trailing rule characters as the anchor added, keeping at least one. ## The 65 sites left - **Test titles, 57 sites.** `describe` / `it` titles, which are string tokens, left as stages 1 to 3 left theirs: `bootstrap-declared-capabilities.test.ts:454`; `bootstrap-platform-admin-existing-holder-scan.test.ts:297`; `bootstrap-platform-admin-promotion-selection.test.ts:281`; `bootstrap-platform-admin-seeded-provenance.test.ts:184`; `bootstrap-platform-admin-walled-owner.test.ts:504`, `:569`, `:587`; `bootstrap-seed-round-trips.test.ts:795` (two numbers), `:980`; `bootstrap-system-capabilities.test.ts:968`, `:1096`; `controlled-by-parent-chain.test.ts:460`, `:540`, `:578`; `controlled-by-parent-detail-write-authority.test.ts:594`, `:650`, `:669`, `:708`, `:724`, `:813`; `explain-engine.test.ts:171`, `:203`, `:853`, `:873`, `:893`; `identifier-storage-ceiling-pin.test.ts:125`, `:143`, `:160`; `insert-check-post-image.test.ts:573`, `:612`, `:662`, `:775`, `:838`, `:875`, `:939`; `objects/default-permission-sets.test.ts:299`; `packaged-permission-set-lock-gate.test.ts:183`; `packaged-permission-set-lock.test.ts:647`, `:812`, `:813`; `packaged-permission-set-restore-leg.test.ts:264`, `:265`; `permission-set-duplicate-name-refusal.test.ts:195`; `plugin-keyed-text-bounds.test.ts:67`; `record-share-tenant-wall.test.ts:149`; `rls-accessible-org-ids-plumbing.test.ts:191`, `:256`, `:325`, `:382`; `rls-check-membership-staging.test.ts:388`, `:400`, `:439`, `:505`; `security-plugin.test.ts:153`; `share-link-tenant-wall.test.ts:239`; `tenant-layer.test.ts:237`. - **Test assertion messages, 3 sites.** String literals passed to `expect`: `identifier-storage-ceiling-pin.test.ts:172`, `:193` (`#12144`) and `packaged-permission-set-lock.test.ts:694` (`#11703`). - **Operator log strings, 2 sites.** `security-plugin.ts:7864` and `:7872`, the two `logger.error` lines of the chain guards (`#11082`). Runtime strings are form D, and the shrink-only `doc-authoring-prose-id` baseline already holds both (`security-plugin.ts`, `#11082: 2`). - **Generated headers, 3 sites.** `translations/{es-ES,ja-JP,zh-CN}.source-hashes.generated.ts:8` (`#11671`). Their producer is a string literal in `packages/cli`, outside this lane; the pointer is on #20594. - There is no quoted ruling carrying a dead number in this package: the one verbatim quotation, 「11843 同意」, carries no `#`. ## Mechanical guard: no code token moves The guard compares the TypeScript parser's leaf nodes, with comments as trivia and JSDoc nodes excluded, base `cd901d7a5` against head. Template literals are therefore read in context. It ran over all 51 touched `.ts` files. - Real run: 221,086 base tokens, **0 files with a token change** (exit 0). - Comment control in `seed-name-lookup.ts` (`TWO events, ONE consequence` to `TWO events, ONE result`): 0 files changed, as expected (exit 0). - Positive control, a code token added in `seed-name-lookup.ts` (an extra key in the batched read's `where`): DIFFER (exit 1). - Positive control, one digit changed inside a kept test title (`bootstrap-system-capabilities.test.ts:1096`): DIFFER (exit 1). Every mutation went through `scripts/ablation-replace.mjs`, and each landed (anchor 1 to 0, blob changed). Each restore was proven byte-identical to the HEAD blob (`36e6be731e6a`, `e1f66feaa6fc`), with `git diff HEAD` empty and a clean tree afterwards. ## Changeset This change ships bytes, so a `patch` changeset for `@objectstack/plugin-security` (`.changeset/20596-plugin-security-provenance-anchors.md`) is included. It says only that the provenance comments were re-anchored. Measured on the built package (A3): `files[]` is `dist`, `README.md` and `CHANGELOG.md`. After the build, the rewritten comments reach `dist`: `ADR-0055 amendment` appears 4 times in each of `dist/index.d.ts`, `index.d.mts`, `index.js` and `index.mjs`; `6feac910b`, `498f4e884` twice in each of the four; `c0714eb5d`, `e1d773eb7`, `db923a3a8`, `470746ae4`, `1d73d45c1`, `9b9581b11` once in each of the four; `ee58392e1` 3 times and `1c83ca226` twice in each declaration file; `5cb62d88b` 4 times and `c25b2d52a` 3 times in each runtime file. Positive control: the unchanged line 「declared the key's SHAPE」 beside a shipped rewrite (`rls-compiler.ts:88-89`) is found once in `index.d.ts`, beside 「Until commit 470746a nobody did」. A never-written negative phrase appears nowhere. The only dead numbers left in `dist` are the two kept `#11082` log strings in the runtime files. ## Gates (head `f90c9b123`) - **Citation judging, as CI runs it:** `pnpm check:issue-citations` (self-test) exits 0. `node scripts/check-issue-citations.mjs` exits 0: the diff-scoped run judged 9 citations across 19 files, and all 9 resolve. - **Doc authoring:** `pnpm check:doc-authoring` exits 0, with the sibling-package prose ids at their baseline and no growth. - **Derived gates:** `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` at `f90c9b123` derived 66 commands: all 57 derived at dispatch, plus `check:duration-unit-keys`, `check:dispatcher-error-vocabulary`, `check:engine-double-contract`, `check:logger-receiver-detach`, `check:objectql-double-limit`, `check:query-options-erasure`, `check:type-check-coverage`, `check:type-check-debt` and `check:where-matcher`. It was re-derived after a fresh `git fetch` (`origin/main` `c6b37cd08`, 3 commits ahead): the same 66. Each ran with its exit code captured before any pipe, and all 66 exit 0. `--ran`, fed each command with its exit code, reports 66 run, 0 NOT MEASURED (a derived zero), 0 unrun, and exits 0. A full `turbo run build` of `./packages/*` and `./packages/*/*` ran first under the shared verify lock (71 of 71 tasks, exit 0), so no gate hit an unbuilt workspace. - **Roster families the derivation lists outside its commands** (their rosters sit in directories this diff touches): `node scripts/check-changeset-fixed.mjs`, `pnpm check:error-code-casing` and `pnpm check:filter-alias-parity`, each exit 0. - **Tests and typecheck, under the verify lock:** - `pnpm --filter @objectstack/plugin-security test`: 147 files pass, 3,202 tests pass and 23 skip. That is every test file in the package, the 32 touched ones included. - `pnpm --filter @objectstack/plugin-security typecheck` exits 0 (`tsc` main, `tsconfig.scripts.json`, and `check:test-typecheck` at zero). The main program reads 69 non-test files; the `tsconfig.test.json` program reads all 216 files under `src/`, the 147 test files included, and all 51 touched files are in it (`--listFiles`). - **Lint, as a proven narrowing:** `eslint --no-inline-config --format json` over the 51 touched `.ts` files gives 51 files, 0 errors and 0 warnings. All 51 are in eslint's own population (`isPathIgnored` is false for each). `eslint.config.mjs` never enables type-aware linting (no `parserOptions.project`, as its own line 328 states), so a comment edit here cannot move the verdict on any untouched file. The repo-wide `pnpm lint` is CI's run. - **Control bytes:** `pnpm check:nul-bytes` exits 0, and a raw scan of the 52 changed files for control bytes finds none. ## Acceptance notes - **The gate's extractor does not see a number after a slash either.** `CITATION_RE` opens with a lookbehind that refuses a `/` before the `#` (`scripts/check-issue-citations.mjs:449`), so in `#A/#B` only `#A` is a citation to the diff gate and the census, dead or alive. It is the same blind-spot family as the hyphen spelling (#20636). This stage rewrote the two such prose sites in `plugin-security` (`permission-set-overlay-discard.ts:25`, `platform-owner-wall-bypass.ts:69`) because they are the same dead numbers in the same comment prose. A raw scan of `packages/**/src` `.ts` files against the board finds 33 dead second numbers of this shape at the base and 31 at the head (one of them the kept title `bootstrap-seed-round-trips.test.ts:795`), in 14 packages. The census cannot count them, so a later stage has to look for them by hand. No instrument change here. - **The hyphen spelling in this package** (#20636 names 1 here on `main`) was `bootstrap-system-capabilities.test.ts:1148`, rewritten. 9 dead `#N-word` sites remain in `packages/**/src` at the head, none in this package. - **The census instrument did not truncate in this stage.** Three enumerations read 185 pages each at the newest frontier. - **Anchors the next stages can reuse.** These numbers stand elsewhere on the census at the head: `#11374` in `drivers` (16), `platform-objects` (14) and `plugin-audit` (2), anchor `3954fb7df` (route A); `#6216` in `core` (8), `mcp` (1) and `plugin-hono-server` (1), anchor `f586f1a89`; `#6483` (8) and `#6608` (4) in `metadata-protocol`, anchor `ee58392e1`; `#6206` in `core` (2), `plugin-approvals` (3), `plugin-audit` (1) and `service-storage` (1), anchor `8e13ca876`; `#8778` in `metadata-core`, `plugin-approvals` and `service-storage`, anchor `7901b2dd2`; `#16608` (4) and `#16805` (2) in `objectql`, anchor `a016f08b8`; `#11343` in `types` (2), anchor `c0714eb5d`; `#8692` in `cli` (2), anchor `712e185db`; `#12144` in `metadata-protocol` (1), anchor `3a04b0125`; `#16682` in `core` (1), anchor `9b9581b11`. - **Base.** The branch is 3 commits behind `origin/main` (`c6b37cd08`, read at 13:54Z). None touches `plugin-security` or any of these numbers; they add three unrelated changesets and move one row of `scripts/doc-authoring-prose-id.baseline.json` (a `packages/lint` entry), so there was no merge. --- _Generated by [Claude Code](https://claude.ai/code/session_01XY5uCwTjZj7884yYtyur4H)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent c4c68ca commit 9a4b2bb

52 files changed

Lines changed: 277 additions & 266 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
'@objectstack/plugin-security': patch
3+
---
4+
5+
Provenance comments in `plugin-security` were re-anchored
6+
7+
Comment and docblock lines under `src/` that cited tracker numbers which no
8+
longer resolve on GitHub now cite the record in this repository that decided
9+
the matter (an ADR where one exists, otherwise the commit in this repository's
10+
history), and say in their own words what was decided. Comments only: no type,
11+
schema, export, log or refusal text, or runtime behaviour changes.

‎packages/plugins/plugin-security/src/bootstrap-declared-capabilities.test.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,12 @@ function makeQl(declared: any[] = []) {
6060
return (v === null ? r[k] == null : r[k] === v);
6161
}),
6262
);
63-
// [#11518] `limit` is HONOURED, and a paged read is ordered by `id`
63+
// [commit e1d773eb7] `limit` is HONOURED, and a paged read is ordered by `id`
6464
// ascending (#4363's pagination tie-breaker). Both are properties of the
6565
// shipped drivers, measured for the sibling double in
6666
// `bootstrap-system-capabilities.test.ts`; this one ignored `limit`
6767
// entirely, which made the whole class of page-cap defect INEXPRESSIBLE
68-
// here — including #11518's, whose consequence lands on THIS seeder.
68+
// here — including the cap commit e1d773eb7 fixed, whose consequence lands on THIS seeder.
6969
if (q?.limit === undefined) return matched;
7070
return [...matched]
7171
.sort((a, b) => (String(a.id) < String(b.id) ? -1 : String(a.id) > String(b.id) ? 1 : 0))
@@ -434,7 +434,7 @@ describe('unowned-declaration diagnostic (#4967 Part 3)', () => {
434434
});
435435

436436
/**
437-
* [#11518] THE CONSEQUENCE THIS SEEDER PAYS FOR A TRUNCATED EXISTENCE PAGE.
437+
* [commit e1d773eb7] THE CONSEQUENCE THIS SEEDER PAYS FOR A TRUNCATED EXISTENCE PAGE.
438438
*
439439
* This is one of the two callers on `main` that read UNSCOPED (the other is
440440
* `permission-set-projection`'s overlay pass), and `seed-name-lookup.ts` capped

‎packages/plugins/plugin-security/src/bootstrap-platform-admin-existing-holder-scan.test.ts‎

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

33
/**
4-
* #16861 — whether this deployment ALREADY has a platform admin, and why the
4+
* Commit 1c83ca226 — whether this deployment ALREADY has a platform admin, and why the
55
* answer stopped being a function of how many ORG admins it has.
66
*
77
* ## The defect, re-measured on this branch's base before anything changed
@@ -58,7 +58,7 @@
5858
* ## Why the row ORDER is permuted rather than a second driver package
5959
*
6060
* Same reason as `bootstrap-platform-admin-promotion-selection.test.ts`
61-
* (#16682): `@objectstack/driver-memory` cannot be declared here without a
61+
* (commit 9b9581b11): `@objectstack/driver-memory` cannot be declared here without a
6262
* `scripts/driver-memory-census.ledger.json` disposition, which is a
6363
* maintainer ruling. Each case runs the REAL engine over the REAL
6464
* better-sqlite3 driver behind a facade that permutes a result ONLY when the

‎packages/plugins/plugin-security/src/bootstrap-platform-admin-promotion-selection.test.ts‎

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

33
/**
4-
* #16682 — WHICH user the `single`-posture bootstrap promotes, and why.
4+
* Commit 9b9581b11 — WHICH user the `single`-posture bootstrap promotes, and why.
55
*
66
* ## The defect, re-measured on this branch's base before anything changed
77
*
@@ -199,7 +199,7 @@ async function seedUser(
199199
email: string,
200200
createdAt: string,
201201
withAccount: boolean,
202-
// [#16682, maintainer ruling batch #100] Absent means UNVERIFIED, which is
202+
// [commit 9b9581b11, maintainer ruling batch #100] Absent means UNVERIFIED, which is
203203
// what `isEmailVerifiedUserRow` reads an absent column as — so every fixture
204204
// that does not say otherwise is a row the declared-owner leg must REFUSE.
205205
emailVerified = false,

‎packages/plugins/plugin-security/src/bootstrap-platform-admin-seeded-provenance.test.ts‎

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

33
/**
4-
* #8692 — what provenance a REAL `bootstrapPlatformAdmin` run leaves on the
4+
* [commit 712e185db] What provenance a REAL `bootstrapPlatformAdmin` run leaves on the
55
* platform default permission sets, and what `os meta resync` then does with it.
66
*
77
* ## Why this file exists at all
@@ -136,7 +136,7 @@ async function rowViaEngine(engine: ObjectQL, name: string): Promise<any> {
136136
}
137137

138138
/**
139-
* A row exactly as a PRE-#8692 install holds it — written the way the old
139+
* A row exactly as an install before commit 712e185db holds it — written the way the old
140140
* seeder wrote it, which is to say WITHOUT `managed_by`, so the value comes
141141
* from the declaration's `defaultValue: 'admin'` by the very mechanism that
142142
* produced it on every install created before the ruling.

‎packages/plugins/plugin-security/src/bootstrap-platform-admin-walled-owner.test.ts‎

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* History of this surface, because the pins below flip an older family:
77
* - #11184 (framework leg of cloud#1509): walled postures stopped promoting
88
* the first registrant; only the env-declared owner elevated.
9-
* - #11343: the walled match additionally required a VERIFIED email.
9+
* - commit c0714eb5d: the walled match additionally required a VERIFIED email.
1010
* - #13147: `OS_PLATFORM_OWNER_EMAIL` became a comma-separated list through
1111
* the ONE parser in `@objectstack/core`.
1212
* - **#11974 (#11663 L4, maintainer acceptance 2026-08-25, Choice 4A/5A):
@@ -24,7 +24,7 @@
2424
* state, and `single` still PROMOTES (Choice 4A — the over-denial guard:
2525
* retiring the walled write must not retire the `single` one).
2626
*
27-
* - **#16682: the `single` SELECTION is repaired.** That guard used to be
27+
* - **Commit 9b9581b11: the `single` SELECTION is repaired.** That guard used to be
2828
* written as "byte-for-byte", and one case snapshotted the incumbent's
2929
* refusal to read `OS_PLATFORM_OWNER_EMAIL` on this branch. The incumbent
3030
* was the defect: an unordered, cap-50 `sys_user` read sorted client-side,
@@ -460,7 +460,7 @@ describe('single posture — "first user is owner" is ruled reasonable and UNCHA
460460
});
461461

462462
/**
463-
* ⚠️ RE-AUTHORED by #16682. This case used to assert the opposite —
463+
* ⚠️ RE-AUTHORED by commit 9b9581b11. This case used to assert the opposite —
464464
* "never consults the owner-email variable: a declared owner does NOT
465465
* redirect the single-org promotion" — and it is worth being explicit about
466466
* what changed and what did NOT, because the two are easy to confuse.
@@ -479,7 +479,7 @@ describe('single posture — "first user is owner" is ruled reasonable and UNCHA
479479
* only on the walled branch.
480480
*
481481
* The authority for the reversal is a MAINTAINER ruling — 2026-09-08,
482-
* decision batch #100, recorded on #16682 (comment 5587754690), which
482+
* decision batch #100, applied by commit 9b9581b11, which
483483
* supersedes the Choice 4A sentence for this one point and states what
484484
* survives it, verbatim:
485485
*
@@ -490,7 +490,7 @@ describe('single posture — "first user is owner" is ruled reasonable and UNCHA
490490
* > `single` one, and the over-denial invariant (`adminPromoted === true`
491491
* > with a grant row minted) stays pinned.
492492
*
493-
* ⛔ An earlier revision of this comment quoted the #16682 TRIAGE seat's
493+
* ⛔ An earlier revision of this comment quoted the TRIAGE seat's
494494
* ruling instead. That quotation was the reviewer's F3 finding: a pin
495495
* recorded under a maintainer ruling cannot be rewritten under a seat's.
496496
* The quotation above is the record that resolved it.
@@ -518,7 +518,7 @@ describe('single posture — "first user is owner" is ruled reasonable and UNCHA
518518
// #11974's over-denial guard, unchanged: the `single` write still happens.
519519
expect(r.adminPromoted).toBe(true);
520520
expect(ql.grants()).toHaveLength(1);
521-
// #16682: and it goes to the address the operator declared, not to
521+
// Commit 9b9581b11: and it goes to the address the operator declared, not to
522522
// whichever row the driver handed back first.
523523
expect(ql.grants()[0]?.user_id).toBe('u_second');
524524
expect(r.basis).toBe('declared-owner');
@@ -550,8 +550,8 @@ describe('single posture — "first user is owner" is ruled reasonable and UNCHA
550550
});
551551

552552
// ───────────────────────────────────────────────────────────────────────────
553-
// [#11974, amended by #16682] The bootstrap-replay trigger set. #11974
554-
// narrowed it to `single` + create/insert: the #11343 update arm (email /
553+
// [#11974, amended by commit 9b9581b11] The bootstrap-replay trigger set. #11974
554+
// narrowed it to `single` + create/insert: commit c0714eb5d's update arm (email /
555555
// email_verified) fired for the walled verify-then-elevate sequence, which no
556556
// longer exists, and its own rationale was that "`single` promotes the oldest
557557
// authenticable human and never reads `email`/`email_verified`".

0 commit comments

Comments
 (0)