Skip to content

feat(spec): retire the themes carrier key and ThemeSchema — app.branding is the one colour surface (#10485, ADR-0049) - #10695

Queued
os-elon wants to merge 6 commits into
mainfrom
claude/issue-10485-retire-themes-carrier
Queued

feat(spec): retire the themes carrier key and ThemeSchema — app.branding is the one colour surface (#10485, ADR-0049)#10695
os-elon wants to merge 6 commits into
mainfrom
claude/issue-10485-retire-themes-carrier

Conversation

@os-elon

Copy link
Copy Markdown
Collaborator

Fixes#10485

What this is

ADR-0049 enforce-or-remove retirement of the defineStack({ themes }) carrier key and the ThemeSchema authoring surface, per the maintainer ruling recorded on the issue (2026-08-21, verbatim, untranslated):

B:退役授权面 — 收掉 themes 载体键与 schema,app.branding 留作唯一颜色面;objectui 引擎代码与单测保留。

The measured defect: authored themes were parsed strictly, ingested and stored — and then read by nothing. No framework package consumed .themes or stored theme items, theme was never a registered metadata type, no first-party app mounted the spec-aware provider, and nothing selected an active theme. Every gate was green and the console never changed. Clause-②: this PR removes previously-accepted themes declarations from the acceptance set (contract-review tier; not queued by the implementing seat).

Removal shape (per the spec-property-retirement playbook)

Pin tests

  • stack-top-level-strict.test.ts — a stack declaring themes (a body that parsed green on 17.0) is refused at the key with unrecognized_keys at the root path, message carrying #10485 + app.branding + primaryColor, and no "Did you mean" rename; positive control: the prescribed app.branding replacement parses green; no theme export survives on ./ui (with anti-vacuity probe).
  • protocol.unrecognised-meta-type.test.tsPUT /meta/theme refused with { code: 'INVALID_REQUEST', status: 400 } and zero rows stored; the ACCEPTED-side specimen for "URL-map-only plugin kind" moved themewebhook (fixture triage: the class survives, the specimen retired).
  • metadata-url-spelling.test.tstheme/themes refused by name; the five surviving plugin kinds pinned by name.
  • protocol.meta-types-mint-door-agreement.test.tstheme reclassified from class 2 (url-map-only, creatable) to class 3 (withdrawn: advertised false, mint refused), with webhook taking the end-to-end write slot.

Docs

content/docs/ui/theming.mdx never shipped (withheld from PR #10483 per the correction on the issue) — nothing to delete or redirect. This PR makes app.branding the one documented colour surface: widget-contract.mdx's Theme section now teaches app.branding (and the still-true token facts — bare-HSL-triple values, base-stylesheet-owned shadcn token set — were salvaged into react-pages.mdx, the optional half of the correction). Getting-started/ui index prose scrubbed; references/ui/theme.mdx deleted by gen:docs.

skills/** touch — line readouts (clause-mandated)

filebeforeafter
skills/objectstack-platform/SKILL.md12861286 (one inline key name removed; no line delta)
skills/objectstack-ui/references/_index.md (generated by gen:skill-refs)5756
whole package skills/objectstack-platform (all .md)26342634
whole package skills/objectstack-ui (all .md)22972296

Net shrink; no expansion. ⚠️skills/** is a governed surface (Prime Directive #14): human merge only — do not queue, arm, or flip out of draft.

File-surface note (declared expansion over the claim comment)

The claimed surface named stack.zod.ts, theme.zod.ts + ui barrel, the ingest row, ADR-0087 registry, changeset, pin tests and docs pointers. The retirement's measured consumer sweep additionally required: shared/metadata-collection.zod.ts (map rows), kernel/metadata-type-schemas.ts (door binding), meta-spelling/* (contract prose + regenerated data), cli stats/explain rows, examples/app-showcase (config + theme sources + coverage/tour prose), scripts/check-stack-collection-maps.mjs (waiver rows in both directions), four metadata-protocol/objectql/rest/runtime protocol-test retriages, qa/downstream-contract fixture row, type-alias-convention.pin.test.ts (Iso700–704 + count 839→834), PROTOCOL_MAP.md, the strictness-ledger row (converted to a retirement paragraph, the notification.zod.ts precedent), skills/objectstack-platform/SKILL.md, and the generated baselines (authorable-surface −57 rows / manifest −6 defs / api-surface / export-origins / spec-changes / upgrade-guide / strictness-ledger counts / meta-url-spelling / reference docs / skill refs). All are the same removal; no new verification surface. packages/spec/src/contracts/metadata-service.ts (H17 trigger of hold #8722) is not touched.

Out of scope, filed

Verification

Consumer-suite readouts below were measured at 2db934d61; origin/main was then merged (PRs #10643/#10644ui/i18n.zod.ts / data/object.zod.ts, verified disjoint from this diff: git diff origin/main...HEAD on those two paths is empty) via the scripts/pm/os-regen-merge.sh discipline (merge committed first, artifacts regenerated on the merged tree). Final union at head 846b572aa (worktree clean): check:generated✓ All 14 generated artifacts are up to date and the full spec suite → Test Files 415 passed (415) · Tests 11049 passed (11049), plus the light-gate set re-run green at the same head (stack-collection-maps, changeset trio + adr-0087-registration, skills-token-ratchet, nul-bytes, merge-driver, affected-docs, cross-package-test-inputs). Each verdict line quoted is the gate's own printed verdict; exit codes captured before any pipe.

Tests — every package whose tests/fixtures referenced themes/ThemeSchema/defineTheme, full suites, direction: downstream consumers of @objectstack/spec (built from the rebuilt dist):

packagereadout
@objectstack/specTest Files 415 passed (415) · Tests 11049 passed (11049) (final head)
@objectstack/metadataTest Files 31 passed (31) · Tests 609 passed (609)
@objectstack/metadata-protocolTest Files 127 passed, 2 skipped (129) · Tests 1741 passed, 10 skipped (1751)
@objectstack/downstream-contractTest Files 2 passed (2) · Tests 19 passed (19)
@objectstack/objectqlTest Files 225 passed (225) · Tests 3984 passed (3984)
@objectstack/cliTest Files 139 passed (139) · Tests 1547 passed (1547)
@objectstack/restTest Files 132 passed (132)
@objectstack/runtimeTest Files 178 passed (178)

Reverse verification (measured direction, not assumed): the consumer suites were run against the rebuilt spec dist BEFORE retriage — theme saves that previously pinned success: true failed with the exact new verdict (Error: [invalid_request] 'theme' is not a metadata type … at refuseUnmintableMetaType), i.e. the retirement reached consumers through the built contract, not through test edits; the pins were then retriaged to record the new contract (specimen swaps themewebhook, plus new #10485 refusal pins). Direction observed: new refusals appeared where acceptance was pinned — diagnostics increased, the expected direction for an accept-set narrowing.

Typecheck:@objectstack/spec (with check:test-typecheck ✓ after removing the Iso700–704 pins), cli, objectql, rest, runtime, downstream-contract, @objectstack/example-showcase — all tsc --noEmit clean after building each dependency closure.

Gates:check:generated green across all 14 artifacts (authorable-surface/manifest deletions self-proved: 6 schema(s) left the published set … each declared (#4725), 5 baseline deletion(s) … carry their own proof (#4650)) · check:stack-collection-maps ✓ (7 enumerations reconciled against 31 declared collections) · check:variant-docs ✓ (18 discriminated union(s) — 8 governed, 10 exempt) · check:liveness ✓ · check:empty-state ✓ · check:strictness-ledger ✓ (row → retirement paragraph; counts regenerated) · check:doc-formula-expressions ✓ · check:durability-log-level ✓ · check:slot-lookup ✓ · check:spec-parsed-alias ✓ · check:test-source-alias ✓ · check:type-source-resolution ✓ · check:merge-driver ✓ · check:cross-package-test-inputs ✓ · docs-audit/check-affected-docs ✓ · check:nul-bytes ✓ · changeset trio (no-major, empty, adr-0087-registration) ✓ · check:skills-token-ratchet ✓ · check:engine-double-contract ✓ · check:where-matcher ✓ · check:query-options-erasure ✓ · check:type-check-coverage ✓ · check:type-check-debt ✓ after full workspace build (lock VERDICT command-exit 0).

Gate list re-derived from the actual diff with node scripts/pm/dispatch-gates.mjs (no paths — merge-base derivation); it added the changeset trio, check:skills-token-ratchet, check-affected-docs, and the test-convention family (query-options-erasure, type-check-coverage, type-check-debt, engine-double-contract, where-matcher) beyond the dispatch list — all run, readouts above.

Generated by Claude Code


Generated by Claude Code

…R-0049)
Ruled B (退役授权面, 2026-08-21): strict-delete the stack themes key with a
guidance prescription, delete ui/theme.zod.ts whole, drop the ingest mapping
and the PLURAL_TO_SINGULAR fold (so /meta/theme gets the #8421 refusal),
register six retired-def entries and the D3 semantic entry
stack-themes-carrier-retired, pin the refusal, re-base docs and the showcase
on app.branding.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B4h3medzvhB9rpfoja9jcw
Specimen swaps (theme -> webhook) in metadata-protocol, objectql, rest and
runtime meta-door tests; new #10485 refusal pins; stack-collection-maps
waivers updated; PROTOCOL_MAP row removed; Iso pin count 839 -> 834.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B4h3medzvhB9rpfoja9jcw
…nt paragraph (#10485)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B4h3medzvhB9rpfoja9jcw
…tire-themes-carrier
# Conflicts:
#	content/docs/ui/index.mdx
@github-actions

github-actionsBot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 4 package(s): @objectstack/cli, @objectstack/metadata, @objectstack/downstream-contract, @objectstack/spec, touching 40 documentable anchor(s).

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

  • content/docs/api/environment-routing.mdx(via ObjectStackDefinitionSchema (symbol))
  • content/docs/automation/hook-bodies.mdx(via ObjectStackDefinitionSchema (symbol))
  • content/docs/concepts/north-star.mdx(via ObjectStackDefinitionSchema (symbol))
  • content/docs/deployment/cli.mdx(via ObjectStackDefinitionSchema (symbol))
  • content/docs/ui/react-pages.mdx(via borderRadius (literal))

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

  • content/docs/releases/v12.mdx(via ObjectStackDefinitionSchema (symbol))
  • content/docs/releases/v16.mdx(via os explain (command))
  • content/docs/releases/v17.mdx(via ObjectStackDefinitionSchema (symbol))

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
  • 18 changed file(s) yielded no anchor (packages/spec/PROTOCOL_MAP.md, packages/spec/api-surface-signatures.json, packages/spec/api-surface/root.json, …) — pages documenting those are invisible to this run
  • 23 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 45 of 221 client-bound route-ledger rows — the other 176 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run: node scripts/docs-audit/affected-docs.mjs --bridge-coverage

Coarse fallback — 135 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 5f2e54cc66330cbc53a17f6e3746acdfcdc14704packageMentionDocs.

Which tree this was computed on

This run read content/docs from e8f5c35fb09c0fb479c101c9eef7ad74eb860128 — the merge of head 90dc771f2593e1d32d73397e587b95371230ba13 into base 5f2e54cc66330cbc53a17f6e3746acdfcdc14704, 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 e8f5c35fb09c0fb479c101c9eef7ad74eb860128 && git checkout e8f5c35fb09c0fb479c101c9eef7ad74eb860128
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 5f2e54cc66330cbc53a17f6e3746acdfcdc14704 90dc771f2593e1d32d73397e587b95371230ba13 && git checkout -B drift-repro 5f2e54cc66330cbc53a17f6e3746acdfcdc14704 && git merge --no-ff 90dc771f2593e1d32d73397e587b95371230ba13
node scripts/docs-audit/affected-docs.mjs --json 5f2e54cc66330cbc53a17f6e3746acdfcdc14704

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

…section (10 of 16) (#10485)
check:quick-reference-counts [row]+[total] remedies: references/ui/theme.mdx
was deleted with the retired surface, so the row goes (retired, not moved)
and M drops 17 -> 16, N 11 -> 10.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01B4h3medzvhB9rpfoja9jcw
@os-zhuang
os-zhuang marked this pull request as ready for review August 21, 2026 13:16
@os-zhuang
os-zhuang enabled auto-merge August 21, 2026 13:16
@os-zhuang
os-zhuang added this pull request to the merge queueAug 21, 2026
Any commits made after this event will not be merged.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationprotocol:uisize/xlteststooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

defineStack({ themes }) is parsed, ingested and never applied — the last hop from a stored theme item to the theme engine does not exist

3 participants

@os-elon@os-zhuang@claude