Skip to content

feat(spec)!: retire a page header's breadcrumb switch — no renderer draws a trail for it (#20758) - #20785

Merged
os-zhuang merged 6 commits into
mainfrom
claude/issue-20758-page-header-breadcrumb-retired
Sep 30, 2026
Merged

os-zhuang merged 6 commits into
mainfrom
claude/issue-20758-page-header-breadcrumb-retired

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Closes #20758

Clause-②: no (narrowing)

PageHeaderProps.breadcrumb retires through the ADR-0087 route, the way icon left the same row. It has a retiredKey() tombstone, the D2 conversion page-header-breadcrumb-removed (it strips true and false from stored and built pages with a notice, retired from the load path), the RETIRED_KEYS_BY_MAJOR[18] entry and the D3 entry page-header-breadcrumb-retired. A stored page is never refused for the key: the props lint reports it as a warning.

nav:breadcrumb stays, because objectui's Studio page palette writes it.

The published skill skills/objectstack-ui/rules/pages.md stops teaching the key (two lines). That path is governed, so this PR lands Tier H, after an authorized approval.

@objectstack/spec minor, BREAKING.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1

@github-actions

github-actions Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/spec, touching 12 documentable anchor(s). ⚠️ 4 changed file(s) yielded no anchor (packages/spec/authorable-defaults/ui.json, packages/spec/authorable-surface/ui.json, packages/spec/src/migrations/entries/retired-keys/18.ui__PageHeaderProps__breadcrumb.ts, …), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/automation/flows.mdx (via lead_record (literal, a string literal in fixture))

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

  • content/docs/releases/v17/17-5.mdx (via retiredAfter (symbol, a field of const object pageHeaderBreadcrumbRemoved), retiredFromLoadPath (symbol, a field of const object pageHeaderBreadcrumbRemoved))

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
  • 4 changed file(s) yielded no anchor (packages/spec/authorable-defaults/ui.json, packages/spec/authorable-surface/ui.json, packages/spec/src/migrations/entries/retired-keys/18.ui__PageHeaderProps__breadcrumb.ts, …) — pages documenting those are invisible to this run
  • 10 name(s) were too generic to anchor anything (single lowercase words)
  • 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 — 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 4b4ee88fbc530a155ce3ea0570ad81d905d3afbb → packageMentionDocs.

Which tree this was computed on

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

node scripts/docs-audit/affected-docs.mjs --json 4b4ee88fbc530a155ce3ea0570ad81d905d3afbb

⚠️ 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 4b4ee88fbc530a155ce3ea0570ad81d905d3afbb → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…d page-header breadcrumb

Claude-Session: https://claude.ai/code/session_01Sfe5YjBLwB9J3y8fvm2xq1
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Contract review

Served-tier: CONTRACT_REVIEW_TIER
Head-sha: 70e0f052ff1369a627db2ca218ce9bd6154435f5
Local-runs: none

Inputs read: card #20758 (body and its 4 comments: claim 5903804962, dev reports 5905125466 and 5905304700, ruling 5905149162), PR #20785 (body, 15-file list, net diff of 70e0f052ff against main; merge-base 9ad654487b, +775/−12, identical to the PR's own stat), the 46 check-runs on the head, the objectstack tree at the head via git show/git grep, and the objectui tree at the head's pin .objectui-sha = db11afd4967c and at objectui origin/main = 0ffc423b13.

① Derived judgments

Accept-set and public-surface changes the diff implies, each judged:

  1. PageHeaderProps.breadcrumb (packages/spec/src/ui/component.zod.ts:535) moves from z.boolean().default(true) to retiredKey(…): input type never, parse refuses true and false with the prescription, key stays in the walked shape. Right. Narrowing at the props row only: PageComponentSchema.properties is z.record(z.string(), z.unknown()).optional().default({}) (page.zod.ts:324), so the page door still accepts a header carrying the key and nothing is hard-refused, which is the card's ruling. Pinned in page-header-breadcrumb-retirement.test.ts (tombstone, not the strict unknown-key arm; PageSchema still parses a stored header with either value).
  2. D2 conversion page-header-breadcrumb-removed (conversions/registry.ts): toMajor: 18, retiredFromLoadPath: true, retiredAfter: '17.5.0' (the spec version at the head), scoped by type === 'page:header', order: 49 (unique and highest in MAJOR_18_CONVERSIONS), fixture with 4 notices covering region, nested children, slotted page, a same-named key on an open-namespace type and a control header. Right, and shaped like its precedents object-kanban-quick-add-removed (18, retiredAfter 17.4.0) and page-structure-inert-keys-removed (17, the icon this row lost).
  3. RETIRED_KEYS_BY_MAJOR[18] gains ui/PageHeaderProps:breadcrumb (entry file entries/retired-keys/18.ui__PageHeaderProps__breadcrumb.ts and the generated region), spelled exactly as the surface baseline row. Right. The pin asserts the family is exactly icon + breadcrumb.
  4. D3 page-header-breadcrumb-retired (entries/semantic/18.page-header-breadcrumb-retired.ts and the generated region): surface without backticks, non-empty reason and acceptanceCriteria, names its D2 id. Right.
  5. STEP18_RATIONALE fragment, order: 51, unique in the table. Right.
  6. Generated artefacts: authorable-surface/ui.json row becomes … [RETIRED]; authorable-defaults/ui.json loses = true; content/docs/references/ui/component.mdx row becomes never / [REMOVED]. Right (the tombstone route: def stays, one [RETIRED] row appears). authorable-surface.base.json:7564 untouched: right — it is the spec 的 #4650 删除闸门在「按 SHA 钉住的消费者构建」里无法锚定 origin/main,硬失败 —— cloud 的镜像构建与 pin bump 全线卡死 #5235 anchor, written only by gen:authorable-surface-base (build-schemas.ts --update-base, "the ONLY mode that writes" it), not a per-PR regeneration; the claim's listing it under "regenerated only" was over-inclusive. api-surface/ui.json unchanged: right (type references, not shapes). content/docs/references/ui/page.mdx untouched: right, it carries no breadcrumb row.
  7. The props lint: rule validateComponentProps is tier: 'advisory', commands: ALL (authoring-rules.ts:1022-1030), and runAuthoringRules is called by validate.ts:461, compile.ts:494 and lint.ts:680, so all three faces warn. The lint pin (validate-component-props.test.ts:81-92) fixes severity warning, path …properties.breadcrumb and the prescription for both values. Right.
  8. nav:breadcrumb KEPT — measured against the objectui tree, not the report. At the pin db11afd4967c and at objectui origin/main 0ffc423b13, git grep nav:breadcrumb -- ':(glob)packages/*/src/**' gives 8 hits at each ref and the control nav:menu 12 files at each. The producer: BLOCK_TYPE_META['nav:breadcrumb'] (previews/block-types.ts:118) feeds TYPES_BY_CATEGORY with no exclusion filter (PALETTE_EXCLUSIONS names only app:launcher, global:notifications, ai:chat_window), the add-block picker's onPick(id) calls addBlock, which pushes { type } into the region (PageBlockCanvas.tsx:358-372). So Studio writes { type: 'nav:breadcrumb' } nodes today. The card's "0 hits" reading is the instrument: a non-magic pathspec packages/*/src is a whole-path fnmatch that must end in /src, so it matches no file, and the same instrument reads 0 for nav:menu. Keeping component.zod.ts:342/:5311, page.zod.ts:159, component.test.ts:1335, format-type.test.ts:1378 and content/docs/ui/pages.mdx:184 untouched: right, per the card's own "with one, the report names it and it stays".
  9. The published skill skills/objectstack-ui/rules/pages.md: the page:header table row drops "breadcrumb +", the os:check definePage example drops breadcrumb: true,. At the head no other breadcrumb remains anywhere under skills/. Right, and inside the scope the ruling 5905149162 (option A) added.
  10. The tree-scoped absence pin: walks packages, examples, skills, content, scripts with exactly the extension set the @objectstack/spec entry in scripts/cross-package-test-inputs.mjs declares (packages/**/*.{ts,mts,cts,js,mjs,cjs,json,md,mdx,yaml,yml}, examples/**/*.{json,md,mdx,yaml,yml}, examples/*/src/**/*.ts, content/**, skills/**, scripts/**), mirrored on @objectstack/spec#test:repo (turbo.json:533). The radius is declared: right. The heldBy witnesses still name only the spec: the rest of the incident-response, training and change-management families — every remaining key and all fifteen defs — has zero readers; whole-def enforce-or-remove is the open question left after #14477 #15513 pin (compliance-families-retirement.test.ts) — one witness per glob suffices, so nothing is owed, but this pin is not registered as a second witness. The whole-directory exclusion packages/spec/src/conversions/ follows the spec: the rest of the incident-response, training and change-management families — every remaining key and all fifteen defs — has zero readers; whole-def enforce-or-remove is the open question left after #14477 #15513 precedent's packages/spec/src/migrations/. The pin is registered in vitest.repo-tests.json, and Test Core runs turbo run test test:repo (ci.yml:725), so CI executed it (green).
  11. component.test.ts re-pinned on recordChrome; the lint fixture's "fully declared props bag" swapped breadcrumb: true for recordChrome: false. Right.

Author-shown and AI-facing sentences tested against the tree, with the moment each is true:

  • (a) component.zod.ts docblock and the conversion docblock, present tense: "PageHeaderRenderer (containers.tsx) reads the key and, when it is not false, draws an EMPTY div[data-page-breadcrumb-slot] in both layouts". True at the pin this repo consumes (db11afd4967c: containers.tsx:1508, :2343-2346, :2379-2380), which main, the merge-base and the head all carry in .objectui-sha. Already false on objectui origin/main since 0ffc423b13 (objectui#11172, committed 2026-09-30T04:56Z, one hour before round 1 was written): the renderer now deliberately does not read the key (containers.tsx:1508-1513). So the sentence is true on main when this PR lands and becomes historical at the next .objectui-sha bump. Over-broad in tense, not false at the head.
  • (b) D3 reason and the conversion docblock: "shows the empty slot's spacing again until the renderer stops drawing it". A durable upgrade-guide sentence whose condition is already met on objectui main. True for a reader on the pinned objectui; moot after the bump. Over-broad in time; harmless.
  • (c) Tombstone, changeset, D3 replacement: "the navigation trail is drawn once, by the app shell's header". AppHeader draws the trail only in its app variant inside /apps/:appName/*; its home and orgs variants draw none (AppHeader.tsx:7-14). Over-broad by one clause for pages outside /apps/*; the D3 reason ("a page outside the shell that needs one is a feature to ask for") and the card body carry that exception, so nothing misleads.
  • (d) Changeset: "The one producer is objectui's Studio page-block inspector ("Show breadcrumb")". block-config.ts:401 at the pin and at objectui main; no other breadcrumb: true|false writer under objectui packages/*/src or apps/** (non-test) at either ref. True at both moments.
  • (e) Changeset: "The one in-repo author found was the published objectstack-ui skill's record-page example. No example app authors it." The measurement is true of 2805a3f033; at the head the skill is fixed and examples/ has 0 hits. True.
  • (f) Conversion docblock: "No example app, skill or doc in this repo authors it." False at 2805a3f033 (the dev said so), true at 70e0f052ff: a sweep of skills/, examples/, apps/ (non-docs), content/docs and docs/ finds no breadcrumb: true|false authoring outside the kit; remaining mentions are the fumadocs BreadcrumbList, the translation label description, the Studio showBreadcrumbs key and prose.
  • (g) Changeset: "os validate / os build / os lint report the key as a warning at properties.breadcrumb". Sourced at item 7. True on main when this lands.
  • (h) Changeset and the RETIRED_KEYS comment: "the true default was never written into a built artifact … only the advisory props lint reads this row". ComponentPropsMap consumers at the head are packages/lint/src/validate-component-props.ts:106 and page-envelope-audit.ts:101, both read-only audits; the page door is the open bag. Sourced and true, so no retired-default residue stage is owed.
  • (i) Changeset: "A typed PageHeaderProps input fails tsc at the key." retiredKey is z.never({ error }).optional() (retired-key.ts:113-115); the pin carries the @ts-expect-error and the file is in the test tsconfig. True.
  • (j) RETIRED_KEYS comment: "Registered under 18, not 17: v17.0.0 was cut before this landed … the ui/ObjectKanbanProps:quickAdd precedent". Spec is at 17.5.0; the quickAdd entry sits under 18 with retiredAfter: '17.4.0'; the tombstone says "removed in @objectstack/spec 17" and prescribes os migrate meta --from 17 (N−1 of toMajor 18), the same wording as the quickAdd tombstone. True.
  • (k) PR body: "That path is governed, so this PR lands Tier H, after an authorized approval." skills/** is a Tier H row (scripts/pm/check-governed-merges.mjs:361); the PR is a draft with no auto-merge. True.
  • (l) Test comment: the walk covers the roots "scripts/cross-package-test-inputs.mjs declares for @objectstack/spec#test (mirrored in turbo.json)". Wrong task name: the root inputs are mirrored on @objectstack/spec#test:repo (turbo.json:533); @objectstack/spec#test (turbo.json:58) carries none. The pin itself lives in the repo project, so the coverage claim holds; only the name in the comment is off.
  • (m) Round-1 report: "8 at objectui origin/main 81f849852a". A stale fetch: objectui main was already 0ffc423b13, four commits past 81f849852a, when the report was written. The nav:breadcrumb count is 8 at 0ffc423b13 too, so nothing in the kit moves; the residue is the tense in (a) and (b).

② Semver level

.changeset/20758-page-header-breadcrumb-retired.md: '@objectstack/spec': minor, BREAKING banner, FROM and TO table, the one-line fix, the retirement-kit paragraph, the NOT MEASURED consumer warning, and the ADR-0087 disposition marker (registered page-header-breadcrumb-removed, page-header-breadcrumb-retired). That matches what the diff publishes: the schema, conversion and migration changes are all inside @objectstack/spec; @objectstack/lint changes are test-only; content/docs and skills/ are not released packages. minor rather than major is the launch-window rule (AGENTS.md §3, the retirement playbook), and Check Changeset (which hosts check-adr-0087-registration and check-changeset-no-major, pr-automation.yml:939-940) is green.

Clause-②: line — no (narrowing) in the PR body and in the changeset body. Well-formed under AGENTS.md:1074-1075 (yes|no plus one arm; (narrowing) is BREAKING). The card's triage wrote yes; the claim 5903804962 overrode it ("a key leaving a published strictObject narrows the accept set and widens nothing"), and the claim fixes scope. Judged right: the diff widens no accept set and adds no export; the new rows in ALL_CONVERSIONS, RETIRED_KEYS_BY_MAJOR[18] and MIGRATIONS_BY_MAJOR[18].semantic are the ADR-0087 disposition itself, exactly as on the quickAdd precedent, and the card's own text names the plain narrowing arm.

③ Boundary flags

Round 1 (5905125466, status: blocked):

  • open_questions[0] (the skill teaches the key; outside the claim; Tier H): answered by ruling 5905149162, option A, and implemented at 70e0f052ff (parent 2805a3f033, no rewrite; stat skills/objectstack-ui/rules/pages.md | 3 +--; trailers name a session only). The absence pin is green in CI.
  • out_of_scope_findings[0] (nav:breadcrumb renders only the placeholder scaffold): outside this repo; placeholders.tsx:86/:133 at the pin agrees; carrier objectui#11166. Stays out of scope.
  • out_of_scope_findings[1] (sdui.manifest.json:2489 still publishes breadcrumb as a page:header input while the props lint warns): escalated with a corrected carrier. The note says the disagreement lasts "until the next .objectui-sha bump (manifest regeneration)". It lasts longer: objectui origin/main 0ffc423b13 still registers the input (containers.tsx:2419, now described "Ignored: … Leave it out.") and keeps the inspector field (block-config.ts:401); objectui's own comment says the entry leaves "once the pin carries the tombstone", that is after this PR releases and objectui bumps its spec pin. Chain: this PR lands, @objectstack/spec releases, objectui bumps its spec pin and drops both, then .objectui-sha bumps here. No gate here reads the manifest against the tombstone, and the props lint is the author door, so this does not block the head.
  • out_of_scope_findings[2] (a stored false regains the empty slot's spacing): already resolved on objectui main by [finding] printMetadataStats has two more rows that say nothing: Runtime: drops at zero plugins, and stats.translations is collected but never rendered at all #11172 (2026-09-30T04:56Z, before round 1); moot at the next .objectui-sha bump. The D3 sentence stays true at the pin (①b).
  • tests: check:dual-build-cjs-loads NOT MEASURED locally → hosted by Build Core (ci.yml:2116), green.
  • deviations: neither report carries the field; the one surface breach (the skill) was raised as an open question and ruled. Nothing further to answer.
  • The report's "PR body … 'Open gap' paragraph is now stale for the seat to revise": the body at review time carries no such paragraph. Revised.

Round 2 (5905304700, status: done): open_questions and out_of_scope_findings empty. Its claims hold (parentage, stat, trailers, pin green, check-governed-merges Tier H, CI reading). One inaccuracy carried from round 1, the stale objectui origin/main sha (①m), without effect on the kit.

Card and claim: the claim's file surface named authorable-surface.base.json:7564 (an anchor, rightly untouched, ①6) and content/docs/references/ui/page.mdx (nothing to regenerate); the nav:breadcrumb rows it listed conditionally stay, per the measurement in ①8. The ruling's Tier H holds on the head: draft PR, label needs:contract-review, no auto-merge, Governed Surface Queue Guard green; an authorized approval is still owed before landing, which is the seat's next step, not this record's.

Check-runs on 70e0f052ff (read last; 46 runs, 35 names, deduped by newest started_at; none queued or in progress): 31 success, 4 skipped, 0 failure. Skipped: Auto Label and Check PR Size (both success at 06:05–06:06Z; the 06:16–06:17Z re-fires skipped), Console Pin Gate (filter output console=false — the diff has no console input), Packed-tarball smoke (opt-in, label-gated). Green and what they carry: Build Core (spec build gates a/b/c, check:dual-build-cjs-loads), Lint & Repo Gates (check:migration-registry, check:cross-package-test-inputs, check:nul-bytes), Type Check · source gates (check:spec-changes, check:upgrade-guide, check:authorable-surface, check:docs, check:generated --reconcile-only), Type Check · consumer gates (check:skill-examples, check:api-surface), Type Check · workspace, Type Check · debt ledger, TypeScript Type Check, Check Changeset (check-adr-0087-registration, check-changeset-no-major), Spec property liveness, Governed Surface Queue Guard, Test Core 1–6 and the Test Core gate (running test test:repo, so the repo-scoped pin ran), Dogfood Regression Gate 1–3 and gate, Dogfood Verify CLI, Temporal Conformance, Build Docs, Check Documentation Links, Flag docs affected by code changes, the two claim guards, the Part-of guard and filter.

Implemented-by: claude/issue-20758-page-header-breadcrumb-retired
Reviewed-by: session_01Sfe5YjBLwB9J3y8fvm2xq1

VERDICT: PASS

Adopted and posted by domain:spec seat 5 (session_01Sfe5YjBLwB9J3y8fvm2xq1) · 2026-09-30T06:48Z · rendered by the seat's at-tier review subagent on this head. The seat read its served tier family from the subagent transcript before posting.

  • The ① sentences named over-broad are kept, with no new head. The record finds none of them false at the head. The present-tense renderer sentences are true at the objectui pin this repo builds against, and objectui#11172 later stopped reading the key on objectui main.
  • ③'s corrected carrier is recorded: sdui.manifest.json:2489 keeps publishing breadcrumb until objectui's own spec pin carries this tombstone. [seam] page:header's breadcrumb ("Show breadcrumb", default true) draws only an empty slot — the declared capability is never honoured objectui#11166 carries that.
  • The claim over-listed authorable-surface.base.json:7564, which is the --update-base anchor, and the record confirms it is rightly untouched.
  • This PR is Tier H (skills/**, check-governed-merges --pr 20785: 1 of 15 paths). The seat does not flip it ready, queue it or arm auto-merge. That waits for an authorized approval on record. needs:contract-review comes off in a separate act, after this record reads back.

Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review September 30, 2026 13:44
@os-zhuang
os-zhuang enabled auto-merge September 30, 2026 13:45
@os-zhuang
os-zhuang added this pull request to the merge queue Sep 30, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

维护者速读 · 2026-09-30T13:46Z

domain:spec seat 5(session_01Sfe5YjBLwB9J3y8fvm2xq1)。这是终稿,由本席对照自己读过的 diff(merge base 起 15 个文件,+775/−12)写成。审核记录是达档复核 PASS 5905749848。

改了什么

  • 页面头组件 page:header 的「显示面包屑」开关 PageHeaderProps.breadcrumb 退役。新写这个键,编译期和解析期都会报错,并附处方:删掉这个键,壳层的导航轨迹不受影响。
  • 已存的页面不会被拒。加载时由 D2 转换 page-header-breadcrumb-removed 去掉这个键并给出提示;props 检查只报 warning。
  • 受管的技能文档 skills/objectstack-ui/rules/pages.md 改了两处,不再教这个键:表格里 page:header 那一行去掉 breadcrumb,示例删掉 breadcrumb: true。本 PR 因此是 Tier H。
  • 独立的面包屑组件 nav:breadcrumb 保留,因为 objectui 的 Studio 组件面板会写它。
  • @objectstack/spec 为 minor,带 BREAKING 标题。

为什么改
objectui 从来没有按这个开关画过面包屑:页面上只有一个空位,没有任何东西去填。导航轨迹由应用壳的页头统一画一次。开关写了不起作用,AI 作者照技能文档写,结果什么也不发生。

风险与代价(含回滚)

  • 代码里写了这个键的作者会在 tsc 和解析时收到带处方的报错;已存的页面照常加载。
  • 回滚办法:revert 本 PR 的合并提交,技能文档的两处也随之恢复。

席位意见
建议批准。复核 PASS,且技能文档两处都是删减,没有新增教学内容。

你要做的
在本 PR 上给一个 APPROVED 审阅,由你或授权账户 os-zhuang / hotlong 之一给出。本席随后做落地前检查,转 ready 并入合并队列。


Generated by Claude Code

Merged via the queue into main with commit f10d802 Sep 30, 2026
58 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-20758-page-header-breadcrumb-retired branch September 30, 2026 14:06
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/l tests tooling

Projects

None yet

3 participants