From dc6a2fe7929594cce5dbd7be6601b2bce68bb0b9 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 29 Sep 2026 06:59:03 +0000 Subject: [PATCH 1/2] docs(lint): re-anchor dead tracker citations in packages/lint/src to the commits that decided them Comment and docblock lines in 22 packages/lint/src files that cited a tracker number answering 404 now cite, in ruling C+D's form C, the commit in this repository's history that decided what the line describes, and say in words what was decided. Comments only: 81 lines out, 81 in; no code token, string, message or hint moves. authoring-rules.ts is left at its base blob while an open PR holds it. Claude-Session: https://claude.ai/code/session_014EJ1ED8X4MMrT18BhVx4tx Co-authored-by: Claude --- packages/lint/src/data-model-rules.ts | 2 +- packages/lint/src/flow-template-grammar.ts | 4 ++-- packages/lint/src/lint-flow-patterns.ts | 18 +++++++++--------- packages/lint/src/lint-liveness-properties.ts | 6 +++--- packages/lint/src/reference-integrity-suite.ts | 2 +- packages/lint/src/runtime-gate.ts | 18 +++++++++--------- .../lint/src/validate-action-body-writes.ts | 6 +++--- packages/lint/src/validate-component-types.ts | 2 +- .../lint/src/validate-empty-combinators.ts | 2 +- packages/lint/src/validate-expressions.ts | 10 +++++----- packages/lint/src/validate-flow-node-writes.ts | 8 ++++---- packages/lint/src/validate-hook-body-writes.ts | 18 +++++++++--------- .../lint/src/validate-list-view-field-refs.ts | 2 +- .../lint/src/validate-page-field-bindings.ts | 10 +++++----- packages/lint/src/validate-react-page-props.ts | 10 +++++----- .../src/validate-readonly-action-writes.ts | 2 +- .../lint/src/validate-readonly-flow-writes.ts | 2 +- .../lint/src/validate-readonly-hook-writes.ts | 2 +- .../lint/src/validate-searchable-fields.ts | 14 +++++++------- packages/lint/src/validate-security-posture.ts | 6 +++--- packages/lint/src/validate-sortable-fields.ts | 10 +++++----- .../src/validate-translation-references.ts | 8 ++++---- 22 files changed, 81 insertions(+), 81 deletions(-) diff --git a/packages/lint/src/data-model-rules.ts b/packages/lint/src/data-model-rules.ts index 0edf745a0aa..23c933289bb 100644 --- a/packages/lint/src/data-model-rules.ts +++ b/packages/lint/src/data-model-rules.ts @@ -61,7 +61,7 @@ export interface LintIssue { * runtime gate's `fingerprint` reads `where` and `path` together (making * `where` more specific cannot merge two findings that were distinct). * - * [#10064] On the runtime gate's WIRE surface (`RuntimeAuthoringIssue.path`, + * [commit def0d3e63] On the runtime gate's WIRE surface (`RuntimeAuthoringIssue.path`, * the 422 `issues[]` / 2xx `advisories`), the top-level collection index of a * collection-resident finding is rewritten to the entry's NAME * (`objects[417].sharingModel` → `objects.acme_invoice.sharingModel`) after diff --git a/packages/lint/src/flow-template-grammar.ts b/packages/lint/src/flow-template-grammar.ts index f317e4d2796..1d5470671af 100644 --- a/packages/lint/src/flow-template-grammar.ts +++ b/packages/lint/src/flow-template-grammar.ts @@ -31,7 +31,7 @@ * - `NOW()` / `TODAY()` with an optional `± N` day offset — closed, two names. * - `$User.` — closed prefix. * - `round` / `floor` / `ceil` / `abs` / `min` / `max` in CALL position — - * closed by maintainer ruling on #11060 ("exactly … every name and semantic + * closed by the maintainer ruling commit 815585513 records ("exactly … every name and semantic * mirrored **1:1 from the CEL stdlib**, ⛔ no second semantics invented"). * - a bare or dotted identifier (`{recordId}`, `{record.id}`, `{status}`) — * **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']; /** * The value-expression function table — the CEL stdlib's numeric six, by the - * #11060 ruling. Mirrors `EXPRESSION_FUNCTION_ARITY`'s key set. + * ruling commit 815585513 records. Mirrors `EXPRESSION_FUNCTION_ARITY`'s key set. */ export const FLOW_TEMPLATE_VALUE_FUNCTIONS: readonly string[] = [ 'round', 'floor', 'ceil', 'abs', 'min', 'max', diff --git a/packages/lint/src/lint-flow-patterns.ts b/packages/lint/src/lint-flow-patterns.ts index 17fdb186d9f..18f08855fa9 100644 --- a/packages/lint/src/lint-flow-patterns.ts +++ b/packages/lint/src/lint-flow-patterns.ts @@ -55,7 +55,7 @@ * specifically (range operators `>=`/`<=` are not flagged — they're the building * block of the correct pattern), keeping false positives near zero. * - * #13681 / #14394 — per-iteration containment, as a PAIR of rules. A `loop` + * commit 8ed9c54b4 / #14394 — per-iteration containment, as a PAIR of rules. A `loop` * body has no error handling of its own: `loop-node.ts` iterates with a bare * `await`, so the first item whose node fails ends the entire run and every * 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' */ export const FLOW_MULTI_WRITE_UNFILTERED = 'flow-multi-write-unfiltered'; /** - * #13681 / #14394 — a `loop` body that runs a node which can fail, with no + * commit 8ed9c54b4 / #14394 — a `loop` body that runs a node which can fail, with no * `try_catch` between the loop and that node. The first failing item kills the * whole sweep: `loop-node.ts:123-135` iterates with a bare `await` and no * `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'; */ export const FLOW_LOOP_BODY_UNCONTAINED = 'flow-loop-body-uncontained'; /** - * #13681 / #14394 — the near-miss shape: a `try_catch` that declares no `catch` + * commit 8ed9c54b4 / #14394 — the near-miss shape: a `try_catch` that declares no `catch` * region. `catch` is optional in the schema (`control-flow.zod.ts:315`) and * omitting it makes the container **fail** (`try-catch-node.ts:190`), so the * 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', * - `http` — a non-2xx (when `failOnError`), a timeout/abort, or a failed * durable enqueue (`http-nodes.ts:208, :249-253`). * - `notify` — no title, an empty resolved recipient set, or a delivery throw - * (`notify-node.ts:293, :300, :446`). The measured #13681 case exactly: one + * (`notify-node.ts:293, :300, :446`). The measured case commit 8ed9c54b4 records, exactly: one * row with a null owner killed the sweep. * - `connector_action` — a degraded connector, an unresolvable action, or a * throwing call (`connector-nodes.ts:69, :76, :124`). @@ -1330,7 +1330,7 @@ function scanApprovalReviseLoops( /** * The minimal `catch` region, measured end to end on the real `AutomationEngine` - * (#13681) and quoted verbatim by both containment rules and by + * (commit 8ed9c54b4) and quoted verbatim by both containment rules and by * `content/docs/automation/flows.mdx`. * * `catch` cannot be empty: `FlowRegionSchema.nodes` is `.min(1)` @@ -1425,7 +1425,7 @@ function scanUncontainedLoopBodies( `that is a legitimate reading and this stays a warning. ` + // The tracker ids stay OUT of the runtime string (`check:doc-authoring`): // an author reading this hint cannot resolve `#NNNN`. The measurement - // and the ruling behind this rule are #13681 / #14394; the docblock on + // and the ruling behind this rule are commit 8ed9c54b4 / #14394; the docblock on // {@link FLOW_LOOP_BODY_UNCONTAINED} carries them for the reader who can. `See content/docs/automation/flows.mdx §"Per-iteration containment".`, // Warning, not `error`: see the severity policy at the top of this @@ -1465,7 +1465,7 @@ function scanUncontainedLoopBodies( /** * #14394 rule B — a `try_catch` with no `catch` region, anywhere in the flow. * - * Measured (#13681): the container fails through, and the run is byte-identical + * Measured (commit 8ed9c54b4): the container fails through, and the run is byte-identical * to the one with no `try_catch` at all. `retry`, when present, only delays it. * * A `catch` that is PRESENT but malformed is deliberately not this rule's @@ -1737,7 +1737,7 @@ export function lintFlowPatterns(stack: AnyRec): FlowLintFinding[] { // purge, and this rule's main habitat — in range (#5383/#5635). scanUnboundedBulkWrites(at, graphNodes, findings); - // (g) #13681/#14394 — a `loop` body running a fallible node with no + // (g) commit 8ed9c54b4 / #14394 — a `loop` body running a fallible node with no // `try_catch` between the loop and it. Per graph like the rest, and // that is what keeps the count right: every `loop` node belongs to // exactly one graph, so its body is descended exactly once, and a @@ -1745,7 +1745,7 @@ export function lintFlowPatterns(stack: AnyRec): FlowLintFinding[] { // parent (see {@link scanUncontainedLoopBodies}). scanUncontainedLoopBodies(at, graphNodes, findings); - // (h) #13681/#14394 — the near-miss: a `try_catch` with no `catch`. Scanned + // (h) commit 8ed9c54b4 / #14394 — the near-miss: a `try_catch` with no `catch`. Scanned // everywhere, not only inside a loop: the container fails through // wherever it is written. Inside a loop body it is the shape (g) // deliberately treats as contained, so exactly one of the two rules diff --git a/packages/lint/src/lint-liveness-properties.ts b/packages/lint/src/lint-liveness-properties.ts index 59129472ae6..f80f0817e02 100644 --- a/packages/lint/src/lint-liveness-properties.ts +++ b/packages/lint/src/lint-liveness-properties.ts @@ -273,7 +273,7 @@ function describe(entry: LedgerEntry): { kind: string; rule: string; defaultHint /** * ── Coverage seam (#14057). Package-internal: NOT part of the published surface, - * same posture as the #10262 seam below `getNested` (exported from the MODULE + * same posture as the test seam commit 2aca1bc4c added below `getNested` (exported from the MODULE * only; `src/index.ts` re-exports neither, and this package's `exports` map * publishes just `.` and `./runtime`). ──────────────────────────────────── * @@ -431,7 +431,7 @@ export function getNested(obj: AnyRec, path: string): unknown[] { } /** - * ── Test seam (#10262). Package-internal: NOT part of the published surface ── + * ── Test seam (commit 2aca1bc4c). Package-internal: NOT part of the published surface ── * * `getNested` above and this wrapper are exported for * `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[] { * - #7079 was closed by re-subjecting to `app.…navigation.children.runAction`; * - #10068 flipped THAT live → subject lost again, and measured across all 30 * shipped ledgers every remaining warned entry is top-level, so there is - * nothing left to re-subject to. Filed as #10262 (this seam). + * nothing left to re-subject to. This seam is commit 2aca1bc4c. * * A broken walk is invisible without it: a `getNested` that stopped at index 0 * "still warns on every single-entry fixture, on every top-level warned key, diff --git a/packages/lint/src/reference-integrity-suite.ts b/packages/lint/src/reference-integrity-suite.ts index faabe2675d5..7889d149c29 100644 --- a/packages/lint/src/reference-integrity-suite.ts +++ b/packages/lint/src/reference-integrity-suite.ts @@ -563,7 +563,7 @@ export const REFERENCE_INTEGRITY_RULES: readonly ReferenceIntegrityRule[] = [ // build the other command would have stopped. Joining the suite is the whole // fix; the two hand-wired call sites are deleted with it (#4345 follow-up). { name: 'validateReadonlyFlowWrites', run: validateReadonlyFlowWrites }, - // [#13653] The SAME question as the member above, on the surface that had no + // [commit 36d287803] The SAME question as the member above, on the surface that had no // answer for it: a hook body's `ctx.api.object('x').update({ readonlyField })`. // A hook's `ctx.api` is a ScopedContext over the TRIGGERING operation's // context, so on a non-system trigger the engine strips the key and the call diff --git a/packages/lint/src/runtime-gate.ts b/packages/lint/src/runtime-gate.ts index e507af9457f..2676161e5a4 100644 --- a/packages/lint/src/runtime-gate.ts +++ b/packages/lint/src/runtime-gate.ts @@ -170,7 +170,7 @@ const TYPE_TO_STACK_KEY: Readonly> = { report: 'reports', email_template: 'emailTemplates', mapping: 'mappings', - // [#19143 above, #19370 here] `position` / `app` — the two collections only + // [#19143 above, commit a227afa41 here] `position` / `app` — the two collections only // `security-role-word` judges. They arrive together with that rule's // crossing, never ahead of it: `DEFAULT_METADATA_TYPE_REGISTRY` declares both // `allowRuntimeCreate: true`, so Studio's app designer, REST `/meta` and an @@ -261,7 +261,7 @@ const TYPE_TO_STACK_KEY: Readonly> = { * here plus a `CONTEXT_STACK_KEYS` entry, made when a rule that RESOLVES * REFERENCES INTO the collection actually crosses the wall, never in advance. * - * [#19370] `positions` / `apps` are the measured limit of that sentence, and + * [commit a227afa41] `positions` / `apps` are the measured limit of that sentence, and * the reason it now says RESOLVES rather than reads. `security-role-word` * crossed the wall reading both collections, and they are still not carried: * the rule judges each identifier and label on its own, so the universe it @@ -359,7 +359,7 @@ export interface RuntimeStackContext { * read — narrows NOTHING. The whole collection is handed over, exactly as * before. The fallback direction is deliberate and is the opposite of a size * threshold: an unknown provenance buys MORE validation input, never less, so - * the gate never stops judging (the #9798 / #9261 / ADR-0110 D3 fail-open + * the gate never stops judging (the fail-open commit c7655d472 closed, #9261, ADR-0110 D3: the * shape this card was explicitly forbidden from re-creating). */ export interface RuntimePackageScope { @@ -724,7 +724,7 @@ export const WRITTEN_STACK_KEYS: ReadonlySet = new Set(Object.values(TYP /** * The collection-resident stack keys whose TOP-LEVEL index the gate rewrites - * to a name key before findings leave it (#10064) — DERIVED, not listed (#13390). + * to a name key before findings leave it (commit def0d3e63) — DERIVED, not listed (#13390). * * These are the collections a written item lands INSIDE **and** that the * context also fills — so a finding's `objects[417]` is an offset into this @@ -743,7 +743,7 @@ export const WRITTEN_STACK_KEYS: ReadonlySet = new Set(Object.values(TYP * clause, which is validity, not completeness, and the compiler held nothing * else. Omitting a member here did not fail to build, fail a test, or fail a * gate; it emitted findings that LOOK correct whose `path` the caller cannot - * resolve, which is the #10064 defect re-created silently. + * resolve, which is the defect commit def0d3e63 fixed, re-created silently. * * [#13977] That reading of `CONTEXT_STACK_KEYS` is now history rather than * description: it is derived from `RuntimeStackContext` and complete by @@ -776,8 +776,8 @@ export const WRITTEN_STACK_KEYS: ReadonlySet = new Set(Object.values(TYP * had to hand-write. Mapping the `dataset` type moved it IN, in the same one-key * edit and with no second spelling to remember: a dataset write's snapshot now * holds the tenant's other datasets beside the written one, so `datasets[3]` is - * again an offset into an array the caller has never seen. That is the #10064 - * defect this constant exists to prevent, and the derivation caught the widening + * again an offset into an array the caller has never seen. That is the defect commit def0d3e63 fixed, + * the one this constant exists to prevent, and the derivation caught the widening * rather than being told about it. */ const NAME_KEYED_STACK_KEYS: readonly string[] = deriveNameKeyedStackKeys( @@ -796,7 +796,7 @@ const PATH_SAFE_NAME = /^[A-Za-z_][A-Za-z0-9_]*$/; const TOP_LEVEL_INDEX = buildTopLevelIndexPattern(NAME_KEYED_STACK_KEYS); /** - * `objects[417].sharingModel` → `objects.acme_invoice.sharingModel` (#10064). + * `objects[417].sharingModel` → `objects.acme_invoice.sharingModel` (commit def0d3e63). * * The maintainer-ruled wire shape for collection-resident findings: the * top-level collection index no caller can resolve is replaced by the entry's @@ -925,7 +925,7 @@ export function runRuntimeAuthoringRules(args: { const before = new Set(runRules(rules, snapshots.baseline, ctx).map(fingerprint)); const added = runRules(rules, snapshots.candidate, ctx) .filter((f) => !before.has(fingerprint(f))) - // [#10064] The wire shape: collection-resident findings key their + // [commit def0d3e63] The wire shape: collection-resident findings key their // top-level collection entry by NAME, not by this gate's private snapshot // index. Rewritten only on what leaves the gate — the differential above // ran on the rules' raw positional paths. diff --git a/packages/lint/src/validate-action-body-writes.ts b/packages/lint/src/validate-action-body-writes.ts index 3ad2d084c6e..b0b6da88c22 100644 --- a/packages/lint/src/validate-action-body-writes.ts +++ b/packages/lint/src/validate-action-body-writes.ts @@ -132,7 +132,7 @@ export const ACTION_RECORD_WRITE_DISCARDED = 'action-record-write-discarded'; export const ACTION_BODY_SOURCE_UNPARSEABLE = 'action-body-source-unparseable'; /** - * [#8663] The action-surface twin of `hook-body-write-unprovisioned-anchor`. + * [commit 192213f66] The action-surface twin of `hook-body-write-unprovisioned-anchor`. * Same question, same wording, same `warning` severity — this rule and the hook * rule share {@link IMPLICIT_FIELDS}, so they shared its blind spot too. */ @@ -314,7 +314,7 @@ export function validateActionBodyWrites(stack: AnyRec): ActionBodyWriteFinding[ // Built lazily: only the unknown-field check needs it, so a stack whose // action bodies never reach `ctx.api` never pays it. let objectFields: Map> | null = null; - // [#8663] Non-empty only for a stack carrying an ADR-0015 `external` object. + // [commit 192213f66] Non-empty only for a stack carrying an ADR-0015 `external` object. let anchors: ReadonlyMap> | null = null; for (const site of sites) { @@ -399,7 +399,7 @@ export function validateActionBodyWrites(stack: AnyRec): ActionBodyWriteFinding[ // (it maps a remote column they vouch for) — never either finding. if (known.has(w.field)) continue; if (IMPLICIT_FIELDS.has(w.field)) { - // [#8663] Implicitly writable SOMEWHERE is not provisioned HERE. + // [commit 192213f66] Implicitly writable SOMEWHERE is not provisioned HERE. if (!anchors.get(w.object)?.has(w.field)) continue; reported.add(dedupeKey); findings.push({ diff --git a/packages/lint/src/validate-component-types.ts b/packages/lint/src/validate-component-types.ts index edae72281a3..93bc0e71fc8 100644 --- a/packages/lint/src/validate-component-types.ts +++ b/packages/lint/src/validate-component-types.ts @@ -2,7 +2,7 @@ /** * [ADR-0078] The page-component TYPE gate — the author-time rejection the open - * `type` union never had (#12950, riding the #12183 ruling of 2026-08-26). + * `type` union never had (commit 225e7690f, riding the #12183 ruling of 2026-08-26). * * ## What was missing * diff --git a/packages/lint/src/validate-empty-combinators.ts b/packages/lint/src/validate-empty-combinators.ts index 7b6eee5a392..7e5af870019 100644 --- a/packages/lint/src/validate-empty-combinators.ts +++ b/packages/lint/src/validate-empty-combinators.ts @@ -7,7 +7,7 @@ * ## The runtime is not changing, and this file changes nothing about it * * #5322 (maintainer ruling, 2026-08-04) settled the RUNTIME semantics of the - * four empty shapes as the boolean identity reduction, and #5659/PR #6528 made + * four empty shapes as the boolean identity reduction, and #5659 (commit 3510e4a25) made * that reduction one implementation — `reduceFilterVerdict` in * `@objectstack/spec/data`, proven against `FILTER_LOGIC_CASES` and consumed by * every backend. This rule touches no translate or evaluation path. It asks the diff --git a/packages/lint/src/validate-expressions.ts b/packages/lint/src/validate-expressions.ts index 0fb0236cc02..3d43ddd17f0 100644 --- a/packages/lint/src/validate-expressions.ts +++ b/packages/lint/src/validate-expressions.ts @@ -525,7 +525,7 @@ function rulePredicates(rule: AnyRec, path: string): Array<{ label: string; raw: * * ## Why this is a rule of its own rather than a missing root * - * Until #6290 the same rejection fell out of `@objectstack/formula`'s + * Until commit e9b526597 the same rejection fell out of `@objectstack/formula`'s * `SCOPE_ROOTS` not listing `current_user` — a global baseline, doing a * per-surface job by accident. Two things were wrong with that: * @@ -568,7 +568,7 @@ function rulePredicates(rule: AnyRec, path: string): Array<{ label: string; raw: * * A denylist cannot track `SCOPE_ROOTS`: every root added there is unreported * here until somebody remembers to copy it across (`current_user` itself - * arrived in #6290 and needed #6584 to be noticed). The allowlist inverts the + * arrived in commit e9b526597, and needed that same change (#6584) to be noticed). The allowlist inverts the * maintenance burden onto the three roots that are pinned by three anchors and * change only when the evaluators do. * @@ -767,7 +767,7 @@ function rulePredicates(rule: AnyRec, path: string): Array<{ label: string; raw: * * `SCOPE_ROOTS`' own docblock made the original widening measurable rather than * a matter of taste: its `current_user` entry claims to be "the last one this - * list was missing (#6290)". `app` is that sentence's second counterexample — + * list was missing" (commit e9b526597 wrote it). `app` is that sentence's second counterexample — * the same mechanism (#6713's point: a hand-maintained list doing a per-surface * job drifts), a second sighting, not an analogy to the first. * @@ -1890,7 +1890,7 @@ export function validateStackExpressions(stack: AnyRec): ExprIssue[] { issues.push({ where, message: verdict.message, source: verdict.source, severity: 'error' }); } } - // [#6290] Per-OPTION `visibleWhen` — a `select`/`multiselect`/`radio` + // [commit e9b526597] Per-OPTION `visibleWhen` — a `select`/`multiselect`/`radio` // option's own predicate (`SelectOptionSchema.visibleWhen`, // `field.zod.ts:143`). It had no traversal here at all, so the whole // option surface reached compile, validate and run time unvalidated: @@ -1900,7 +1900,7 @@ export function validateStackExpressions(stack: AnyRec): ExprIssue[] { // // Deliberately checked on the SAME `record` scope as the field-level // slots, and that is the whole of the difference between the two faces - // after #6290: `current_user` is a declared root platform-wide (ADR-0068 + // after commit e9b526597: `current_user` is a declared root platform-wide (ADR-0068 // D1), so it passes here — options resolve through // `resolveCascadingOptions` against the host's predicate scope, which // binds it (ADR-0068 / objectui#2284), and the showcase's diff --git a/packages/lint/src/validate-flow-node-writes.ts b/packages/lint/src/validate-flow-node-writes.ts index e48eff35d0f..63f8854ee31 100644 --- a/packages/lint/src/validate-flow-node-writes.ts +++ b/packages/lint/src/validate-flow-node-writes.ts @@ -104,7 +104,7 @@ import { recordsOf } from './object-graph.js'; /** * `error` for the existence verdict — a literal key against a literal object is - * a certainty (see the module note). [#8663] `warning` for the provenance one: + * a certainty (see the module note). [commit 192213f66] `warning` for the provenance one: * the same widening `validateFlowTemplatePaths` carries, for the same reason. * The two questions have different certainties, so they cannot share a * severity; the suite that runs this rule is severity-agnostic by contract and @@ -128,7 +128,7 @@ export interface FlowNodeWriteFinding { export const FLOW_NODE_WRITE_UNKNOWN_FIELD = 'flow-node-write-unknown-field'; /** - * [#8663] The flow-node twin of `hook-body-write-unprovisioned-anchor`. This + * [commit 192213f66] The flow-node twin of `hook-body-write-unprovisioned-anchor`. This * rule reached the same blind spot from the same direction: it imports * {@link IMPLICIT_FIELDS} from the hook rule, so it inherited the set's * object-independence along with its contents. @@ -214,7 +214,7 @@ export function validateFlowNodeWrites(stack: AnyRec): FlowNodeWriteFinding[] { // Built lazily: a stack whose flows carry no write node never pays it. let objectFields: Map> | null = null; - // [#8663] Non-empty only for a stack carrying an ADR-0015 `external` object. + // [commit 192213f66] Non-empty only for a stack carrying an ADR-0015 `external` object. let anchors: ReadonlyMap> | null = null; flows.forEach((flow, flowIndex) => { @@ -259,7 +259,7 @@ export function validateFlowNodeWrites(stack: AnyRec): FlowNodeWriteFinding[] { // maps a remote column the author vouches for (#7859's direction). if (known.has(fieldName)) continue; if (IMPLICIT_FIELDS.has(fieldName)) { - // [#8663] Implicitly writable SOMEWHERE is not provisioned HERE. + // [commit 192213f66] Implicitly writable SOMEWHERE is not provisioned HERE. if (!anchors.get(objectName)?.has(fieldName)) continue; findings.push({ severity: 'warning', diff --git a/packages/lint/src/validate-hook-body-writes.ts b/packages/lint/src/validate-hook-body-writes.ts index 2dde3fef50b..9508cea9ca6 100644 --- a/packages/lint/src/validate-hook-body-writes.ts +++ b/packages/lint/src/validate-hook-body-writes.ts @@ -9,11 +9,11 @@ // `Object.assign`, and `validateRecord` walks declared fields on insert and // `continue`s past a key with no field def on update. // -// [#13657] What happens after that used to be DRIVER-DEPENDENT, and neither +// [commit b003cf2e8] What happens after that used to be DRIVER-DEPENDENT, and neither // half was acceptable — SQL failed the whole write with an untyped // `SQLITE_ERROR` far from the authoring mistake, while schemaless drivers // (memory, MongoDB) spread the payload and PERSISTED the stray key as a column -// nothing downstream reads. #13657 closed that: the declared-field door now +// nothing downstream reads. Commit b003cf2e8 closed that: the declared-field door now // runs a second time over the payload the `before*` hooks produced, so the key // is refused `INVALID_FIELD` / 400 identically on every driver, before any // statement is built. @@ -161,7 +161,7 @@ export const HOOK_BODY_WRITE_UNKNOWN_FIELD = 'hook-body-write-unknown-field'; export const HOOK_BODY_SOURCE_UNPARSEABLE = 'hook-body-source-unparseable'; /** - * [#8663] The write-axis twin of `flow-template-field-unprovisioned` (#8340): + * [commit 192213f66] The write-axis twin of `flow-template-field-unprovisioned` (#8340): * the body writes a field {@link IMPLICIT_FIELDS} exempts, but on THIS target * the platform registered that anchor without provisioning storage for it. * @@ -349,7 +349,7 @@ const INPUT_ENVELOPE_KEYS: ReadonlySet = new Set(['id', 'options', 'ast' * of this extension would drift exactly the way the five hand-copied lists * #4330 collapsed did. * - * ⛔ [#8663] This set is OBJECT-INDEPENDENT and therefore only half an answer. + * ⛔ [commit 192213f66] This set is OBJECT-INDEPENDENT and therefore only half an answer. * It says a name COULD be implicitly writable somewhere; it cannot say whether * the platform actually provisioned storage for it on the object being written. * On an ADR-0015 `external` object the two diverge — the registered anchor has @@ -364,7 +364,7 @@ export const IMPLICIT_FIELDS: ReadonlySet = new Set([ ]); /** - * [#8663] The CONSEQUENCE clause every unprovisioned-anchor WRITE diagnostic + * [commit 192213f66] The CONSEQUENCE clause every unprovisioned-anchor WRITE diagnostic * states — one wording across the three write surfaces (hook body, action body, * flow node), paired with `unprovisionedAnchorCause` / `unprovisionedAnchorHint` * from `system-fields.ts` the way #8340's four read-axis rules pair with them. @@ -376,7 +376,7 @@ export const IMPLICIT_FIELDS: ReadonlySet = new Set([ * that module's own note reserves the per-site consequence to the site, and the * "site" for this family is the family, not any one of its three files. * - * ## Every clause below is measured, not inferred (#8663) + * ## Every clause below is measured, not inferred (commit 192213f66) * * The card that produced this rule asserted a structural resemblance to the * read-axis gap and explicitly declined to guess the runtime behaviour. Measured @@ -823,7 +823,7 @@ export function validateHookBodyWrites( // Built lazily: a stack whose hooks are all L1/handler-based never pays it. let objectFields: Map> | null = null; - // [#8663] `objectName -> its unprovisioned injected anchors`. Empty for every + // [commit 192213f66] `objectName -> its unprovisioned injected anchors`. Empty for every // ordinary stack (only an ADR-0015 `external` object contributes an entry), so // the lookup below doubles as the "nothing to say here" fast path. let anchors: ReadonlyMap> | null = null; @@ -891,7 +891,7 @@ export function validateHookBodyWrites( // object, so a partial miss is not statically wrong). if (!inputJudgeable) continue; if (IMPLICIT_FIELDS.has(w.field)) { - // [#8663] The membership test above answered "addressable somewhere", + // [commit 192213f66] The membership test above answered "addressable somewhere", // not "provisioned HERE". Ask the second question before going silent. // // EVERY target must be unprovisioned, mirroring the everywhere-miss @@ -930,7 +930,7 @@ export function validateHookBodyWrites( path, message: `body writes '${w.field}' to its input, but ${objDesc} ${declares}. The sandboxed script runs ` + - // The post-hook declared-field door (#13657) is what refuses it; the + // The post-hook declared-field door (commit b003cf2e8) is what refuses it; the // id stays in this comment rather than in the string, which reaches // authors and operators who cannot resolve a tracker number. `clean and the value is copied back onto the record payload unfiltered, so the write is then ` + diff --git a/packages/lint/src/validate-list-view-field-refs.ts b/packages/lint/src/validate-list-view-field-refs.ts index 9d1ab6f07ac..2590220fc83 100644 --- a/packages/lint/src/validate-list-view-field-refs.ts +++ b/packages/lint/src/validate-list-view-field-refs.ts @@ -836,7 +836,7 @@ export function validateListViewFieldRefs(stack: AnyRec): ListViewFieldRefFindin // `PUT /api/v1/meta/view` door carries and the runtime publish gate // snapshots. Recognisers mirrored from the sort/search twins, which carry // the full notes: the flattened list overlay (#9313, `viewKind: 'list'` with - // no nested `config`) and the ViewItem record (#10001, one level down + // no nested `config`) and the ViewItem record (commit f1b5ad39a, one level down // inside `config`). const views = asArray(stack.views); for (let vi = 0; vi < views.length; vi++) { diff --git a/packages/lint/src/validate-page-field-bindings.ts b/packages/lint/src/validate-page-field-bindings.ts index fb75fed3aaf..040e1642826 100644 --- a/packages/lint/src/validate-page-field-bindings.ts +++ b/packages/lint/src/validate-page-field-bindings.ts @@ -39,7 +39,7 @@ * this table names is a live (non-retired) key on its `ComponentPropsMap` * schema, and `component-field-specs-liveness.test.ts` pins that: a future * retirement that forgets this table turns that test red instead of leaving a - * tombstoned key listed here as if it were still-valid spelling (#6629). + * tombstoned key listed here as if it were still-valid spelling (commit cd584d559). * * ── Shared with the react page surface ────────────────────────────────── * @@ -205,7 +205,7 @@ export const COMPONENT_FIELD_SPECS: Readonly> // Every `ElementFilterProps` key is a `retiredKey()` tombstone now, so no // spec-conformant page carries `fields` on it, and the #5068 props gate // reports an authored one by name with the element-retirement prescription — - // the same #5775/#6629 residue class as the record-picker entries below. + // the same #5775 residue class (commit cd584d559) as the record-picker entries below. // `element:form` had the same `{ props: ['fields'] }` entry until #9249 // retired that element the same way (ADR-0049, the #9220 shape one element // over); its tombstones' prescription names the live replacement, the @@ -215,7 +215,7 @@ export const COMPONENT_FIELD_SPECS: Readonly> // `searchFields` (deleted, ADR-0049) were retired in #5775 and are // `retiredKey()` tombstones on `ElementRecordPickerPropsSchema` — so no // spec-conformant page carries either, and this rule's job (resolve a field - // NAME against the object) is not the question a retired key raises (#6629). + // NAME against the object) is not the question a retired key raises (commit cd584d559). // // A non-conformant page that writes one anyway is not left unattended: the // #5068 props gate reports the key with its rename/delete prescription. That @@ -397,9 +397,9 @@ export function checkFieldRefs( // it: `validatePageFieldBindings` below, and `checkBlockFieldProps` in // `validate-react-page-props`. // - // [#8664] What NOTICES if one stops is a behaviour test through the + // [commit 8798cd2a6] What NOTICES if one stops is a behaviour test through the // top-level entry point — nothing else can. No CI gate reads call sites: - // `check-cross-package-test-inputs`, named here until #8664, is an + // `check-cross-package-test-inputs`, named here until commit 8798cd2a6, is an // input-scoping gate (it decides which packages CI runs and how the `test` // task cache is keyed, from a declared glob list) and has no view of // argument passing. Measured by dropping the argument at each site: both diff --git a/packages/lint/src/validate-react-page-props.ts b/packages/lint/src/validate-react-page-props.ts index c2955e5de5e..f5684f07744 100644 --- a/packages/lint/src/validate-react-page-props.ts +++ b/packages/lint/src/validate-react-page-props.ts @@ -124,7 +124,7 @@ interface BlockSpec { requiredBindings: string[]; knownProps: Set; /** - * [#11284] Deprecated overlay spellings, read from the contract rather than + * [commit 5383fa670] Deprecated overlay spellings, read from the contract rather than * restated: prop name → its canonical replacement + the authoring note the * warning quotes. A `required` prop that is deprecated is a required * BINDING, not a required spelling — the canonical `replacedBy` prop @@ -312,7 +312,7 @@ function filterAttrValue(tsc: typeof ts, sf: ts.SourceFile, attr: ts.JsxAttribut export const REACT_PAGE_SOURCE_UNPARSEABLE = 'react-page-source-unparseable'; /** - * [#11284] A prop written in a deprecated react-tier spelling (maintainer + * [commit 5383fa670] A prop written in a deprecated react-tier spelling (maintainer * ruling 2026-08-23: the react tier converges on the metadata-tier * vocabulary, deprecate-first). Warning, never error: the old spelling keeps * working for the whole deprecation window — this is the loud half of @@ -1145,7 +1145,7 @@ export function validateReactPageProps(stack: AnyRec): ReactPropFinding[] { if (!hasSpread) { for (const req of block.requiredBindings) { if (used.has(req)) continue; - // [#11284] A required prop that is DEPRECATED requires the + // [commit 5383fa670] A required prop that is DEPRECATED requires the // binding, not the spelling: the canonical replacement satisfies // it, so the new vocabulary is accepted without the old one. const dep = block.deprecated.get(req); @@ -1186,7 +1186,7 @@ export function validateReactPageProps(stack: AnyRec): ReactPropFinding[] { }); continue; } - // [#11284] Deprecate-first: the old spelling keeps working, and + // [commit 5383fa670] Deprecate-first: the old spelling keeps working, and // every use says so — the contract's note names the canonical // metadata-tier spelling to write instead. const dep = block.deprecated.get(u); @@ -1234,7 +1234,7 @@ export function validateReactPageProps(stack: AnyRec): ReactPropFinding[] { `${path} › searchableFields`, 'searchableFields', // A `` prop is a view-level narrowing — the checker's - // default, spelled out here because the #8404 provenance index + // default, spelled out here because the provenance index of commit b849e6911 // follows it positionally. 'narrowing', unprovisionedAnchors, diff --git a/packages/lint/src/validate-readonly-action-writes.ts b/packages/lint/src/validate-readonly-action-writes.ts index ba6b7733cba..a425235c79b 100644 --- a/packages/lint/src/validate-readonly-action-writes.ts +++ b/packages/lint/src/validate-readonly-action-writes.ts @@ -4,7 +4,7 @@ // declares `readonlyWhen` THROUGH `ctx.api` is a SILENT NO-OP on every record // whose predicate is TRUE (#13770). // -// The action-surface sibling of `validate-readonly-hook-writes.ts` (#13653) and +// The action-surface sibling of `validate-readonly-hook-writes.ts` (commit 36d287803) and // `validate-readonly-flow-writes.ts` - the same question ("is this declared // field writable through THIS channel?") on the third write surface. It reuses // both halves of the existing machinery rather than growing its own: the flow diff --git a/packages/lint/src/validate-readonly-flow-writes.ts b/packages/lint/src/validate-readonly-flow-writes.ts index f885b445a77..d456d0a1b0e 100644 --- a/packages/lint/src/validate-readonly-flow-writes.ts +++ b/packages/lint/src/validate-readonly-flow-writes.ts @@ -115,7 +115,7 @@ export interface FieldReadonlyMeta { * neither flag is recorded as `{false, false}` so callers can distinguish a * "known-writable field" from an "unknown field" (absent from the map). * - * Exported for `validate-readonly-hook-writes.ts` (#13653), which asks the + * Exported for `validate-readonly-hook-writes.ts` (commit 36d287803), which asks the * IDENTICAL question one surface over — "is this declared field writable * through this channel?" — about a hook body's `ctx.api` update instead of a * flow node's `config.fields`. Shared rather than copied for the reason #4330 diff --git a/packages/lint/src/validate-readonly-hook-writes.ts b/packages/lint/src/validate-readonly-hook-writes.ts index 8bfef029863..3c1ad4455f0 100644 --- a/packages/lint/src/validate-readonly-hook-writes.ts +++ b/packages/lint/src/validate-readonly-hook-writes.ts @@ -1,7 +1,7 @@ // Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. // // Build-time guardrail: an L2 hook body that writes a field the target object -// declares `readonly: true` THROUGH `ctx.api` is a SILENT NO-OP (#13653). +// declares `readonly: true` THROUGH `ctx.api` is a SILENT NO-OP (commit 36d287803). // // `ctx.api` is a `ScopedContext` built over the TRIGGERING operation's // execution context (`buildHookApi` in packages/objectql/src/engine.ts), so a diff --git a/packages/lint/src/validate-searchable-fields.ts b/packages/lint/src/validate-searchable-fields.ts index 03309fc480e..965210ecbc7 100644 --- a/packages/lint/src/validate-searchable-fields.ts +++ b/packages/lint/src/validate-searchable-fields.ts @@ -97,7 +97,7 @@ * the runtime would refuse — `created_by` in a view's narrowing — is a * missed finding, not a wrong one.) * - * Skip 3 answers EXISTENCE, and since #8404 it no longer ends the matter. On an + * Skip 3 answers EXISTENCE, and since commit b849e6911 it no longer ends the matter. On an * ADR-0015 `external` object the platform registers its injected anchors and * provisions no storage behind them (#7865 / #8116), so `owner_id` there is * addressable and empty on every record. Existence rightly stays silent — @@ -305,11 +305,11 @@ export function checkSearchableFieldList( path: string, subject: string, role: SearchableFieldRole = 'narrowing', - // [#8404] `objectName -> its unprovisioned injected anchors` + // [commit b849e6911] `objectName -> its unprovisioned injected anchors` // ({@link indexUnprovisionedAnchors}). OPTIONAL, and its absence means // exactly one thing: this caller did not build the index, so the provenance // question goes unasked and only existence/admissibility are answered — the - // pre-#8404 behaviour, preserved for out-of-repo callers of this exported + // behaviour before commit b849e6911, preserved for out-of-repo callers of this exported // core (cloud graph-lint, the AI authoring path). Every in-repo caller passes // it: `validateSearchableFields` below and `validate-react-page-props`. unprovisionedAnchors?: ReadonlyMap>, @@ -359,7 +359,7 @@ export function checkSearchableFieldList( continue; } - // ── [#8404] Provenance — the second question about a name skip 3 kept ── + // ── [commit b849e6911] Provenance — the second question about a name skip 3 kept ── // // Existence answered "yes" (authored, or a registry-injected system // column). On a federated object the injected anchor is addressable and @@ -493,7 +493,7 @@ export function checkSearchableFieldList( * (the canonical set, ADR-0061) and the list views that narrow it, including * the two standalone `views[]` shapes the `PUT /api/v1/meta/view` door * carries and the runtime publish gate snapshots: the flattened list overlay - * (#9313, top-level set) and the ViewItem record (#10001, + * (#9313, top-level set) and the ViewItem record (commit f1b5ad39a, * `config.searchableFields` one level down). Returns findings (empty = clean). * * The react page surface (``) is deliberately @@ -584,7 +584,7 @@ export function validateSearchableFields(stack: AnyRec): SearchableFieldFinding[ // `viewKind: 'list'` (required on the overlay arm since #7741, refused by // name on the strict container schema) with no nested `config` (that // shape is a ViewItem RECORD — judged by its own record rung below since - // #10001). A `narrowing`, like + // commit f1b5ad39a). A `narrowing`, like // every list-view surface: the overlay's set is echoed verbatim as the // `$searchFields` override and judged by the #4254 ingress gate. if (view.viewKind === 'list' && !isRec(view.config)) { @@ -598,7 +598,7 @@ export function validateSearchableFields(stack: AnyRec): SearchableFieldFinding[ ); } - // ── [#10001] The RECORD rung: a standalone ViewItem record ── + // ── [commit f1b5ad39a] The RECORD rung: a standalone ViewItem record ── // // The self rung's structural complement — `ViewMetadataSchema`'s member 1 // (`ViewItemWireSchema`, `{ name, object, viewKind: 'list', config }`), diff --git a/packages/lint/src/validate-security-posture.ts b/packages/lint/src/validate-security-posture.ts index 92f29cba259..0835e8c2071 100644 --- a/packages/lint/src/validate-security-posture.ts +++ b/packages/lint/src/validate-security-posture.ts @@ -13,7 +13,7 @@ * | security-external-wider (error) | ADR-0090 D11 external ≤ internal| * | security-wildcard-vama (error) | ADR-0066 superuser wildcard | * | security-anchor-high-privilege(error) | ADR-0090 D5/D9 anchors — declared `everyone` suggestions (`isDefault: true`) only; a `guest`-bound set is outside a package-time linter's sight and is the bind-time gate's alone (#16110) | - * | security-role-word (error) | ADR-0090 D3 vocabulary freeze — own function/registry entry since #8310; CLI + runtime publish gate since #19370 | + * | security-role-word (error) | ADR-0090 D3 vocabulary freeze — own function/registry entry since #8310; CLI + runtime publish gate since commit a227afa41 | * | security-book-audience-unknown-set(warn)| ADR-0046 §6.7 { permissionSet } | * | security-private-no-readscope (info) | admin-intent mismatch class | * | security-master-detail-ungranted(warn) | framework#2700 os-tianshun-mtc#43| @@ -821,7 +821,7 @@ export function validateSecurityPosture(stack: AnyRec, opts?: { nowMs?: number } // block's `runtimeTypes` widened: a door that refuses a permission set named // `role_manager` while a position named `sales_role` walks through — the // exact split the registry's #7220 pin refuses to build. - // [#19370] It has since crossed, whole, on its own entry — the two write + // [commit a227afa41] It has since crossed, whole, on its own entry — the two write // types are mapped and all five are declared there. The two entries remain // separate: that is what let each cross on its own evidence. @@ -1099,7 +1099,7 @@ export function validateSecurityPosture(stack: AnyRec, opts?: { nowMs?: number } * the registry refuses to build it in either direction. The rule therefore * stayed behind WHOLE, on its own CLI-only registry entry. * - * [#19370] It is now ACROSS, still whole and still its own entry: mapping + * [commit a227afa41] It is now ACROSS, still whole and still its own entry: mapping * `position` / `app` in `TYPE_TO_STACK_KEY` gives the gate a snapshot to build * for those two write types, and the entry declares all five write types the * six collections belong to. The split earned its keep exactly here — each diff --git a/packages/lint/src/validate-sortable-fields.ts b/packages/lint/src/validate-sortable-fields.ts index 47b255663c3..dbc4b24a935 100644 --- a/packages/lint/src/validate-sortable-fields.ts +++ b/packages/lint/src/validate-sortable-fields.ts @@ -91,7 +91,7 @@ * without this rung the dispatch widening (#9313's other half) would be * a silent no-op that reads as coverage. See the self rung note at the * walk below for how the shape is recognised. - * - `views[].config.sort` on a standalone ViewItem RECORD (#10001) — the + * - `views[].config.sort` on a standalone ViewItem RECORD (commit f1b5ad39a) — the * wire union's OTHER standalone member (`ViewItemWireSchema`, * `{ name, object, viewKind: 'list', config }`), through the same door: * objectui's `updateView` round-trips the whole record on every @@ -131,7 +131,7 @@ * #4463 P2 gap this module's first landing recorded — and is walked since * #9313 (the self rung above). Its sibling shape, a standalone ViewItem * RECORD (`{ name, object, viewKind, config }` — `config.sort` one level - * down), was #9313's recorded follow-up scope and is walked since #10001 + * down), was #9313's recorded follow-up scope and is walked since commit f1b5ad39a * (the record rung above). * * ── Skips, matching the search axis one for one (ADR-0072 D1) ──────────── @@ -169,7 +169,7 @@ * nothing. Existence rightly stays silent; PROVENANCE is a second question, * asked only of the names skip 3 already kept and answered by the per-object * index ({@link indexUnprovisionedAnchors}) rather than the object-independent - * union. This is the SORT twin of the SEARCH wiring #8404 added on the + * union. This is the SORT twin of the SEARCH wiring commit b849e6911 added on the * identical index, and it is the same shape the four filter/binding rules * carry since #8340. * @@ -564,7 +564,7 @@ export function validateSortableFields(stack: AnyRec): SortableFieldFinding[] { // `viewKind: 'list'` (REQUIRED on the overlay arm since #7741, and a key // the strict container schema refuses by name, so a container can never // match) with no nested `config` (a body carrying one is a ViewItem - // RECORD, judged by its own record rung below since #10001). + // RECORD, judged by its own record rung below since commit f1b5ad39a). // `view-walk.ts` established the same // `self` rung for the section-carrying shapes; this is its list twin. // @@ -583,7 +583,7 @@ export function validateSortableFields(stack: AnyRec): SortableFieldFinding[] { ); } - // ── [#10001] The RECORD rung: a standalone ViewItem record ── + // ── [commit f1b5ad39a] The RECORD rung: a standalone ViewItem record ── // // The self rung's structural complement — `ViewMetadataSchema`'s member 1 // (`ViewItemWireSchema`): `{ name, object, viewKind: 'list', config }`, diff --git a/packages/lint/src/validate-translation-references.ts b/packages/lint/src/validate-translation-references.ts index 19a604da51a..42b1c2bda36 100644 --- a/packages/lint/src/validate-translation-references.ts +++ b/packages/lint/src/validate-translation-references.ts @@ -231,7 +231,7 @@ function strName(v: unknown): string | undefined { * Add a validation rule's own `name` to the universe, then recurse into a * `conditional` rule's `then` / `otherwise` branch — each branch is itself a * full rule (with its own `name`, and possibly its own nested branches), and - * mirrors the recursion `evaluateRule` performs at runtime (#14700). See the + * mirrors the recursion `evaluateRule` performs at runtime (commit de3c52beb). See the * call site in {@link buildUniverse} for why the wrapper's own name is kept * too, even though `then` / `otherwise` are what a caller actually reads. */ @@ -297,7 +297,7 @@ interface ObjectFacts { * (`objects[].validations[].name`, including a nested `conditional` rule's * `then` / `otherwise` branch — the branch is itself a full rule and is the * address `checkConditional` / `authoredRuleMessage` actually key on; - * #14700). `objects.._validations..message` (#14253) is keyed by + * commit de3c52beb). `objects.._validations..message` (#14253) is keyed by * that name, so a ghost here is a rule message that renders in the source * locale inside an otherwise translated refusal. */ @@ -547,7 +547,7 @@ function collectPageTabs(page: AnyRec, factsFor: (objectName: string) => ObjectF * very same view `.default` — so a container declaring only a default * `list` produced a registry entry keyed `default` and a lint fact set that * knew no such view. The CLI i18n walker demanded `_views.default.label` - * (#6124, leg 1) and this rule called the key an orphan, in ONE `os lint` run: + * (commit b3c1f3cd5, leg 1) and this rule called the key an orphan, in ONE `os lint` run: * six instances on the showcase, and no author action could make both green. * Ruled 2026-08-06 (#5164): canonical = the runtime identity's bare key. * Leg 1's `defaultListViewKey` in `packages/cli/src/utils/i18n-extract.ts` is @@ -980,7 +980,7 @@ function buildUniverse(stack: AnyRec): Universe { // #14253: `_validations.` is keyed by the rule's own `name`. A rule // without a name has no key and is not registered — the resolver cannot // address it either, so nothing is lost by skipping it here. - // #14700: a `conditional` rule's `then` / `otherwise` branch is itself a + // Commit de3c52beb: a `conditional` rule's `then` / `otherwise` branch is itself a // full rule, and its `name` — not the wrapper's — is the address // `checkConditional` delegates to and `authoredRuleMessage` keys on (see // `packages/objectql/src/validation/rule-validator.ts`). A flat walk over From 2ce32f6b48bae3c73e40e34261c8570e53e3ac8f Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 29 Sep 2026 07:02:46 +0000 Subject: [PATCH 2/2] chore(changeset): patch for the lint provenance re-anchoring Claude-Session: https://claude.ai/code/session_014EJ1ED8X4MMrT18BhVx4tx Co-authored-by: Claude --- .changeset/lint-provenance-anchors.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .changeset/lint-provenance-anchors.md diff --git a/.changeset/lint-provenance-anchors.md b/.changeset/lint-provenance-anchors.md new file mode 100644 index 00000000000..661b5fa245d --- /dev/null +++ b/.changeset/lint-provenance-anchors.md @@ -0,0 +1,11 @@ +--- +'@objectstack/lint': patch +--- + +Provenance comments in `@objectstack/lint` were re-anchored + +Comment and docblock lines under `src/` that cited tracker numbers which no +longer resolve on GitHub now cite the commit in this repository's history that +decided the matter, and say in their own words what was decided. Comments +only: no rule id, finding message, hint, severity, type or runtime behaviour +changes.