Skip to content

Commit 04b202e

Browse files
objectstack-fleet[bot]hotlongclaude
authored
docs(rest): re-anchor the dead tracker citations in packages/rest/src to the commits that decided them (#20632)
Part of #20594 Clause-②: no ## What changed This is stage 2 of the `domain:cli` lane of the dead-citation sweep: `packages/rest/src/**`. Every comment or docblock site in scope that cited a tracker number answering 404 now cites, in ruling C+D's form C (comment 5749154545 on #19123), the commit in this repository's history that decided what the line describes, and says in its own words what that commit decided. PR #20533 is the method and PR #20624 (stage 1, `packages/runtime`) the precedent this follows line for line. Later stages cover `cli`, `types` and the rest of the lane, so this PR says `Part of` and the card stays open. That is **457 comment sites on 445 lines in 85 files, covering 74 numbers**: the census's 191 sites, 256 more in test comments (which the census defers), and 10 sites whose dead number is the second half of a slash-joined pair the citation grammar does not read (`#3984/#6241`, `#9901/#10255` four times, `#10993/#11235/#11292`, `#11235/#11242` twice, `#10993/#11242`, `#7543/#15071`). Each rewritten line cites one of **70 distinct commits**. ADR-0076 D11 is the only ADR that records any of these numbers, and it records #8850 only as the extraction it names as landed in `8664a2c99`, so that commit is the anchor there. No other ADR or ruling-record file in `docs/adr/` or `scripts/adr-anchors/` records the decision behind any of these numbers, so every anchor is a commit. The anchors the landed stages already gave the same numbers are reused where the rest sites describe the same decision (30 numbers, for example `79c46da90` for #9934, `7986d973f` / `311433f6b` for the compound-name retirement, `6a180e42d` for #13279 and `cf6e0a193` for #15071), so each number carries one anchor across the tree. Only comments changed. Every touched file keeps its line count (451 lines out, 451 in, over 85 files), so no line citation into these files moves. Six of the 451 lines held no dead site; each is the other half of a sentence that had to change: - `discovery-schema-conformance.test.ts:343` (「(reaffirmed by」 to 「(which commits」, because line 344 now names the two commits that landed the ruling), - `package-door-16019-raw-statement-fault-code.test.ts:51` and `error-response.ts:1485` (a trailing 「PR」 whose number wrapped onto the next line), - `error-response-structured-arm-door-parity.test.ts:463` (「That card added the limb」 to 「That commit」, because line 459's tag now names the commit), - `rest-hook-script-fault-envelope.test.ts:331` (「both sides of that card」 to 「that fix」), - `rest-server.ts:908` (「(#14409, landed」 to 「(landed as commit」, the sha `3ecb7dc1a` already standing on line 909). **No citation number is added.** Every tracker number on an added line was already on the line it replaces. No PR number stands on an added line. One of the 70 shas is on a removed line, and it was there before: `rest-14078-invalid-date-total-arm.test.ts:19` read 「PR #14409 (landed `3ecb7dc1a`)」 and now reads 「Commit 3ecb7dc drove」. No code token moves (see the guard below). Three dead comment sites are left on purpose, listed under "The sites left". One more file: a `patch` changeset for `@objectstack/rest`, because the rewritten docblocks ship (see Changeset below). ## Census: `packages/rest`, before and after **Instrument.** The gate's own `node scripts/check-issue-citations.mjs --census --json`, read-only and unchanged, run with the fleet token. Its surface is comment prose in `packages/**/src/**/*.ts` with string literals blanked, and it defers `*.test.ts`. The count is its `allocated-but-absent` findings under `packages/rest/`. Both runs enumerated the whole board (185 pages), so neither read a truncated board. | reading | tree | board | whole-repo `allocated-but-absent` | rest sites | lines | files | numbers | |---|---|---|---|---|---|---|---| | before | base `a186aea996`, run 2026-09-29T10:28:18Z to 10:36:06Z | enumerated, 185 pages, frontier #20628, 18,455 numbers | 2,015 | **191** | 186 | 14 | 51 | | after | head `93e4d69ba6`, run 11:11:30Z to 11:17:37Z | enumerated, 185 pages, frontier #20630, 18,457 numbers | 1,764 | **0** | 0 | 0 | 0 | The before count equals the card's 191 at `f11b5f20a2`. The whole-repo drop is 251: this diff's 191, plus the 60 of PR #20626 (`packages/plugins/plugin-sharing`, 63 to 3), which landed on `main` in between and came in with the merge. No other package moved. **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 `packages/rest/src` (256 files), against the board enumerated through the gate's own `enumerateBoard`. The lit controls #20594, #19123 and #20624 answered 200 and are on both boards; the dead controls #13214, #14541 and #15071 answered 404 and are on neither. | reading | tree | board | citations | dead | src comment | test comment | src string | test string | |---|---|---|---|---|---|---|---|---| | before, 10:29Z | `a186aea996` | 185 pages, frontier #20628 | 4,620 | **577** | 191 | 259 | 1 | 126 | | after, 11:21Z | `93e4d69ba6` | 185 pages, frontier #20631 | 4,174 | **130** | 0 | 3 | 1 | 126 | Its src-comment column equals the census's 191 and 0, which is the control on the second instrument, and a site-by-site comparison of the two before-readings is identical. Resolving comment citations move by one (1,364 to 1,365 in src): `(#10993/#11235/#11292)` became `(#10993, commit 376c70f, #11292)`, so the grammar now reads the live `#11292` that the slash hid. The drop is 447 grammar-read sites; the other 10 rewritten sites are the slash-joined ones the grammar never read. Separately, every one of the 77 numbers was probed on its web endpoint: 76 answer 404 (deleted) and one, #14026, answers 302 to objectstack-ai/objectui#10102 (transferred), which is why it is left (see below). ## Per-number table Sites and files are the dead comment sites in scope at the base, tests and slash-joined halves included. `left` is a site with no deciding commit (see below). `strings kept` counts string-literal sites, which are tokens and stay as they were. Every anchor was read in its message or its diff, not only in its subject: it is the commit that made the change the line describes, and its own message or diff names the number it replaces or adds the citation the line carries. | number | comment sites / files | rewritten | left | strings kept | anchor | |---|---|---|---|---|---| | `#6037` | 5/3 | 5 | 0 | 0 | `18189983d` | | `#6122` | 2/2 | 2 | 0 | 0 | `64cd01082` | | `#6206` | 1/1 | 1 | 0 | 0 | `8e13ca876` | | `#6216` | 6/2 | 6 | 0 | 2 | `f586f1a89` | | `#6241` | 10/3 (1 slash-joined) | 10 | 0 | 1 | `83a3b1f2e` | | `#6259` | 2/1 | 2 | 0 | 0 | `6968885ef` | | `#6303` | 1/1 | 1 | 0 | 0 | `465c5fc14` | | `#6306` | 9/5 | 9 | 0 | 3 | `fec784863` | | `#6307` | 4/2 | 4 | 0 | 0 | `293476148` | | `#6349` | 4/2 | 4 | 0 | 4 | `2443bb4c4` | | `#6474` | 1/1 | 1 | 0 | 0 | `18189983d` | | `#6535` | 3/2 | 3 | 0 | 0 | `a92b1793c` | | `#6640` | 1/1 | 1 | 0 | 1 | `2ab1257c9` | | `#6704` | 5/1 | 5 | 0 | 1 | `c3f491626` | | `#8641` | 1/1 | 0 | 1 | 0 | — | | `#8850` | 3/3 | 3 | 0 | 0 | `8664a2c99` | | `#8885` | 6/3 | 6 | 0 | 3 | `30b1c636a` | | `#8919` | 7/3 | 7 | 0 | 7 | `b5378550e` | | `#9741` | 12/1 | 12 | 0 | 0 | `2a29caa53` | | `#9805` | 1/1 | 1 | 0 | 0 | `45862a53d` | | `#9934` | 19/10 | 19 | 0 | 4 | `79c46da90` | | `#9967` | 2/2 | 2 | 0 | 4 | `8f266f1cd` | | `#10063` | 2/2 | 2 | 0 | 1 | `9e04c3e35` | | `#10178` | 1/1 | 1 | 0 | 0 | `38cf397ea` | | `#10179` | 0/0 | 0 | 0 | 1 | | | `#10255` | 18/4 (4 slash-joined) | 18 | 0 | 2 | `6ce58a735` | | `#10340` | 13/3 | 13 | 0 | 2 | `26f3588fb` | | `#10345` | 13/6 | 13 | 0 | 6 | `cad8b42f0` | | `#10350` | 1/1 | 1 | 0 | 0 | `490879ad0` | | `#10485` | 2/1 | 2 | 0 | 1 | `35ad101bc` | | `#10537` | 9/3 | 9 | 0 | 1 | `e634ecf6a` | | `#10888` | 2/2 | 2 | 0 | 0 | `d806081dd` | | `#11006` | 3/1 | 3 | 0 | 0 | `cccbe51bf` | | `#11130` | 1/1 | 1 | 0 | 0 | `851909530` | | `#11235` | 4/2 (1 slash-joined) | 4 | 0 | 0 | `376c70f98` | | `#11242` | 3/2 (3 slash-joined) | 3 | 0 | 0 | `98ea3443f` | | `#12144` | 1/1 | 1 | 0 | 0 | `3a04b0125` | | `#12176` | 11/7 | 11 | 0 | 2 | `7986d973f` | | `#12194` | 15/5 | 15 | 0 | 4 | `311433f6b` | | `#12195` | 35/16 | 35 | 0 | 7 | `7986d973f` | | `#13182` | 2/2 | 2 | 0 | 0 | `5b3ff63cc` | | `#13197` | 1/1 | 1 | 0 | 0 | `56c093c4d` | | `#13213` | 2/1 | 2 | 0 | 0 | `4801296e7` | | `#13214` | 18/6 | 18 | 0 | 14 | `cc837dbfe`, `889ec5b42`, `3d10755f0` | | `#13244` | 5/2 | 5 | 0 | 1 | `889ec5b42` | | `#13255` | 4/1 | 4 | 0 | 6 | `43028a8f8` | | `#13258` | 1/1 | 1 | 0 | 0 | `3d10755f0` | | `#13279` | 23/5 | 23 | 0 | 5 | `6a180e42d` | | `#13280` | 13/4 | 13 | 0 | 2 | `add6a1b1c` | | `#13282` | 1/1 | 1 | 0 | 0 | `43028a8f8` | | `#13377` | 3/2 | 3 | 0 | 0 | `e10cf3444` | | `#13378` | 2/1 | 2 | 0 | 0 | `82faea03f` | | `#13454` | 1/1 | 1 | 0 | 0 | `7ad57e17a` | | `#14026` | 1/1 | 0 | 1 | 0 | — | | `#14365` | 1/1 | 0 | 1 | 0 | — | | `#14366` | 14/4 | 14 | 0 | 2 | `53cbad9f7` | | `#14369` | 3/2 | 3 | 0 | 0 | `a3d5724c8`, `53cbad9f7` | | `#14389` | 7/3 | 7 | 0 | 7 | `10220a7bf` | | `#14390` | 1/1 | 1 | 0 | 0 | `9d7f7259f` | | `#14409` | 2/2 | 2 | 0 | 0 | `3ecb7dc1a` | | `#14541` | 27/4 | 27 | 0 | 5 | `6d178a408` | | `#14613` | 2/2 | 2 | 0 | 0 | `81208086a` | | `#14677` | 1/1 | 1 | 0 | 0 | `a4e4d2d78` | | `#14683` | 8/2 | 8 | 0 | 0 | `96326040f` | | `#14691` | 15/2 | 15 | 0 | 2 | `b3a63d32c` | | `#14704` | 9/3 | 9 | 0 | 2 | `1c7adc73d` | | `#14723` | 7/4 | 7 | 0 | 4 | `65846bc46` | | `#14725` | 3/3 | 3 | 0 | 2 | `f5cc78b63` | | `#14849` | 3/1 | 3 | 0 | 0 | `226e72443` | | `#14907` | 1/1 | 1 | 0 | 0 | `e1d4f9e3f` | | `#14908` | 1/1 | 1 | 0 | 0 | `d5cbb44f3` | | `#15021` | 2/1 | 2 | 0 | 8 | `cc238db8b` | | `#15034` | 6/2 | 6 | 0 | 0 | `abf9101f1` | | `#15065` | 1/1 | 1 | 0 | 0 | `1c7adc73d` | | `#15071` | 23/4 (1 slash-joined) | 23 | 0 | 3 | `cf6e0a193` | | `#16650` | 1/1 | 1 | 0 | 0 | `001a83b04` | | `#17058` | 3/1 | 3 | 0 | 4 | `94c930248` | | `#18546` | 3/2 | 3 | 0 | 3 | `58f60e37e` | | **total** | **460** | **457** | **3** | **127** | **70 distinct commits** | Every cited sha matches exactly one object (`git rev-parse --disambiguate`, count 1 for each of the 70), is a commit, has one parent, and is an ancestor of the base (`merge-base --is-ancestor`, exit 0 for all 70). The checkout is not shallow (`--is-shallow-repository` false); the control leg `13a6cb4ad` exits 0 and the negative control (this branch's first WIP commit, not on `main`) exits 1. Several numbers are the PR number of their own anchor commit (#6122, #6303, #6474, #11242, #13213, #13244, #13258, #13282, #14409, #14677, #14908, #15065, #16650), so the sha is the same object the number named. **Numbers with more than one anchor, by site:** - `#13214` (18 sites) was one card with three commits. `cc837dbfe` (the ownership gate, the 2026-08-30 ruling) for the 11 sites that describe the gate; `889ec5b42` for the 5 in `ui-view-route-identity.measurement.test.ts`, the identity measurement it created; `3d10755f0` for the tenancy file's header, the measurement it created; and `rest-server.ts:2247`, 「Driven and reported on #13214 (PRs #13244, #13258)」, now reads 「Measured in commits 889ec5b (identity) and 3d10755 (tenancy)」: those PRs are exactly those two commits. - `#14369` (3 sites): `a3d5724c8` (the liveness census it recorded) for `rest-server.ts:1172` and `rest-sub-config-parse-not-cast.test.ts:48`. `rest-server.ts:4092` said the zero read sites of `api.documentation` / `api.responseFormat` came from 「the #14369 census」, but `a3d5724c8` explicitly left `api` out of that census; the zero was measured by `53cbad9f7` (its changeset: no other read site for either key), which is the anchor there. - `#11235` / `#11242` / `#10993`: `376c70f98` derives the discovery `version` in metadata-protocol (#11235), and `98ea3443f` is #11242's own squash, which landed the #10993 ruling on `/health` and the dispatcher's `/discovery`. So 「the #10993 ruling … reaffirmed by #11235/#11242」 now reads 「the #10993 ruling, landed by commits 98ea344 and 376c70f」 (`rest-server.ts:4528`, `discovery-schema-conformance.test.ts:343-344`). `#10993`, `#11292` and `#11297` answer 200 and stay. - `#6037` / `#6474`: one commit, `18189983d` (#6474 is its PR number), so 「(#6037 / PR #6474)」 became 「(commit 1818998)」. **Wordings to check, each true of its commit:** - A commit does not rule. Where a line said a number ruled, it now says what the commit did with the ruling: 「the ruling commit 79c46da landed says it does」, 「the ruling commit cf6e0a1 implemented fences it」, 「the ruling commit 10220a7 implemented」, 「the 2026-08-20 ruling, landed as commit 6ce58a7」, 「recorded in commit 6ce58a7's message (option A)」 (its message reads 「Ruled on #10255 (2026-08-20, option A)」), and 「question was ruled on 2026-08-20 and landed as commit 6ce58a7」 where the line said 「filed as #10255」. - `#14541`'s contract review: 「the #14541 contract review (condition N)」 now reads 「the contract review of commit 6d178a4 (condition N)」; that commit's message lists the conditions it carries. 「#14541's §4」 and 「#14541 §5」 in `error-response-generic-passthrough-object-parity.test.ts` are sections of `error-response-structured-arm-door-parity.test.ts` (the file `6d178a408` created), so they now name that file. 「measured on the #14541 branch」 reads 「on the branch that landed as commit 6d178a4」. - A line that named a DEFECT by its number now says so: 「Before commit 9e04c3e the draft→active promotion door could not…」, 「Before commit 26f3588 the `/meta` doors decided ORGANIZATION SCOPE from the RAW url」, 「the defect commit 2443bb4 fixed」 and 「would be the defect commit 26f3588 fixed」. - `#13255`: 「As written for #13255 this file repaired nothing」 reads 「As first written (commit 43028a8)」, the commit that created the file and answered the measurement; 「CONTEXT-LOST family (#13255), still unruled」 reads 「first measured by commit 43028a8」 (the ruling on that family never landed, which the line still says). - `#13214` in the identity file: 「the half #13214 marks UNMEASURED」 reads 「the half left UNMEASURED until commit 889ec5b」, and 「#13214 asks for an INDEPENDENT reproduction」 reads 「commit 889ec5b is an INDEPENDENT reproduction」. - 「the #8885 sweep」 reads 「the sweep behind commit 30b1c63」, the commit that registered the 9 codes the sweep found; 「#14849 predicted」 reads 「The card behind commit 226e724 predicted」; 「the hazard #13377 names」 reads 「the hazard commit e10cf34 was written to remove」; 「The concrete harm #6704 names」 reads 「removed」. - Quoted ruling: `error-response-sandbox-arm-message.test.ts:340` sits inside a verbatim ruling quote, so the commit stands in an editorial bracket (「not from [commit 1c7adc7]'s list」), as PR #20624 did. - Two markdown tables in comments (`meta-state-route-engine-outage.test.ts:76`, `objectql-slot-consumer-census.test.ts:43`): the rewritten cell is wider than its column, and its padding is reduced rather than widening the four sibling rows. ## The sites left **No deciding commit (3 sites, all in test files, so the census does not see them):** - `meta-object-owd-gate.test.ts:516` (#8641): 「whether it should stay is #8641's question」, an open decision. The commit that added the citation calls it a pointer to the open decision card, and no commit decides it. - `rest-sub-config-parse-not-cast.test.ts:321` (#14365): the `z.partialRecord` question 「deferred to #14365」 was never taken (`git log -S partialRecord`); `b3a63d32c` made it moot by retiring the record, which the other half of the same line now cites. - `import-integration.test.ts:1043` (#14026): not deleted, TRANSFERRED. The web endpoint answers 302 to objectstack-ai/objectui#10102, the REST read follows the redirect, and the board enumeration does not list it, so the census and the supplementary reading both class it `allocated-but-absent`. The line says how an issue was raised; no commit decides that, so form C has nothing to cite. **String sites kept as tokens (127).** 126 are test titles and test-code strings in 41 files. One is a non-test string: the `note` field of the REST route ledger's `GET /api/v1/meta/object/:name/state/:field` row at `rest-route-ledger.ts:290`, which ends 「(#10179)」 (see Acceptance notes). ## Mechanical guard: no code token moves The check compares the TypeScript parser's leaf tokens (TypeScript 6.0.3, JSDoc nodes excluded, comments being trivia) of each touched file at base `a186aea996` against the working tree at `93e4d69ba6`, over all 85 touched `.ts` files. Controls mutate the head text in memory only, so nothing on disk moved for them. - Real run: 272,653 base tokens, **0 files with a token change** (exit 0). - Comment-insertion control (`error-response.ts`): 0 files changed (exit 0). - Code-insertion positive control (a declaration in the same file): DIFFER at token 0 (exit 1). - String positive control (the first string literal past offset 2000 of the same file, one character added inside it): DIFFER at token 26 (exit 1). Line balance: every touched file is +N/−N (451/451), and every line count is equal at base and head. A raw scan of the 86 changed files for control bytes finds none (its positive control on a scratch file with a U+0001 byte matches). ## Changeset This change ships bytes, so a `patch` changeset for `@objectstack/rest` is included, in PR #20624's form and level. It says only that the provenance comments were re-anchored. Measured on the built package: `files[]` is `dist`, `README.md` and `CHANGELOG.md`. After `pnpm --filter @objectstack/rest build`, the rewritten docblocks reach `dist`: for example `53cbad9f7` appears 4 times in `dist/index.d.ts`, and `26f3588fb` 8 times and `b3a63d32c` 5 times in `dist/index.js`. The positive control, the unchanged sentence 「It was VALIDATE-ONLY from #11637」 of the same `rest-server.ts` docblock whose first line now reads 「[commit 53cbad9] The parsed output is CONSUMED」, is in `dist/index.d.ts` beside it; a negative control phrase appears nowhere. ## Gates (head `93e4d69ba6`) This host has no `flock`, so `os-verify-lock.sh` ran in its declared unlocked mode. Its disclosure, verbatim, from each locked run at this head: ```text os-verify-lock: VERDICT command-exit 0 · UNLOCKED (declared) · no usable `flock` on this host, so the shared verify lock was NEVER taken and NOTHING was serialized · ran 47s · declare it in the PR body · pnpm --filter '@objectstack/rest...' build os-verify-lock: VERDICT command-exit 0 · UNLOCKED (declared) · no usable `flock` on this host, so the shared verify lock was NEVER taken and NOTHING was serialized · ran 102s (1m42s) · declare it in the PR body · pnpm exec turbo run build --filter='./packages/*' --filter='./packages/*/*' --concurrency=4 os-verify-lock: VERDICT command-exit 0 · UNLOCKED (declared) · no usable `flock` on this host, so the shared verify lock was NEVER taken and NOTHING was serialized · ran 76s (1m16s) · declare it in the PR body · pnpm --filter @objectstack/rest exec vitest run --project local --maxWorkers=2 os-verify-lock: VERDICT command-exit 0 · UNLOCKED (declared) · no usable `flock` on this host, so the shared verify lock was NEVER taken and NOTHING was serialized · ran 2s · declare it in the PR body · pnpm --filter @objectstack/rest exec vitest run --project repo --maxWorkers=2 os-verify-lock: VERDICT command-exit 0 · UNLOCKED (declared) · no usable `flock` on this host, so the shared verify lock was NEVER taken and NOTHING was serialized · ran 9s · declare it in the PR body · pnpm --filter @objectstack/rest typecheck ``` The branch merged `origin/main` once (`93e4d69ba6`, merging `542670da6d`) before these runs, as the dispatch orders; `origin/main` has not moved since (read at 11:19Z). The merge brought PR #20626 and PR #20587 and touched none of this diff's files. The dependency closure was built first (`pnpm --filter '@objectstack/rest...' build`, 26 packages), then the whole workspace (`turbo run build --filter='./packages/*' --filter='./packages/*/*'`, 71 tasks, 71 successful). - **Tests:** `vitest run --project local`: 227 files, 4,382 tests passed, 50 skipped. `--project repo` (which holds the touched `meta-state-route-doc-spelling.test.ts`): 1 file, 8 tests passed. Together they are all 228 test files of the package, so every touched test file ran. - **Typecheck:** `pnpm --filter @objectstack/rest typecheck` exits 0. `tsc --listFiles` counts 28 `src` files (no tests) under `tsconfig.json` and all 228 test files under `tsconfig.test.json`, which `check:test-typecheck` judges: 0 files, 0 errors, 0 pinned signatures in the ledger. - **Lint:** the repo-wide `pnpm lint` (`eslint . --no-inline-config`) exits 0 at `93e4d69ba6` (2026-09-29T11:19:30Z to 11:20:00Z). Not narrowed. - **Citation judging:** `node scripts/check-issue-citations.mjs --base origin/main` exits 0: 19 citations judged across 14 files (18 resolve, 1 resolves as a pull request). These are the live numbers that stay on rewritten lines. It defers `*.test.ts`, so the added-minus-removed count over the whole diff covers the rest: 0 numbers added. - **Derived gates:** `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands` at `93e4d69ba6` derived 68 families. All 68 exit 0, and `--ran` over a record carrying each exit code reads 「68 derived, 68 run, 0 NOT-MEASURED, 0 UNRUN」 (a derived zero). - `check:dual-build-cjs-loads` and `check:type-check-debt` first exited 3 (PREREQUISITE NOT MET, nothing measured) on the closure-only build; after the whole-workspace build both exited 0. - Among them: `check:doc-authoring`, `check:nul-bytes`, `check:rest-log-declared`, `check:route-envelope`, `check:system-context-census` (106 elevation read sites, the page's 102 symbols held) and `check:issue-citations` (self-test). - **Artifact rosters:** 33 of the 36 non-self-test roster rows exit 0 at `93e4d69ba6`, `check-changeset-fixed` (the one whose roster sits under `.changeset/`) and `check:route-ledger-census` among them. The other three, `check-closing-target-claim`, `check-partof-closing-keyword` and `check-single-claim-paths`, answer 「NOT WIRED」 (exit 2) without a pull request's context; they are run against this PR once it exists and reported on the card. ## Hypotheses (measured first) - **H0 holds.** The filtered census answers 191 dead sites at `a186aea996` (186 lines, 14 files, 51 numbers), equal to the card's count at `f11b5f20a2`: no net drift, although PR #20601 (merged as `eb4b17c346`, before this base) touches four files in `packages/rest`. - **H1 holds.** After the rewrite the filtered census answers 0. The supplementary reading leaves 3 test-comment sites, the three listed above: an open decision, an untaken option and a transferred issue, none with a deciding commit. No site was held for an open PR: the claim's read and this stage's two reads of the open PRs' file lists (10:27:35Z, 7 open PRs; 11:30:34Z, 8 open PRs) found none touching `packages/rest`. - **H2 holds, by the token guard.** A comment-stripped comparison of every touched file (the parser's leaf tokens, JSDoc excluded) is empty, and its code and string controls fire. The emitted `dist` is not byte-identical, because the docblocks ship, which is why the changeset is `patch`. ## Acceptance notes - **Form D, not touched here.** 127 dead numbers stand inside string literals: 126 in test titles and test-code strings, and one in the `note` of the REST route ledger's legal-next-state row (`rest-route-ledger.ts:290`, 「(#10179)」), which is ledger data, not an author-shown refusal. Ruling D (no number, the lesson in words) is a string change outside this comment-only scope; the card already carries a form-D stage for the lane. - **A transferred issue among the 404s.** #14026 answers 302 to objectstack-ai/objectui#10102 on its web endpoint. The census classes it `allocated-but-absent` (deleted and transferred are only told apart under `--probe-cause`), and `scripts/check-issue-citations.mjs`'s header says the `transferred` arm has no positive specimen on this tree; this is one. Noted, not filed. - **The grammar does not read a slash-joined number.** `CITATION_RE` refuses a `#` preceded by `/`, so the second number of `#A/#B` is never judged. In `packages/rest/src` six such dead numbers stood at 10 comment sites, all rewritten here; one more, `#14389` in `#14095/#14389`, stands inside a string (`error-response-structured-arm-door-parity.test.ts:187`) and is kept. The same shape PR #20624 and PR #20612 reported. Noted, not filed. - **Outside the scope and the census surface.** `packages/rest/vitest.config.ts:21` cites #17853, which answers 404; `packages/rest/test-typecheck-debt.json`, written by `gen:test-typecheck-debt`, carries #13470, #13454, #13377 and #13378 in its prose, all 404. Neither is under `src/**`. The other numbers in `vitest.config.ts`, `tsconfig.json` and `tsconfig.test.json` answer 200. - **Two comments stale on their own, not touched.** The anchor research found `rest-server.ts`'s `api` docblock near `:1115` and the 「zero read sites」 sentence at `:4092` both overtaken by `80153f5a4`, whose own acceptance notes record it. This PR re-anchors their citations and leaves their claims alone. - **An attribution corrected by the anchor.** `rest-server.ts:4092` credited its zero-read-site count to 「the #14369 census」, which (`a3d5724c8`) excluded `api`; it now cites `53cbad9f7`, the commit that measured it. - **Base.** One merge of `origin/main` (`93e4d69ba6`) before the `--base origin/main` run, as the dispatch orders. ## Deviations - Ten sites beyond the census's read grammar carry a slash-joined dead number and are rewritten; six more lines are the other half of a rewritten sentence (listed under What changed). - The whole-workspace build ran with `--concurrency=4`, not 2, to stay inside the ten-minute foreground cap on this host; it took 1m42s. - Anchor research for 33 of the 77 numbers ran in three read-only research subagents; every proposal was verified here against the commit's message or diff, and the wording of each changed line was reviewed and corrected by hand in a second pass. - Commit trailers are AGENTS.md's model-free pair (`Claude-Session` plus `Co-authored-by: Claude`), and the pre-push trailer check passed on every push. The merge commit carries git's default message. --- _Generated by [Claude Code](https://claude.ai/code/session_local_1d2a197c-c20e-4e90-9be8-413d4d432289)_ --------- Co-authored-by: Jack Zhuang <50353452+hotlong@users.noreply.github.com> Co-authored-by: Claude <noreply@anthropic.com>
1 parent 5363e2d commit 04b202e

86 files changed

Lines changed: 462 additions & 451 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/rest': patch
3+
---
4+
5+
Provenance comments in `@objectstack/rest` 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 commit in this repository's history that
9+
decided the matter, and say in their own words what was decided. Comments
10+
only: no route, error code, refusal text, type, export or runtime behaviour
11+
changes.

‎packages/rest/src/analytics-dataset-selection-door.test.ts‎

Lines changed: 3 additions & 3 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-
* [#17058] `POST /analytics/dataset/query` parses its `selection` AT THE DOOR.
4+
* [commit 94c930248] `POST /analytics/dataset/query` parses its `selection` AT THE DOOR.
55
*
66
* The defect: the route checked only that `selection.measures` was a non-empty
77
* array, so every other member reached `dataset-executor` unrefused — while the
@@ -17,9 +17,9 @@
1717
* one that matters most: a fully-loaded VALID selection still passes. A door
1818
* that refuses too much is a worse defect than the one being fixed.
1919
*
20-
* ## [#17551, ruled] The half #17058 could not door
20+
* ## [#17551, ruled] The half commit 94c930248 could not door
2121
*
22-
* #17058 parsed a PROJECTION — the seven members whose declarations coincide
22+
* Commit 94c930248 parsed a PROJECTION — the seven members whose declarations coincide
2323
* with `AnalyticsQuery`'s — and projected `runtimeFilter`, `dateGranularity`,
2424
* `compareTo` and `totals` AWAY, because `DatasetSelection` had no Zod schema
2525
* anywhere in the repo and authoring one in this consumer is the second

‎packages/rest/src/analytics-fault-user-message.test.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
* ①b — the arm that re-dresses `classifiedRefusalAnswer`'s body with
2525
* `...refusalFields` — IS the arm the card measured, and it does carry the mark
2626
* because that body comes from `resolveErrorResponse`, whose arms already ride
27-
* it (`withDeclaredUserMessage`, #9934). §5 pins ①b as untouched, so the two
27+
* it (`withDeclaredUserMessage`, commit 79c46da90). §5 pins ①b as untouched, so the two
2828
* classified arms are not flattened into one story in either direction.
2929
*
3030
* What ①, ③a and ③b have in common is that none of them holds a classified body
@@ -43,7 +43,7 @@
4343
* 1. `classifyDataError` (`error-response.ts`), whose only caller is the
4444
* exported `mapDataError`, which IS `withDeclaredUserMessage(error,
4545
* classifyDataError(…))`. That door already carries the mark, applied one
46-
* layer OUT and branch-agnostically over every arm — the shape #9934 chose
46+
* layer OUT and branch-agnostically over every arm — the shape commit 79c46da90 chose
4747
* deliberately, and the reason the shared body-builder carries no mark of
4848
* its own.
4949
* 2. this route's ③a.
@@ -323,7 +323,7 @@ describe('[#12710] §4 both doors carry the same producer mark for the same thro
323323
const flat = dataDoor(c.error());
324324
// POSITIVE CONTROL — without this the analytics assertion below could pass
325325
// for the wrong reason (two doors agreeing the mark does not belong on
326-
// this terminal). #9934 rules that it does; `/data` is where that ruling
326+
// this terminal). The ruling commit 79c46da90 landed says it does; `/data` is where that ruling
327327
// already lives.
328328
expect(
329329
flat.body.userMessage,

‎packages/rest/src/auth-gate-allowlist-fault-window.measurement.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-
* [#15021] MEASUREMENT — does the #13906 fail-closed window also refuse the
4+
* [commit cc238db8b] MEASUREMENT — does the #13906 fail-closed window also refuse the
55
* ALLOW-LISTED remediation routes `isAuthGateAllowlisted` exists to keep
66
* reachable?
77
*
@@ -530,7 +530,7 @@ describe('[#15021] §5 can a mounted route capture a CONCRETE remediation path?'
530530
// mounts (`plugin-auth`'s `/api/v1/auth/*`, `plugin-hono-server`'s
531531
// `/auth/me/*`) that never enter `computeExecCtx`.
532532
//
533-
// ⚠️ If this goes RED, the reachability qualifier on #15021 is gone and the
533+
// ⚠️ If this goes RED, the reachability qualifier commit cc238db8b pinned is gone and the
534534
// card's impact sentence has become true: a mounted route now answers a
535535
// remediation path, and §2 says every such answer is 503 for the duration
536536
// of a session-backend fault. ⛔ Do not relax this to make a new mount

‎packages/rest/src/direct-mount-base-follows-apipath.test.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.
22
//
3-
// [#6306] ONE API base for the whole REST surface — pinned end to end through
3+
// [commit fec784863] ONE API base for the whole REST surface — pinned end to end through
44
// the plugin that composes it in production.
55
//
66
// The defect this replaces: `RestServer.getApiBasePath()` answers
@@ -13,7 +13,7 @@
1313
// `/api/v1` (`packages.*` ×4, `datasources/:name/external/*` ×5). Those 9
1414
// were also absent from `{apiPath}/openapi.json` (71 paths vs 79), because
1515
// that document is filtered to this server's base — the filter is what made
16-
// the split visible (#5822 / PR #6303).
16+
// the split visible (#5822 / commit 465c5fc14).
1717
//
1818
// What is pinned here, and at which level. This file drives
1919
// `createRestApiPlugin(config).start(ctx)` — the real composition — over a

‎packages/rest/src/discovery-advertised-direct-mounts.parity.test.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,15 @@
1717
// chain together against the live surface, so ANY future change that moves
1818
// only one side goes red here: move the mount without the advertisement (or
1919
// vice versa) and the advertised URL stops resolving in the handler table.
20-
// #6306 was the first such move and it landed with no edit in this file —
20+
// Commit fec784863 was the first such move and it landed with no edit in this file —
2121
// which is the property working, not the pin missing it.
2222
//
2323
// The non-default-base case is the load-bearing one: it drives the
2424
// composition at a base that is not `/api/v1` to prove nothing re-derives the
2525
// convention. Note the level this file measures at — it calls
2626
// `mountAndRecordDirectRoutes` directly, so `versionedBase` is its own
2727
// parameter and the projection is pinned independently of WHO chooses that
28-
// base. Since #6306 the production chooser is `RestServer.getApiBasePath()`
28+
// base. Since commit fec784863 the production chooser is `RestServer.getApiBasePath()`
2929
// (so `apiPath` deployments mount and advertise under `{apiPath}`); that
3030
// wiring — plugin config in, mounted+advertised+documented URLs out — is
3131
// pinned end to end in `direct-mount-base-follows-apipath.test.ts`.
@@ -219,7 +219,7 @@ describe('[#6633] /discovery advertises the direct-mount surfaces where they are
219219
// The mount base is an input here, deliberately decoupled from the
220220
// RestServer's own base: that is what proves the advertisement is read
221221
// off the recorded mounts rather than re-derived from config. It is also
222-
// what kept advertisement and mount inseparable across #6306's move.
222+
// what kept advertisement and mount inseparable across commit fec784863's move.
223223
const { table } = boot({ versionedBase: '/backend/api/v9' });
224224
const discovery = await readDiscovery(table);
225225

‎packages/rest/src/discovery-schema-conformance.test.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,8 @@ describe('[#4828] the REST /discovery live shape conforms to DiscoverySchema', (
340340
// line after calling the producer, so the wire answer was the MOUNTED PATH
341341
// SEGMENT (`'v1'` by default) — the string the caller had just typed to reach
342342
// the endpoint. `DiscoverySchema` declares `version` under "System Identity"
343-
// next to `name` and `environment`, and the #10993 ruling (reaffirmed by
344-
// #11235/#11242) settled that as the SERVING ARTIFACT's version.
343+
// next to `name` and `environment`, and the #10993 ruling (which commits
344+
// 98ea3443f and 376c70f98 landed) settled that as the SERVING ARTIFACT's version.
345345
//
346346
// Every assertion below pins PROVENANCE, never a literal version string: the
347347
// wire answer is compared against the producer's own answer, or against a

‎packages/rest/src/error-response-generic-passthrough-object-parity.test.ts‎

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

33
/**
4-
* #14725 — the GENERIC declared-status passthrough must answer one refusal
4+
* Commit f5cc78b63 — the GENERIC declared-status passthrough must answer one refusal
55
* with one body, on both REST error doors.
66
*
77
* ## What was measured, on `origin/main` @ `a12b15e394`
88
*
9-
* #14541 made the two doors agree for every error a BESPOKE arm classifies.
9+
* Commit 6d178a408 made the two doors agree for every error a BESPOKE arm classifies.
1010
* They still disagreed for every error that reaches the GENERIC declared-status
1111
* passthrough, because the two copies of that one passthrough differed by
1212
* exactly one key: `classifyDataError`'s copy ends `...(object ? { object } :
@@ -121,8 +121,8 @@ const singleDoor = (error: unknown, object?: string): Wire => mapDataError(error
121121
*
122122
* ⚠️ "Three siblings" is itself easy to over-read, so the measured limit: §3
123123
* keys on `RECORD_LOCKED`, one of §1's OWN codes, so an arm for that code
124-
* migrates §3 along with §1. Only §2 and #14541's §4 are independent of the
125-
* codes below. #14541 §5's "every arm in the SHARED classification has a §1
124+
* migrates §3 along with §1. Only §2 and the door-parity file's §4 are independent of the
125+
* codes below. The door-parity file's §5 "every arm in the SHARED classification has a §1
126126
* parity case" reddens when an arm ARRIVES, but goes green again as soon as its
127127
* author adds the parity case it asks for — it does not hold THIS file's §1 to
128128
* the passthrough.
@@ -140,7 +140,7 @@ describe('#14725 — the generic declared-status passthrough carries `object` on
140140
// The card's own measurement. `DUPLICATE_RECORD` HAS a bespoke arm
141141
// keyed on `DuplicateRecordError`'s class/`name`; a bare property
142142
// write does not carry it, which is exactly the shape the card
143-
// measured on the #14541 branch.
143+
// measured on the branch that landed as commit 6d178a408.
144144
{ code: 'DUPLICATE_RECORD', status: 409, message: 'A record with this value already exists' },
145145
{ code: 'RECORD_LOCKED', status: 409, message: 'This record is frozen' },
146146
// A 4xx from the other end of the band, so the pin is not a

‎packages/rest/src/error-response-sandbox-arm-message.test.ts‎

Lines changed: 10 additions & 10 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-
* #14704 — the single-record `/data` door must not ship the QuickJS debug
4+
* Commit 1c7adc73d — the single-record `/data` door must not ship the QuickJS debug
55
* wrapper out of a declared-code structured arm.
66
*
77
* ## What was measured, on `origin/main` @ `99b4deba49`
@@ -21,7 +21,7 @@
2121
*
2222
* The bulk door is right because #11588 taught `resolveErrorResponse`'s
2323
* declared-status passthrough to read `sandboxBusinessMessage`, and because
24-
* #14541 excludes a sandbox-origin error from the shared consult entirely. The
24+
* commit 6d178a408 excludes a sandbox-origin error from the shared consult entirely. The
2525
* single door reached the arms and shipped the wrapper — #11588's own defect,
2626
* one door over, with the direction reversed rather than closed.
2727
*
@@ -36,7 +36,7 @@
3636
* §3 the non-sandbox control: a plain producer on the same codes keeps
3737
* `error.message` byte for byte — the two-read rule is a read of a field
3838
* the sandbox populated, never a strip of the wrapper off `.message`;
39-
* §4 CONVERGED (#15071, maintainer ruling 2026-09-04 / batch #27, option B):
39+
* §4 CONVERGED (commit cf6e0a193, maintainer ruling 2026-09-04 / batch #27, option B):
4040
* a sandboxed CRASH carrying a declared code reaches the unwrap door's
4141
* sanitised `500 UNCLASSIFIED_FAULT` whatever code it declares — the
4242
* terminal moved above the arms (`isSandboxCrash`). This section was the
@@ -47,7 +47,7 @@
4747
* crash branch moves", so an ordinary declared refusal is untouched;
4848
* §5 the bulk-door control: this change is unreachable from
4949
* `resolveErrorResponse`, which declines the consult for a sandbox-origin
50-
* error (#14541), so nothing moves on those routes;
50+
* error (commit 6d178a408), so nothing moves on those routes;
5151
* §6 the drift guard: every arm in the shared classification that relays a
5252
* PRODUCER sentence asks the shared rule, so the next arm cannot
5353
* reintroduce the raw relay silently.
@@ -63,7 +63,7 @@ const HERE = dirname(fileURLToPath(import.meta.url));
6363

6464
/**
6565
* The classification's own source, read once: §4-derivation and §6 both scan it
66-
* — one re-derives the arm list from the tree (the #15071 ruling's execution
66+
* — one re-derives the arm list from the tree (the ruling commit cf6e0a193 landed: its execution
6767
* constraint), the other guards the sentence rule. Same package, so the read
6868
* does not escape it (AGENTS.md → cross-package test inputs).
6969
*/
@@ -233,8 +233,8 @@ describe('#14704 · the single `/data` door never ships the QuickJS wrapper out
233233
});
234234

235235
/**
236-
* FLIPPED by #15071, deliberately and in that card's PR, from
237-
* `ACCEPTED DIVERGENCE` to `CONVERGED` — the same discipline PR #15065 used
236+
* FLIPPED by commit cf6e0a193, deliberately and in that commit, from
237+
* `ACCEPTED DIVERGENCE` to `CONVERGED` — the same discipline commit 1c7adc73d used
238238
* on its own §4 one file over. ⛔ The section is not DELETED: it is the only
239239
* thing that would notice the divergence coming back, and what changes is
240240
* its verdict, not its existence.
@@ -256,7 +256,7 @@ describe('#14704 · the single `/data` door never ships the QuickJS wrapper out
256256
*
257257
* - **the flip**, per arm and by NAME over {@link ARMS} — the list the
258258
* ruling required be RE-DERIVED from the tree rather than copied from
259-
* #14704, and `§4-derivation` below is the guard that keeps it derived;
259+
* the list commit 1c7adc73d enumerated, and `§4-derivation` below is the guard that keeps it derived;
260260
* - **the positive control STAYS** and is still a control: the same crash
261261
* carrying NO declared code reaches the same sanitised 500, so a green
262262
* flip leg cannot be read as "the terminal swallowed everything";
@@ -337,7 +337,7 @@ describe('#14704 · the single `/data` door never ships the QuickJS wrapper out
337337

338338
/**
339339
* The ruling's own execution constraint: *"the seat re-derives the arm
340-
* list from the tree, not from #14704's list."* Re-deriving once is a
340+
* list from the tree, not from [commit 1c7adc73d]'s list."* Re-deriving once is a
341341
* reading that rots; this leg is the same re-derivation asked
342342
* mechanically, so the next arm added to the shared classification is
343343
* either covered above or excused here BY NAME.
@@ -422,7 +422,7 @@ describe('#14704 · the single `/data` door never ships the QuickJS wrapper out
422422
});
423423

424424
it('a sandbox-origin error never reaches the shared consult there (#14541)', () => {
425-
// Proof by the consequence #14541 recorded: the arms' structured
425+
// Proof by the consequence commit 6d178a408 recorded: the arms' structured
426426
// fields are absent on this door for a sandbox producer.
427427
const wire = bulkDoor(sandboxRefusal({ code: 'DELETE_RESTRICTED', status: 409, object: 'account', dependentObject: 'contact' }), 'account');
428428
expect(wire.body).not.toHaveProperty('dependentObject');

0 commit comments

Comments
 (0)