Skip to content

Commit f29c83d

Browse files
docs(lint): re-anchor the five dead tracker citations in authoring-rules.ts to the commits that decided them (#20631)
Part of #20597 Clause-②: no Stage 2 of the `packages/lint` dead-citation sweep (claim `5888191846`). Stage 1 (PR #20612) left `packages/lint/src/authoring-rules.ts` at its base blob while PR #20593 held the file. That PR has landed (`e651556e2d`). Each of the file's five comment and docblock lines that cited a tracker number answering 404 now cites, in ruling C+D's form C, the commit in this repository's history that decided what the line states. Each line still says what was decided. Comments only: 5 lines out, 5 in, in one file, plus one `@objectstack/lint` `patch` changeset. This PR says `Part of`: the form-D finding-message string at `validate-react-page-props.ts:1198` (`(#11284)`, shown to authors) stays on the card as a separate decision. It is byte-identical here (see Acceptance notes). ## Measurement The instrument is the gate's own `node scripts/check-issue-citations.mjs --census --json`, filtered to `packages/lint/`. - **Before:** base `1322cc72c9`, 2026-09-29T10:18:50Z to 10:22:33Z, board enumerated (185 pages, frontier #20627). Repo-wide `allocated-but-absent` 2,209. - **After:** head `2e1955b492`, 11:13:21Z to 11:16:47Z (185 pages, frontier #20630). Repo-wide `allocated-but-absent` 2,204, exactly 5 fewer. No finding at head is absent at base. | site in `authoring-rules.ts` | before | after | anchor | |---|---|---|---| | `:201` (the `AuthoringFinding.path` docblock) | #10064 | commit | `def0d3e63` | | `:1123` | #16659 | commit | `ecdfc9411` | | `:1722` | `(PR #8546)` | commit | `ba5e957ef` | | `:1748` | `[#19370]` | commit | `a227afa41` | | `:1768` | `[ADR-0090 D3 / #8310 → #19370]` | commit | `a227afa41` (ADR-0090 D3 and #8310 stay) | | **`packages/lint` total** | **5** | **0** | 4 numbers, to 4 distinct shas | The five lines on `origin/main` `e651556e2d` are the same lines at the base: `packages/lint` is byte-identical between `e651556e2d` and `1322cc72c9`. ## Why each anchor decides its line Each sha resolves uniquely (`rev-parse --disambiguate` gives 1 object). Each is single-parent. `merge-base --is-ancestor` exits 0 against `origin/main` and against the base, and the repository is not shallow. Each commit's own diff was read for the rule its line states. - **#10064 to `def0d3e63`**: "key collection-resident publish-gate finding paths by name, not the private snapshot index". Its body names #10064 as the card it lands, "(maintainer ruling 2026-08-20: Option A)". Its own diff wrote this very docblock: the positional-as-rules-emit-it sentence, the `objects.acme_invoice.sharingModel` example and the pointer to `nameKeyFindingPath`, which the same commit introduced in `runtime-gate.ts`. - **#16659 to `ecdfc9411`**: the squash commit that declares a time-triggered flow's acting organization. Its diff adds `FLOW_SCHEDULE_ORGANIZATION_MISSING` (`flow-schedule-organization-missing`, at `warning`) to `validate-flow-trigger-readiness.ts`. It also wrote the `authoring-rules.ts` sentence "... added a sixth id, `flow-schedule-organization-missing`, at `warning`" that this line opens, and its sub-commits name #16659. The live #17396 retirement beside it stays. - **`(PR #8546)` to `ba5e957ef`**: PR #8546's own squash commit, "permission/book cross the runtime publish gate; object measured dirty stays behind". Its `authoring-rules.ts` diff changes `runtimeTypes: ['seed']` to `['seed', 'permission', 'book']`, which is #8310 slice 1 as the line states. The live #8310 stays. - **#19370 to `a227afa41`** (two sites): "`security-role-word` crosses to the runtime publish gate, whole". Its body names #19370 as the card it lands. Its own `authoring-rules.ts` diff wrote both lines: "[#19370] It has since crossed, also whole, on its own entry" and the `[ADR-0090 D3 / #8310 → #19370]` marker. Stage 1 cited the same commit for the same number in `runtime-gate.ts` and `validate-security-posture.ts`. Rung: no file under `docs/adr/**`, `docs/NORTH-STAR.md` or `scripts/adr-anchors/` names any of the four numbers. So the commit rung is right, as in stage 1. ADR-0090 D3 already stands on `:1768` and is kept. ## Mechanical proof - **Token and residue guard.** A scratch instrument on the TypeScript 6.0.3 parser compares the base blob with the head blob at two levels. The first is leaf AST tokens, with JSDoc nodes excluded. The second is the non-comment residue: every comment range dropped, everything else compared byte for byte. The controls mutate the head text in memory only. - Real run: 3,543 tokens at base and at head, tokens EQUAL, residue EQUAL (exit 0). - Dark control, a whole comment line inserted: tokens EQUAL, residue EQUAL, comment ranges 957 to 958 (exit 0). - Lit control, a code statement inserted: DIFFER at token 0, residue DIFFER (exit 1). - Lit control, one character inserted into a parser-located string literal: DIFFER at token 5, residue DIFFER (exit 1). The first string control was a no-op and is void: it searched by text and landed in a comment, reading EQUAL. It was re-anchored on a parser-located literal and re-run. The mutation was confirmed landed. - **Line balance**: +5/−5, and every changed line is comment-shaped. The file has 2,011 lines at base and at head. - **Tracker numbers**: removed #10064, #16659, #8546 and #19370 ×2. The added lines carry only the live #8310 ×2, which stands on both the removed and the added side of `:1722` and `:1768`. So added-not-removed is empty, and no `PR #N` stands on an added line. There are 215 `#N` tokens at base and 210 at head. - **Shas**: 4 distinct on added lines (`a227afa41` ×2), none on removed lines. - **Literal readers**: `scripts/doc-authoring-prose-id.baseline.json` pins this file's string sites as #4463, #4716, #4717, #7220, #8309 and #9698, none of them these four numbers. `check-docs-transcript-drift` loads the registry module, not its comments. ## Tests and gates (at head `2e1955b492`) - Build under `os-verify-lock`: `pnpm exec turbo run build --concurrency=2 --filter=./packages/* --filter=./packages/*/*`. The last run printed Tasks 71 successful, 71 total, and VERDICT command-exit 0. It took three attempts inside a 270 s timeout on a shared box. The first two were cut off at 39 of 46 and 66 of 68 tasks, and turbo's cache carried their finished tasks forward. - `pnpm --filter @objectstack/lint exec vitest run --maxWorkers=2` under the lock: Test Files 115 passed (115), Tests 5379 passed (5379), VERDICT command-exit 0. - `pnpm --filter @objectstack/lint typecheck` under the lock: exit 0. `check:test-typecheck` OK (2 files, 6 errors, 2 pinned signatures held). VERDICT command-exit 0. - Lint, as a proven narrowing: `eslint --no-inline-config --format json packages/lint/src/authoring-rules.ts` reports 1 file, 0 errors, 0 warnings. `isPathIgnored` is false, read through eslint's API. `eslint.config.mjs:327-328` says type-aware linting is never enabled, so a comment edit cannot move an untouched file's verdict. The repo-wide `pnpm lint` is CI's. - `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands` derived 54 families, and all 54 ran with exit 0. `--ran` reads "54 derived, 54 run, 0 NOT-MEASURED, 0 UNRUN", a derived zero. Among them: - `node scripts/check-issue-citations.mjs`, the live diff-scoped run, judged 2 citations in 1 file, the kept #8310 ×2, and both answer as issues. `pnpm check:issue-citations` passes its self-test (114 cases in 8 batteries). - `pnpm check:doc-authoring`: the sibling prose-id baseline holds, 810 pinned sites across 230 files, no growth. - `pnpm check:nul-bytes`: OK over 9,253 tracked text files. A control-byte scan of both changed files finds none. - Generated pages: none to regenerate. No page under `content/docs/references/` names the four numbers, `AuthoringFinding` or `nameKeyFindingPath`, and no generator reads `packages/lint/src`. - Changeset: `patch` for `@objectstack/lint`, a new file (stage 1's `lint-provenance-anchors.md` is untouched). `files[]` ships `dist`, and the rewritten comments reach it: - `commit def0d3e` is in the `AuthoringFinding` docblock of `dist/runtime-*.d.ts`, beside the unchanged "Positional as RULES emit it", the positive control. - `commit ba5e957` (cited only here) and `commit a227afa` are in `dist/index.js` and `dist/index.cjs`. - None of the four numbers remains in `dist`. - Merge probe: a no-driver `merge-tree` of the head onto `origin/main` `542670da6d`, from a bare shared clone with no `merge.*` config, exits 0. None of the three commits `main` gained since the base touches `packages/lint`. - No ablation or reverse verification: the change is comment-only, so there is no behaviour to invert. ## Hypotheses (measured first) 1. **Holds.** At the base the census reads exactly 5 dead sites in `packages/lint`, all in `authoring-rules.ts`, and after the change it reads 0. The card's sixth site, the `(#11284)` string at `validate-react-page-props.ts:1198`, is outside the census because the census blanks string literals. It was read directly: still present, and the file is byte-identical from base to head. 2. **Holds.** The five sites read `:201` #10064, `:1123` #16659, `:1722` `(PR #8546)`, `:1748` and `:1768` #19370, on `e651556e2d` and at the base alike. All four anchors were re-verified above from their own diffs, not copied. 3. **Holds.** PR #20593's new lines cite #20553, #20611 and #20552 (and ADR-0041). All three answer 200, and the census finds no dead site on them. None of the five lines' sentences changed in meaning. The one adjacency is described under Acceptance notes. ## Deviations - Commit trailers follow AGENTS.md's model-free pair (`Claude-Session` plus `Co-authored-by: Claude`), not the model-named trailer the harness reminder suggested. The pre-push trailer check passed on both pushes. - The first lit string control was a no-op: it searched by text and landed in a comment. It is reported void above and was re-run on a parser-located literal. ## Acceptance notes **Form D, not touched (why this PR says `Part of`):** `validate-react-page-props.ts:1198` is the `react-prop-deprecated` finding `message`. It ends "...is removed after the deprecation window (#11284)." An author sees it, so it takes ruling D (no number). That is a string change, outside this comment-only claim. `scripts/doc-authoring-prose-id.baseline.json` pins it (`#11284: 1` for that file), and that baseline is shrink-only. **An ordinal beside PR #20593's insertion, kept verbatim:** the paragraph above `:1123` now ends "#20553 made it five", counting the rules that emit `error`. `:1123` reads "Commit ecdfc94 added a sixth id", an ordinal that commit wrote itself. The two count different things: rules that emit `error`, and ids in the rule file. The ordinal is also imprecise on its own terms, because `validate-flow-trigger-readiness.ts` exported six ids before `ecdfc9411`, so the new one was its seventh. This PR moves only the tracker number, so the word stays as written. **Outside the census's surface (noted, not swept):** stage 1 notes that lint test titles and hand-written docs still cite these numbers. `content/docs/deployment/validating-metadata.mdx` cites #19370 at `:472`, `:483` and `:515`. --- _Generated by [Claude Code](https://claude.ai/code/session_014EJ1ED8X4MMrT18BhVx4tx)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 3f45b6c commit f29c83d

2 files changed

Lines changed: 16 additions & 5 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
---
2+
'@objectstack/lint': patch
3+
---
4+
5+
Provenance comments in `@objectstack/lint`'s authoring-rule registry were re-anchored
6+
7+
Five comment and docblock lines in `src/authoring-rules.ts` that cited tracker
8+
numbers which no longer resolve on GitHub now cite the commit in this
9+
repository's history that decided the matter, and keep saying what was
10+
decided. Comments only: no rule id, finding message, hint, severity, type or
11+
runtime behaviour changes.

‎packages/lint/src/authoring-rules.ts‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ export interface AuthoringFinding {
198198
* on the runtime gate's wire surface the top-level collection index of a
199199
* collection-resident finding is rewritten to the entry's NAME
200200
* (`objects.acme_invoice.sharingModel`) — see `nameKeyFindingPath` in
201-
* `runtime-gate.ts` (#10064).
201+
* `runtime-gate.ts` (commit def0d3e63).
202202
*/
203203
path: string;
204204
/** What is wrong. */
@@ -1120,7 +1120,7 @@ export const AUTHORING_RULES: readonly AuthoringRule[] = [
11201120
// cannot decide), as did `flow-draft-status-ambiguous` (draft flows DO fire;
11211121
// that one is ambiguity of intent, not a dead flow).
11221122
//
1123-
// #16659 added a sixth id, `flow-schedule-organization-missing`, at
1123+
// Commit ecdfc9411 added a sixth id, `flow-schedule-organization-missing`, at
11241124
// `warning`; #17396 RETIRED it. The criterion above is what retired it: this
11251125
// stack is not enough to know the flow is dead, because a deployment-level
11261126
// switch and the tenancy posture decide whether the key is required, and
@@ -1719,7 +1719,7 @@ export const AUTHORING_RULES: readonly AuthoringRule[] = [
17191719
// `security-master-detail-ungranted` per-write vs 4 whole-stack,
17201720
// PR #7886). `RuntimeStackContext` now carries `permissions`/`books` in
17211721
// BOTH differential passes and `TYPE_TO_STACK_KEY` maps both types.
1722-
// - #8310 slice 1: `runtimeTypes` gains `permission` + `book` (PR #8546).
1722+
// - #8310 slice 1: `runtimeTypes` gains `permission` + `book` (commit ba5e957ef).
17231723
// `object` measured DIRTY on that tree and was escalated, not forced.
17241724
// - #8310 slice 2 (this state): `object` crosses under the maintainer
17251725
// ruling recorded on #8310 (2026-08-13, 「接受你的全部建议」): an
@@ -1745,7 +1745,7 @@ export const AUTHORING_RULES: readonly AuthoringRule[] = [
17451745
// where a permission set named `role_manager` is refused and a position named
17461746
// `sales_role` walks through, the #7220 failure this table refuses to build
17471747
// in either direction. So it was split out and held back WHOLE (#8310's
1748-
// explicit call). [#19370] It has since crossed, also whole, on its own
1748+
// explicit call). [commit a227afa41] It has since crossed, also whole, on its own
17491749
// entry; the split is what let each half cross on its own evidence, and it
17501750
// stays split for that reason rather than being folded back.
17511751
//
@@ -1765,7 +1765,7 @@ export const AUTHORING_RULES: readonly AuthoringRule[] = [
17651765
runtimeTypes: ['seed', 'permission', 'book', 'object'],
17661766
run: (stack) => validateSecurityPosture(stack),
17671767
},
1768-
// [ADR-0090 D3 / #8310 → #19370] The vocabulary freeze, split out of
1768+
// [ADR-0090 D3 / #8310 → commit a227afa41] The vocabulary freeze, split out of
17691769
// `validateSecurityPosture` the day the rest of that block crossed the
17701770
// runtime wall — so that it could stay behind WHOLE rather than cross for
17711771
// three of the six collections it judges (#7220: one rule id must sit on ONE

0 commit comments

Comments
 (0)