Skip to content

docs(dogfood): re-anchor the dead tracker citations in packages/qa/dogfood's files outside src to the commits and ADR that decided them - #20898

Merged
objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-20594-qa-dogfood-citations
Sep 30, 2026
Merged

objectstack-fleet[bot] merged 1 commit into
mainfrom
claude/issue-20594-qa-dogfood-citations

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #20594
Clause-②: no

What changed

This is stage 15 of the domain:cli lane's dead-citation sweep: packages/qa/dogfood's dead citations in files outside src/**, the largest package left after stage 14 (claim 5914651671). The package has no src/ at all, so the surface is its test/**, README.md, tsconfig.json and vitest.config.ts.

Every comment site on that surface whose tracker number answers 404 now cites the object that decided what the line describes, in ruling C+D's form C (comment 5749154545 on #19123): the ADR clause when one records the ruling, otherwise the commit in this repository's history. Stages 1 to 14 of this card are the precedents; the latest is PR #20883.

Census

Instrument. The card's gate does not read these files: its declared surface is packages/**/src/**, and surfaceFor answers null for all 27 touched paths (the control packages/cli/src/commands/init.ts answers package-docblocks). So the census is taken by hand, with the gate's own grammar, as stage 14 took it:

  • Files: every tracked file of packages/qa/dogfood outside src/**, with CHANGELOG.md (claim) and package.json (not on the claim's list) left out. That is 178 files.
  • Extraction: extractCitations from scripts/check-issue-citations.mjs, with its comment-prose projection for code and JSONC files and the whole file for README.md. The whole-file extraction minus the comment projection gives the string sites.
  • Numbers kept: only those naming this repository (namesThisRepository).
  • Probe: each distinct number, GET /repos/objectstack-ai/objectstack/issues/N; 404 means dead.
tree probe window (UTC) numbers answer 200 answer 404 dead comment sites comment sites dead string sites
before base 4edb61449b 2026-09-30 15:46:43 to 15:49:29 386 359 27 94 (24 numbers, 27 files) 1,145 28 (13 files)
after head 57ffb83b00 2026-09-30 15:59:37 to 16:02:15 375 359 16 0 1,051 28 (13 files)

Per-number anchors

Each anchor was checked by blame on the site, and in the anchor's own message or diff. "Reused" names an earlier stage that gave the number the same anchor.

number sites anchor what it decided
#6293 9 c39a911ae the build stand-in: build-shaped-artifact.ts runs the real lowering, and no published surface grows (its subject names the card) reused (cli src)
#6483 15 ee58392e1 the ADR-0005 rollback of permission (and eight more types) to allowOrgOverride: false; allowRuntimeCreate stays open reused (spec, plugin-security, runtime)
#8460 4 ADR-0029 D9.2a the ruling itself, 2026-08-13, option A "tenant wins"; implemented in 01a7337fc, which amends the ADR reused (spec stage 6)
#8676 9 d6e80b28b flags sys_account.password and previous_password_hashes internal reused (plugin-auth)
#8711 3 2ce1eb41b half (2): the ruled narrowing of the matrix's completeness claim to routes (its message records the maintainer ruling) new
#8711 1 60ade586e half (1): the two active rows with no covers, and why (matrix.ts:393) new
#8811 1 d6e793507 adds the grant-validity-window matrix row (its subject names the card) new
#8839 7 c25b2d52a comment moderation stops being dead behind the delete floor; ruling of 2026-08-15, reading 1 reused (plugin-security)
#8919 1 b5378550e gates /meta publish and rollback on manage_metadata, with the enumeration pin reused (rest, runtime, cloud-connection)
#9797 7 1258dcaee the PR itself: the opt-in whole-operation dispatch that restores the unscoped multi-delete refusal new
#9934 2 79c46da90 the producer-side userMessage marking, including the QuickJS side-channel reused (types, rest, client, runtime, plugin-hono-server, spec)
#10243 1 266436a7f the toggle ruling: POST /automation/:name/toggle joins the manage_metadata write set (automation-toggle-tenant-scope:4) reused (runtime, service-automation)
#10243 1 02b41232d the measured cross-organization toggle leak ADR-0126 §7.2 retires (packaged-activation-ledger-reach:291) reused (runtime, service-automation)
#10943 1 46d34ab7c fallbackImport becomes a caller-supplied parameter reused (types, cli, verify)
#10996 1 02b41232d the PR itself, the first landing of this file as a measurement new
#11477 7 6dd3e6968 /admin/remove-user authorizes before the break-glass guard (its message records "Ruled option A on" the card) reused (plugin-auth, verify)
#11530 1 033a34c7c the PR itself: retires the set_user_role console action new
#11686 1 7131f12bf the PR itself: hasPlatformAdminStanding as the one authority new
#12176 3 7986d973f stage 3 of the ruled retirement: un-mounts the compound arities, PUT /meta/:type/:section/:name among them. The ruling's D3 ordinal is kept beside it reused (rest, client, runtime, spec)
#12194 1 311433f6b declares the metadata item-name grammar reused (rest, client, runtime, spec)
#13214 4 cc837dbfe the ruled ownership gate at GET /ui/view/:object/:type; its diff writes these census lines and its message the 2026-08-30 ruling reused (rest)
#16589 4 555a89cbd driver-memory refuses a tenant-scoped call; its diff names the card at every seam reused (trigger-schedule)
#16659 6 ecdfc9411 a time-triggered flow declares its acting organization; its diff adds these pins and the fixture. The F2 ordinal is kept, as the trigger-schedule stage kept it reused (trigger-schedule, service-automation, spec, lint)
#16687 1 779710213 the PR itself; its squash carries the contract-review patch round the line describes new
#17853 1 08f5f0e5a a vitest filter that selects nothing says so (the same sentence stage 14 rewrote in cli's config) reused (qa, cli)
#19306 2 f9e16d856 a packaged permission set's DELETE stops reporting a deletion; its diff adds both pins new

ADR and ruling records. A grep of docs/adr and scripts/adr-anchors for the 24 numbers finds three: #8460, #6483 and #10243. ADR-0029 D9.2a is the ruling for #8460 (it carries the number in its heading), so it is cited. The #6483 hits (ADR-0086, ADR-0094, ADR-0126 and two adr-anchors entries) and the #10243 hits (ADR-0126, ADR-0131) mention those landings as history; none records the ruling itself, so those two stay on the commit every earlier stage anchored them to. The control number 7329 finds 1 file in the same tree.

Anchor checks:

  • Each sha is unambiguous: git rev-parse --disambiguate gives count 1 for each of the 24.
  • Each is a plain commit with one parent.
  • Each is on the base: merge-base --is-ancestor against 4edb61449b exits 0 for all 24.
  • The history is complete: the checkout is not shallow. Control leg: 255588bd36, the parent of the oldest anchor ee58392e1 (2026-08-09), exits 0. Negative control: the base as an ancestor of ee58392e1 exits 1.

Verification

All at head 57ffb83b00. Heavy runs went through scripts/pm/os-verify-lock.sh with OS_VERIFY_LOCK_SLOT=issue-20594-dogfood.

  • Build (dependency closure): pnpm exec turbo run build --filter='@objectstack/dogfood^...' --concurrency=2 → 63 successful, 63 total (32 cached), lock verdict exit 0.
  • Every touched test file ran, by name. Dogfood has two vitest projects (shared-showcase and isolated) and no tier split, so one run named all 21 touched test files plus the unit tests of the two touched helpers no touched test imports (authz-probe-blind-spot.test.ts, the census module's only importer, and enterprise-organizations.test.ts): pnpm --filter @objectstack/dogfood exec vitest run --maxWorkers=2 FILES → Test Files 23 passed (23), Tests 317 passed (317), lock verdict command-exit 0. vitest.config.ts is loaded by that run.
  • Typecheck: pnpm --filter @objectstack/dogfood typecheck (tsc --noEmit) → lock verdict command-exit 0. --listFilesOnly shows 26 of the 27 touched files in the program; the 27th is vitest.config.ts.
  • Token guard (TypeScript leaf tokens via getChildren, JSDoc nodes skipped), base 4edb61449b against head, 27 files, 52,502 base tokens: 0 files differ. Controls, in memory only: a comment inserted into each file, 0 of 27 differ; a statement appended, 27 of 27; one character flipped inside each file's first StringLiteral, 27 of 27.
  • Control bytes: a scan of the 27 files finds 0 (positive control, a scratch file holding U+0001: 1). pnpm check:nul-bytes exits 0.
  • Derived gates and lint: listed under "Gates".

Gates

All at head 57ffb83b00, exit codes captured before any pipe.

  • Derivation: node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands, no paths, derives 53 commands for this change set (27 paths against merge base 4edb61449b). Re-derived after two fetches of origin/main (to 00a92e18da, then 33b6e8bece): the same 53, and none of the upstream commits touches a derivation input or a file here.
  • All 53 exit 0. One needed a second run for a reason outside the diff: pnpm check:dual-build-cjs-loads first exited 3 (PREREQUISITE NOT MET, no dist/ for 8 packages outside dogfood's build closure); after pnpm exec turbo run build --filter='./packages/*' --filter='./packages/*/*' --concurrency=2 (71 of 71, all cached) it exits 0.
  • Reconciliation: dispatch-gates --ran over the recorded COMMAND :: exit CODE list → "53 derived, 53 run, 0 NOT-MEASURED, 0 UNRUN", exit 0.
  • pnpm lint (repo-wide eslint . --no-inline-config, the family the derivation does not name) → exit 0, 2026-09-30T16:13:49Z to 16:18:00Z.
  • node scripts/check-issue-citations.mjs (diff mode, in the 53) reads 0 files, because none of these paths is on its declared surface; the hand census above is the measurement for this surface.
  • A local git merge-tree --write-tree of this head against origin/main 33b6e8bece is clean.

The 53 derived commands:

  • node scripts/check-ci-filter-parity.mjs
  • node scripts/check-closing-keyword-parity.mjs
  • node scripts/check-closing-keyword-parity.mjs --self-test
  • node scripts/check-comment-mask-adoption.mjs
  • node scripts/check-comment-mask-adoption.mjs --self-test
  • node scripts/check-comment-mask-corpus.mjs
  • node scripts/check-issue-citations.mjs
  • node scripts/check-keyed-text-bounds.mjs
  • node scripts/check-keyed-text-bounds.mjs --self-test
  • node scripts/check-platform-object-tenancy-census.mjs
  • node scripts/check-platform-object-tenancy-census.mjs --self-test
  • node scripts/check-plugin-teardown-shape.mjs
  • node scripts/check-plugin-teardown-shape.mjs --self-test
  • node scripts/check-registry-log-declared.mjs
  • node scripts/check-registry-log-declared.mjs --self-test
  • node scripts/check-rest-log-spy-declared.mjs
  • node scripts/check-rest-log-spy-declared.mjs --self-test
  • node scripts/check-system-context-census.mjs
  • node scripts/check-system-context-census.mjs --self-test
  • node scripts/check-undeclared-dep-imports.mjs
  • node scripts/check-undeclared-dep-imports.mjs --self-test
  • node scripts/docs-audit/check-affected-docs.mjs
  • node scripts/docs-audit/check-drift-comment.mjs
  • pnpm --filter @objectstack/spec run check:empty-state
  • pnpm --filter @objectstack/spec run check:liveness
  • pnpm --filter @objectstack/spec run check:strictness-ledger
  • pnpm --filter @objectstack/spec run check:variant-docs
  • pnpm check:cross-package-test-inputs
  • pnpm check:dispatcher-error-vocabulary
  • pnpm check:doc-authoring
  • pnpm check:driver-memory-census
  • pnpm check:dts-closure
  • pnpm check:dual-build-cjs-loads
  • pnpm check:engine-double-contract
  • pnpm check:gitlink-declared
  • pnpm check:issue-citations
  • pnpm check:lean-entry-closure
  • pnpm check:logger-receiver-detach
  • pnpm check:nul-bytes
  • pnpm check:objectql-double-limit
  • pnpm check:org-identifier
  • pnpm check:page-declaration-shape
  • pnpm check:published-files
  • pnpm check:query-options-erasure
  • pnpm check:refd-timer-probe
  • pnpm check:slot-lookup
  • pnpm check:sourcemap-no-sources-content
  • pnpm check:test-source-alias
  • pnpm check:tier-file-adoption
  • pnpm check:type-check-coverage
  • pnpm check:type-check-debt
  • pnpm check:watch-hint-literal
  • pnpm check:where-matcher

Acceptance notes


Generated by Claude Code

…gfood's files outside src to the commits and ADR that decided them

Comment prose only, in test/** and vitest.config.ts: every comment site
whose tracker number answers 404 now cites the commit in this repository's
history that decided what the line describes, or the ADR clause that records
the ruling (ADR-0029 D9.2a). String literals, describe/it titles and
messages are untouched. Every file keeps its line count.

Claude-Session: https://claude.ai/code/session_01VvcEokUG1tvVxkceYfR5XB
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

⚠️ 1 changed file(s) yielded no anchor (packages/qa/dogfood/vitest.config.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files. Nothing else in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 1 changed package(s)).

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/qa/dogfood/vitest.config.ts) — pages documenting those are invisible to this run
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 2 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 33b6e8bece79e70156dc2c1880813f8d88af61d4 → packageMentionDocs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants