Skip to content

fix(spec): registration remedies name the entry file and gen:migration-registry, never the generated registry.ts - #21021

Merged
objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-20809-gate-b-names-entries-route
Oct 1, 2026
Merged

objectstack-fleet[bot] merged 2 commits into
mainfrom
claude/issue-20809-gate-b-names-entries-route

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Fixes #20809

Clause-②: no

What this changes

RETIRED_KEYS_BY_MAJOR, RETIRED_DEFS_BY_MAJOR and every step's semantic list are generated into packages/spec/src/migrations/registry.ts from one file per entry under packages/spec/src/migrations/entries/. Gate (b) of packages/spec/scripts/build-schemas.ts, the def-removal gate and four sibling remedies still told an author to paste lines into, or delete lines from, that generated file. An author who followed them typed between generated markers, which the next gen:migration-registry run reverts and check:migration-registry fails first.

Every such remedy now names the entry file and the generator command. Where the gate knows the id and the major, it prints the exact file and the one declaration it carries. Where the major is the author's to establish (check (c) proof 1), it names the directory and entries/README.md. This is the route the retirement kit's checklist landed first (PR #20828, merged as 745ac30a), quoted from .claude/skills/spec-property-retirement/SKILL.md on main:

在 packages/spec/src/migrations/entries/retired-keys/ 加一个文件(命名见 entries/README.md),再跑 pnpm --filter @objectstack/spec gen:migration-registry 把它生成进 registry.ts,⛔ 永不在那里手打。

Gate (b) before, as printed at 05be35259:

   1. Declare each retirement by its EXACT key in RETIRED_KEYS_BY_MAJOR
      (packages/spec/src/migrations/registry.ts) — copy these lines in:

        'api/HttpFindQueryParams:distinct',

      under `17: [ … ]` (create the major's array if it is the first).

After (the template rendered for the test's fixture key; the pins below assert it from a real run):

   1. Register each retirement by its EXACT key in RETIRED_KEYS_BY_MAJOR. That table
      is generated: add one entry file per key (named per
      packages/spec/src/migrations/entries/README.md; these names are the generator's own) —

        packages/spec/src/migrations/entries/retired-keys/17.api__HttpFindQueryParams__distinct.ts
          export const entry = 'api/HttpFindQueryParams:distinct';

      — with a `//` comment above the `export` saying why the key was retired (it
      lands above the entry in the table), then run
      `pnpm --filter @objectstack/spec gen:migration-registry`. ⛔ Never type an entry into the
      generated table by hand: the next run reverts it, and check:migration-registry
      fails it first. ...

The two docblocks the card names now say what the guidance slot is for: prescriptions for keys the shape does not declare (wrong-layer pointers, and the upgrade for a spelling removed from the shape). A key retired in place is a retiredKey() tombstone in the shape, never a guidance row, because shared/alias-integrity.test.ts ("no guidance key is itself a declared key") makes a guidance row for a declared key dead. No guidance table entry changes.

The dispatch's hypotheses, measured

H1 — every printed sentence that routes an author into migrations/registry.ts. git grep -n -E 'migrations/registry\.ts|copy these lines|step in src/migrations' -- packages/spec/scripts/build-schemas.ts returns 10 lines at 05be35259 and 2 at this head (both code comments). Positive control: the PM's four named sites (:789, :1128, :2637, :2836) are among the 10. I also read the lines that name a table without a file. Verdicts (line numbers at 05be35259):

Site Printed Verdict
:789 manifest disappearance "declare each one in RETIRED_DEFS_BY_MAJOR (src/migrations/registry.ts)" Same route. It now prints one entries/retired-defs/ file per def, plus the generator.
:1089 check (a), aged-out route "requires the exact key be declared in RETIRED_KEYS_BY_MAJOR" Correct as it stands. It states a precondition, names no file and asks for no edit.
:1100 code comment, where the gate READS the table Correct. Not printed.
:1127-1130 gate (b) "copy these lines in" Fixed (this card).
:1183-1185 (b2) "delete the entry from packages/spec/src/migrations/registry.ts" Same route. Each row now names its entry file (from the entry's own id and major, so a key carried through a declared def rename still names the file on disk), plus the generator.
:1222-1224 (b3) same Same route, same fix. It also says that a respelled id renames the file.
:2578-2579 def (b2) mirror same Same route, same fix.
:2619 info line "RETIRED_DEFS_BY_MAJOR, major N" Correct. A report, not a remedy.
:2636-2639 def-removal gate "copy these lines in" Same route (pointer 5908348030). Fixed like gate (b).
:2781 check (c) violation row "no entry in RETIRED_KEYS_BY_MAJOR names this EXACT key" Correct. A diagnosis; the route is in the footer's proof 1.
:2824-2825 check (c) proof 1 "(src/migrations/registry.ts) … writes it down" Same route. It now names the entry directory, entries/README.md and the generator. It names the README rather than a file because the true major is the author's to establish.
:2835-2836 check (c) proof 3 "(src/migrations/registry.ts)" Same route. It now names the entry directory; the manifest gate it defers to prints the file.
:3261-3262 default-change remedy "add a semantic entry to this major's step in src/migrations/registry.ts" Same defect on the third generated table. Fixed in place under the bounded rule: same defect class, same file, mechanical, same gate family.

H2 — the naming source. entries/README.md defines a file as MAJOR.ID.ts with / and : replaced by __. The generator's shardNameFor is, in its own words, "the whole naming rule, in one place", and loadEntries refuses a file whose name does not match its id. Every remedy prints its file name through shardNameFor (with KINDS / ENTRIES_DIR for the directory), imported from the generator. No second copy of the convention exists, and the README stays the one human description.

H3 — whether the docblock text ships. Measured after pnpm --filter @objectstack/spec build, with npm pack --dry-run:

  • src/ai/tool.zod.ts ships verbatim through files[] (src/**/*.zod.ts).
  • src/shared/strict-object.ts does not ship as source, but its edited JSDoc is in dist/shared/index.d.ts and dist/shared/index.d.mts. Positive control: the untouched aliases docblock is in the same two files.
  • Neither script ships.

So this PR takes a patch changeset, .changeset/20809-guidance-slot-docblocks.md, and no skip-changeset.

Landing site beyond the claimed surface: the generator

build-migration-registry.ts ran its CLI at module top level, and in write mode it rewrites registry.ts, so nothing could import shardNameFor from it. The fix is at the producer: the CLI body moves into main(), behind an entry guard spelled the way check-generated.ts (same directory) spells it, with realpath on both sides. shardNameFor's docblock now names its second reader.

Why not move the rule into a new scripts/lib/ module, or import scripts/invoked-as.mjs: CI runs check:migration-registry only when a changed path is in its selector arm (scripts/ci/select-gate-families.sh, migration_registry). That arm lists the generator's read set path by path. A new import would add an input outside the arm, and a later edit to that input alone would skip the gate. The guard adds only node:fs's realpathSync, so the generator's read set is unchanged.

New test packages/spec/scripts/build-migration-registry-entry.test.ts pins both directions of the guard, each as a real tsx process: a direct run reaches the generator, a run through a symlink also reaches it, and an import prints nothing beyond what the importer asked for.

Tests (at c2e5b3b81)

  • pnpm --filter @objectstack/spec exec vitest run --project repo scripts/build-schemas-check-mode.test.ts, the whole file: 88 passed (88), Duration 995 s, lock verdict command-exit 0.
    • Gate (b): the remedy names entries/retired-keys/ plus shardNameFor(major, key), the declaration and the generator command. It contains no paste line, no copy these lines and no migrations/registry.ts.
    • New control: every file and declaration pair is parsed off the red run's own output and written into the sandbox. The sandbox's own generator (which refuses a misnamed file) then runs, and gate (b) is silent on the re-run. The existing "registered by exact name ⇒ (b) silent" case still passes.
    • The def-removal gate, the manifest disappearance check, (b2), def (b2), (b3) and the end-to-end unpublish repro each pin their entry file and the generator.
  • pnpm --filter @objectstack/spec test (the local project, which includes the new guard test): 585 files, 17208 passed | 1 todo, command-exit 0.
  • pnpm --filter @objectstack/spec typecheck (tsc on src, tsconfig.scripts.json covering both changed scripts and the new test, and the test-typecheck ledger): command-exit 0.
  • pnpm --filter @objectstack/spec check:migration-registry: --self-test: ok, src/migrations/registry.ts is current (330 semantic, 242 retired-key, 211 retired-def). This is byte-identical to the reading taken before any edit.

Ablations (one-shot; each leg went through scripts/ablation-replace.mjs, which proves the mutation landed and the restore matched HEAD)

  • A1 — guard deleted (main() called unconditionally). The import probe goes red: the importer printed ✓ wrote src/migrations/registry.ts (330 semantic, 242 retired-key, 211 retired-def). Both run probes stay green. The first A1 attempt was refused by the tool before any run, because the replacement was a substring of the anchor and its count could not rise. It is recorded here as a no-op, and the re-run used a distinct marker.
  • A3 — raw argv[1] comparison (no realpath). The symlink run probe goes red: exit 0 with empty output, the silent no-op the guard spelling exists to prevent. The other two stay green.
  • B — gate (b) reverted to paste lines. Of the six cases in gate (b)'s describe block, two go red: the remedy case (no entry-file path) and the new follow-the-printed-route control ([] pairs parsed, against the 2 expected). The other 4 stay green.
  • Every restore was proven: blob equal to HEAD and git diff HEAD empty.

Gates

Derived from this diff with node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack: the change set is 7 paths against the merge base 05be35259, giving 88 commands. All 88 were run at c2e5b3b81. The --ran reconciliation reads 88 derived — 86 run, 2 NOT-MEASURED, 0 UNRUN.

  • 86 exit 0. These include check:migration-registry, check:authorable-surface, check:api-surface, check:docs, check:doc-authoring, check:nul-bytes, check:empty-changeset, check:changeset-no-major, check:cross-package-test-inputs, check:test-source-alias, check:type-check-coverage and check:issue-citations. Three of them needed a second run:
    • check:doc-formula-expressions and check:lean-entry-closure first refused with exit 3 (prerequisite not met). Both passed after a turbo run build of their 14-package closure.
    • check:pm-dispatch-gates was first cut by this run's own 900 s per-command cap, which is not counted. The uncapped re-run printed dispatch-gates self-test: 1976 cases pass in 1259 s. Its exit 0 is read from the absence of pnpm's failure marker, not from a captured status.
  • NOT MEASURED: check:dual-build-cjs-loads and check:type-check-debt. Both exit 3 (prerequisite not met): they read every workspace package's dist/, which lint.yml builds first, and that whole-tree build was not run in this worktree on a shared 4-core box. CI runs them.
  • pnpm --filter @objectstack/spec check:generated (named by the dispatch): "All 15 generated artifacts are up to date", exit 0.
  • origin/main advanced 11 commits past the base during these runs. None of them touches these 7 paths or src/migrations/, so they are not merged here; the PR's CI runs on the merge ref.

Acceptance notes

  • scripts/lib/sharded-artifacts.ts (about :353) writes the manifest shard description into every json-schema.manifest/ shard, and that text still says "must be declared in RETIRED_DEFS_BY_MAJOR (src/migrations/registry.ts)". It is the same family as the H1 rows. It is not changed here, because changing it regenerates every manifest shard, the hottest generated artifact. Carrier: none.
  • src/data/object.zod.ts's UNKNOWN_KEY_GUIDANCE has a section comment, "Tombstones for RETIRED keys", that uses the same loose term the two docblocks used. The card scoped this to two docblocks with no table edits. Carrier: none.
  • scripts/lib/default-changes.ts (about :52) has a code comment that still says "semantic entry to the major's step in src/migrations/registry.ts". The printed remedy it describes is fixed here. Carrier: none.
  • The changeset follows the dispatch's H3 rule (shipped text ⇒ patch) and AGENTS.md's skip-changeset criterion ("a diff that publishes nothing from any released package"). os-dev's fast path lists comments as non-publishing; this PR measured the shipped bytes instead.

Review

A docblock edit in packages/spec/src owes an at-tier contract review at landing (run by the seat). No governed surface is touched.


Generated by Claude Code

claude added 2 commits October 1, 2026 00:35
…n-registry, never the generated table

Gate (b), the def-removal gate, the manifest disappearance check and the
(b2)/(b3) mirrors printed lines to paste into, or delete from,
src/migrations/registry.ts, whose tables are generated from
src/migrations/entries/. Each remedy now names the entry file (from the
generator's own shardNameFor, made importable behind an entry guard) and
the generator command. The guidance-slot docblocks say what the slot is
for now: keys the shape does not declare.

Claude-Session: https://claude.ai/code/session_017VaLJnYwhPsanVCe9dMCJU
Co-authored-by: Claude <noreply@anthropic.com>
… paste line; changeset for the shipped docblocks

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

github-actions Bot commented Oct 1, 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. ⚠️ 1 changed file(s) yielded no anchor (packages/spec/src/ai/tool.zod.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

What this run could not see
  • 1 changed file(s) yielded no anchor (packages/spec/src/ai/tool.zod.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 — 137 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 2f2fa11d756f665a4c06160480c1dce15b9d67a4 → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 2febc4b64f71e7f5683d26c78b61a34ed03bcad2 — the merge of head c2e5b3b8146a6917038bb6647b658e29fc7ce1ee into base 2f2fa11d756f665a4c06160480c1dce15b9d67a4, 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 2febc4b64f71e7f5683d26c78b61a34ed03bcad2 && git checkout 2febc4b64f71e7f5683d26c78b61a34ed03bcad2
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 2f2fa11d756f665a4c06160480c1dce15b9d67a4 c2e5b3b8146a6917038bb6647b658e29fc7ce1ee && git checkout -B drift-repro 2f2fa11d756f665a4c06160480c1dce15b9d67a4 && git merge --no-ff c2e5b3b8146a6917038bb6647b658e29fc7ce1ee

node scripts/docs-audit/affected-docs.mjs --json 2f2fa11d756f665a4c06160480c1dce15b9d67a4

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

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: c2e5b3b8146a6917038bb6647b658e29fc7ce1ee
Local-runs: none

Reviewed as an isolated subagent on PR #21021 (card #20809), from the card's body and its three comments (the pointer, the claim, the os-dev report), the PR body, its 7-file list, the net diff against main, files read at the head by git show, and the check-runs on the head. Nothing was built, run or re-run.

① Derived judgments

Accept set — unchanged, judged right. The three packages/spec/src/** hunks are docblock text only: shared/strict-object.ts (the file-header bullet for guidance and the StrictObjectOptions.guidance JSDoc) and ai/tool.zod.ts (the docblock above TOOL_RETIRED_KEY_GUIDANCE). No schema shape, no guidance-table row, no retiredKey(), no alias and no enum moves; the card's ⛔ "no guidance table entry changes" holds. The new wording (the slot holds prescriptions for keys the shape does not declare; a key retired in place is a retiredKey() tombstone in the shape) matches what the slot does: an entry suppresses the rename suggestion for an undeclared spelling, and shared/alias-integrity.test.ts makes a guidance row for a declared key dead. Clause-②: no is the right declaration.

Published surface — text only, and it does ship, judged right. src/shared/index.ts re-exports ./visibility, whose exported VISIBILITY_STRICT_OPTIONS is typed StrictObjectOptions, so the edited JSDoc reaches the ./shared entry's bundled declarations (dist/shared/index.d.ts and .d.mts), which the package exports map addresses. src/ai/tool.zod.ts ships verbatim through files[] (src/**/*.zod.ts). Both are hover and source text, not accept-set bytes; the consequence is a changeset (see ②), not a Clause-② arm. No generated artifact is in the diff (no json-schema/, api-surface/, liveness/ or src/migrations/registry.ts), which is consistent with docblock-only source changes; Spec property liveness and Check Changeset are green on the head.

Printed remedies in packages/spec/scripts/build-schemas.ts (unshipped) — judged right. Measured on the head versus the merge base 05be35259: grep -n -E 'migrations/registry\.ts|copy these lines|step in src/migrations' returns 10 lines at the base and 2 at the head, both code comments (the new section header at :771 and the existing check (a) comment at :1162). The ten printed sites named in the PR's H1 table are all rerouted. Each remedy that knows the id and the major prints the exact entry file plus its one declaration through renderNewEntryFiles; the undo remedies ((b2), (b3), def (b2)) print each registered entry's on-disk file through retiredKeyEntryFiles / retiredDefEntryFiles, which look the id up under every major and map a renamed-def carry through carryAuthorableKey (from scripts/lib/renamed-defs.ts), so the file named is the one that exists; check (c) proof 1 and the default-change remedy name the directory and entries/README.md because the major there is the author's to establish. Every remedy carries MIGRATION_REGISTRY_COMMAND, which equals the package script gen:migration-registry (tsx scripts/build-migration-registry.ts). CURRENT_MAJOR moved up to :767, after SPEC_VERSION (:300), so the earlier manifest-disappearance remedy at about :850 can use it. The three table-naming lines left alone (:1089 precondition, :2619 info line, :2781 diagnosis row) print no route and are right as they stand.

The card's ⛔ on restating the naming convention — held. entryFileOf composes ENTRIES_DIR, KINDS[].dir and shardNameFor, all imported from the generator; shardNameFor is the one rule (MAJOR.ID.ts, / and : to __) and entries/README.md at the head documents that same rule with the same example (17 plus data/AggregationNode:distinct). The remedies name the README by its path, which exists at the head; no second prose copy of the convention was added.

The generator packages/spec/scripts/build-migration-registry.ts (unshipped) — judged right. The CLI body moved verbatim into main(argv) (the --self-test branch, the exit-when-alone rule, --check versus write, the stale-registry message) behind invokedDirectly, a realpath-on-both-sides comparison spelled byte-for-byte as the sibling check-generated.ts spells it (:993-1000 there). The remaining top-level statements (pkgRoot, the exported path constants, KINDS, closeMarker) have no side effect, so an import runs nothing and shardNameFor, KINDS, ENTRIES_DIR and type Kind are importable, which is what build-schemas.ts and the check-mode test now do. Both package scripts (gen:migration-registry, check:migration-registry) run the file as argv[1] under tsx, so the guard answers run for them. check:entry-guard walks only the root scripts/ (ROOT_DIR_WATCH_HINTS is scripts/**, held by its own self-test), so a package-local hand-typed guard is outside its population, and the dev's reason for not importing scripts/invoked-as.mjs (it would add a read-set input outside the migration_registry selector arm) is sound: that arm names packages/spec/scripts/build-migration-registry.ts path by path, so this PR's edit to the generator selects the scoped check:migration-registry step in CI.

Tests — the card's two pins are present, judged right. build-schemas-check-mode.test.ts (the repo vitest project, listed in vitest.repo-tests.json) pins gate (b) and the def-removal gate on the entry file, the export const entry declaration and REGEN_COMMAND, with not.toContain('migrations/registry.ts') and not.toContain('copy these lines') (the self-test on the message); keeps the registered-by-exact-name control; and adds the follow-the-printed-route control, which parses the file and declaration pairs off the red run, writes them into the sandbox, runs the sandbox's own generator and asserts gate (b) is then silent. :789, (b2), def (b2), (b3) and the unpublish repro each pin their entry file. The new build-migration-registry-entry.test.ts (the local project via scripts/**/*.test.ts) pins both guard directions as real tsx processes, including the symlink run. tsconfig.scripts.json includes scripts/**/*, so both scripts and the new test are in the typecheck program (Type Check · source gates green on the head).

Coordination with the kit — judged right. The PR quotes the retirement kit's section 3 as it reads on main (745ac30a, an ancestor of origin/main; .claude/skills/spec-property-retirement/SKILL.md lines 182-184): one file under entries/retired-keys/, naming per entries/README.md, then gen:migration-registry, never typed in registry.ts. The gate and the kit now say the same route, and this card landed second and quotes the first, as the card's Order section asks. No governed surface is in the diff (Governed Surface Queue Guard green).

② Semver level

.changeset/20809-guidance-slot-docblocks.md declares '@objectstack/spec': patch and carries Clause-②: no, matching the PR body's Clause-②: no. Right: the diff ships text (a published declaration's JSDoc and a shipped source docblock), and skip-changeset is reserved for a diff that publishes nothing from any released package (AGENTS.md Post-Task step 3; the os-dev rule that published means what each package's files[] ships). No accept set widens or narrows, so neither minor nor a breaking level applies, and no ADR-0087 disposition is owed. The changeset body states that no schema, guidance entry, prescription or parse behaviour changes, which the diff bears out. Check Changeset is green on the head. The dev's deviation from the os-dev fast path (comments as non-publishing) is the measured call, and it is the right one here.

③ Boundary flags

open_questions is empty. The five deviations and three out-of-scope findings in the os-dev report:

  • Deviation 1, landing beyond the claimed file surface (the generator's main() and guard, plus the new guard test). Answered: accepted. The card's own ⛔ (no second copy of the naming rule) forces the remedies to read shardNameFor from the generator, and the generator ran its CLI at import, so the guard is the minimal change that makes the card's instruction satisfiable. Both files are unshipped scripts; the generator's read set is unchanged (only realpathSync from node:fs was added), and its path is already in the migration_registry selector arm, so CI's scoped gate covers the edit. Escalated to the seat as bookkeeping only: the claim's file surface should be amended to name packages/spec/scripts/build-migration-registry.ts and packages/spec/scripts/build-migration-registry-entry.test.ts, as the dev asked. Not blocking.
  • Deviation 2, in-place fixes beyond the named lines ((b2), (b3), def (b2), check (c) proofs 1 and 3, the default-change remedy). Answered: accepted. The card's pointer comment already folded the def-removal gate and :789 in; the others are the same defect (a printed remedy routing an author into the generated file), in the same file, mechanical, and each is named in the PR's H1 table with its verdict.
  • Deviation 3, patch instead of skip-changeset. Answered in ②: patch is right.
  • Deviation 4, main not pulled before the PR. Answered: at read the PR is mergeable against base 2f2fa11d7, and CI runs on the merge ref (2febc4b64, per the docs-drift comment). The eleven intervening commits touch none of the 7 paths or src/migrations/. Not blocking; the seat's landing re-read of the checks covers it.
  • Deviation 5, measurement notes (the first targeted run selected nothing; one exit code read from the absence of the failure marker). Informational; the check-runs on the head are the verdicts.
  • Out-of-scope 1, scripts/lib/sharded-artifacts.ts at about :353. The manifest shard description still says "must be declared in RETIRED_DEFS_BY_MAJOR (src/migrations/registry.ts)", and json-schema.manifest/ ships in files[], so this is the same defect family on a published artifact. Leaving it out of this PR is right (the card scopes build-schemas remedies and two docblocks; the change regenerates every manifest shard). Escalated: it is recorded with carrier none, so the seat should file a follow-up card or it is lost. Not blocking.
  • Out-of-scope 2, the "Tombstones for RETIRED keys" section comment inside src/data/object.zod.ts's UNKNOWN_KEY_GUIDANCE. Answered: the card's ⛔ on guidance-table edits makes leaving it right; fold into the same follow-up card.
  • Out-of-scope 3, the scripts/lib/default-changes.ts comment at about :52. Answered: an unshipped comment whose printed remedy is fixed here; fold into the same follow-up card.

Check-runs on the head, as read at 2026-10-01T02:20Z

33 check-runs: 22 success, 3 skipped (Build Docs, Console Pin Gate, Packed-tarball smoke (opt-in): path and opt-in skips), 0 failure, and 8 still in_progress at the reading: Lint & Repo Gates (the job carrying the scoped check:migration-registry, check:entry-guard and check:api-surface), Temporal Conformance (live PG + MySQL), Test Core (1/6), (2/6), (3/6), (5/6), (6/6), and Type Check · workspace. Green at the reading include Build Core, Test Core (4/6), Type Check · source gates, Type Check · consumer gates, Type Check · debt ledger, Check Changeset, Spec property liveness, Governed Surface Queue Guard, the three Dogfood Regression Gate shards and Dogfood Verify CLI. The in-progress runs are not a FAIL; the seat re-reads every check before landing, and this PASS is conditional on those eight concluding green.

Implemented-by: claude/issue-20809-gate-b-names-entries-route
Reviewed-by: session_017VaLJnYwhPsanVCe9dMCJU

VERDICT: PASS


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 1, 2026 02:32
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 1, 2026 02:32
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 1, 2026
Merged via the queue into main with commit ebb66aa Oct 1, 2026
37 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-20809-gate-b-names-entries-route branch October 1, 2026 04:12
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 protocol:ai size/l tests tooling

Projects

None yet

2 participants