Repository navigation
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 intoSep 30, 2026
Conversation
…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>
Contributor
📓 Docs Drift Check
What this run could not see
Coarse fallback — 2 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
objectstack-fleet
Bot
deleted the
claude/issue-20594-qa-dogfood-citations
branch
September 30, 2026 17:21
This was referenced Sep 30, 2026
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Oct 7, 2026
…es' files outside src to the commits that decided them (objectstack-ai#20923) Part of objectstack-ai#20594 Clause-②: no ## What changed This is stage 16 of the `domain:cli` lane's dead-citation sweep: **the 17 comment sites left in eleven lane packages' files outside `src/**`** (claim `5917064266`; the list on stage 15's landing `5916232164`). The file surface is the one stage 14 set: `README.md`, `tsconfig*.json`, `vitest.config.*`, `tsup.config.*` and `test/**`. Every comment site on that surface whose tracker number answers 404 now cites the commit that decided what the line describes, in ruling C+D's form C (comment `5749154545` on objectstack-ai#19123). Stages 1 to 15 of this card are the precedents; the latest are PR objectstack-ai#20883 and PR objectstack-ai#20898. - **17 sites on 16 lines in 14 files**, covering **9 numbers**, now cite **9 distinct commits**. - The 14 files: 5 JSONC configs (`tsconfig.test.json` in plugin-hono-server, plugin-dev and verify; plugin-hono-server's `tsconfig.typecheck.json`; client's `tsconfig.json`), 6 `vitest.config.ts` (client, cloud-connection, mcp, rest, runtime, types) and 3 test files (`qa/vitest-filter-preflight` 2, `qa/downstream-contract` 1). - **Comments only.** 16 lines out and 16 in, and every file keeps its line count. A token guard (below) shows zero non-comment tokens changed. - **String literals, `describe` / `it` titles and messages are untouched** (they belong to objectstack-ai#20752, fold `5911936313`). - **No tracker number is added.** The live numbers that share a changed line stay as they were: objectstack-ai#4914, objectstack-ai#12542 and objectstack-ai#17978 all answer 200. - **Sites left without a deciding commit: none.** - Where an earlier stage anchored a number and the line here describes the same decision, the same anchor is reused: 6 of the 9 numbers. The other 3 anchors are new (marked below). ## Census **Instrument.** The card's gate does not read these files (its declared surface is `packages/**/src/**`), so the census is taken by hand with the gate's own grammar, as stages 14 and 15 took it: - **Files:** every tracked file of the eleven packages outside `src/**`, with `CHANGELOG.md` left out: 81 files. Each is classed ON stage 14's file list (48 files) or OFF it (33: `package.json`, `LICENSE`, ledgers, `objectstack.config.ts` and the like). Only ON-list comment sites are this stage's. - **Extraction:** `extractCitations` from `scripts/check-issue-citations.mjs`, with its comment-prose projection for code and JSONC files and the whole file for `*.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, on-list | comment sites | dead comment sites, off-list | dead string sites | |---|---|---|---|---|---|---|---|---|---| | before | base `cb4c31dd52` | 2026-09-30 18:18:37 to 18:19:15 | 94 | 80 | 14 | **17** (9 numbers, 14 files) | 212 | 2 | 11 | | after | head `1e3782200f` | 2026-09-30 18:23:26 to 18:24:03 | 88 | 80 | 8 | **0** | 195 | 2 | 11 | - The before count matches the list on stage 15's landing, package by package. - No number present in both probes changed its answer. The 6 numbers that left the census (objectstack-ai#8651, objectstack-ai#10485, objectstack-ai#12181, objectstack-ai#13176, objectstack-ai#15145, objectstack-ai#16917) were only on the rewritten lines. - Comment sites fell by exactly 17. The off-list and string counts did not move. **Per package, dead on-list comment sites, before to after:** | package | before | after | |---|---|---| | `packages/plugins/plugin-hono-server` | 4 | 0 | | `packages/plugins/plugin-dev` | 2 | 0 | | `packages/client` | 2 | 0 | | `packages/qa/vitest-filter-preflight` | 2 | 0 | | `packages/cloud-connection` | 1 | 0 | | `packages/mcp` | 1 | 0 | | `packages/qa/downstream-contract` | 1 | 0 | | `packages/rest` | 1 | 0 | | `packages/runtime` | 1 | 0 | | `packages/types` | 1 | 0 | | `packages/verify` | 1 | 0 | | **total** | **17** | **0** | ## Per-number anchors Each anchor was checked by blame on the site and in the anchor's own message or diff. "Reused" names earlier stages that gave the number the same anchor. | number | sites | anchor | what it decided | | |---|---|---|---|---| | `objectstack-ai#13176` | 4: plugin-hono-server and plugin-dev `tsconfig.test.json` (:3 and :61 / :56) | `a68c61267` | plugin-security's test layer enters tsc under a sibling `tsconfig.test.json` at zero residue, with no `test-typecheck-debt.json`; its diff writes the number into that config's header and into the TEST_DEBT graduation | reused (plugin-security) | | `objectstack-ai#11332` | 1: plugin-hono-server `tsconfig.typecheck.json:12` | `dce5cd4f0` | retires the manifest's `capabilities` / `configuration` / `extensions` containers as `retiredKey()` tombstones (ADR-0049); its changeset names the number | reused (spec) | | `objectstack-ai#10724` | 1: the same line | `be21955ba` | retires the nine dead `contributes` members as `retiredKey()` tombstones (ADR-0049); its subject names the number | reused (spec) | | `objectstack-ai#12181` | 2: client `tsconfig.json:8`, `vitest.config.ts:33` | `cf71d73f8` | `meta.deleteItem`'s reset carriers; this same commit wrote both blocks (the `paths` rules and the alias for the real-door test), and its changeset names the number | reused (client, cli) | | `objectstack-ai#17853` | 5: vitest-filter-preflight's two test headers, rest / runtime / types `vitest.config.ts` | `08f5f0e5a` | a vitest filter that selects no test file says so; its message names the card it lands. The sentence in the three configs is the one stage 14 and stage 15 rewrote in cli's and dogfood's | reused (qa, cli, dogfood) | | `objectstack-ai#16917` | 1: cloud-connection `vitest.config.ts:64` | `7ce3154e6` | the comment-only repair of this file, which wrote the "paraphrased rather than quoted" sentence; its message names the card it lands | **new** | | `objectstack-ai#8651` | 1: mcp `vitest.config.ts:18` | `8c65046e4` | pins mcp's three engine doubles to metadata-core's dispatch predicates, adds that devDependency and creates this config for the alias; its message names the card it lands | **new** | | `objectstack-ai#10485` | 1: downstream-contract `test/contract.test.ts:46` | `35ad101bc` | retires `ThemeSchema` and the `themes` carrier key (ADR-0049, kept beside it); its subject names the number, and it wrote this line | reused (spec, qa, cli) | | `objectstack-ai#15145` | 1: verify `tsconfig.test.json:1` | `45a72b0cc` | wires verify's test layer into `typecheck` through this file; its diff writes the number into this line and into the coverage-ledger graduation | **new** | **ADR and ruling records.** A grep of `docs/adr` and `scripts/adr-anchors` for the 9 numbers finds one hit: ADR-0088 names objectstack-ai#10724 in a correction note (history, not the ruling), so that number stays on the commit every earlier stage anchored it to. The sentence it sits in already names ADR-0049. 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 9. - **Each is a plain commit** with one parent. - **Each is on the base:** `merge-base --is-ancestor` against `cb4c31dd52` exits 0 for all 9. - **The history is complete:** the checkout is not shallow. Control leg: `01218124ae`, the parent of the oldest anchor `8c65046e4` (2026-08-16), exits 0. Negative control: the base as an ancestor of `8c65046e4` exits 1. ## Verification All at head `1e3782200f`. Heavy runs went through `scripts/pm/os-verify-lock.sh` with `OS_VERIFY_LOCK_SLOT=issue-20594-outside`. - **Build (whole workspace):** `pnpm exec turbo run build --filter='./packages/*' --filter='./packages/*/*' --concurrency=2` → 71 successful, 71 total (9 cached), lock verdict command-exit 0. - **Typecheck, ten packages** (cloud-connection declares no `typecheck` script): `pnpm --workspace-concurrency=2 --filter` plugin-hono-server, plugin-dev, client, vitest-filter-preflight, mcp, downstream-contract, rest, runtime, types, verify `run typecheck` → 10 of 10 `Done`, 0 `error TS`, lock verdict command-exit 0. That reads every touched JSONC config (plugin-hono-server's runs `tsconfig.typecheck.json` by name; the `tsconfig.test.json` files are read by `check:test-typecheck`, all at their recorded ledgers). `--listFilesOnly` holds all 3 touched test files in their packages' programs. - **Tests, by name** (one lock call, verdict command-exit 0). Each touched test file ran, and each touched `vitest.config.ts` was loaded by a run of its own package: - vitest-filter-preflight: `test/config-wiring-sweep.test.ts`, `test/filter-preflight.test.ts` → 2 files, 97 tests passed. - downstream-contract: `test/contract.test.ts` → 1 file, 13 tests passed. - client: `src/meta-delete-item-carriers.test.ts` (the suite the edited alias block serves) → 20 passed. - cloud-connection: `src/canonical-expression-envelopes.test.ts` (the suite the alias exists for) → 16 passed. - mcp: `src/mcp-stdio-tools.test.ts` (the engine doubles the edited block describes) → 12 passed. - rest, runtime, types (`--project local`): `src/rest-exec-ctx-memo.test.ts` 4 passed, `src/app-plugin.ordering.test.ts` 3 passed, `src/email-verified.test.ts` 2 passed. - **Token guard**, base `cb4c31dd52` against head, 14 files, 5,764 base tokens: **0 files differ**. TypeScript files are compared as leaf tokens (`getChildren`, JSDoc nodes skipped), JSONC files as the scanner's non-trivia token stream plus their parsed value (0 of 5 values differ). Controls, in memory only: a comment inserted into each file, 0 of 14 differ; a statement appended, 14 of 14; one character flipped inside each file's first string token, 14 of 14 (9 `StringLiteral`, 5 JSON strings). - **Control bytes:** a scan of the 14 files finds 0 (positive control, a scratch file holding U+0001: 1). `pnpm check:nul-bytes` exits 0. - **Nothing publishes.** `npm pack --dry-run` in each of the 9 public packages packs only `dist/**`, `README.md`, `CHANGELOG.md`, `LICENSE` and `package.json`: 0 of the 11 touched files in those packages is packed. After the build, the first 48 characters of each of the 16 added comment lines occur in 0 files of any package's `dist/`; control: a `src` docblock phrase an earlier stage wrote ("Maintainer-seat ruling, landed by commit cf71d73") occurs in `packages/client/dist/index.d.ts`. The other two packages are private. ## Gates All at head `1e3782200f`, exit codes captured before any pipe. - **Derivation:** `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands`, no paths, derives **52 commands** (14 paths against merge base `cb4c31dd52`). Re-derived after fetching `origin/main` to `4d0b9cd542`: the same 52, and none of the 4 upstream commits touches a derivation input or a file here. - **All 52 exit 0**, each on its first run. - **Reconciliation:** `dispatch-gates --ran` over the recorded `COMMAND :: exit CODE` list → "52 derived, 52 run, 0 NOT-MEASURED, 0 UNRUN", exit 0. - **Roster gates the derivation marks as keeping a roster under `packages/`:** `pnpm check:authz-resolver`, `pnpm check:error-code-casing` and `pnpm check:filter-alias-parity` → exit 0 each. - **`pnpm lint`** (repo-wide `eslint . --no-inline-config`, the family the derivation does not name) → exit 0, 2026-09-30T18:26:35Z to 18:30:31Z. - `node scripts/check-issue-citations.mjs` (diff mode, in the 52) 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` `4d0b9cd542` is clean. **The 52 derived commands:** stage 15's list with `pnpm --filter @objectstack/spec run check:skill-examples` and `node scripts/check-tenant-audit-census.mjs` (with its `--self-test`) in, and `check:empty-state`, `check:liveness`, `check:strictness-ledger` and `check:variant-docs` (spec) out: - `node scripts/check-ci-filter-parity.mjs` - `node scripts/check-closing-keyword-parity.mjs` and `--self-test` - `node scripts/check-comment-mask-adoption.mjs` and `--self-test` - `node scripts/check-comment-mask-corpus.mjs` - `node scripts/check-issue-citations.mjs` - `node scripts/check-keyed-text-bounds.mjs` and `--self-test` - `node scripts/check-platform-object-tenancy-census.mjs` and `--self-test` - `node scripts/check-plugin-teardown-shape.mjs` and `--self-test` - `node scripts/check-registry-log-declared.mjs` and `--self-test` - `node scripts/check-rest-log-spy-declared.mjs` and `--self-test` - `node scripts/check-system-context-census.mjs` and `--self-test` - `node scripts/check-tenant-audit-census.mjs` and `--self-test` - `node scripts/check-undeclared-dep-imports.mjs` and `--self-test` - `node scripts/docs-audit/check-affected-docs.mjs` - `node scripts/docs-audit/check-drift-comment.mjs` - `pnpm --filter @objectstack/spec run check:skill-examples` - `pnpm check:cross-package-test-inputs`, `check:dispatcher-error-vocabulary`, `check:doc-authoring`, `check:driver-memory-census`, `check:dts-closure`, `check:dual-build-cjs-loads`, `check:engine-double-contract`, `check:gitlink-declared`, `check:issue-citations`, `check:lean-entry-closure`, `check:logger-receiver-detach`, `check:nul-bytes`, `check:objectql-double-limit`, `check:org-identifier`, `check:page-declaration-shape`, `check:published-files`, `check:query-options-erasure`, `check:refd-timer-probe`, `check:slot-lookup`, `check:sourcemap-no-sources-content`, `check:test-source-alias`, `check:tier-file-adoption`, `check:type-check-coverage`, `check:type-check-debt`, `check:watch-hint-literal`, `check:where-matcher` ## Acceptance notes - **Changeset:** none. Nine of the eleven packages publish, but no touched file is in any package's `files` (measured above), and `qa/vitest-filter-preflight` and `qa/downstream-contract` are private. The PR carries `skip-changeset`. - **Left in these eleven packages, not this stage's:** 2 dead comment sites off stage 14's file list, in plugin-hono-server's `objectstack.config.ts` (:19 objectstack-ai#11332, :26 objectstack-ai#10724), and 11 dead string sites: the `test-typecheck-debt.json` notes in client (1), mcp (1), rest (7) and runtime (1), and vitest-filter-preflight's `package.json` description (1). All 13 are among the 55 off-list sites stage 14 listed. - **What remains on this card after this stage:** the 55 off-list sites stage 14 listed, and the five `cli` sites with no deciding commit (objectstack-ai#10149, objectstack-ai#11048, objectstack-ai#14874 x3). None of them is touched here. - **Grammar reach, measured on this surface:** the gate's grammar does not extract the second number of a slash-joined pair such as `objectstack-ai#10374/objectstack-ai#13522`. On these 81 files that shape holds 4 such numbers (objectstack-ai#3060, objectstack-ai#7778, objectstack-ai#13522, objectstack-ai#14016), and all 4 answer 200 (2026-09-30T19:04Z), so the census above misses no dead site. - **No open PR touches these files.** The claim's serial check read all 11 open PRs' file lists at `cb4c31dd52`; objectstack-ai#20602 and objectstack-ai#20583 on this seat stay in `packages/rest/src` and `packages/cli/src`. --- _Generated by [Claude Code](https://claude.ai/code/session_01VvcEokUG1tvVxkceYfR5XB)_ Co-authored-by: Claude <noreply@anthropic.com>
akarma-synetal
pushed a commit
to akarma-synetal/framework
that referenced
this pull request
Oct 7, 2026
… stage 14's list to the commits that decided them (objectstack-ai#20947) Part of objectstack-ai#20594 Clause-②: no ## What changed This is stage 17 of the `domain:cli` lane's dead-citation sweep: **the comment sites in lane files outside stage 14's file list** (claim `5918748154`; the list on stage 16's landing `5918606717` and stage 14's report `5914100460`). The claim names six files: - `packages/cli/bin/run.js` and `packages/cli/bin/run-dev.js`; - `packages/cli/scripts/check-app-nav-i18n.mjs`; - `packages/cli/vitest-tiers.ts` and `packages/cli/vitest-tiers.fixtures.ts`; - `packages/plugins/plugin-hono-server/objectstack.config.ts`. Every comment site in those files whose tracker number answers 404 now cites the commit that decided what the line describes, in ruling C+D's form C (comment `5749154545` on objectstack-ai#19123), except one site with no deciding commit. Stages 1 to 16 of this card are the precedents; the latest are PR objectstack-ai#20883, PR objectstack-ai#20898 and PR objectstack-ai#20923. - **27 sites on 27 lines in 6 files**, covering **8 numbers**, now cite **8 distinct commits**. 6 of the 8 anchors are reused from earlier stages for the same decision; 2 are new (marked below). - **Comments only.** 27 lines out and 27 in, and every file keeps its line count. A token guard (below) shows zero non-comment tokens changed. - **String literals, `describe` / `it` titles and messages are untouched.** They belong to objectstack-ai#20752 (fold `5911936313`). That includes the 14 dead numbers inside strings in `check-app-nav-i18n.mjs`. - **No tracker number is added.** The live numbers that share a changed line stay as they were: objectstack-ai#14554, objectstack-ai#15564 and objectstack-ai#16746 all answer 200. - **One site is kept without a deciding commit:** `bin/run.js:225` (objectstack-ai#14874). See "Kept" below. - **A `patch` changeset for `@objectstack/cli`**, because `bin/run.js` is packed (see "Publish check"). ## Census **Instrument.** The card's gate does not read these files (its declared surface is `packages/**/src/**`), so the census is taken by hand with the gate's own grammar, as stages 14 to 16 took it: - **Files:** every tracked file of the 19 lane packages outside `src/**`, with `CHANGELOG.md` left out: 538 files. Each is classed as one of the claim's six files, as ON stage 14's file list (`README.md`, `tsconfig*.json`, `vitest.config.*`, `tsup.config.*`, `test/**`), or as neither. - **Extraction:** `extractCitations` from `scripts/check-issue-citations.mjs`, with its comment-prose projection for code and JSON files and the whole file for prose files. 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 | 200 | 404 | dead comment sites, the six files | dead comment sites, whole lane surface | dead string sites, whole lane surface | |---|---|---|---|---|---|---|---|---| | before | base `aaad682dbc` | 2026-09-30 20:09:40 to 20:15:09 | 852 | 798 | 54 | **28** (9 numbers) | 33 | 97 | | after | head `89264b0c1e` | 2026-09-30 20:23:18 to 20:28:44 | 848 | 798 | 50 | **1** | 6 | 97 | - The before count matches stage 14's per-file counts for comments: `bin/` 10, `check-app-nav-i18n.mjs` 13 (plus 14 string sites, 27 in all), `vitest-tiers*.ts` 3, `objectstack.config.ts` 2. - No number present in both probes changed its answer. The 4 numbers that left the census (objectstack-ai#10724, objectstack-ai#11332, objectstack-ai#12964, objectstack-ai#14715) were only on the rewritten lines. - Comment sites across the whole surface fell by exactly 27 (2,452 to 2,425). The string count did not move. **Per file, dead comment sites, before to after:** | file | before | after | |---|---|---| | `packages/cli/bin/run-dev.js` | 6 | 0 | | `packages/cli/bin/run.js` | 4 | 1 | | `packages/cli/scripts/check-app-nav-i18n.mjs` | 13 | 0 | | `packages/cli/vitest-tiers.ts` | 2 | 0 | | `packages/cli/vitest-tiers.fixtures.ts` | 1 | 0 | | `packages/plugins/plugin-hono-server/objectstack.config.ts` | 2 | 0 | | **total** | **28** | **1** | **What the lane surface outside `src/**` still holds after this stage:** 6 dead comment sites, all without a deciding commit (`bin/run.js:225` and the five stage 14 kept), and 97 dead string sites (objectstack-ai#20752's form D). ## Per-number anchors Each anchor was checked by blame on the site and in the anchor's own message or diff. "Reused" names the earlier stage that gave the number the same anchor. | number | sites | anchor | what it decided | | |---|---|---|---|---| | `objectstack-ai#12964` | 3: `run-dev.js:71`, `:152`, `:466` | `e6fd1caf7` | `bin/run-dev.js` collects oclif's module-load warnings and names the missing build output instead of "command not found"; its changeset names the number, and it wrote `:152` and `:466` itself | reused (stage 14, cli tests) | | `objectstack-ai#14715` | 2: `run-dev.js:362`, `:400` | `accb9231c` | the squash of that number's PR (its subject names it): the never-read reader's case keeps its product assertions, "the child exits on its own, with code 2" | reused (stage 14) | | `objectstack-ai#14858` | 4: `run-dev.js:377`; `run.js:163`, `:168`, `:220` | `0c5e97368` | a closed stderr read end exits 2 instead of dying of an uncaught EPIPE; its subject names the number, and it added the `run-dev.js` listener and docblock that `:377` heads | reused (stage 14, cli tests) | | `objectstack-ai#17891` | 9 in `check-app-nav-i18n.mjs` (`:112`, `:221`, `:237`, `:261`, `:289`, `:302`, `:502`, `:552`, `:706`) | `ca9d9d361` | widens `check:app-nav-i18n` from one app to the declared platform-app population (the Account shell in the roster, one build probe per shell, per-app counts in the pass line); its message names the card it lands | **new** | | `objectstack-ai#17759` | 4 in `check-app-nav-i18n.mjs` (`:148`, `:238`, `:259`, `:537`) | `c744c0af3` | translates the Account app's contributed `nav_connect_agent` in all four locales, one namespace per app; its message names the card it lands | **new** | | `objectstack-ai#13504` | 3: `vitest-tiers.ts:5`, `:67`; `vitest-tiers.fixtures.ts:194` | `44813ba57` | the tier half of that card: the named `unit` / `integration` tiers and the behavioural predicate that replaced the text-match census | reused (stage 14, `vitest.config.ts`) | | `objectstack-ai#11332` | 1: `objectstack.config.ts:19` | `dce5cd4f0` | retires the manifest's `capabilities` / `configuration` / `extensions` containers (ADR-0049); it wrote this comment | reused (stage 16) | | `objectstack-ai#10724` | 1: `objectstack.config.ts:26` | `be21955ba` | retires the nine dead `contributes` members (ADR-0049); its subject names the number, and it wrote this comment | reused (stage 16) | **ADR and ruling records.** A grep of `docs/adr` and `scripts/adr-anchors` for the 8 numbers (and objectstack-ai#14874) finds one hit: ADR-0088 names objectstack-ai#10724 in a correction note (history, not the ruling), so that number stays on the commit stage 16 anchored it to. The sentence it sits in already names ADR-0049. 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 8. - **Each is a plain commit** with one parent. - **Each is on the base:** `merge-base --is-ancestor` against `aaad682dbc` exits 0 for all 8. - **The history is complete:** the checkout is not shallow, and an exit 0 from `--is-ancestor` proves itself. Negative control: the base as an ancestor of the oldest anchor `be21955ba` (2026-08-25) exits 1. ## Kept: no deciding commit found `bin/run.js:225` keeps objectstack-ai#14874 ("npm packs a `bin` target regardless" of `files`). The history search this stage ran: - `git log --grep` for the number finds only this card's re-anchoring commits. - `git log -S` finds the earliest mention in `95d5cbb316`, which cites objectstack-ai#14874 as the measurement ("objectstack-ai#14874 measured the other half of the same lesson"). It does not decide it. - `5023630b1` records the same measurement in its changeset, but neither its message nor its diff names the number. Stage 14 named it as a candidate, and the ACCEPT `5914299201` ruled that a commit which only restates or applies a decision is not the anchor. The five `cli` sites stage 14 kept (objectstack-ai#10149, objectstack-ai#11048, objectstack-ai#14874 ×2 in `test/published-entry-stderr-error-listener.test.ts` and 1 in `test/published-subpath-hook-body.pin.test.ts`) were searched again the same way. For objectstack-ai#10149, `cc21aad8ed` is "Part of" it and leaves the decision to the maintainer, and `d18bc32770` applies its reasoning. For objectstack-ai#11048, `568de194ec` files it unassigned as an open support decision. So no deciding commit was found, and they stay as they are. ## Verification All at head `89264b0c1e`. Heavy runs went through `scripts/pm/os-verify-lock.sh` with `OS_VERIFY_LOCK_SLOT=issue-20594-offlist`. - **Build (whole workspace):** `pnpm exec turbo run build --filter='./packages/*' --filter='./packages/*/*' --concurrency=2` → 71 successful, 71 total (7 cached), lock verdict command-exit 0. - **Typecheck:** `pnpm --workspace-concurrency=2 --filter @objectstack/cli --filter @objectstack/plugin-hono-server run typecheck` → both `Done`, 0 `error TS`, lock verdict command-exit 0. `check:test-typecheck` holds both ledgers where they were: cli 3 files / 28 errors / 6 pinned signatures, plugin-hono-server 0. `--listFilesOnly` shows cli's `tsconfig.test.json` program holds `vitest-tiers.ts` and `vitest-tiers.fixtures.ts`, and plugin-hono-server's `tsconfig.typecheck.json` holds `objectstack.config.ts`. - **cli `unit` tier:** `pnpm --filter @objectstack/cli exec vitest run --project unit --maxWorkers=2` → 239 files, 3391 tests passed, lock verdict command-exit 0. It holds `test/vitest-tiers-partition.test.ts`, which imports both `vitest-tiers*.ts` files, and every run loads `vitest.config.ts`, which imports `vitest-tiers.ts`. - **cli `integration` tier**, run locally because the diff touches `bin/` (the spawn entries): `--project integration --maxWorkers=2` → 67 files, 572 passed and 1 skipped (a data-conditional `skipIf` in `test/migrate-meta-default-range.test.ts`), lock verdict command-exit 0. It holds `test/published-entry-stderr-error-listener.test.ts`, which spawns `bin/run.js`. - **Nightly-tier files that spawn the two entries**, by name under `OS_TEST_TIERS=nightly`: `test/run-dev-unbuilt-workspace.e2e.test.ts`, `test/published-entry-stderr-nonblocking.e2e.test.ts` and `test/run-dev-stderr-nonblocking.e2e.test.ts` → 3 files, 21 tests passed, lock verdict command-exit 0. - **The script, the way CI calls it:** `pnpm check:app-nav-i18n` (`--self-test`, then the real run; `lint.yml` runs this) → exit 0. The self-test passes, and the pass line reads `OK (11 contributor(s), 4 locale(s), 2 app(s) — setup: 55 merged nav id(s), account: 12 merged nav id(s) — every id labelled in every locale)`. - **The entries, smoke:** `node packages/cli/bin/run.js --help` exit 0 (66 lines); `node packages/cli/bin/run-dev.js --help` exit 0 (66 lines); `node packages/cli/bin/run.js --version` exit 0; `node packages/cli/bin/run.js no-such-command-xyz` exit 2 with oclif's `command … not found`. - **Token guard**, base `aaad682dbc` against head, 6 files, 6,224 base tokens: **0 files differ**. Leaf tokens come from the TypeScript parser (`getChildren`, JSDoc nodes skipped; `.js` / `.mjs` parsed as JS). Controls, in memory only: a comment inserted into each file, 0 of 6 differ; a statement appended, 6 of 6; one character flipped inside each file's first `StringLiteral`, 6 of 6. The comment control's first form put its comment above the shebang in the three `#!` files and moved tokens in 3 of 6. It was corrected to insert below the shebang before it was used as a reading. - **Control bytes:** a scan of the 6 files and the changeset finds 0 (positive control, a scratch file holding U+0001: 1). `pnpm check:nul-bytes` exits 0. - **Publish check:** `npm pack --dry-run` in `packages/cli` packs `bin/run.js` (a `bin` target, packed regardless of `files`) beside `dist/**`, `README.md`, `CHANGELOG.md`, `LICENSE` and `package.json`. It packs none of `bin/run-dev.js`, `scripts/` or `vitest-tiers*.ts`, so the `patch` changeset covers `bin/run.js` alone. `plugin-hono-server` packs no `objectstack.config.ts`, and its `src/` never imports that file. After the build, the first 48 characters of each of the 27 added comment lines occur in 0 files of any package's `dist/`. Control: the `src` docblock phrase `document" (commit 2b641dd). Both device-flow` occurs in 1 file of `packages/cli/dist`. (plugin-hono-server's bundler keeps no comments, so its `dist` gives no reading either way: its own control phrase occurs in 0 files.) ## Gates All at head `89264b0c1e`, exit codes captured before any pipe. - **Derivation:** `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands`, no paths, derives **57 commands** (7 paths against merge base `aaad682db`). Re-derived after fetching `origin/main` to `31c39964fc`: the same 57. None of the 5 upstream commits touches a derivation input or a file here. - **All 57 exit 0**, each on its first run. - **Reconciliation:** `dispatch-gates --ran` over the recorded `COMMAND :: exit CODE` list → "57 derived, 57 run, 0 NOT-MEASURED, 0 UNRUN", exit 0. - **Roster gates the derivation marks as keeping a roster under a touched directory:** `node scripts/check-changeset-fixed.mjs`, `pnpm check:authz-resolver`, `pnpm check:error-code-casing`, `pnpm check:filter-alias-parity` and `node scripts/release-pending-publish.mjs --self-test` → exit 0 each. - **`pnpm lint`** (repo-wide `eslint . --no-inline-config`, the family the derivation does not name) → exit 0, 2026-09-30T21:33:42Z to 21:36:25Z. - `node scripts/check-issue-citations.mjs` (diff mode, in the 57) reads 0 files, because none of these paths is on its declared surface. The hand census above is the measurement for this surface. - The changeset gates in the 57: `check-empty-changeset` ("1 declaring changeset(s) added"), `check-changeset-no-major` ("no `major` bump"), `check-adr-0087-registration` ("no declared-breaking changeset"). - A local `git merge-tree --write-tree` of this head against `origin/main` `3fbf3ca617` is clean. **The 57 derived commands:** stage 16's 52, minus `pnpm --filter @objectstack/spec run check:skill-examples`, `pnpm check:dispatcher-error-vocabulary`, `pnpm check:engine-double-contract`, `pnpm check:objectql-double-limit`, `pnpm check:query-options-erasure`, `pnpm check:type-check-coverage`, `pnpm check:type-check-debt` and `pnpm check:where-matcher`, plus the changeset family (`check-adr-0087-registration`, `check-changeset-no-major`, `check-empty-changeset`, each with its `--self-test`; `pnpm check:changeset-gate-self-tests`, `pnpm check:objectui-changeset`, `pnpm check:pm-changeset-deadline-census`), `pnpm check:i18n`, `pnpm check:i18n-coverage`, `pnpm check:i18n-walk-parity` and `node scripts/pm/release-rehearsal-clone.mjs --self-test`. ## Acceptance notes - **Not this card's: dead numbers in strings.** `check-app-nav-i18n.mjs` holds 14 (objectstack-ai#17891 ×13, objectstack-ai#17759 ×1: the self-test's `expect` titles and messages, and the `--self-test` pass line, which prints `(objectstack-ai#17891)` at runtime). The lane surface holds 97 dead string sites in all. They belong to objectstack-ai#20752's form D (fold `5911936313`). - **What this card has left:** the 6 comment sites without a deciding commit, listed above. --- _Generated by [Claude Code](https://claude.ai/code/session_01VvcEokUG1tvVxkceYfR5XB)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #20594
Clause-②: no
What changed
This is stage 15 of the
domain:clilane's dead-citation sweep:packages/qa/dogfood's dead citations in files outsidesrc/**, the largest package left after stage 14 (claim5914651671). The package has nosrc/at all, so the surface is itstest/**,README.md,tsconfig.jsonandvitest.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
5749154545on #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.vitest.config.tsand 26 undertest/**: 21 test files, 4 helper modules and 1 fixture.describe/ittitles and messages are untouched. They belong to runtime strings in thedomain:clipackages carry tracker numbers (114 messages in 8 packages, 254 ledgered ids): this lane's share of the #20513 A/A burn-down #20752 (form D, fold5911936313); 28 such sites stay on this file list, listed in the acceptance notes.installAttachmentAccessHooksdoes not authorize an UNSCOPED multi-delete: no id + nowherereads as "nothing to authorize" anddeleteManyruns over the whole table #4757, driver-memory 完全没有行级租户隔离(#3724 的未修姊妹面):多租户下静默不隔离 #6915, [security]sys_accountstores live third-party OAuth access/refresh/id tokens as plain columns, and the object is API-readable #7987, [finding] An org-less test fixture cannot observe theorg_member-gated write floor, so a real 403 defect records as a PASSING cell #8074, The i18n catalog is resolved ahead of the document, so a tenant's own Studio rename never reaches either/meta/objectread — and neither do extension scalar overrides #8284, [finding] 79 of 82 dogfood fixtures boot org-less, and nothing has swept them for #8023's disarm now that a probe exists #8408, The #4757 unscoped multi-delete refusal on sys_attachment never fires through ObjectQL.delete — per-row hook dispatch bypasses it #9719, Measure whether /meta/* write routes refuse an unauthenticated (@anon) principal — server-side half of objectui#5828 #11373 and [finding] the silent partial-filter drop #17853 fixes in packages/cli is live in the seven other packages that declare vitestprojects#17978 all answer 200.── … ─────) is shortened by the characters its heading gained, never below one dash. Three of the five section headers keep their width;admin-route-nonadmin-refusal:339grows by 2 characters andtwo-doors-permission:81, which already ended in one dash, by 11.Census
Instrument. The card's gate does not read these files: its declared surface is
packages/**/src/**, andsurfaceForanswers null for all 27 touched paths (the controlpackages/cli/src/commands/init.tsanswerspackage-docblocks). So the census is taken by hand, with the gate's own grammar, as stage 14 took it:packages/qa/dogfoodoutsidesrc/**, withCHANGELOG.md(claim) andpackage.json(not on the claim's list) left out. That is 178 files.extractCitationsfromscripts/check-issue-citations.mjs, with its comment-prose projection for code and JSONC files and the whole file forREADME.md. The whole-file extraction minus the comment projection gives the string sites.namesThisRepository).GET /repos/objectstack-ai/objectstack/issues/N; 404 means dead.4edb61449b57ffb83b00660a9b247: 94 comment sites and 28 string sites in 13 files.README.mdcites fix(analytics): make organization timezone drive date-dimension bucketing (#1982) #2018 and fix(security)[P0]: enforce RLS on by-id writes — close member-edits-others'-records hole (#1985) #1994, andpackage.json's description cites fix(analytics): make organization timezone drive date-dimension bucketing (#1982) #2018, fix(security)[P0]: enforce RLS on by-id writes — close member-edits-others'-records hole (#1985) #1994 and fix: array field types persist + Field.time accepts time-of-day #2004. All answer 200.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.
#6293c39a911aebuild-shaped-artifact.tsruns the real lowering, and no published surface grows (its subject names the card)src)#6483ee58392e1permission(and eight more types) toallowOrgOverride: false;allowRuntimeCreatestays open#846001a7337fc, which amends the ADR#8676d6e80b28bsys_account.passwordandprevious_password_hashesinternal#87112ce1eb41b#871160ade586eactiverows with nocovers, and why (matrix.ts:393)#8811d6e793507grant-validity-windowmatrix row (its subject names the card)#8839c25b2d52a#8919b5378550e/metapublish and rollback onmanage_metadata, with the enumeration pin#97971258dcaee#993479c46da90userMessagemarking, including the QuickJS side-channel#10243266436a7fPOST /automation/:name/togglejoins themanage_metadatawrite set (automation-toggle-tenant-scope:4)#1024302b41232dpackaged-activation-ledger-reach:291)#1094346d34ab7cfallbackImportbecomes a caller-supplied parameter#1099602b41232d#114776dd3e6968/admin/remove-userauthorizes before the break-glass guard (its message records "Ruled option A on" the card)#11530033a34c7cset_user_roleconsole action#116867131f12bfhasPlatformAdminStandingas the one authority#121767986d973fPUT /meta/:type/:section/:nameamong them. The ruling'sD3ordinal is kept beside it#12194311433f6b#13214cc837dbfeGET /ui/view/:object/:type; its diff writes these census lines and its message the 2026-08-30 ruling#16589555a89cbddriver-memoryrefuses a tenant-scoped call; its diff names the card at every seam#16659ecdfc9411F2ordinal is kept, as the trigger-schedule stage kept it#16687779710213#1785308f5f0e5a#19306f9e16d856ADR and ruling records. A grep of
docs/adrandscripts/adr-anchorsfor 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 number7329finds 1 file in the same tree.Anchor checks:
git rev-parse --disambiguategives count 1 for each of the 24.merge-base --is-ancestoragainst4edb61449bexits 0 for all 24.255588bd36, the parent of the oldest anchoree58392e1(2026-08-09), exits 0. Negative control: the base as an ancestor ofee58392e1exits 1.Verification
All at head
57ffb83b00. Heavy runs went throughscripts/pm/os-verify-lock.shwithOS_VERIFY_LOCK_SLOT=issue-20594-dogfood.pnpm exec turbo run build --filter='@objectstack/dogfood^...' --concurrency=2→ 63 successful, 63 total (32 cached), lock verdict exit 0.shared-showcaseandisolated) 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, andenterprise-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.tsis loaded by that run.pnpm --filter @objectstack/dogfood typecheck(tsc --noEmit) → lock verdict command-exit 0.--listFilesOnlyshows 26 of the 27 touched files in the program; the 27th isvitest.config.ts.getChildren, JSDoc nodes skipped), base4edb61449bagainst 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 firstStringLiteral, 27 of 27.pnpm check:nul-bytesexits 0.Gates
All at head
57ffb83b00, exit codes captured before any pipe.node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands, no paths, derives 53 commands for this change set (27 paths against merge base4edb61449b). Re-derived after two fetches oforigin/main(to00a92e18da, then33b6e8bece): the same 53, and none of the upstream commits touches a derivation input or a file here.pnpm check:dual-build-cjs-loadsfirst exited 3 (PREREQUISITE NOT MET, nodist/for 8 packages outside dogfood's build closure); afterpnpm exec turbo run build --filter='./packages/*' --filter='./packages/*/*' --concurrency=2(71 of 71, all cached) it exits 0.dispatch-gates --ranover the recordedCOMMAND :: exit CODElist → "53 derived, 53 run, 0 NOT-MEASURED, 0 UNRUN", exit 0.pnpm lint(repo-wideeslint . --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.git merge-tree --write-treeof this head againstorigin/main33b6e8beceis clean.The 53 derived commands:
node scripts/check-ci-filter-parity.mjsnode scripts/check-closing-keyword-parity.mjsnode scripts/check-closing-keyword-parity.mjs --self-testnode scripts/check-comment-mask-adoption.mjsnode scripts/check-comment-mask-adoption.mjs --self-testnode scripts/check-comment-mask-corpus.mjsnode scripts/check-issue-citations.mjsnode scripts/check-keyed-text-bounds.mjsnode scripts/check-keyed-text-bounds.mjs --self-testnode scripts/check-platform-object-tenancy-census.mjsnode scripts/check-platform-object-tenancy-census.mjs --self-testnode scripts/check-plugin-teardown-shape.mjsnode scripts/check-plugin-teardown-shape.mjs --self-testnode scripts/check-registry-log-declared.mjsnode scripts/check-registry-log-declared.mjs --self-testnode scripts/check-rest-log-spy-declared.mjsnode scripts/check-rest-log-spy-declared.mjs --self-testnode scripts/check-system-context-census.mjsnode scripts/check-system-context-census.mjs --self-testnode scripts/check-undeclared-dep-imports.mjsnode scripts/check-undeclared-dep-imports.mjs --self-testnode scripts/docs-audit/check-affected-docs.mjsnode scripts/docs-audit/check-drift-comment.mjspnpm --filter @objectstack/spec run check:empty-statepnpm --filter @objectstack/spec run check:livenesspnpm --filter @objectstack/spec run check:strictness-ledgerpnpm --filter @objectstack/spec run check:variant-docspnpm check:cross-package-test-inputspnpm check:dispatcher-error-vocabularypnpm check:doc-authoringpnpm check:driver-memory-censuspnpm check:dts-closurepnpm check:dual-build-cjs-loadspnpm check:engine-double-contractpnpm check:gitlink-declaredpnpm check:issue-citationspnpm check:lean-entry-closurepnpm check:logger-receiver-detachpnpm check:nul-bytespnpm check:objectql-double-limitpnpm check:org-identifierpnpm check:page-declaration-shapepnpm check:published-filespnpm check:query-options-erasurepnpm check:refd-timer-probepnpm check:slot-lookuppnpm check:sourcemap-no-sources-contentpnpm check:test-source-aliaspnpm check:tier-file-adoptionpnpm check:type-check-coveragepnpm check:type-check-debtpnpm check:watch-hint-literalpnpm check:where-matcherAcceptance notes
@objectstack/dogfoodisprivate: true, so nothing here publishes; the PR carriesskip-changeset.objectstack buildcannot reuselowerCallables—JSON.stringify(stack)silently drops every callable instead #6293, ADR-0005:57 白名单表与注册表的分歧不止 flow:page/app/action/permission/tool/skill 六类 ADR 写 ❌ 而 allowOrgOverride:true,另有 dataset/book/position 三类表里没有却默认成了 true #6483, [security]sys_account.passwordandprevious_password_hashesserialize on the generic data API — to admins cross-user, and to the user themselves #8676, Does a DEACTIVATEDsys_positionstill receive sharing-rule shares?expandPositionUsersnever reads the catalogue row, so today it does #8710, The ADR-0056 D10 authz conformance matrix has no row for the grant-catalogueactiveflag, and its completeness check cannot notice #8711, [finding] The ADR-0056 D10 authz matrix has no row for the ADR-0091 grant validity windows either — a second instance of #8711's gap #8811, contract: a hook refusal has no way to mark its message user-facing — the console's 403 substitution (ruled in #3821) needs a producer-side opt-in channel #9934, Decide whether POST /api/v1/automation/:name/toggle belongs in the manage_metadata write set — it mutates flow enablement with no authoring capability #10243, [security][finding] 同一 break-glass 守卫的第三张面孔:/admin/remove-user 上全局 hooks.before 跑在 adminMiddleware 之前,已认证的非管理员即可触达其查找与拒绝 #11477, fix(platform-objects): retire the set_user_role action from sys_user #11530, fix(auth): resolve the id-shaped platform-admin question in one place #11686, Retiresys_scim_provider— consumer sweep first, no data migration (leg 1a of #11632, ruled on #11693) #11757, Ban/in metadata item names — retire compound-name addressing (maintainer-ruled direction): census, migration surface, staged plan #12176, authz-conformancediscover()reaches 1 of 17 route registrars in rest-server.ts — the ratchet's route-completeness guarantee is false for 66 of 85 mounted routes #13260, [finding] The InMemory driver silently ignores the engine's tenant scope for objects that OMIT atenancyblock — its guard only refuses an explicitenabled: true, so memory-driver runs show cross-organization rows a SQL driver refuses #16589, A schedule-triggered flow'snotifydelivers nothing on a multi-organization install: the run carries no organization, so the tenant-scoped inbox/delivery writes are refused (#8844) while the run reads healthy #16659). They aredescribe/ittitles and string values such as the matrix rows'note:text. They belong to runtime strings in thedomain:clipackages carry tracker numbers (114 messages in 8 packages, 254 ledgered ids): this lane's share of the #20513 A/A burn-down #20752 (form D).660a9b247, report5914100460): 17 comment sites in the other lane packages outsidesrc/**(plugin-hono-server4;plugin-dev,clientandqa/vitest-filter-preflight2 each;cloud-connection,mcp,qa/downstream-contract,rest,runtime,typesandverify1 each), the fiveclisites with no deciding commit, and the 55 off-list sites stage 14 listed. None of them is touched here.packages/qa/dogfood(all 10 open PRs' file lists read at 2026-09-30T15:56:00Z). The in-flight branch for automation: the create and update doors register a flow in the engine only and persist nothing, so a created flow is gone after a restart and an update is overwritten by the stored definition #20862 adds one new file there,automation-authoring-doors-durable.dogfood.test.ts, which is not among these 27.Generated by Claude Code