Skip to content

feat(spec)!: retire page-header-subtitle-alias and inline-action-api-params-to-body-extra from the load path at 18 - #23485

Merged
objectstack-fleet[bot] merged 9 commits into
mainfrom
claude/issue-23421-retire-page-aliases-at-18
Oct 14, 2026
Merged

objectstack-fleet[bot] merged 9 commits into
mainfrom
claude/issue-23421-retire-page-aliases-at-18

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #23421

Clause-②: yes (narrowing)

What

The two ADR-0087 D2 conversions page-header-subtitle-alias (page:header properties.description to subtitle) and inline-action-api-params-to-body-extra (an inline type: 'api' action's object-form params to bodyExtra) were declared toMajor: 17 for protocol 17's one-major window. On the 18.0.0-next line they were still load-active, so os validate and the load path converted silently what the metadata save door (once PR #23418 moves the component-props rule onto it) refuses. This PR retires both from the load path, the way every other retired entry is marked: retiredFromLoadPath: true and retiredAfter: '17.7.0', the newest published stable release under the 18.0.0-next.0 label.

After this change every door that judges page props answers the same way: os validate, os build, os lint, and the save door after #23418 all refuse the old spelling, and the refusal names the rename. Stored rows keep healing. applyConversionsToStoredItem replays the full chain with includeRetired: true, so does the artifact-ingestion door inside its window, and os migrate meta replays the chain too.

Premise check (done before any edit)

  • ADR-0087 D2, "Window": "each conversion is applied by the loader for one major (N accepts N-1 shapes at load), then retired from the load path in N+1". toMajor: 17 means 18 is N+1. The section "The load-window's second half is now mechanical" names MetadataConversion.retiredFromLoadPath as the field that implements that retirement.
  • conversions/types.ts: RetiredConversionState is retiredFromLoadPath: true plus a required retiredAfter. apply.ts skips such an entry unless includeRetired is set. stored.ts pins includeRetired: true.
  • Precedent: at 61b12584f, 45 toMajor: 17 entries carry retiredFromLoadPath (retiredAfter 16.1.0). Among the toMajor: 18 entries, 69 are retired, 7 of them with retiredAfter: '17.7.0' (for example declared-index-unique-scope and email-template-category-is-system-removed).
  • The premise holds, so this PR takes the retirement route. It does not touch the other route (the save door applying live-window conversions).

Changes

  • packages/spec/src/conversions/registry.ts: the two entries get the two fields, and their docblocks now record the retirement in place of "Live window; retires at 18".
  • packages/spec/src/ui/component.zod.ts: PageHeaderProps description moves from an aliases row (a bare "Did you mean description to subtitle?") to a guidance row. It is the upgrade prescription in house form: it names @objectstack/spec 18 and subtitle, followed by the os migrate meta --from 16 house sentence.
  • packages/spec/src/ui/action.zod.ts: the object-form params refusal keeps its bodyExtra instruction. It now also says the loader rewrote that form on an inline page button until @objectstack/spec 18, and it ends in the MIXED two-clause os migrate meta --from 16 sentence. The partial form is used because the conversion only covers the inline element:button case.
    • Why these two text edits are here although the claim's file surface does not name ui/*.zod.ts: shared/retired-key-removal-version.pin.test.ts requires every entry retired after the newest stable release to be joined to the prescriptions an author meets, and requires each of those prescriptions to name the derived release (18). Neither refusal named a release, so the pin went red on exactly these two ids. The landing spot is the producer of the refusal text, in the same package.
  • Pin flips (load-bearing, not just deletions):
    • conversions/conversions.test.ts: the two entries' rewrite cases run the data-at-rest posture (includeRetired: true). New cases assert that the authoring posture rewrites nothing on both page:header and the kebab page-header, and on the object-form params. They also assert the entry fields (toMajor: 17, retiredFromLoadPath: true, retiredAfter: '17.7.0') and that the bodyExtra refusal is what an author meets. The premise pin on PageHeaderProps (refuses description, names subtitle) stays verbatim.
    • lint/src/validate-component-props.test.ts: the "normalized tier" block asserted the normalized tier says nothing about description. It now asserts that the normalized tier refuses it as component-props-unknown-key, error, at the exact path, naming subtitle, and that the raw tier gives the same answer.
    • shared/retired-key-removal-version.pin.test.ts: two JOIN rows.
  • Vehicle swaps: spec/src/stack-conversions-record.test.ts, cli/test/stack-conversion-record-door.test.ts and cli/src/commands/validate-json-strict-exit.e2e.test.ts used page-header-subtitle-alias as their live conversion. Their own docblocks said to re-point them at a live entry when it retired. They now ride page-component-visibility-to-visibleWhen (visibility to visibleWhen on the same page:header node, retiresIn: 16), and every assertion is unchanged in substance.
  • .changeset/23421-retire-page-aliases-at-18.md: minor, with the BREAKING banner, Clause-②: yes (narrowing), the FROM to TO mapping, and the ADR-0087 disposition. In words, the disposition marker is "adr-0087: not-required (already-registered page-header-subtitle-alias, inline-action-api-params-to-body-extra)". Both conversions are already in the step-17 chain and are the whole mechanical migration, so there is no new D2 conversion and no D3 semantic entry. check-adr-0087-registration accepts it.

For the seat: one sentence in PR #23418 becomes false

PR #23418's changeset .changeset/23388-page-component-rules-runtime-door.md carries the paragraph that begins "Two live-window ADR-0087 D2 aliases ... are converted at objectstack validate and at load but not at this door". Once this PR lands, that paragraph is false: neither alias is converted at objectstack validate or at load any more. This PR does not edit #23418's files. The same goes for the comment block in packages/lint/src/authoring-rules.ts (the validateComponentProps entry, "normalized for a reason worth stating ..."), which still cites page-header-subtitle-alias as the converted alias that makes the tier matter. That file is in #23418's diff, so it is left for that landing. #23418 is not addressed here.

Verification (at 6f0fcb21f, after merging origin/main at 3d231ba78)

  • pnpm --filter @objectstack/spec test: 676 files, 20576 tests passed (after the merge).
  • pnpm --filter @objectstack/spec test:repo: 59 files, 1011 tests passed (before the merge, which touched no tree-scoped pin input of this diff).
  • pnpm --filter @objectstack/spec check:generated: all 14 generated artifacts up to date.
  • Before the merge: typecheck: @objectstack/spec, @objectstack/lint and @objectstack/cli each exit 0.
  • @objectstack/lint full vitest, @objectstack/cli --project unit (287 files, 4307 tests), and the two touched CLI integration and e2e files: test/stack-conversion-record-door.test.ts (21/21) and src/commands/validate-json-strict-exit.e2e.test.ts under OS_TEST_TIERS=nightly (7/7).
  • Red before the flip: with only the registry edit applied, conversions.test.ts had 5 failing cases and stack-conversions-record.test.ts had 30, all asserting the two conversions ran on the authoring path. The lint tier case and the removal-version pin each went red the same way.
  • The gate families came from node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack (93 families, the same set before and after the merge). All 93 were run at 6f0fcb21f with exit 0, and the list was reconciled with --ran.

Acceptance notes

  • page-header (kebab): the conversion's walk still lists it, for the data-at-rest replays. Retired, a source page-header node's description is neither converted nor judged, because ComponentPropsMap has no page-header row. This is harmless: objectui at the pinned .objectui-sha no longer registers page-header (its components changeset "drop page-header from the opt-in protocol placeholders"), so such a node renders the unknown-component panel whatever its props say.
  • The boot path loading source through defineStack does not run the props gate (that gate runs at os validate / os build / os lint and, after feat(lint)!: the two page component rules run on the runtime publish door (ruling B) #23418, at the save door). This is the same posture every other retired page prop already has (page:header icon and breadcrumb).
  • In-repo authors of either old spelling: zero (examples/, packages/platform-objects, packages/plugins, packages/services). The control grep on page:header finds the canonical subtitle in use.

Generated by Claude Code

…params-to-body-extra from the load path at 18 (wip)

Claude-Session: https://claude.ai/code/session_01D6F9axfoPzR7t8G1J7Ytzz
Co-authored-by: Claude <noreply@anthropic.com>
…Retired; the record-door vehicle moves to a live conversion

Claude-Session: https://claude.ai/code/session_01D6F9axfoPzR7t8G1J7Ytzz
Co-authored-by: Claude <noreply@anthropic.com>
…ader key with the rename

Claude-Session: https://claude.ai/code/session_01D6F9axfoPzR7t8G1J7Ytzz
Co-authored-by: Claude <noreply@anthropic.com>
…ve page visibility conversion

Claude-Session: https://claude.ai/code/session_01D6F9axfoPzR7t8G1J7Ytzz
Co-authored-by: Claude <noreply@anthropic.com>
… refuses them, joined in the removal-version pin

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

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec, touching 4 documentable anchor(s).

⛔ 2 release-owned page(s) name something this change touched. These are read-only:

  • content/docs/releases/v17/17-5.mdx (via retiredAfter (symbol, a field of const object inlineActionApiParamsToBodyExtra; a field of const object pageHeaderSubtitleAlias), retiredFromLoadPath (symbol, a field of const object inlineActionApiParamsToBodyExtra; a field of const object pageHeaderSubtitleAlias))
  • content/docs/releases/v17/17-6.mdx (via PageHeaderProps (symbol, a top-level const object))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • the SDK route bridge reached 54 of 206 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • 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 — 142 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 a1285f26db92269642ebb90ab70fe3840dda51cb → packageMentionDocs.

Which tree this was computed on

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

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

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

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs a1285f26db92269642ebb90ab70fe3840dda51cb → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 6f0fcb21f4efcdfcd6213ab9ad1675341204ffa8
Local-runs: none

Inputs read: card #23421 (body + 3 comments: triage 6163717752, claim 6165302231, dev report 6168805850), PR #23485 (body, 10-file list, net diff vs main at the head; merge base 3d231ba78), and the 37 check-runs on the head. The premise was verified against the repo tree read-only (docs/adr/0087-metadata-protocol-upgrade-contract.md, packages/spec/src/conversions/{types,apply,stored,registry}.ts, packages/spec/package.json, packages/spec/CHANGELOG.md, packages/spec/src/shared/{strict-object.ts,retired-key-removal-version.pin.test.ts}, scripts/pm/clause2-line.mjs, scripts/check-changeset-no-major.mjs, scripts/check-adr-0087-registration.mjs, AGENTS.md item 3). Nothing was built, run or re-run.

① Derived judgments

  1. The claim's premised ruling — premise verified, and RIGHT. The claim (6165302231) ruled: retire both conversions from the load path at 18 if ADR-0087 ends the window that way, otherwise stop. The premise holds, read independently of the dev's own premise check: ADR-0087 D2 "Window" (lines 143–144) says each conversion is applied by the loader for one major, "then retired from the load path in N+1"; the section "The load-window's second half is now mechanical" (lines 453–456) names MetadataConversion.retiredFromLoadPath as that retirement; conversions/types.ts RetiredConversionState is retiredFromLoadPath: true plus a required retiredAfter; apply.ts:156 skips such an entry unless includeRetired; stored.ts:107 pins includeRetired: true. Both entries read toMajor: 17, so 18 is N+1. retiredAfter: '17.7.0' is the right stamp: the package label is 18.0.0-next.0 (prerelease, so the newest published stable is the highest stamp, 17.7.0, which is also the newest ## 17.x in CHANGELOG.md), and 7 existing entries already carry retiredAfter: '17.7.0'. The route taken (retire, not "save door applies live-window conversions") is the one the premise licenses. Right.
  2. Accept-set narrowing on the authoring funnel — RIGHT and correctly characterised. defineStack / os validate / os build / os lint (normalizeStackInput) stop rewriting page:header properties.description → subtitle and an inline type:'api' action's object params → bodyExtra; the author now meets the props-gate refusal. This is the finding's class (b) fix: the save door's raw judgment and the CLI's normalized judgment now agree (the lint pin flip in validate-component-props.test.ts asserts both tiers refuse at the same path naming subtitle). Right.
  3. Data at rest unchanged — RIGHT. applyConversionsToStoredItem replays with includeRetired: true; the artifact-ingestion door decides per entry by retiredAfter; os migrate meta replays by id. The conversions.test.ts cases now run under includeRetired: true for the rewrite properties and add two authoring-posture cases asserting no rewrite and the entry fields. The new case for the button also asserts ElementButtonPropsSchema refuses the object form naming bodyExtra. Right.
  4. Public-surface text changes (component.zod.ts, action.zod.ts) — RIGHT, and owed by a gate. retired-key-removal-version.pin.test.ts requires every entry whose retiredAfter equals the newest published stable release to have a JOIN row, and every prescription it renders to name the derived major (@objectstack/spec 18 / protocol 18 via majorsNamed) and, for any os migrate meta --from N, N = toMajor − 1 = 16. Neither refusal named a release on main, so stamping retiredAfter: '17.7.0' turns that pin red on exactly these two ids; the producer of the refusal text is the only place that satisfies it. PageHeaderProps moves description from aliases to guidance (both are strictObject options, strict-object.ts:158): the new text names @objectstack/spec 18, subtitle, and --from 16; the pin's refusal() reads the parse issue messages and will see exactly that. The action.zod.ts object-form params refusal keeps its bodyExtra instruction and adds "until @objectstack/spec 18" and the --from 16 sentence; the JOIN row filters issues at path action. The only majors named in either text are 18 (the regex does not match ADR-0087 or #NNNN). These two edits are inside the claim's package but outside its file surface — judged under ③. Right.
  5. Vehicle swap to page-component-visibility-to-visibleWhen — RIGHT in substance. The entry is live (toMajor: 15, no retiredFromLoadPath, registry.ts:572), rewrites the component-level key via renameVisibilityAlias emitting path: ${path}.visibleWhen, from: 'visibility', to: 'visibleWhen', so HEADER_PATH = pages[0].regions[0].components[0].visibleWhen and retiresIn: 16 (= toMajor + 1) are the correct notice. The strict-parse expectation { dialect: 'cel', source } matches PageComponentSchema.visibleWhen: EvaluatedExpressionInputSchema lowering. The three suites' own docblocks prescribed the re-point. Every assertion is unchanged in substance. One wrong sentence in the diff, flagged under ③ (item c).
  6. Changeset content — RIGHT. minor with the BREAKING banner, FROM → TO mapping and one-line fix for both renames, the os migrate meta --from 16 sentence, the stored-data posture, and exactly one ADR-0087 marker: adr-0087: not-required (already-registered page-header-subtitle-alias, inline-action-api-params-to-body-extra). already-registered is an accepted category of check-adr-0087-registration.mjs for ids that resolve at HEAD and pre-exist the diff; both do (the diff adds two fields to existing entries, no new entry). Check Changeset concluded success.
  7. Clause-② spellings. The claim declared Clause-②: no; the changeset declares Clause-②: yes (narrowing). What the diff IS: an accept-set narrowing of the authoring funnel with no new accepted shape or export, so the exact spelling is no (narrowing) (check-changeset-no-major.mjs: "no (narrowing) is a truthful no to the widening question and a breaking change at the same time"). Both no and yes (narrowing) are well-formed to readClause2Line (the token is first after the colon; the arm is the first word of the parenthetical) and yes (narrowing) reaches the same level verdict as no (narrowing) (clean, at least minor, breaking carried by the banner during the launch window, major forbidden). The claim's bare no is the understatement: it named no arm although its own Container & model: line says "(a narrowing)". Acceptable to the gate either way; the yes is over-declared, not wrong at the gate. One placement defect in the PR body, flagged under ③ (item b).
  8. In-scope census left for the seat — RIGHT to leave. The claim asked the dev to list the other toMajor: 17 entries still live with a verdict each; the report's first out_of_scope_findings entry does so (7 flow-node entries overdue, sharing-rule-access-level-full-to-edit overdue but needs an enumWithRetiredValues prescription first, datasource-driver-mongo-to-mongodb and retry-policy-converged deliberately kept and needing a ruling), plus the older-window stragglers including the new vehicle itself. Not this card's diff; the seat files one closing card as the dispatch asked.

② Semver level

@objectstack/spec: minor, with the BREAKING (authoring) banner and migration, matches what the diff publishes: a narrowing of the authoring accept set in a released package, shipped during the v18 launch window where check-changeset-no-major.mjs forbids major and requires the banner + ADR-0087 disposition as the breaking-ness carriers (AGENTS.md item 3: "(narrowing) is BREAKING", "yes takes at least minor"). skip-changeset would be wrong (the package publishes). @objectstack/lint and @objectstack/cli have test-only edits and correctly carry no changeset. Check Changeset: success.

Clause-②: yes (narrowing) — as the changeset declares; the diff's exact arm is narrowing, and no (narrowing) would be the tighter value. Both spellings are accepted by the gate and grade identically.

③ Boundary flags

Dev flags (report 6168805850, deviations and out_of_scope_findings); open_questions: [].

a. File-surface extension (ui/component.zod.ts, ui/action.zod.ts, shared/retired-key-removal-version.pin.test.ts) — the claim said "stop on a breach and explain it"; the dev did not stop but explained in the PR body and the report. Answered: ACCEPTED. The extension is forced by a gate the claim itself named ("any D2 bookkeeping the step-18 retirement owes … as the gates name it"): the removal-version pin requires the refusal text to name the release, and the refusal text is produced only in those two schema files. The edits change refusal wording only; no accepted shape moves. The two refusal strings are judged RIGHT in ① item 4.

b. PR body carries no readable Clause-②: declaration — the PR body mentions `Clause-②: yes (narrowing)` only inside a bullet sentence ("with the BREAKING banner, Clause-②: yes (narrowing), the FROM to TO mapping…"). readClause2Line reads declarations by position (line-initial, with at most a bullet, blockquote marker or bold as decoration); this is the "inline-key" placement near-miss, so check-changeset-no-major.mjs read value: null from the PR and graded the level axis not-measured-moot (exit 0, because spec is already minor). The changeset's own line is well-formed and check-adr-0087-registration reads the arm there. ESCALATED to the adopting seat as a PR-body edit (no code change): add a bare line Clause-②: yes (narrowing) (or no (narrowing)) to the PR body so the level axis is measured, not moot. Not a defect of the head.

c. One wrong sentence in a docblock — packages/cli/src/commands/validate-json-strict-exit.e2e.test.ts lines 63–65 now read "that conversion, page-component-visibility-to-visibleWhen, retired from the load path at protocol 18 and the fixture was re-pointed here". The retired conversion is page-header-subtitle-alias; the new vehicle is the live one. Comment-only, no assertion rides on it, but it states the opposite of the truth in the file that teaches the next re-pointer. ESCALATED as a one-line follow-up fix (this PR or the seat's closing card).

d. The new vehicle is itself overdue — page-component-visibility-to-visibleWhen is toMajor: 15 and still live at 18, which the dev's own census names. The three re-pointed suites will need re-pointing again when the family closing card retires it. Answered: noted; the suites' docblocks already prescribe it, and this card's scope is the two entries the finding named.

e. PR #23418's changeset paragraph and authoring-rules.ts comment become false on landing — both files are in #23418's diff, so this PR correctly leaves them; the dev flagged it as "noted, not filed". Answered: ESCALATED to the seat, who owns both PRs: the later lander (per triage, this card lands with or before #23418) updates the paragraph and the validateComponentProps comment, or #23418 takes it into its landing.

f. Kebab page-header source nodes carrying description are neither converted nor judged after retirement — the dev grounds harmlessness in objectui at the pinned .objectui-sha no longer registering page-header. Answered: accepted as stated; the same posture already holds for page:header icon and breadcrumb, and the walk still lists the kebab type for data-at-rest replays.

g. Check-runs on the head — 22 completed success, 6 completed skipped (opt-in/matrix placeholders), and 15 in progress at brief time: Build Core, Lint · CI, release & engine gates, Lint · ESLint, Lint · docs & code guards, Lint · repo & tooling gates, Lint · scoped · query-options erasure, Lint · scoped · slot lookup & corpus, Test Core (1/6) … Test Core (6/6), Type Check · consumer gates, Type Check · debt ledger, Type Check · workspace. Read once; no watcher. The queue reads their conclusions when they land; this record does not pre-empt them. Of the completed ones, the gate families this diff touches — Check Changeset, Spec property liveness, Governed Surface Queue Guard, Lint · PM dispatch-gates, Type Check · source gates, the four claim/branch guards — all concluded success.

h. Claim's Clause-②: no versus the changeset's yes (narrowing) — judged in ① item 7: no gate couples the two, both parse, the level verdict is the same. No action.

Implemented-by: claude/issue-23421-retire-page-aliases-at-18
Reviewed-by: session_01D6F9axfoPzR7t8G1J7Ytzz

VERDICT: PASS

Adopted by domain:spec seat 3 (#18883), baozhoutao, session session_01D6F9axfoPzR7t8G1J7Ytzz, at 2026-10-14T13:00Z: rendered by an isolated read-only reviewer at CONTRACT_REVIEW_TIER. ③-b: the seat adds a bare Clause-②: line to the PR body (no push). ③-c: carried by the family closing card #23487, which re-points the same three suites. ③-e: PR #23418 takes the two sentences in its patch round after this lands.


Generated by Claude Code

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 14, 2026 13:25
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 14, 2026
Merged via the queue into main with commit 8693110 Oct 14, 2026
49 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-23421-retire-page-aliases-at-18 branch October 14, 2026 13:47
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:ui size/m tests tooling

Projects

None yet

2 participants