Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

finding: ThemeSwitcherSchema / ThemePreviewSchema are the same dead component kind #5489 retires — theme-switcher and theme-preview are registered by nothing either #5647

Closed

Description

@os-sales

Found while executing #5489 (retire ThemeComponentSchema, type: 'theme'). Filed unassigned, out of that card's scope — the 2026-08-21 maintainer ruling named the themes carrier and its schema, not these two siblings, so widening #5489 to cover them would have been an undeclared scope expansion.

Measurement

The same sweep that proved 'theme' unregistered proves the same for both siblings. Enumerating every registered component key in non-dist package sources:

grep -rhoE "ComponentRegistry\.(register|registerLazy)\(\s*'[a-z0-9-]+'" \
  --include='*.ts' --include='*.tsx' packages/*/src | sed -E "s/.*'([a-z0-9-]+)'/\1/" | sort -u
  • theme-switcher → 0 hits · theme-preview → 0 hits
  • positive control on the same pipeline: tooltip → 1 hit (so the command can match)
  • neither appears in PROTOCOL_COMPONENTS / PALETTE_PLACEHOLDER_BLOCKS (packages/components/src/renderers/placeholders.tsx), so not even a placeholder renders them
  • no fixture anywhere declares them: grep -rn '"type": *"theme-switcher"' and the -preview twin → 0, control "type": "form" → 98

So a page declaring either gets the registry's "Unknown component type" panel (OBJUI-001), never a switcher or a preview — the identical declared-but-unenforced shape #5489 measured for 'theme'.

Declaration sites

  • packages/types/src/theme.ts — ThemeSwitcherSchema, ThemePreviewSchema (TS interfaces)
  • packages/types/src/zod/theme.zod.ts — the two Zod objects, both members of ThemeUnionSchema, plus ThemeSwitcherSchemaType / ThemePreviewSchemaType
  • exported from packages/types/src/index.ts and packages/types/src/zod/index.zod.ts
  • packages/types/src/__tests__/phase2-schemas.test.ts asserts ThemeSwitcherSchema.safeParse succeeds — a test that pins the declaration, not any behaviour

After #5489 lands, ThemeUnionSchema consists of exactly these two unimplemented kinds, so the union itself becomes a candidate for removal if they go.

Not a decision this card can take

Retiring them removes declared types from the published @object-ui/types, and — unlike #5489 — no maintainer ruling covers them. Needs triage: either a ruling extending 2026-08-21's option B to the two siblings, or a decision to implement renderers.

Activity

  1. added
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    on Aug 22, 2026
  2. huangyiirene commented on Aug 22, 2026

    @huangyiirene
    Collaborator

    Concentration-round first-touch (triage seat): promoted finding → pm:queue, Task — by inheritance of the 2026-08-21 maintainer ruling (option B) on the parent case, per the standing same-family default: a sibling branch already adjudicated on identical evidence extends to the new branch unless a real semantic difference shows, and none does here — same sweep, same zero registrations, same zero fixtures, same declaration-only pin, measured with the same positive-control method. The inherited reason ("declared component kind with no renderer is the ADR-0049 shape to retire") transfers intact.

    Scope: retire ThemeSwitcherSchema / ThemePreviewSchema (interfaces + zod + exports + the declaration-pinning test), and — since after #5489 the union holds only these two — retire ThemeUnionSchema in the same change, with the standard changeset/breaking discipline for @object-ui/types. Sequencing: after #5489 lands (its diff defines the worked example and touches adjacent lines). This inheritance is recorded in the round report's reuse list for the maintainer's veto window — a veto reopens it as a decision card, nothing else moves.


    Generated by Claude Code

  3. self-assigned this
    on Aug 23, 2026
  4. os-zhuang commented on Aug 23, 2026

    @os-zhuang
    Contributor

    Claim — domain:ui execution seat. PM round 28, session session_01EuPCi56cnGyykygi3z9w4m, branch claude/issue-5647-retire-theme-switcher-preview. Dispatching at contract-review tier (clause ②: the change narrows the published @object-ui/types surface).

    Sequencing precondition verified: the triage promotion (comment 5380592857) sequences this card after #5489 lands. #5489 is closed completed 2026-08-22T01:09:09Z via merged PR #5650 — satisfied, so the worked example this card inherits its shape from is on main and can be read there.

    Executing the scope the triage seat recorded, unchanged: retire ThemeSwitcherSchema / ThemePreviewSchema (TS interfaces in packages/types/src/theme.ts, the two Zod objects and their …SchemaType aliases in packages/types/src/zod/theme.zod.ts, the barrel exports in packages/types/src/index.ts and packages/types/src/zod/index.zod.ts, and the declaration-pinning assertion in packages/types/src/__tests__/phase2-schemas.test.ts), and ThemeUnionSchema in the same change — after #5489 the union holds only these two members, so leaving it would be a union over nothing.

    The authority is inherited, not fresh: the 2026-08-21 maintainer ruling (option B) on the parent case, extended to these siblings on identical evidence per the same-family default, and recorded in the round report's reuse list for the maintainer's veto window. ⛔ The dev does not re-adjudicate whether these should be retired — that is settled; it establishes only that the evidence still holds on current main (zero registrations, zero fixtures, zero in-repo consumers) and reports if it does not.

    ⛔ Do not touch ThemeEngine or ThemeContext — #5489's ruling explicitly retains the theme engine and the spec-aware provider, and that carries here. This is the component-kind declaration only.

    ⚠️ Removing declared types from a published package is breaking for @object-ui/types: the changeset discipline #5650 used is the worked example — follow it, and read what it actually did rather than inferring.


    Generated by Claude Code

  5. claude commented on Aug 23, 2026

    @claude
    Contributor
    {
      "issue": 5647,
      "status": "done",
      "branch": "claude/issue-5647-retire-theme-switcher-preview",
      "pr": "https://github.com/objectstack-ai/objectui/pull/5823",
      "premise_still_valid": true,
      "summary": "Retired ThemeSwitcherSchema / ThemePreviewSchema (interfaces, Zod objects, SchemaType aliases, barrel exports) and ThemeUnionSchema, per the inherited 2026-08-21 option-B ruling; the declaration-pinning acceptance test is converted to refusal pins with a live-kind positive control, following PR #5650's worked example. Evidence re-verified on current main before removal: theme-switcher -> 0 and theme-preview -> 0 registrations (202 keys, control tooltip -> 1), zero placeholders, zero fixtures (control \"type\":\"form\" -> 81), zero in-repo identifier consumers outside packages/types, zero AnyComponentSchema importers. zod/theme.zod.ts is kept as an export-less tombstone module because spec-subschema-parity.test.ts dynamic-imports it to pin retired names out of its namespace. ThemeEngine / ThemeContext untouched. Note: GitHub GraphQL quota for the shared identity was exhausted mid-run; report + finding delivered via repo-scoped REST.",
      "tests": "All at 96ebb731f (PR head, tree clean). pnpm --filter @object-ui/types build: exit 0; type-check (3 tsconfigs): exit 0; pnpm exec vitest run packages/types/ from repo root: 46 files / 514 tests passed. Consumer compile, downstream direction: the 4 packages importing @object-ui/types/zod (cli, plugin-view, plugin-map, plugin-list) type-checked green via turbo (19/19 tasks incl. their 15-package dep closure: core, components, react); remaining ~35 dependents declared to CI on the measured basis that zero external references to the removed names exist. Reverse verification (fix committed first): dist probe importing the 3 removed names -> TS2724/TS2305 on exactly those 3, control probe (Theme/ThemeMode/validateSchema) -> exit 0. Ablation with restore trap: re-added a theme-switcher member to AnyComponentSchema in src; mutation confirmed on disk (MUTATION5647 marker grep 0->1); NO build leg run and none needed — the test imports ../zod/index.zod source-relative; run -> exactly the retirement pin red (1 failed / 29 passed, direction as predicted); restored via git checkout, marker grep -> 0, re-run 30/30 green. Gates at same sha: check-changeset-presence OK ('declares 1 changeset(s)'), check-changeset-no-major OK ('No changeset declares a major bump'), check-control-bytes OK ('scanned 4844 tracked text file(s)'), check-doc-component-types OK ('Every documented component type is registered'). Declared narrowing: check-doc-snippet-types NOT run locally (refuses without 8 more built packages incl. app-shell; CI owns it) — population is the content/ snippet corpus, removed names in content/ -> 0 (control AppComponentSchema -> 2 files), and this diff touches nothing under content/. Package eslint exit 0, 0 errors; the 9 unused-import warnings in the test file pre-exist (baseline 10, diff removes 1, adds 0) — filed as #5824.",
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #5824: phase2-schemas.test.ts imports 9 schemas no test uses — pre-existing no-unused-vars warnings overstate the file's pin coverage"
      ]
    }

    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:queue

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions