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.

Remove/localize the six dangling @objectstack/spec/ui theme-schema imports in packages/types/src/zod/theme.zod.ts — the ruled FIRST leg of unbreaking objectstack's Console Pin Gate #5710

Closed

Description

@os-zhuang

Filed by the skills seat (session session_01MsbKEG4LtERSLaDrbehM3e, 2026-08-22) executing the maintainer's recorded ruling on objectstack-ai/objectstack#10856 — this is the missing first leg of that ruling, uncarded until now, which is why the repair has been stalled since the ruling landed this morning.

The ruling (recorded on objectstack#10856, 2026-08-22, decision-inbox digest, accepted verbatim 「接受所有」)

Ruled: Options A + C. A fixes the instance: the objectui side goes first — objectui removes/localizes the six dangling @objectstack/spec/ui theme-schema imports in packages/types/src/zod/theme.zod.ts (the ordering is forced, since objectui's tip carries the same dangling import as the pin), and only then does objectstack bump the Console pin past it. Option B (restoring the six retired exports as a compatibility surface) is not taken.

The defect this leg repairs

objectstack PR #10695 (2026-08-21, ADR-0049 ruled retirement, card objectstack#10485) deleted ThemeSchema / ColorPaletteSchema / TypographySchema / BorderRadiusSchema / ShadowSchema / ThemeModeSchema from @objectstack/spec/ui. objectui's packages/types/src/zod/theme.zod.ts still imports all six — measured on origin/main 0b1326d today (lines 24–25 for Shadow/ThemeMode; the import block starts ~line 20). Consequence: objectstack's Console Pin Gate cannot build the vendored SPA against the current framework tree — red on every objectstack merge-queue build (non-blocking, but ~89 red queue builds/24h and a triage channel full of identical false alarms; the count is on objectstack#10856).

Scope

  • Remove the six imports and either delete the re-exports or localize the schema definitions into @object-ui/types (the file's own comment at ~line 81 says which are retained on purpose — honour it; the maintainer's original retirement ruling kept objectui's ThemeEngine/ThemeContext intact, so localizing is the expected shape where an engine consumer still needs the shape).
  • Downstream consumers of the re-exported names inside objectui keep compiling — measure the consumer set before choosing delete vs localize per name.
  • ⛔ Do not touch the spec side; restoring exports was explicitly rejected.

Downstream

objectstack#10856 (pm:blocked on this card) executes the pin bump once this lands on objectui main. The class-level rule (a pin-breaking removal ships with its pin bump) is objectstack#10986, separately queued.

Refs: objectstack#10856 (the ruled card, full measurement history) · objectstack PR #10695 (the retirement) · objectui #5489/#5650 (the component-kind retirement — related, deliberately different symbols).

Activity

  1. added
    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seat
    and removed on Aug 22, 2026
  2. self-assigned this
    on Aug 22, 2026
  3. os-zhuang commented on Aug 22, 2026

    @os-zhuang
    ContributorAuthor

    Claim: PM loop round 17
    Session: session_01EuPCi56cnGyykygi3z9w4m
    Branch: claude/issue-5710-theme-zod-dangling-imports
    Worktree: objectui-issue-5710
    Domain: domain:ui
    File surface: packages/types/src/zod/theme.zod.ts, packages/types/src/zod/index.zod.ts, packages/types/src/theme.ts, packages/providers/src/types.ts and the parity tests under packages/types/src/__tests__/ + packages/providers/src/__tests__/ (stop on breach; explain in the report)
    Container & model: M, mode:subagent, model: claude-fable-5
    Clause-②: yes
    Serial constraints cleared: no in-flight card shares this surface. Round-17 siblings are fenced disjoint — #5619 (packages/auth + packages/app-shell/src/console/** + apps/console) and #5637 (packages/components/src/renderers/basic/record-picker.tsx). ⛔ packages/app-shell/src/chrome/ThemeProvider.tsx:3 mentions ThemeModeSchema in prose only and is fenced OUT of this card (it is also inside #5619's package). PR #5400 (changeset-release/main, Version Packages) is never touched. Predecessor on this surface, 78cbdb5 (#5489/#5650, ThemeComponentSchema retirement), is merged.

    Tier basis. node scripts/pm/dispatch-gates.mjs --tier packages/types/src/zod/theme.zod.ts packages/types/src/theme.ts packages/providers/src/types.ts — run at dispatch, not recalled — returns "no path-derived mandate … the tier stays the PM's per-card judgment call (floor sonnet · default opus · ceiling fable). Clause ② is NOT reachable from paths … judged from the card CONTENT." Judged from content: this card sits on the spec-mirroring surface (theme.zod.ts re-exports @objectstack/spec/ui zod validators by reference), so clause ② is declared yes and the card is dispatched at CONTRACT_REVIEW_TIER (claude-fable-5, scripts/pm/dispatch-gates.mjs:2722) rather than below it. Maintainer authorization for this seat to dispatch above its own served tier, quoted verbatim, 2026-08-22: 「你虽然是 opus,但是可以派 fable 的卡」. No needs:contract-review compensating label is attached because none is owed at-tier — and for the record it does not exist in this repo (scripts/pm/ensure-pm-labels.sh:238 creates it for objectstack-ai/objectstack only).

    Premise re-verified before dispatch, on origin/main (not the shared worktree).

    • objectui origin/main = 7138bc1. All six imports present in packages/types/src/zod/theme.zod.ts (import block lines ~21–29). Card's measurement stands.
    • objectstack origin/main = 95437e7. All six names return 0 export matches under packages/spec/src/ui/; control (PageSchema, FormViewSchema) returns live hits at page.zod.ts:410 / view.zod.ts:2394. The retirement is real and the zero is not a broken grep.

    ⚠️ One measured fact the card does not carry — the named file is not the whole dangling set. packages/providers imports ThemeModeSchema directly from @objectstack/spec/ui at src/types.ts:2 (feeding ThemePreference at :39) and in two tests (__tests__/spec-symbol-batch7.test.ts:28-29, __tests__/theme-mode-spec-parity.test.tsx:21). Against the framework tree those dangle for exactly the same reason. Treat this as a PM mechanism assumption, not a finding to accept on my word — re-measure it, and see the dispatch brief for how the ruling's observable requirement (a green Console Pin Gate) governs whether they are in scope.


    Generated by Claude Code

  4. os-zhuang commented on Aug 22, 2026

    @os-zhuang
    ContributorAuthor
    {
      "issue": 5710,
      "status": "done",
      "branch": "claude/issue-5710-theme-zod-dangling-imports",
      "pr": "https://github.com/objectstack-ai/objectui/pull/5713",
      "premise_still_valid": true,
      "summary": "Executed the REMOVE branch of the objectstack#10856 ruling at head 64e469a: the six spec imports, six re-exports and their SchemaType helpers deleted from zod/theme.zod.ts; barrel, theme.ts interface members and three parity tests repointed; changeset (minor) added. Zone 2b conditional stop did NOT fire — measurement collapsed the fork: no engine/provider code consumes the runtime validators (they consume the Theme/ThemePreference TYPES via the 17.1.0 pin), so nothing forces localizing a schema body. PM corrections: (1) Zone 2.2's 'only non-test runtime consumers are re-exports/theme.ts/providers-typeof' missed two — ThemePreviewSchema.theme/.mode at theme.zod.ts:101-102 consumed ThemeDefinitionSchema/ThemeModeSchema at runtime; both props dropped (BaseSchema is .passthrough(), so the keys now pass through unvalidated on a kind nothing renders; the kind's fate stays with open #5647 — flagged for PM review as the one consequential judgment call in this PR). (2) The retirement is bigger than the card: the spec deleted ui/theme.zod.ts WHOLE, types included, so theme.ts's six export-type re-exports also dangle against the tree — deliberately untouched (gate-invisible, un-ruled), filed as #5716. (3) Zone 2.2 providers question answered: src/types.ts:2 is import type (erased at tsc emit — cannot redden the gate) and the two test files are outside every bundle graph; providers left wholly untouched and coherent on the pin; the batch7 test self-declares spec-retirement a re-triage tripwire. Gate mechanism measured from objectstack ci.yml + build-console.sh: deps tsc builds resolve objectui's OWN lockfile pin (green regardless), redness comes only from named VALUE imports of retired names in the console SPA vite build where OBJECTSTACK_SPEC_DIST aliases the framework spec — after this PR that set is empty. Assumption #1 confirmed: six names 0 exports on objectstack 95437e7, controls PageSchema/FormViewSchema live. Card body complete (ends with the Refs: line naming objectstack#10856, PR #10695, objectui #5489/#5650).",
      "tests": "All at 64e469a under the container verify lock (os-verify-lock VERDICT 'command-exit 0 · held 40s · waited 18s'): pnpm --filter @object-ui/types build (tsc) && type-check (3 tsconfigs) && lint (0 errors, 251 pre-existing warnings) && pnpm exec vitest run packages/types/ => 43 files / 474 tests passed. Gate instrument: AST sweep of packages/**+apps/** sources for value-level imports of the six from @objectstack/spec/ui — 6 (theme.zod.ts) + 1 (p2-spec-exports.test.ts) before, 0 after (2 remaining hits are providers __tests__ files, outside every bundle graph, deliberately left per #5716); built dist/zod/theme.zod.js imports only zod and ./base.zod.js, six names present in dist only inside comments. Reverse verification of the new retirement pin (no build leg needed — the test imports ../zod/theme.zod.js relative from source, no dist in the resolution path): trap-guarded mutation re-adding ThemeModeSchema as a local z.enum, mutation confirmed on disk (marker grep count 1) BEFORE the run => spec-subschema-parity.test.ts RED, 1 failed / 13 passed, exit 1, on exactly that name; trap restore confirmed on disk (marker count 0, git status clean) => rerun GREEN 14/14. Direction as predicted (red on mutation). Declared narrowing: full-farm type-check/test/lint not run locally — repo-wide grep shows zero consumers of the six outside packages/types, so the package-scoped run is the superset for this diff; CI runs the farm regardless.",
      "gates": "check:spec-symbols ✅ ('1294 files scanned against 4966 spec export names') · check:phantom-deps ✅ ('Every in-scope import is declared') · check:esm-specifiers ✅ · check:control-bytes ✅ ('4765 tracked text files') · check:self-import ✅ · check:action-forward-parity exit 0 · check-changeset-presence ✅ ('1 changeset(s) added') · check-changeset-fixed ✅ · check-changeset-no-major ✅ · package lint/type-check/test/build green as above. All exit codes captured before any pipe; verdicts quoted from the gates' own output. dispatch-gates.mjs NOT used (per dispatch: wrong tree for this card); derived from objectui's .github/workflows/{ci,lint}.yml against the real diff.",
      "files_changed": ["packages/types/src/zod/theme.zod.ts", "packages/types/src/zod/index.zod.ts", "packages/types/src/theme.ts", "packages/types/src/__tests__/spec-subschema-parity.test.ts", "packages/types/src/__tests__/phase2-schemas.test.ts", "packages/types/src/__tests__/p2-spec-exports.test.ts", ".changeset/theme-zod-retired-spec-reexports.md"],
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #5715: app-shell clientValidation.ts:590 reads (await import('@objectstack/spec/ui')).ThemeSchema at runtime — dangling against the tree, invisible to the pin gate (namespace property access, deps compile against the pin), currently unreachable (theme not a registered metadata type); app-shell was hard out-of-fence",
        "filed as #5716: the theme TYPE surface (theme.ts's six export-type re-exports, providers ThemePreference derivation, two providers value-import tests, index.ts export type * as UI) still derives from the retired spec module — compiles only on the 17.1.0 pin; blocks any objectui spec-pin refresh past the retirement; localize-vs-shrink needs a ruling"
      ]
    }

    Generated by Claude Code


    Generated by Claude Code

  5. os-zhuang commented on Aug 22, 2026

    @os-zhuang
    ContributorAuthor

    os-dev-report

    (Supersedes the previous comment — the sanitizer ate its HTML-comment marker on write, verified by read-back; this copy leads with the literal marker text. Same JSON.)

    {
      "issue": 5710,
      "status": "done",
      "branch": "claude/issue-5710-theme-zod-dangling-imports",
      "pr": "https://github.com/objectstack-ai/objectui/pull/5713",
      "premise_still_valid": true,
      "summary": "Executed the REMOVE branch of the objectstack#10856 ruling at head 64e469a: the six spec imports, six re-exports and their SchemaType helpers deleted from zod/theme.zod.ts; barrel, theme.ts interface members and three parity tests repointed; changeset (minor) added. Zone 2b conditional stop did NOT fire — measurement collapsed the fork: no engine/provider code consumes the runtime validators (they consume the Theme/ThemePreference TYPES via the 17.1.0 pin), so nothing forces localizing a schema body. PM corrections: (1) Zone 2.2's 'only non-test runtime consumers are re-exports/theme.ts/providers-typeof' missed two — ThemePreviewSchema.theme/.mode at theme.zod.ts:101-102 consumed ThemeDefinitionSchema/ThemeModeSchema at runtime; both props dropped (BaseSchema is .passthrough(), so the keys now pass through unvalidated on a kind nothing renders; the kind's fate stays with open #5647 — flagged for PM review as the one consequential judgment call in this PR). (2) The retirement is bigger than the card: the spec deleted ui/theme.zod.ts WHOLE, types included, so theme.ts's six export-type re-exports also dangle against the tree — deliberately untouched (gate-invisible, un-ruled), filed as #5716. (3) Zone 2.2 providers question answered: src/types.ts:2 is import type (erased at tsc emit — cannot redden the gate) and the two test files are outside every bundle graph; providers left wholly untouched and coherent on the pin; the batch7 test self-declares spec-retirement a re-triage tripwire. Gate mechanism measured from objectstack ci.yml + build-console.sh: deps tsc builds resolve objectui's OWN lockfile pin (green regardless), redness comes only from named VALUE imports of retired names in the console SPA vite build where OBJECTSTACK_SPEC_DIST aliases the framework spec — after this PR that set is empty. Assumption #1 confirmed: six names 0 exports on objectstack 95437e7, controls PageSchema/FormViewSchema live. Card body complete (ends with the Refs: line naming objectstack#10856, PR #10695, objectui #5489/#5650).",
      "tests": "All at 64e469a under the container verify lock (os-verify-lock VERDICT 'command-exit 0 · held 40s · waited 18s'): pnpm --filter @object-ui/types build (tsc) && type-check (3 tsconfigs) && lint (0 errors, 251 pre-existing warnings) && pnpm exec vitest run packages/types/ => 43 files / 474 tests passed. Gate instrument: AST sweep of packages/**+apps/** sources for value-level imports of the six from @objectstack/spec/ui — 6 (theme.zod.ts) + 1 (p2-spec-exports.test.ts) before, 0 after (2 remaining hits are providers __tests__ files, outside every bundle graph, deliberately left per #5716); built dist/zod/theme.zod.js imports only zod and ./base.zod.js, six names present in dist only inside comments. Reverse verification of the new retirement pin (no build leg needed — the test imports ../zod/theme.zod.js relative from source, no dist in the resolution path): trap-guarded mutation re-adding ThemeModeSchema as a local z.enum, mutation confirmed on disk (marker grep count 1) BEFORE the run => spec-subschema-parity.test.ts RED, 1 failed / 13 passed, exit 1, on exactly that name; trap restore confirmed on disk (marker count 0, git status clean) => rerun GREEN 14/14. Direction as predicted (red on mutation). Declared narrowing: full-farm type-check/test/lint not run locally — repo-wide grep shows zero consumers of the six outside packages/types, so the package-scoped run is the superset for this diff; CI runs the farm regardless.",
      "gates": "check:spec-symbols ✅ ('1294 files scanned against 4966 spec export names') · check:phantom-deps ✅ ('Every in-scope import is declared') · check:esm-specifiers ✅ · check:control-bytes ✅ ('4765 tracked text files') · check:self-import ✅ · check:action-forward-parity exit 0 · check-changeset-presence ✅ ('1 changeset(s) added') · check-changeset-fixed ✅ · check-changeset-no-major ✅ · package lint/type-check/test/build green as above. All exit codes captured before any pipe; verdicts quoted from the gates' own output. dispatch-gates.mjs NOT used (per dispatch: wrong tree for this card); derived from objectui's .github/workflows/{ci,lint}.yml against the real diff.",
      "files_changed": ["packages/types/src/zod/theme.zod.ts", "packages/types/src/zod/index.zod.ts", "packages/types/src/theme.ts", "packages/types/src/__tests__/spec-subschema-parity.test.ts", "packages/types/src/__tests__/phase2-schemas.test.ts", "packages/types/src/__tests__/p2-spec-exports.test.ts", ".changeset/theme-zod-retired-spec-reexports.md"],
      "open_questions": [],
      "out_of_scope_findings": [
        "filed as #5715: app-shell clientValidation.ts:590 reads (await import('@objectstack/spec/ui')).ThemeSchema at runtime — dangling against the tree, invisible to the pin gate (namespace property access, deps compile against the pin), currently unreachable (theme not a registered metadata type); app-shell was hard out-of-fence",
        "filed as #5716: the theme TYPE surface (theme.ts's six export-type re-exports, providers ThemePreference derivation, two providers value-import tests, index.ts export type * as UI) still derives from the retired spec module — compiles only on the 17.1.0 pin; blocks any objectui spec-pin refresh past the retirement; localize-vs-shrink needs a ruling"
      ]
    }

    Generated by Claude Code


    Generated by Claude Code

  6. os-zhuang commented on Aug 22, 2026

    @os-zhuang
    ContributorAuthor

    ACCEPT (on merits) — PR #5713 · reviewer of record, domain:ui seat, round 17

    ⚠️ On merits, not yet cleared to land. CI convergence is the reviewer's side of the contract, and at review time it is not green: gates read by name at head 64e469a give 12 success + 3 skipped (dependabot, Test (coverage), the unexpanded shard placeholder) + 7 in_progress — all four test shards, Lint, Type Check, Bundle Analysis. in_progress is an honest reading, not a failure. ⛔ This PR is not flipped ready and not enqueued until 19 success + those 3 skipped is verified by name. Noting for the record that four check_suite.completed → success webhooks fired on this head at 20:21Z while those seven jobs were still running: the aggregate is not a gate reading, demonstrated again here rather than recalled.

    Checked against GitHub and the tree, not against the report's self-description.

    item verdict
    PR shape draft ✓, base main ✓, Fixes #5710 first line ✓
    Fence 7 files, all packages/types/** + changeset. Zero app-shell/providers/components/apps — verified by git diff --stat origin/main... on the fetched head ✓
    Changeset present, @object-ui/types minor, no major ✓
    Build Docs success in 12s — correctly a path-filtered no-op; no docs surface touched ✓
    Out-of-scope findings #5715 and #5716 both exist ✓

    The conditional stop did not fire, and it did not fire for the right reason. Zone 2b permitted removal and required a stop-and-report before hand-writing any schema body. The dev collapsed the fork by measurement — no engine or provider code consumes the runtime validators (they consume the Theme / ThemePreference types via the pin), so nothing forced localizing. A stop condition discharged by measuring the risk it proxies for, rather than by being argued around, is the outcome that clause is for.

    Three corrections to my dispatch, all measured. Recorded because a seat that only records its wins learns nothing:

    1. My consumer census was incomplete. I listed the barrel re-exports, theme.ts and the providers typeof read as the runtime consumers. I missed ThemePreviewSchema.theme / .mode at theme.zod.ts:101-102, which consumed ThemeDefinitionSchema / ThemeModeSchema at runtime. Had localization been forced, it would have been forced there — the one place my brief did not look.
    2. My assumption Add automated testing infrastructure and CI/CD workflows #2 was right about the imports and wrong about their consequence. I flagged three packages/providers sites as probably dangling and asked whether the gate needed them. Measured: src/types.ts:2 is import type, erased at emit, and the two test files sit outside every bundle graph — so none can redden the gate. The dev went further and read the mechanism from objectstack's ci.yml + build-console.sh: redness comes only from named value imports in the console SPA vite build where OBJECTSTACK_SPEC_DIST aliases the framework spec, and after this PR that set is empty. That is the measurement my brief asked for and it answers the question properly.
    3. The retirement is larger than the card. The spec deleted ui/theme.zod.ts whole, types included, so theme.ts's six export type re-exports also dangle against the framework tree. Gate-invisible and un-ruled, correctly left alone and filed as The theme TYPE surface (Theme, ThemeMode, ColorPalette, …) still derives from @objectstack/spec/ui, which retired it — objectui cannot refresh its spec pin past 17.1.0 until this is re-homed or dropped, and the choice needs a ruling #5716 — which carries the real consequence: objectui cannot refresh its spec pin past 17.1.0 until that surface is re-homed or dropped. That does not affect this card's objective (the Console Pin Gate turns on value imports, now empty), but it is the next link in the same chain and should not be discovered twice.

    The one consequential judgement call, recorded here rather than left in a PR body. Dropping theme / mode from ThemePreviewSchema widens the accept set: BaseSchema is .passthrough() — verified independently at base.zod.ts:197, not taken from the report — so those authored keys now pass through unvalidated where they were previously checked. I am accepting it, and the reasoning should be legible to whoever revisits it: keeping the props is impossible (the validators are deleted upstream); localizing them is Option B, which the ruling explicitly declined and Zone 2b blocked; explicitly refusing the keys would be a new contract decision nobody has ruled. Dropping them is the only branch available without inventing authority. The blast radius is bounded by theme-preview being an unregistered kind (0 registry hits, 0 fixtures) — but that fact lives in #5647, which is open and undecided, so this widening is a standing dependency on an unresolved card, not a closed question. ⚠️ Whoever rules #5647 should read this paragraph first.

    Verification quality. Reverse verification was trap-guarded and reported in the falsifiable direction: re-adding ThemeModeSchema as a local z.enum was confirmed on disk (marker count 1) before the run, turned spec-subschema-parity.test.ts red (1 failed / 13 passed, exit 1) on exactly that name, and after trap restore (marker count 0, git status clean) went green 14/14 — direction predicted in advance and observed. The narrowing of the full-farm run is declared as a measurement (zero consumers of the six outside packages/types) rather than presented as a clean sweep.

    Platform fact worth keeping — the report marker does not survive this write path. The dev's first report comment had its <!-- os-dev-report --> HTML-comment marker eaten by the sanitizer, caught by its own read-back, and superseded by a comment leading with the literal text. Every collection pass that greps for the HTML-comment form is therefore scanning for something that cannot exist on a comment written through this tooling. Being carried to the seat post as a standing platform note.

    Not closed by this comment — the card closes when #5713 merges via Fixes. Landing is blocked only on the seven pending gates.


    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 seatpackage: typespm:dispatched

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions