Skip to content

Commit aa23e2c

Browse files
docs(lint): re-anchor the dead tracker citations in packages/lint/src to the commits that decided them (#20612)
Part of #20597 Clause-②: no The `packages/lint` stage of the dead-citation sweep: the `domain:spec` lane's only package (census `5884031174` on #20556, claim `5885046469`). Every comment or docblock line in 22 of the 23 claimed `packages/lint/src/` files 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 describes, and says in its own words what was decided. Comments only: 81 lines out, 81 in, across 22 files. No code token, string literal, rule message, hint or rule id moves. `authoring-rules.ts` (5 sites) is excluded and left at its base blob: PR #20593 (#20553) edits it and was still open at the last read (2026-09-29T07:34Z). So this PR says `Part of`: those 5 sites stay for a follow-up once that PR lands, with their anchors already verified (see Acceptance notes). The census is the gate's own `node scripts/check-issue-citations.mjs --census --json`, filtered to `packages/lint/`. Before: base `7a1faf1a5d`, 2026-09-29T06:42:03Z to 06:45:24Z, board enumerated (185 pages, frontier #20606). After: head `0c7b847f18`, 07:28:22Z to 07:31:52Z (185 pages, frontier #20611). ## Measurement | file (under `packages/lint/src/`) | dead before | after | numbers, then anchor | |---|---:|---:|---| | `lint-flow-patterns.ts` | 9 | 0 | #13681 ×9 to `8ed9c54b4` (#14394 stays, 200) | | `validate-hook-body-writes.ts` | 9 | 0 | #8663 ×6 to `192213f66`; #13657 ×3 to `b003cf2e8` | | `runtime-gate.ts` | 8 | 0 | #10064 ×5 to `def0d3e63`; #19370 ×2 to `a227afa41` (#19143 stays); #9798 to `c7655d472` (#9261 stays) | | `validate-searchable-fields.ts` | 7 | 0 | #8404 ×4 to `b849e6911`, the `pre-#8404` control at `:312` included; #10001 ×3 to `f1b5ad39a` | | `authoring-rules.ts` | 5 | **5** | excluded: PR #20593 holds the file | | `validate-expressions.ts` | 5 | 0 | #6290 ×5 to `e9b526597` (#6584, that commit's own PR, stays) | | `validate-react-page-props.ts` | 5 | 0 | #11284 ×4 to `5383fa670`; #8404 to `b849e6911` | | `validate-sortable-fields.ts` | 5 | 0 | #10001 ×4 to `f1b5ad39a`; #8404 to `b849e6911` | | `validate-flow-node-writes.ts` | 4 | 0 | #8663 ×4 to `192213f66` | | `validate-page-field-bindings.ts` | 4 | 0 | #6629 ×2 to `cd584d559` (plus the slash-joined `:208`, see Deviations); #8664 ×2 to `8798cd2a6` | | `validate-translation-references.ts` | 4 | 0 | #14700 ×3 to `de3c52beb` (#14253 stays); #6124 to `b3c1f3cd5` | | `lint-liveness-properties.ts` | 3 | 0 | #10262 ×3 to `2aca1bc4c` | | `validate-action-body-writes.ts` | 3 | 0 | #8663 ×3 to `192213f66` | | `validate-security-posture.ts` | 3 | 0 | #19370 ×3 to `a227afa41` (#8310 stays) | | `flow-template-grammar.ts` | 2 | 0 | #11060 ×2 to `815585513` | | `data-model-rules.ts` | 1 | 0 | #10064 to `def0d3e63` | | `reference-integrity-suite.ts` | 1 | 0 | #13653 to `36d287803` | | `validate-component-types.ts` | 1 | 0 | #12950 to `225e7690f` (#12183 stays) | | `validate-empty-combinators.ts` | 1 | 0 | #6528 to `3510e4a25` (#5659 stays) | | `validate-list-view-field-refs.ts` | 1 | 0 | #10001 to `f1b5ad39a` | | `validate-readonly-action-writes.ts` | 1 | 0 | #13653 to `36d287803` | | `validate-readonly-flow-writes.ts` | 1 | 0 | #13653 to `36d287803` | | `validate-readonly-hook-writes.ts` | 1 | 0 | #13653 to `36d287803` | | **23 files** | **84** | **5** | 21 numbers; 19 removed from the 22 edited files, to 19 distinct shas | Per-file counts at base equal the claim's (census at `f11b5f20a2`) in all 23 files. A second instrument agrees site for site: every `#N` in the 23 files, classified by the TypeScript parser as comment, string or code, and each of 360 distinct numbers probed by REST `issues/N` without following redirects. At base it found 1,323 sites (1,259 comment, 64 string, 0 code); 339 numbers answer 200 and 21 answer 404, the census's 21. Its dead comment sites are the census's 84 plus one slash-joined `#5775/#6629` the grammar does not read, and it found one dead **string**: `validate-react-page-props.ts:1198` (see Acceptance notes). At head: 1,243 sites and 344 numbers, the same 339 answer 200, and 5 answer 404, all in `authoring-rules.ts` comments or that one string. Lit controls #16862, #16847 and #17698 answered 200, and dead controls #16714, #16715 and #16697 answered 404, at every checkpoint (5 at base, 5 at head). ## Why each anchor decides its line Each sha resolves uniquely, is an ancestor of `origin/main` and of the base, has one parent, and names the number it replaces in its own message (15 of 19) or its own diff (17 of 19); every one does at least one. Each was read for the rule its line states. - **#13681 to `8ed9c54b4`**: lands the per-iteration containment rule PAIR (`flow-loop-body-uncontained`, `flow-try-catch-without-catch`) and its measured minimal `catch`; its diff wrote all nine lines, and its changeset records the measurements the lines cite. #14394 (the rule card, 200) stays beside it. - **#8663 to `192213f66`**: "three write rules ask anchor provenance before exempting a system column"; its body names #8663 and its diff wrote the `[#8663]` lines in all three rule files. - **#13657 to `b003cf2e8`**: the post-hook half of the declared-field door, one envelope on every driver; its diff wrote the three lines. - **#10064 to `def0d3e63`**: name-keys collection-resident publish-gate finding paths; its body reads "maintainer ruling 2026-08-20: Option A" for #10064. - **#19370 to `a227afa41`**: `security-role-word` crosses to the runtime publish gate, whole, per ruling batch #203 item 3 letter B; it maps `position` / `app` and writes the past-tense crossing lines. - **#9798 to `c7655d472`**: the change that carried #9798 to done (its body names it), restoring the sys_comment unscoped multi-delete refusal that could not fire through the wired engine, the declared-but-unenforced fail-open the line lists beside #9261 and ADR-0110 D3. - **#8404 to `b849e6911`**: warns when `searchableFields` declares an unprovisioned injected anchor, adding the optional provenance index the lines describe; the SORT twin line names it as the SEARCH wiring. - **#10001 to `f1b5ad39a`**: a standalone ViewItem record's nested `config.sort` / `config.searchableFields` reach the runtime publish gate, the RECORD rung. - **#6290 to `e9b526597`**: `current_user` joins `SCOPE_ROOTS`, the field-level rejection becomes its own rule, and option-level `visibleWhen` is walked for the first time. `:770` quotes `SCOPE_ROOTS`' docblock in `packages/formula`; the quote now stops at "the last one this list was missing", verbatim, with the commit outside the quotation. - **#11284 to `5383fa670`**: the ListView react-tier vocabulary converges on the metadata-tier spelling, deprecate-first; its changeset reads "(#11284, maintainer ruling 2026-08-23)". - **#6629 to `cd584d559`**: drops the retired `displayField` / `searchFields` from the record_picker entry and adds `component-field-specs-liveness.test.ts`. - **#8664 to `8798cd2a6`**: names what actually guards the `unprovisionedAnchors` wiring; its diff wrote both lines. - **#14700 to `de3c52beb`**: descends into `conditional` `then` / `otherwise` when building the `_validations` universe; its diff wrote all three lines. - **#6124 to `b3c1f3cd5`**: the squash commit of #6124 itself, leg 1 of the `_views` key ruling (the CLI i18n extractor keyed by the runtime view identity). - **#10262 to `2aca1bc4c`**: adds the package-internal test seam for `getNested`'s array fan-out; its diff wrote all three lines. - **#11060 to `815585513`**: its body records "Maintainer ruling on #11060 (2026-08-23): option A", the CEL-mirrored six with no second semantics, which the lines quote. - **#13653 to `36d287803`**: gates a hook body's `ctx.api` write to a readonly field, and shares `buildReadonlyIndex` from the flow rule, the export `:118` describes. - **#12950 to `225e7690f`**: created `validate-component-types.ts`, the author-time rejection for unknown component types in spec-reserved namespaces (stage 5's anchor for the same number). - **#6528 to `3510e4a25`**: the squash commit of #6528 itself, one implementation of the filter identity reduction (maintainer ruling 2026-08-06, option 1). The line read `PR #6528`; it now names the commit. Rung: no ADR, `docs/NORTH-STAR.md` or `scripts/adr-anchors/` file records any of these 19 decisions (the one lint anchor file, `data-model-rules.ts`, pins ADR-0120, which none of these lines cites), so the commit rung is the right one, as in #20234's stages. ## Mechanical proof - **Token guard** (scratch `tokcmp.mjs`: TypeScript 6.0.3 leaf tokens, JSDoc kinds excluded, controls mutate the head text in memory only). The merge base `c96beb2707` against the head, 22 files, 54,508 base tokens (the 22 files are byte-identical at `7a1faf1a5d` and at the merge base): - Real run: 0 files with a token change (exit 0). - Comment-insertion control (`runtime-gate.ts`): 0 (exit 0). - Code-insertion positive control (`validate-hook-body-writes.ts`): DIFFER at token 216 (exit 1). - String positive control (a parser-located `StringLiteral` in `validate-react-page-props.ts`): DIFFER at token 5 (exit 1). - **Line balance**: every file is +N/−N (81/81 across 22 files), every changed line is comment-shaped, and every line count is equal at base and head. - **Tracker numbers**: added-not-removed is empty in every file, and no `PR #N` stands on an added line. Net-removed: 80 sites (the census's 79 in these files plus the slash-joined one), 19 numbers. The numbers kept on added lines all answer 200: #5659, #5775, #8310, #8340, #9261, #9313, #12183, #13390, #14253, #14394, #19143, and #6584 (a pull request, the anchor commit's own PR). - **Shas**: 19 distinct on added lines, 0 on removed lines. `rev-parse --disambiguate` answers 1 object for each; `merge-base --is-ancestor` exits 0 against `origin/main` and against the base; each is single-parent; the repository is not shallow; the control leg `e9584681a4` exits 0. - **Literal readers**: every string or regex literal in the repository that carries one of the 21 numbers (85 literals) was matched against the 23 files' text: no reader of any rewritten line. The lint tests that read these sources as text stay green below. For example, `validate-expressions.test.ts` strips comments before it matches, and `validate-security-posture.runtime-surface.test.ts` collects the `stack.X` reads inside `validateSecurityRoleWord`, which no added line carries. ## Tests and gates (at head `0c7b847f18`) - `pnpm exec turbo run build --concurrency=2 --filter=./packages/* --filter=./packages/*/*` under `os-verify-lock`: Tasks 71 successful, 71 total, VERDICT command-exit 0. - `pnpm --filter @objectstack/lint exec vitest run --maxWorkers=2` under the lock: Test Files 115 passed (115), Tests 5363 passed (5363); then `pnpm --filter @objectstack/lint typecheck`: exit 0, `check:test-typecheck` OK (2 files / 6 errors / 2 pinned signatures held). VERDICT command-exit 0. The same two runs passed with the same counts on the pre-merge head `2ce32f6b48`. - Lint, a proven narrowing: `eslint --no-inline-config --format json` over the 22 touched `.ts` files gives 22 files, 0 errors, 0 warnings. `isPathIgnored` is false for all 22, 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`: 54 families derived, all run, every one exit 0. `--ran` reads "54 derived, 54 run, 0 NOT-MEASURED, 0 UNRUN", a derived zero (every line carries its exit code). Among them: - `node scripts/check-issue-citations.mjs` (the live diff-scoped run) judged 18 citations across 22 files: 17 answer as issues and 1 answers as a pull request, the kept #6584; `pnpm check:issue-citations` (self-test, 114 cases in 8 batteries) passes. - `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,239 tracked text files; a control-byte scan of the 23 changed files finds none. - No generated page carries a lint docblock: no page under `content/docs/references/` names any of the 19 numbers, and no generator reads `packages/lint/src`, so nothing was regenerated. - Changeset: `patch` for `@objectstack/lint`. `files[]` ships `dist`, and the rewritten comments reach it: 12 of the 19 shas appear in the built `dist` (for example `8ed9c54b4` and `def0d3e63` in `index.d.ts`, `b849e6911` in `index.js` and `index.d.ts`); the positive control, the unchanged sentence "the near-miss shape: a `try_catch` that declares no `catch`" of an exported docblock, is in `index.d.ts`. Hence patch, not `skip-changeset`. - Merge probe: a no-driver `merge-tree` of the head onto `origin/main` `0f6dcac5e9`, from a bare shared clone with no `merge.*` config, exits 0. The two commits `main` gained after the merge touch none of the 23 files. - No ablation or reverse verification: the change is comment-only, so there is no behaviour to invert. ## Hypotheses (measured first) 1. **Holds.** 84 dead sites, 21 numbers, 23 files at the tip `7a1faf1a5d`, equal per file to the claim. 2. **Holds.** Only comment and docblock lines moved. The one dead number inside a string (`validate-react-page-props.ts:1198`, a finding `message`) stays byte-identical; no test or script reads a rewritten line by literal. 3. **Holds, and conditions the card.** PR #20593 was still open at 07:34Z, so `authoring-rules.ts` stays at its base blob. At that read, the 9 open PRs' full file lists and the newest `Claim:` on all 11 `pm:dispatched` cards name none of the other 23 paths. 4. **Holds.** `validate-searchable-fields.ts:312` `pre-#8404` is listed dead before and is gone after. 5. **Holds, with nothing to regenerate.** No lint docblock projects into a generated page; no release page is touched. ## Deviations - Two changed lines beyond the census's sites. `validate-page-field-bindings.ts:208` carried `#5775/#6629`, a slash-joined dead number the citation grammar does not read; it now reads "the same #5775 residue class (commit cd584d5)", stage 5's precedent for the slash-joined `#9972`. `runtime-gate.ts:780` is the other half of the rewritten `:779` sentence and held no number. - `origin/main` was merged once (`0c7b847f18`, merging `c96beb2707`): the first derivation read STALE TREE because `scripts/sdui-manifest.record.json` changed on `main`. The merge was clean, no driver-routed path and no lockfile change, and it touches none of the 23 files; the build, tests and gates above ran after it. - Commit trailers follow AGENTS.md's model-free pair (`Claude-Session` plus `Co-authored-by: Claude`); the pre-push trailer check passed on every push. ## Acceptance notes **What stays for this card** (why it says `Part of`): `authoring-rules.ts`, 5 sites, excluded while PR #20593 holds it. Anchors, verified the same way, for whoever takes it after that PR lands: `:198` #10064 to `def0d3e63`; `:1117` #16659 to `ecdfc9411` (it added `flow-schedule-organization-missing` to the registry); `:1687` "(PR #8546)" to `ba5e957ef`, that PR's own squash commit; `:1713` and `:1733` #19370 to `a227afa41`. **Form D, not touched:** `validate-react-page-props.ts:1198` is the `react-prop-deprecated` finding `message`, which ends "...is removed after the deprecation window (#11284)." An author sees it, so it takes ruling D (no number), which is a string change and outside this comment-only scope. `scripts/doc-authoring-prose-id.baseline.json` pins it (`#11284: 1` for this file). It needs a form-D carrier. **Outside the census's surface**, which blanks strings and defers test files (noted, not swept here): - `packages/lint/src/*.test.ts` titles and comments still cite several of these dead numbers (#6290, #8404, #8663, #10001, #10064, #10262, #13681, #19370 and others). - Hand-written docs pages cite them too: `content/docs/automation/hook-bodies.mdx` (#8663, #13657), `content/docs/automation/flows.mdx` (#11060) and `content/docs/deployment/validating-metadata.mdx` (#19370). - `packages/formula/src/cel-engine.ts` cites #6290 four times, including the docblock `validate-expressions.ts:770` quotes. It is in the census, in another lane's package. **Wording, each true of its commit.** - `validate-expressions.ts:571` keeps #6584 beside `e9b526597`: #6584 is that commit's own PR, so "arrived in commit e9b5265, and needed that same change (#6584) to be noticed" states the one act both old numbers named. - `runtime-gate.ts:362` names the #9798 shape in words, as the fail-open that commit c7655d4 ended, next to #9261 and ADR-0110 D3. - `lint-flow-patterns.ts:343` reads "The measured case commit 8ed9c54 records, exactly: one row with a null owner killed the sweep"; that commit wrote the sentence, and `c02f70e13` later fixed the same shape in the showcase flow. --- _Generated by [Claude Code](https://claude.ai/code/session_014EJ1ED8X4MMrT18BhVx4tx)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 7510663 commit aa23e2c

23 files changed

Lines changed: 92 additions & 81 deletions
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` 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 rule id, finding message, hint, severity, type or runtime behaviour
11+
changes.

‎packages/lint/src/data-model-rules.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export interface LintIssue {
6161
* runtime gate's `fingerprint` reads `where` and `path` together (making
6262
* `where` more specific cannot merge two findings that were distinct).
6363
*
64-
* [#10064] On the runtime gate's WIRE surface (`RuntimeAuthoringIssue.path`,
64+
* [commit def0d3e63] On the runtime gate's WIRE surface (`RuntimeAuthoringIssue.path`,
6565
* the 422 `issues[]` / 2xx `advisories`), the top-level collection index of a
6666
* collection-resident finding is rewritten to the entry's NAME
6767
* (`objects[417].sharingModel` → `objects.acme_invoice.sharingModel`) after

‎packages/lint/src/flow-template-grammar.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
* - `NOW()` / `TODAY()` with an optional `± N` day offset — closed, two names.
3232
* - `$User.<path>` — closed prefix.
3333
* - `round` / `floor` / `ceil` / `abs` / `min` / `max` in CALL position —
34-
* closed by maintainer ruling on #11060 ("exactly … every name and semantic
34+
* closed by the maintainer ruling commit 815585513 records ("exactly … every name and semantic
3535
* mirrored **1:1 from the CEL stdlib**, ⛔ no second semantics invented").
3636
* - a bare or dotted identifier (`{recordId}`, `{record.id}`, `{status}`) —
3737
* **OPEN**: it addresses the run's `VariableMap`, which holds the flow's
@@ -101,7 +101,7 @@ export const FLOW_TEMPLATE_DATE_FUNCTIONS: readonly string[] = ['NOW', 'TODAY'];
101101

102102
/**
103103
* The value-expression function table — the CEL stdlib's numeric six, by the
104-
* #11060 ruling. Mirrors `EXPRESSION_FUNCTION_ARITY`'s key set.
104+
* ruling commit 815585513 records. Mirrors `EXPRESSION_FUNCTION_ARITY`'s key set.
105105
*/
106106
export const FLOW_TEMPLATE_VALUE_FUNCTIONS: readonly string[] = [
107107
'round', 'floor', 'ceil', 'abs', 'min', 'max',

‎packages/lint/src/lint-flow-patterns.ts‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
* specifically (range operators `>=`/`<=` are not flagged — they're the building
5656
* block of the correct pattern), keeping false positives near zero.
5757
*
58-
* #13681 / #14394 — per-iteration containment, as a PAIR of rules. A `loop`
58+
* commit 8ed9c54b4 / #14394 — per-iteration containment, as a PAIR of rules. A `loop`
5959
* body has no error handling of its own: `loop-node.ts` iterates with a bare
6060
* `await`, so the first item whose node fails ends the entire run and every
6161
* later item goes unprocessed, silently. The containment spelling exists and was
@@ -261,7 +261,7 @@ export const FLOW_DECISION_INCLUSIVE_OVERLAP = 'flow-decision-inclusive-overlap'
261261
*/
262262
export const FLOW_MULTI_WRITE_UNFILTERED = 'flow-multi-write-unfiltered';
263263
/**
264-
* #13681 / #14394 — a `loop` body that runs a node which can fail, with no
264+
* commit 8ed9c54b4 / #14394 — a `loop` body that runs a node which can fail, with no
265265
* `try_catch` between the loop and that node. The first failing item kills the
266266
* whole sweep: `loop-node.ts:123-135` iterates with a bare `await` and no
267267
* `try`/`catch` anywhere in the file, so the body's failure propagates out of
@@ -279,7 +279,7 @@ export const FLOW_MULTI_WRITE_UNFILTERED = 'flow-multi-write-unfiltered';
279279
*/
280280
export const FLOW_LOOP_BODY_UNCONTAINED = 'flow-loop-body-uncontained';
281281
/**
282-
* #13681 / #14394 — the near-miss shape: a `try_catch` that declares no `catch`
282+
* commit 8ed9c54b4 / #14394 — the near-miss shape: a `try_catch` that declares no `catch`
283283
* region. `catch` is optional in the schema (`control-flow.zod.ts:315`) and
284284
* omitting it makes the container **fail** (`try-catch-node.ts:190`), so the
285285
* wrapped region dies exactly like an unwrapped one — measured side by side, the
@@ -340,7 +340,7 @@ const DATA_NODE_TYPES = new Set(['get_record', 'create_record', 'update_record',
340340
* - `http` — a non-2xx (when `failOnError`), a timeout/abort, or a failed
341341
* durable enqueue (`http-nodes.ts:208, :249-253`).
342342
* - `notify` — no title, an empty resolved recipient set, or a delivery throw
343-
* (`notify-node.ts:293, :300, :446`). The measured #13681 case exactly: one
343+
* (`notify-node.ts:293, :300, :446`). The measured case commit 8ed9c54b4 records, exactly: one
344344
* row with a null owner killed the sweep.
345345
* - `connector_action` — a degraded connector, an unresolvable action, or a
346346
* throwing call (`connector-nodes.ts:69, :76, :124`).
@@ -1330,7 +1330,7 @@ function scanApprovalReviseLoops(
13301330

13311331
/**
13321332
* The minimal `catch` region, measured end to end on the real `AutomationEngine`
1333-
* (#13681) and quoted verbatim by both containment rules and by
1333+
* (commit 8ed9c54b4) and quoted verbatim by both containment rules and by
13341334
* `content/docs/automation/flows.mdx`.
13351335
*
13361336
* `catch` cannot be empty: `FlowRegionSchema.nodes` is `.min(1)`
@@ -1425,7 +1425,7 @@ function scanUncontainedLoopBodies(
14251425
`that is a legitimate reading and this stays a warning. ` +
14261426
// The tracker ids stay OUT of the runtime string (`check:doc-authoring`):
14271427
// an author reading this hint cannot resolve `#NNNN`. The measurement
1428-
// and the ruling behind this rule are #13681 / #14394; the docblock on
1428+
// and the ruling behind this rule are commit 8ed9c54b4 / #14394; the docblock on
14291429
// {@link FLOW_LOOP_BODY_UNCONTAINED} carries them for the reader who can.
14301430
`See content/docs/automation/flows.mdx §"Per-iteration containment".`,
14311431
// Warning, not `error`: see the severity policy at the top of this
@@ -1465,7 +1465,7 @@ function scanUncontainedLoopBodies(
14651465
/**
14661466
* #14394 rule B — a `try_catch` with no `catch` region, anywhere in the flow.
14671467
*
1468-
* Measured (#13681): the container fails through, and the run is byte-identical
1468+
* Measured (commit 8ed9c54b4): the container fails through, and the run is byte-identical
14691469
* to the one with no `try_catch` at all. `retry`, when present, only delays it.
14701470
*
14711471
* A `catch` that is PRESENT but malformed is deliberately not this rule's
@@ -1737,15 +1737,15 @@ export function lintFlowPatterns(stack: AnyRec): FlowLintFinding[] {
17371737
// purge, and this rule's main habitat — in range (#5383/#5635).
17381738
scanUnboundedBulkWrites(at, graphNodes, findings);
17391739

1740-
// (g) #13681/#14394 — a `loop` body running a fallible node with no
1740+
// (g) commit 8ed9c54b4 / #14394 — a `loop` body running a fallible node with no
17411741
// `try_catch` between the loop and it. Per graph like the rest, and
17421742
// that is what keeps the count right: every `loop` node belongs to
17431743
// exactly one graph, so its body is descended exactly once, and a
17441744
// nested loop is judged in its own graph rather than through its
17451745
// parent (see {@link scanUncontainedLoopBodies}).
17461746
scanUncontainedLoopBodies(at, graphNodes, findings);
17471747

1748-
// (h) #13681/#14394 — the near-miss: a `try_catch` with no `catch`. Scanned
1748+
// (h) commit 8ed9c54b4 / #14394 — the near-miss: a `try_catch` with no `catch`. Scanned
17491749
// everywhere, not only inside a loop: the container fails through
17501750
// wherever it is written. Inside a loop body it is the shape (g)
17511751
// deliberately treats as contained, so exactly one of the two rules

‎packages/lint/src/lint-liveness-properties.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ function describe(entry: LedgerEntry): { kind: string; rule: string; defaultHint
273273

274274
/**
275275
* ── Coverage seam (#14057). Package-internal: NOT part of the published surface,
276-
* same posture as the #10262 seam below `getNested` (exported from the MODULE
276+
* same posture as the test seam commit 2aca1bc4c added below `getNested` (exported from the MODULE
277277
* only; `src/index.ts` re-exports neither, and this package's `exports` map
278278
* publishes just `.` and `./runtime`). ────────────────────────────────────
279279
*
@@ -431,7 +431,7 @@ export function getNested(obj: AnyRec, path: string): unknown[] {
431431
}
432432

433433
/**
434-
* ── Test seam (#10262). Package-internal: NOT part of the published surface ──
434+
* ── Test seam (commit 2aca1bc4c). Package-internal: NOT part of the published surface ──
435435
*
436436
* `getNested` above and this wrapper are exported for
437437
* `lint-liveness-properties.test.ts` to drive the array fan-out against a
@@ -455,7 +455,7 @@ export function getNested(obj: AnyRec, path: string): unknown[] {
455455
* - #7079 was closed by re-subjecting to `app.…navigation.children.runAction`;
456456
* - #10068 flipped THAT live → subject lost again, and measured across all 30
457457
* shipped ledgers every remaining warned entry is top-level, so there is
458-
* nothing left to re-subject to. Filed as #10262 (this seam).
458+
* nothing left to re-subject to. This seam is commit 2aca1bc4c.
459459
*
460460
* A broken walk is invisible without it: a `getNested` that stopped at index 0
461461
* "still warns on every single-entry fixture, on every top-level warned key,

‎packages/lint/src/reference-integrity-suite.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,7 +563,7 @@ export const REFERENCE_INTEGRITY_RULES: readonly ReferenceIntegrityRule[] = [
563563
// build the other command would have stopped. Joining the suite is the whole
564564
// fix; the two hand-wired call sites are deleted with it (#4345 follow-up).
565565
{ name: 'validateReadonlyFlowWrites', run: validateReadonlyFlowWrites },
566-
// [#13653] The SAME question as the member above, on the surface that had no
566+
// [commit 36d287803] The SAME question as the member above, on the surface that had no
567567
// answer for it: a hook body's `ctx.api.object('x').update({ readonlyField })`.
568568
// A hook's `ctx.api` is a ScopedContext over the TRIGGERING operation's
569569
// context, so on a non-system trigger the engine strips the key and the call

‎packages/lint/src/runtime-gate.ts‎

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ const TYPE_TO_STACK_KEY: Readonly<Record<string, string>> = {
170170
report: 'reports',
171171
email_template: 'emailTemplates',
172172
mapping: 'mappings',
173-
// [#19143 above, #19370 here] `position` / `app` — the two collections only
173+
// [#19143 above, commit a227afa41 here] `position` / `app` — the two collections only
174174
// `security-role-word` judges. They arrive together with that rule's
175175
// crossing, never ahead of it: `DEFAULT_METADATA_TYPE_REGISTRY` declares both
176176
// `allowRuntimeCreate: true`, so Studio's app designer, REST `/meta` and an
@@ -261,7 +261,7 @@ const TYPE_TO_STACK_KEY: Readonly<Record<string, string>> = {
261261
* here plus a `CONTEXT_STACK_KEYS` entry, made when a rule that RESOLVES
262262
* REFERENCES INTO the collection actually crosses the wall, never in advance.
263263
*
264-
* [#19370] `positions` / `apps` are the measured limit of that sentence, and
264+
* [commit a227afa41] `positions` / `apps` are the measured limit of that sentence, and
265265
* the reason it now says RESOLVES rather than reads. `security-role-word`
266266
* crossed the wall reading both collections, and they are still not carried:
267267
* the rule judges each identifier and label on its own, so the universe it
@@ -359,7 +359,7 @@ export interface RuntimeStackContext {
359359
* read — narrows NOTHING. The whole collection is handed over, exactly as
360360
* before. The fallback direction is deliberate and is the opposite of a size
361361
* threshold: an unknown provenance buys MORE validation input, never less, so
362-
* the gate never stops judging (the #9798 / #9261 / ADR-0110 D3 fail-open
362+
* the gate never stops judging (the fail-open commit c7655d472 closed, #9261, ADR-0110 D3: the
363363
* shape this card was explicitly forbidden from re-creating).
364364
*/
365365
export interface RuntimePackageScope {
@@ -724,7 +724,7 @@ export const WRITTEN_STACK_KEYS: ReadonlySet<string> = new Set(Object.values(TYP
724724

725725
/**
726726
* The collection-resident stack keys whose TOP-LEVEL index the gate rewrites
727-
* to a name key before findings leave it (#10064) — DERIVED, not listed (#13390).
727+
* to a name key before findings leave it (commit def0d3e63) — DERIVED, not listed (#13390).
728728
*
729729
* These are the collections a written item lands INSIDE **and** that the
730730
* context also fills — so a finding's `objects[417]` is an offset into this
@@ -743,7 +743,7 @@ export const WRITTEN_STACK_KEYS: ReadonlySet<string> = new Set(Object.values(TYP
743743
* clause, which is validity, not completeness, and the compiler held nothing
744744
* else. Omitting a member here did not fail to build, fail a test, or fail a
745745
* gate; it emitted findings that LOOK correct whose `path` the caller cannot
746-
* resolve, which is the #10064 defect re-created silently.
746+
* resolve, which is the defect commit def0d3e63 fixed, re-created silently.
747747
*
748748
* [#13977] That reading of `CONTEXT_STACK_KEYS` is now history rather than
749749
* description: it is derived from `RuntimeStackContext` and complete by
@@ -776,8 +776,8 @@ export const WRITTEN_STACK_KEYS: ReadonlySet<string> = new Set(Object.values(TYP
776776
* had to hand-write. Mapping the `dataset` type moved it IN, in the same one-key
777777
* edit and with no second spelling to remember: a dataset write's snapshot now
778778
* holds the tenant's other datasets beside the written one, so `datasets[3]` is
779-
* again an offset into an array the caller has never seen. That is the #10064
780-
* defect this constant exists to prevent, and the derivation caught the widening
779+
* again an offset into an array the caller has never seen. That is the defect commit def0d3e63 fixed,
780+
* the one this constant exists to prevent, and the derivation caught the widening
781781
* rather than being told about it.
782782
*/
783783
const NAME_KEYED_STACK_KEYS: readonly string[] = deriveNameKeyedStackKeys(
@@ -796,7 +796,7 @@ const PATH_SAFE_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/;
796796
const TOP_LEVEL_INDEX = buildTopLevelIndexPattern(NAME_KEYED_STACK_KEYS);
797797

798798
/**
799-
* `objects[417].sharingModel` → `objects.acme_invoice.sharingModel` (#10064).
799+
* `objects[417].sharingModel` → `objects.acme_invoice.sharingModel` (commit def0d3e63).
800800
*
801801
* The maintainer-ruled wire shape for collection-resident findings: the
802802
* top-level collection index no caller can resolve is replaced by the entry's
@@ -925,7 +925,7 @@ export function runRuntimeAuthoringRules(args: {
925925
const before = new Set(runRules(rules, snapshots.baseline, ctx).map(fingerprint));
926926
const added = runRules(rules, snapshots.candidate, ctx)
927927
.filter((f) => !before.has(fingerprint(f)))
928-
// [#10064] The wire shape: collection-resident findings key their
928+
// [commit def0d3e63] The wire shape: collection-resident findings key their
929929
// top-level collection entry by NAME, not by this gate's private snapshot
930930
// index. Rewritten only on what leaves the gate — the differential above
931931
// ran on the rules' raw positional paths.

‎packages/lint/src/validate-action-body-writes.ts‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ export const ACTION_RECORD_WRITE_DISCARDED = 'action-record-write-discarded';
132132
export const ACTION_BODY_SOURCE_UNPARSEABLE = 'action-body-source-unparseable';
133133

134134
/**
135-
* [#8663] The action-surface twin of `hook-body-write-unprovisioned-anchor`.
135+
* [commit 192213f66] The action-surface twin of `hook-body-write-unprovisioned-anchor`.
136136
* Same question, same wording, same `warning` severity — this rule and the hook
137137
* rule share {@link IMPLICIT_FIELDS}, so they shared its blind spot too.
138138
*/
@@ -314,7 +314,7 @@ export function validateActionBodyWrites(stack: AnyRec): ActionBodyWriteFinding[
314314
// Built lazily: only the unknown-field check needs it, so a stack whose
315315
// action bodies never reach `ctx.api` never pays it.
316316
let objectFields: Map<string, Set<string>> | null = null;
317-
// [#8663] Non-empty only for a stack carrying an ADR-0015 `external` object.
317+
// [commit 192213f66] Non-empty only for a stack carrying an ADR-0015 `external` object.
318318
let anchors: ReadonlyMap<string, ReadonlySet<string>> | null = null;
319319

320320
for (const site of sites) {
@@ -399,7 +399,7 @@ export function validateActionBodyWrites(stack: AnyRec): ActionBodyWriteFinding[
399399
// (it maps a remote column they vouch for) — never either finding.
400400
if (known.has(w.field)) continue;
401401
if (IMPLICIT_FIELDS.has(w.field)) {
402-
// [#8663] Implicitly writable SOMEWHERE is not provisioned HERE.
402+
// [commit 192213f66] Implicitly writable SOMEWHERE is not provisioned HERE.
403403
if (!anchors.get(w.object)?.has(w.field)) continue;
404404
reported.add(dedupeKey);
405405
findings.push({

‎packages/lint/src/validate-component-types.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
/**
44
* [ADR-0078] The page-component TYPE gate — the author-time rejection the open
5-
* `type` union never had (#12950, riding the #12183 ruling of 2026-08-26).
5+
* `type` union never had (commit 225e7690f, riding the #12183 ruling of 2026-08-26).
66
*
77
* ## What was missing
88
*

‎packages/lint/src/validate-empty-combinators.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* ## The runtime is not changing, and this file changes nothing about it
88
*
99
* #5322 (maintainer ruling, 2026-08-04) settled the RUNTIME semantics of the
10-
* four empty shapes as the boolean identity reduction, and #5659/PR #6528 made
10+
* four empty shapes as the boolean identity reduction, and #5659 (commit 3510e4a25) made
1111
* that reduction one implementation — `reduceFilterVerdict` in
1212
* `@objectstack/spec/data`, proven against `FILTER_LOGIC_CASES` and consumed by
1313
* every backend. This rule touches no translate or evaluation path. It asks the

0 commit comments

Comments
 (0)