Skip to content

Commit b237592

Browse files
claude[bot]claude
andauthored
feat(devx): a symbol-anchor corpus over scripts/** refuses line citations in gate headers, and the free ones are migrated (#15765) (#15806)
* feat(devx): symbol-anchors gains a comment-prose doc projection and a tracked-target line-citation scope The extractor already reads comment prose exactly as it reads an ADR paragraph; what it also reads is the CODE around it, so a raw `.mjs` corpus judges a gate's own self-test fixtures. `commentProse` projects a JavaScript-shaped source down to its comment characters through the shared `js-comment-mask` scanner, blanking rather than deleting so line numbers survive. `defineCorpus` grows two options, both defaulting to today's behaviour: `docProjection` (refused loudly when present but not callable) and `judgeUntrackedLineAnchors`, the same scope call `checkBarePaths` makes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk * feat(devx): register a scripts/** symbol-anchor corpus and migrate the free citations Second `defineCorpus` registration over `scripts/**` `.mjs` comment prose, so a cross-file `path:NNN` naming a tracked file is REFUSED under the existing ANCHOR_GRAMMAR and symbol/file-level anchors resolve. 31 of the 32 judged citations are migrated; two files another lane's live PR holds carry a dated allowance row that the self-test forces to be deleted the day the citation goes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 2de7e53 commit b237592

21 files changed

Lines changed: 683 additions & 53 deletions

.github/workflows/lint.yml

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2284,7 +2284,7 @@ jobs:
22842284
# commands and the gate reds (3/2) — which is exactly what it did here.
22852285
# Both existing collectors in this file carry self-tests ONLY, for the
22862286
# same reason. Keep the sweep out of the collector block.
2287-
- name: ADR symbol-anchor gate self-tests
2287+
- name: Symbol-anchor gate self-tests
22882288
run: |
22892289
failed=""
22902290
run_self_test() {
@@ -2299,16 +2299,25 @@ jobs:
22992299
}
23002300
run_self_test node scripts/symbol-anchors.mjs --self-test
23012301
run_self_test node scripts/check-adr-symbol-anchors.mjs --self-test
2302+
run_self_test node scripts/check-scripts-symbol-anchors.mjs --self-test
23022303
if [ -n "$failed" ]; then
23032304
echo ""
2304-
echo "ADR symbol-anchor self-tests — the following FAILED:"
2305+
echo "Symbol-anchor self-tests — the following FAILED:"
23052306
printf "%s" "$failed"
23062307
exit 1
23072308
fi
23082309
23092310
- name: ADR symbol anchors resolve (no line numbers survive)
23102311
run: node scripts/check-adr-symbol-anchors.mjs
23112312

2313+
# The SECOND corpus (#15765), and it is a `defineCorpus` registration over
2314+
# `scripts/**` comment prose — ⛔ not a second resolver. Its own sweep is a
2315+
# separate step for the same `check-step-collectors` reason stated above:
2316+
# a production sweep inside the collector block re-invokes the stub the
2317+
# harness plants and the count comes out 4/3.
2318+
- name: scripts/** symbol anchors resolve (no line citations on tracked targets survive)
2319+
run: node scripts/check-scripts-symbol-anchors.mjs
2320+
23122321
# NOTE: the standing platform test checklist (docs/qa/platform-checklist/)
23132322
# is validated by `pnpm check:platform-checklist`, but by MAINTAINER
23142323
# DECISION it is NOT wired into CI — it runs on a periodic manual cadence

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
"check:adr-anchors": "node scripts/check-adr-anchors.mjs --self-test && node scripts/check-adr-anchors.mjs",
8787
"check:adr-links": "node scripts/check-adr-links.mjs --self-test && node scripts/check-adr-links.mjs",
8888
"check:adr-symbol-anchors": "node scripts/symbol-anchors.mjs --self-test && node scripts/check-adr-symbol-anchors.mjs --self-test && node scripts/check-adr-symbol-anchors.mjs",
89+
"check:scripts-symbol-anchors": "node scripts/symbol-anchors.mjs --self-test && node scripts/check-scripts-symbol-anchors.mjs --self-test && node scripts/check-scripts-symbol-anchors.mjs",
8990
"check:platform-checklist": "node scripts/checklist-select.mjs --self-test && node scripts/check-platform-checklist.mjs",
9091
"check:org-identifier": "node scripts/check-org-identifier.mjs --self-test && node scripts/check-org-identifier.mjs",
9192
"check:runner-env-posture": "node scripts/check-runner-env-posture.mjs --self-test && node scripts/check-runner-env-posture.mjs",

scripts/audits/14423-databaseloader-cost-probe.mjs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license.
33
//
44
// #14423 step 1 (census) — empirical confirmation that `DatabaseLoader.loadManyKeyed()`
5-
// costs NOTHING extra over `loadMany()` (same query, same cache — `readTypeRows()`,
6-
// `packages/metadata/src/loaders/database-loader.ts:936`), while a `listNames()` +
7-
// per-name `load()` read costs a SEPARATE query (`list()`, `:1062`) plus one query
5+
// costs NOTHING extra over `loadMany()` (same query, same cache —
6+
// `packages/metadata/src/loaders/database-loader.ts#readTypeRows`, `#list`), while
7+
// a `listNames()` + per-name `load()` read costs a SEPARATE query plus one query
88
// PER NAME (`load()`'s `_findOne`, via `baseFilter(type,name)`) — a real N+1 against
99
// `loadMany`'s single query. MEASUREMENT ONLY — ships nothing.
1010

scripts/audits/14423-unbound-declarations-before-count.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
* (`runActionGovernanceInventory`, `collectEngineActionDeclarations`,
1010
* `reconcileActionRegistrations` — all exported from its public entry) and
1111
* drives it exactly as `ObjectQLPlugin.runGovernanceInventory`
12-
* (`packages/objectql/src/plugin.ts:2475`) does, over a controlled standalone
12+
* (`packages/objectql/src/plugin.ts#runGovernanceInventory`) does, over a controlled standalone
1313
* source that isolates the ONE population the identity fix can move:
1414
* standalone `action` declarations whose BODY carries no `name` (the C2/C6
1515
* shape) and are otherwise `type: 'script'` with no `body` and no bound

scripts/check-agent-test-spelling.mjs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,16 @@
8080
* printing. FIVE of the six are forms a naive bare-`--` selector would have RED,
8181
* and every one of them is correct as written:
8282
*
83-
* .github/workflows/ci.yml:1122 pnpm turbo run test --filter=@objectstack/dogfood -- --shard=N/3
84-
* .github/workflows/lint.yml:2443 pnpm dev -- --fresh (quoted in this gate's own wiring comment)
85-
* AGENTS.md:126 pnpm dev -- --fresh -p <random>
86-
* AGENTS.md:133 pnpm dev:crm -- --fresh -p 38421
87-
* AGENTS.md:388 pnpm dev -- --fresh -p <random>
83+
* ⚠️ The rows name the FILE, never a line in it. The line each sat on when this
84+
* was measured is kept beside it as data, because that is a dated reading and
85+
* not a pointer -- and a pointer written `file:NNN` rots silently, which is the
86+
* whole finding of #15765. `--list` re-derives the live position on every run.
87+
*
88+
* `.github/workflows/ci.yml` (was line 1122) pnpm turbo run test --filter=@objectstack/dogfood -- --shard=N/3
89+
* `.github/workflows/lint.yml` (was line 2443) pnpm dev -- --fresh (quoted in this gate's own wiring comment)
90+
* `AGENTS.md` (was line 126) pnpm dev -- --fresh -p <random>
91+
* `AGENTS.md` (was line 133) pnpm dev:crm -- --fresh -p 38421
92+
* `AGENTS.md` (was line 388) pnpm dev -- --fresh -p <random>
8893
*
8994
* The sixth is prose inside `scripts/check-examples-live-imports.mjs`, cleared
9095
* because its command word is a `check:` script.

scripts/check-doc-anchors.mjs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,14 @@
8181
// 200 internal fragment links across `content/**`, of which 4 pointed at
8282
// headings that do not exist:
8383
//
84-
// content/docs/automation/flows.mdx:240 #notify
85-
// content/docs/concepts/metadata-lifecycle.mdx:77 #overlay-whitelist
86-
// content/docs/permissions/authentication.mdx:75 /docs/deployment/cli#os-login--json-is-ndjson--the-one-exception
87-
// content/docs/protocol/kernel/http-protocol.mdx:764 /docs/api/client-sdk#clientdata--crud-operations
84+
// The FRAGMENT is the durable identifier of each row, so the file is named as a
85+
// file-level anchor and the line it sat on at measurement time is data beside
86+
// it — a dated reading, not a pointer (#15765).
87+
//
88+
// `content/docs/automation/flows.mdx` (was line 240) #notify
89+
// `content/docs/concepts/metadata-lifecycle.mdx` (was line 77) #overlay-whitelist
90+
// `content/docs/permissions/authentication.mdx` (was line 75) /docs/deployment/cli#os-login--json-is-ndjson--the-one-exception
91+
// `content/docs/protocol/kernel/http-protocol.mdx` (was line 764) /docs/api/client-sdk#clientdata--crud-operations
8892
//
8993
// Three of the four are the exact shape the card predicted — an anchor written
9094
// from the heading a reader SEES, one dash off from the heading the slugger

scripts/check-init-service-contract.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -788,7 +788,8 @@ function selfTest() {
788788
}
789789
`;
790790

791-
// 13. #4772 VERBATIM, pre-fix (`f2eb85007^`, packages/plugins/plugin-auth/src/auth-plugin.ts:346):
791+
// 13. #4772 VERBATIM, pre-fix — `packages/plugins/plugin-auth/src/auth-plugin.ts`
792+
// as it stood at `f2eb85007^` (line 346 there, a dated reading, not a pointer):
792793
// init() resolves the workspace-provided `cache` through `getServiceAsync`,
793794
// via an optional call on a cast `ctx`, inside a best-effort try/catch, and
794795
// the plugin's declarations cover `data`/`manifest`/objectql — never `cache`.

scripts/check-org-identifier.mjs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -203,10 +203,13 @@
203203
// ... of them wrong today ............................................ 0
204204
// the same literal in the SCANNED (non-test) population ............... 0
205205
//
206-
// packages/spec/src/data/hook.test.ts:619 #3290 absence pin
207-
// packages/plugins/plugin-audit/src/audit-writers.test.ts:1666 absence pin
208-
// packages/plugins/plugin-audit/src/comment-access-hooks.test.ts:529 #9691
209-
// packages/services/service-storage/src/attachment-access-hooks.test.ts:750
206+
// (the file, never a line in it — the recipe above re-derives the position on
207+
// every run, and a `file:NNN` pointer written here would rot silently, #15765)
208+
//
209+
// `packages/spec/src/data/hook.test.ts` #3290 absence pin
210+
// `packages/plugins/plugin-audit/src/audit-writers.test.ts` absence pin
211+
// `packages/plugins/plugin-audit/src/comment-access-hooks.test.ts` #9691
212+
// `packages/services/service-storage/src/attachment-access-hooks.test.ts`
210213
//
211214
// (The recipe reports 5 matches across those 4 files: `hook.test.ts` carries a
212215
// second one whose `tenantId` sits inside a COMMENT in the literal's body.)

scripts/check-overlay-whitelist-table.mjs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,9 +162,9 @@
162162
* ## Scope: this table only, deliberately
163163
*
164164
* Sibling pages state the same facts correctly in PROSE, not in a machine-shaped
165-
* type→flag table: `content/docs/permissions/authorization.mdx:236`
165+
* type→flag table: `content/docs/permissions/authorization.mdx`
166166
* ("`permission` declares `allowOrgOverride: false`"),
167-
* `content/docs/automation/jobs.mdx:42` (a job-vs-flow comparison table whose
167+
* `content/docs/automation/jobs.mdx` (a job-vs-flow comparison table whose
168168
* flag mention sits inside an English cell), `content/docs/ai/agents.mdx`,
169169
* `content/docs/permissions/capabilities.mdx`,
170170
* `content/docs/references/system/email-template.mdx`.

scripts/check-platform-checklist.mjs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@
4646
// `use`. A recipe nobody opts into is dead text a runner may still replay.
4747
// Both directions together are what the trap vocabulary beside them has
4848
// always had — used implies documented, documented implies used.
49-
// - every SYMBOL ANCHOR (`path/to/file.ts#symbolName`) resolves: the cited
49+
// - every SYMBOL ANCHOR (`<dir>/<file>.ts#<symbol>`, the spelling
50+
// `scripts/symbol-anchors.mjs#ANCHOR_GRAMMAR` defines) resolves: the cited
5051
// file is in the tree and the cited symbol is still in it, comments masked
5152
// — a symbol surviving only in a docblock is ABSENT. A shrink-never floor
5253
// per family file keeps the population from being emptied one deleted

0 commit comments

Comments
 (0)