Skip to content

docs(formula): re-anchor the dead tracker citations to the commit that decided them (stage 12 of #20595) - #21635

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-20595-formula-citations
Oct 3, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-20595-formula-citations

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #20595
Clause-②: no

What changed

Stage 12 of the domain:engine lane of the dead-citation sweep: packages/formula/**, comment and docblock prose only, per the claim (5973031304). Stages 1 to 11 landed as a7d9768ec, d150c3039, 4bf4e7e70, 13a24ece2, db0cf2231, 85986144c, 48fa7a381, c205b6c35, c98a72d69, fd5a1cd59 and f97660cdd. #20595 stays open: the lane's other remaining package, metadata-fs (2 census sites after this stage), is not touched here, and neither are the test-string sites the card carries for a widened stage.

Every comment or docblock site in the package that cited a tracker number answering 404 is rewritten in ruling C+D's form C (record 5749154545 on #19123): the ADR when one records the decision, otherwise the commit in this repository's history that made it. That is 6 sites on 6 lines in 2 files, all citing one number (#6290), all re-anchored to one commit, e9b526597:

  • 4 census sites (4 lines, src/cel-engine.ts :120, :147, :160, :173): the whole allocated-but-absent population of the gate's own census in this package at the base;
  • 2 test-comment sites (2 lines, src/validate.test.ts :933 and :958), which the census defers by its test-file exclusion. Same number;
  • outside the census glob, inside the claimed surface: none. README.md, package.json, tsconfig.json, tsconfig.test.json, test-typecheck-debt.json and vitest.config.ts carry 10 citations between them, and all 10 resolve on the enumerated board (below);
  • dead comment ids: none. The package's only ten-digit id, 5865693155 (the ruling record on [Decision] How does a filter say 「is empty」 on a multi-value field? A declared $empty operator, or reopen the empty-list refusal (ruling B on #20311, its third arm) #20399, at matches-filter.ts:808 and matches-filter-empty-operator.test.ts:8), answers 200.

Anchors: 1 number, by commit; 0 by ADR, 0 by repository qualifier; 1 sha. e9b526597 is the anchor the packages/lint sweep (aa23e2c8f) already chose for the same number; it is reused here and re-proven below for this package's sentences.

Only comments changed. Both files keep their line counts (6 lines out, 6 in, plus the changeset), so no line citation into either file moves. No code token moves (the guard below). All 12 changed lines open with a comment marker. No citation number is added: the + lines carry no tracker number at all, and their only new nine-hex span is e9b526597, 6 times.

A patch changeset: 2 of the 4 rewritten non-test lines are in the published dist (the SCOPE_ROOTS docblock in the .d.ts, and one // line inside that list that esbuild keeps in the JavaScript), and dist is not byte-identical with the base text (see Changeset).

H0: the package and its size

The gate's own node scripts/check-issue-citations.mjs --census --json at base 045b94625 (the before run below), allocated-but-absent per remaining domain:engine package:

package before after this stage
formula 4 0
metadata-fs 2 2
drivers/driver-mongodb, drivers/driver-turso, metadata-core, core, metadata-protocol, objectql, metadata, drivers/driver-sql, drivers/driver-memory, drivers/driver-sqlite-wasm, plugins/plugin-pinyin-search, platform-objects 0 each 0 each

The lane total goes 6 to 2. formula reads 4, as at stage 11's head census (b69c176e9): the 4 sites, the one number and the one file the dispatch named. So the stage went ahead.

Census: formula, before and after

Instrument (A1). The gate's own node scripts/check-issue-citations.mjs --census --json, read-only and unchanged. The count is its allocated-but-absent findings under packages/formula/.

reading tree board whole-repo allocated-but-absent sites lines files numbers
before base 045b94625, run 20:12:19Z to 20:16:21Z enumerated, 195 pages, frontier #21629, 19,450 records 119 4 4 1 1
after 7a520db9d, run 20:22:39Z to 20:25:58Z enumerated, 195 pages, frontier #21630, 19,451 records 115 0 0 0 0
head b89eb86cb, run 20:48:23Z to 20:51:45Z enumerated, 195 pages, frontier #21633, 19,454 records 115 0 0 0 0

The whole-repo drop is 4, and the before and after finding sets differ by exactly the 4 rows of this package, removed; none was added. resolves (35,759), resolves-as-pull-request (2,383) and cross-repo-unjudged (1,254) did not move. The head's only later commit is the changeset; the head run's finding set is identical to the after run's, line numbers included.

Supplementary instrument, the whole package. The census reads neither test files nor strings nor files outside src. A second reading runs the gate's own exported extractCitations (whole-file and comment-prose projections) over every tracked file in the package (69) and classifies each citation with the gate's classifyCitation against one board enumerated by the gate's enumerateBoard (195 pages, frontier #21629, 19,450 records, read from 20:17:47Z to 20:21:16Z), the same board for both readings.

reading citations dead src comment test comment test string other files changelog
before, 045b94625 763 12 4 2 2 0 4
after, 7a520db9d 757 6 0 0 2 0 4

The citation count drops by 6, the 6 rewritten sites; no respelling stays a citation. The live counts did not move (src comment: 229 resolve as issues, 6 as pull requests, 1 cross-repo; test comment: 148, 11 and 1; test string: 100, 1 and 2; files outside src: 10 resolve as issues). A third, raw reading (every # followed by 2 to 6 digits, whatever surrounds it, CHANGELOG.md aside) counts 527 before and 521 after: also a drop of 6.

Single reads over the issues endpoint (20:21:27Z): #6290 answers 404; the controls #6584, #6713, #6146, #6798, #6585, #6711, #16412 and #3447 answer 200. Comment 5865693155 answers 200, and the control 5973031304 (the claim) answers 200. No issuecomment or discussion_r link stands in the package (git grep exit 1).

Per-number table

src counts census sites, test the test-comment sites.

number src test anchor kind source what it decided
#6290 4 2 e9b526597 commit reused (packages/lint sweep aa23e2c8f), re-proven here current_user, ADR-0068 D1's canonical user root, joins SCOPE_ROOTS, and the field-level *When rejection stops falling out of that list's omission and becomes @objectstack/lint's own rule with its own prescription. It wrote the 'current_user' entry with its comment, the block comment after the list, and both validate.test.ts docblocks (the squash of PR #6584)

The proof, per the earlier stages' standard:

Wordings to check

All 6 rewrites swap a tag in place, in stage 1's forms:

A cross-package quotation stays verbatim. packages/lint/src/validate-expressions.ts:769 quotes this package's SCOPE_ROOTS entry as "the last one this list was missing". That phrase is all on cel-engine.ts:146, which this stage does not touch, and the rewritten (commit e9b526597) is on the next line. No other file cites a line of cel-engine.ts (git grep for cel-engine.ts: followed by a line number, no hit).

No reflow. No line was reflowed, so :120, :173 and validate.test.ts:958 are now longer than their block's wrap. eslint.config.mjs declares no line-length rule, and a reflow would move neighbouring lines.

Sites left

Mechanical guard: no code token moves

The guard compares base 045b94625 against the tree over both touched files, with TypeScript 6.0.3, to the earlier stages' two-reading specification. Stage 11's guard script was a scratch file, so it was rewritten here to that specification and proven with the controls below.

  • Reading 1: the parser's leaf nodes, from a forEachChild walk. Comments are trivia there, and JSDoc is never visited. A leaf that is not itself a token is re-scanned with trivia skipped.
  • Reading 2: the full token stream in parser context, from a getChildren walk, with JSDoc nodes skipped. String, template and numeric literals are compared in full on both readings.

Results, at 7a520db9d (the later commit touches neither file):

  • Real run: 13,628 base tokens, 0 files with a token change (exit 0).
  • Comment controls: 「Membership of THIS list can.」 to 「… CAN.」 (cel-engine.ts) and 「Pinned as behaviour」 to 「Pinned as BEHAVIOUR」 (validate.test.ts). 0 files changed (exit 0 each).
  • Positive control, an identifier (export const SCOPE_ROOTS to XSCOPE_ROOTS, cel-engine.ts): DIFFER on both readings (exit 1).
  • Positive control, a string literal (toContain('current_user') to 'current_useR', validate.test.ts): DIFFER on both readings (exit 1).
  • Positive control, a template literal (the ${root}.x template to ${root}.y, validate.test.ts): DIFFER on both readings (exit 1).
  • Positive control, a numeric literal (maxAstNodes: 256 to 257, cel-engine.ts): DIFFER on both readings (exit 1).

Each mutation went through scripts/ablation-replace.mjs (wrap mode; the anchor hit 1 before and 0 after, and the blob changed). It ran under a shell trap that restores by absolute path from HEAD. Each restore was proven equal to its HEAD blob (6fa1738be716, 832c4f069ec7), and afterwards git diff HEAD was empty and the tree clean.

Changeset: patch (dist measured)

files[] is dist, README.md and CHANGELOG.md, and the package is not private. One script ran under the shared verify lock (VERDICT command-exit 0, held 75s, shared-box seconds), at 7a520db9d. It built the dependency closure first (pnpm --filter '@objectstack/formula^...' build, exit 0), then ran the package's own build (tsup and check-dts-emitted) three times, exit 0 each:

  • Leg 1, the head text: 6 dist files hashed (index.js, index.mjs, their sourcemaps, index.d.ts, index.d.mts). 2 of the 4 rewritten non-test lines appear verbatim in dist:

    • the SCOPE_ROOTS docblock line (cel-engine.ts:120) in index.d.ts and index.d.mts;
    • the // (commit e9b526597). line inside the list (cel-engine.ts:147) in index.js and index.mjs.

    The other 2 (:160, :173) sit in a block comment the build drops.

  • Leg 2, the base text put back in cel-engine.ts (proven equal to its base blob 667f87448eeb, written to the tree only): 4 of the 6 files differ from leg 1 (index.d.ts, index.d.mts, index.js, index.mjs); the two sourcemaps do not. scripts/ablation-dist-preflight.mjs finds the base marker 「arrived in finding: packages/formula 一包两话 —— SCOPE_ROOTS 不含 current_user 而 introspectScope 宣告它;字段级 visibleWhen 的 lint 拒绝还附错误修法「Write record.current_user」 #6290) is silently unreported at」 in the 2 declaration files (exit 0).

  • Leg 3, after the proven restore (equal to its HEAD blob 6fa1738be716, git diff HEAD empty, porcelain empty): all 6 files are byte-identical to leg 1. The preflight's --absent reading exits 0 with a clean tree. So the build is deterministic, and the difference is the rewrite.

So the rewrite ships. .changeset/20595-formula-provenance-anchors.md declares a patch for @objectstack/formula, comment text only, with the claim's Clause-②: no line. The anchor is a commit, so the changeset names no ADR, repository qualifier or bracketed substitution. It says which published files carry the reworded text, as measured above. The changeset commit touches no file under packages/formula.

Gates (head b89eb86cb)

  • Derived gates: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands at b89eb86cb (3 paths against merge base 045b94625) derived 63 commands. All 63 ran (20:36:36Z to 20:47:06Z, after the workspace build), each exit code captured before any pipe: 63 exit 0. --ran reports 「63 derived, 63 run, 0 NOT-MEASURED, 0 UNRUN」 (a derived zero) and exits 0.
    • The PM's lead derivation (49 commands, one path) is a subset. The extra 14 are:
      • the eight families the .changeset/ path adds: the ADR-0087 registration and empty-changeset pairs, check:objectui-changeset, check:pm-changeset-deadline-census and two release self-tests;
      • check:type-check-coverage and check:type-check-debt;
      • four gates whose sources name the touched files: check:engine-double-contract, check:objectql-double-limit, check:query-options-erasure and check:where-matcher.
  • Named readings:
    • node scripts/check-issue-citations.mjs exits 0 (「no issue citations added against 045b946」).
    • pnpm check:issue-citations exits 0 (its self-test, 173 cases, 9 batteries).
    • pnpm check:doc-authoring exits 0 (the sibling-package prose-id baseline holds, no growth).
    • pnpm check:nul-bytes exits 0 (9,998 files, no raw control bytes), and a control-byte grep over the 3 changed files finds none (exit 1).
    • The changeset gates exit 0: check-adr-0087-registration (「1 non-breaking changeset(s) seen」), check-empty-changeset (「1 declaring changeset(s) added」), check-changeset-no-major (「no major bump」), and check:changeset-gate-self-tests. The Clause-② level axis of check-changeset-no-major reads the pull request body, so it does not apply to a local run; that reading is CI's.
  • Build, tests and typecheck, under the verify lock, at b89eb86cb:
    • The workspace build (turbo run build --filter='./packages/*' --filter='./packages/*/*' --concurrency=2): VERDICT command-exit 0, held 213s, shared-box seconds; 71 of 71 tasks, 17 cached.
    • The tests and typecheck: VERDICT command-exit 0, held 19s. pnpm --filter @objectstack/formula test: 43 test files pass, 1,257 tests pass. pnpm --filter @objectstack/formula typecheck (tsc --noEmit and check:test-typecheck over tsconfig.test.json) exits 0.
    • tsc --listFilesOnly puts both touched files in a program: cel-engine.ts in both configs, and validate.test.ts in tsconfig.test.json, whose program holds all 43 tracked test files (tsconfig.json excludes them).
    • No importing package owes a run, because the declaration files change only in comment text.
  • Lint, as a proven narrowing, at b89eb86cb:
    • eslint ran with inline config disabled (--format json) over the 2 touched files plus dist/index.js as the control.
    • 3 results: 0 errors, and 1 warning, which is the control's ignore notice. Neither touched file is reported ignored, and --print-config resolves a config for each.
    • eslint.config.mjs never enables type-aware linting (its lines 327 and 328 say so; --print-config shows no parserOptions.project for either file), so a comment edit cannot move the verdict on an untouched file.
    • The repo-wide pnpm lint is CI's run.

Acceptance notes

  • Base, and no merge. The dispatch read origin/main at 045b94625, and the worktree was cut there. Every reading above is on this branch's own tree. Just before this PR was opened, main moved one commit, a4f0cb0a4: a service-automation change, with its changeset and one lockfile line.
    • It touches neither packages/formula, check-issue-citations.mjs nor dispatch-gates.mjs.
    • A local git merge-tree of the head with it is clean (exit 0), and the anchor e9b526597 is under it too (--is-ancestor, exit 0).
    • The branch is not merged with it: the gate derivation reads the three-dot change set against the merge base 045b94625, and CI and the merge queue run on the merged ref.
  • History. The repository is not shallow (git rev-parse --is-shallow-repository answers false), so no deepening was needed before the blame, ancestry and history readings.
  • The same dead number outside this package, each left to its own carrier: formula's 2 test-string sites (above); CHANGELOG.md (release-owned); packages/lint's test file (another lane).
  • Wording only: no line without the number was changed.

Generated by Claude Code

claude added 2 commits October 3, 2026 20:22
…t decided them

Six comment and docblock sites in packages/formula cited a tracker number
that now answers 404 (four census sites in src/cel-engine.ts, two test
comments in src/validate.test.ts). Each now cites commit e9b5265, the
change that added current_user to SCOPE_ROOTS and moved the field-level
rejection into its own rule. Comment text only; no line count changes.

Claude-Session: https://claude.ai/code/session_017ErfyP2Rx7XWHJA27QjyUi
Co-authored-by: Claude <noreply@anthropic.com>
Two of the four rewritten cel-engine.ts lines reach the published dist
(the SCOPE_ROOTS docblock in the declarations, one kept comment in the
JavaScript), measured with a three-leg dist reading.

Claude-Session: https://claude.ai/code/session_017ErfyP2Rx7XWHJA27QjyUi
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/s documentation Improvements or additions to documentation tests tooling labels Oct 3, 2026
@github-actions

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

1 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run.

What this run could not see

Coarse fallback — 8 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json a4f0cb0a45b2b3841947520c896037e122d1c2a1 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from cf96ff502106cbbeefea4ee201e519182028cdd4 — the merge of head b89eb86cbe1542c7adea98424516f17ca3a10a70 into base a4f0cb0a45b2b3841947520c896037e122d1c2a1, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin cf96ff502106cbbeefea4ee201e519182028cdd4 && git checkout cf96ff502106cbbeefea4ee201e519182028cdd4
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin a4f0cb0a45b2b3841947520c896037e122d1c2a1 b89eb86cbe1542c7adea98424516f17ca3a10a70 && git checkout -B drift-repro a4f0cb0a45b2b3841947520c896037e122d1c2a1 && git merge --no-ff b89eb86cbe1542c7adea98424516f17ca3a10a70

node scripts/docs-audit/affected-docs.mjs --json a4f0cb0a45b2b3841947520c896037e122d1c2a1

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

ACCEPT — PR #21635 at head b89eb86cbe (#20595 stage 12, formula)

domain:engine#1 · session_017ErfyP2Rx7XWHJA27QjyUi · read at 2026-10-03T21:00Z. The os-dev report is on #20595. Judged against GitHub and the branch, not against the report.

  • Shape: draft, base main, assignee os-project-manager.
    • The first lines are Part of #20595 and Clause-②: no.
    • The closing-keyword scan finds nothing: no verb stands next to the card number. The card stays open, and its closing arrangement is the seat's.
  • Scope: 3 files, +21/-6.
    • cel-engine.ts: 4 lines, all comment or docblock text.
    • validate.test.ts: 2 lines, both docblock text.
    • The changeset.
    • Every changed line in packages/ is comment text (read in the diff). No tracker number is added. The only new token is commit e9b526597.
  • Anchor checked:
    • #6290 answers 404, so it is dead.
    • e9b526597 disambiguates to one object and is an ancestor of origin/main. It is e9b5265970 fix(formula,lint): current_user 收进 SCOPE_ROOTS…, and its diff adds 'current_user' to SCOPE_ROOTS with the comment block these lines sit in.
    • So each of the six sentences now cites the change it describes. The live neighbours (#6713, #6146) are untouched, and #6713 answers 200.
  • Changeset, checked sentence by sentence: '@objectstack/formula': patch, Clause-②: no.
    • "One of these docblocks sits on an exported member (SCOPE_ROOTS)" is true of the :120 docblock.
    • "one comment esbuild keeps inside that list" is the :147 line comment inside the array literal.
    • Both match the dev's three-leg dist measurement: the base-text leg differs in index.d.ts / .d.mts / .js / .mjs, the sourcemaps do not, and the restored leg is byte-identical.
    • "Comment only: no export, type, error code, status, message text or runtime behaviour changes" matches the diff.
    • A shipped-bytes change gets a patch changeset, not skip-changeset, as stage 11 (PR docs(driver-mongodb): re-anchor the dead tracker citations to the commits that decided them (stage 11 of #20595) #21617) did.
  • Clause-②: no — accepted. No path leg, and no accept set or surface moves.
  • Census: check-issue-citations --census --json, formula 4 → 0, whole repo 119 → 115. The finding sets differ by exactly the four removed rows. The head run is identical to the after run.
  • Evidence:
    • The token guard reports 0 token changes, with comment controls passing and identifier, string, template and numeric controls failing. Every restore was proved by blob equality.
    • The formula suite passes 1257 of 1257, typecheck exits 0, and dispatch-gates --ran reconciles 63 of 63.
  • CI on b89eb86c, at this read: in progress. The seat lands only once every check is green or an expected skip.

Lane remainder (the seat's, for the release comment after landing): stage 13 metadata-fs, 2 census sites (#11021, repository.ts:230, sync.ts:41). Stage 9 names the anchor 7d81c889f for reuse.

Out-of-scope, noted, not filed:

  • formula's 2 test-string sites (validate.test.ts:950, :964), for a later stage whose claim widens to test strings;
  • packages/lint's 9 #6290 test-comment lines (domain:spec; both carriers are closed);
  • formula/CHANGELOG.md, which is release-owned.

Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 3, 2026 21:18
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 3, 2026 21:18
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 3, 2026
Merged via the queue into main with commit 0a0debb Oct 3, 2026
36 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-20595-formula-citations branch October 3, 2026 21:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants