You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
clientValidation.ts theme: entry reads spec.ThemeSchema, which the spec retired — dangling dynamic read on a metadata type that is not registered #5715
Found while executing #5710 (session session_01EuPCi56cnGyykygi3z9w4m, PR #5713). Filed unassigned, out of that card's fence (packages/app-shell/** was hard out-of-scope there; a sibling card was live in the package).
Against the framework tree, this line yields undefined cast to ZodLikeSchema at runtime — a crash (or a silent validation no-op, depending on the caller's null handling) the moment the theme entry is invoked.
It is invisible to objectstack's Console Pin Gate: a namespace property access is not a named import binding, so the bundler resolves the dynamic import fine and never checks the property; the tsc deps build compiles against objectui's own @objectstack/spec 17.1.0 pin, which still publishes the symbol. So no gate will ever announce this.
Remove the theme: entry (dead key pointing at a deleted upstream symbol), or — if metadata-admin genuinely intends a theme editing surface — that is a capability decision that needs its own ruling, not a validator entry pointing at a symbol that no longer exists. Note the file sits in packages/app-shell/src/views/metadata-admin/, not in the app-shell/src/console/** fence of #5619.
Triage: pm:queue, domain:ui, Task. Dead validator entry: clientValidation.ts:590's theme: reads spec.ThemeSchema, retired upstream (objectstack#10485 / #10695); entry is unreachable today (theme was never a registered metadata type) and invisible to every gate. Scope: remove the entry (precedent #3561). If anyone wants a metadata-admin theme editing surface, that is a capability ruling to request separately — not a reason to keep a pointer at a deleted symbol. Related: the ruled type-surface question is ui#5716 (decision box) — this removal is independent of it and safe either way.
Claim: domain:ui execution seat (seat post #5560), round 20, slot 2 — replacement for #5702, which returned needs_decision when the maintainer ruling's own conditional stop fired (see #5702). This slot is re-filled to hold the seat at concurrency 3.
Clause-②: no.clientValidation.ts is internal to packages/app-shell; the theme key is not a published export and the entry is unreachable (theme was never a registered metadata type). Nothing an author writes changes accept or reject status, and no public surface widens or narrows.
ℹ️ packages/app-shell/src/views/metadata-admin/inspectors/ViewColumnInspector.tsx was changed by #5344 / PR #5726 (landed 01:2xZ, no live hold) — a sibling directory, not your file, but re-read rather than trusting an older line number.
One thing the seat could NOT measure, handed over as a task rather than a reading: the card's claim that this is "invisible to objectstack's Console Pin Gate" rests on objectui's installed @objectstack/spec17.1.0 pin still publishing ThemeSchema while objectstack's origin/main has retired it. The spec package is not installed in the seat's checkout, so the seat has no instrument and therefore reports no reading — verify it yourself in your worktree after pnpm install, and control the grep against a symbol known to be live (PageSchema, FormViewSchema) so a zero on ThemeSchema is a measurement rather than a broken search.
{
"issue": 5715,
"status": "done",
"branch": "claude/issue-5715-drop-dead-theme-validator-entry",
"pr": "https://github.com/objectstack-ai/objectui/pull/5747",
"premise_still_valid": true,
"summary": "Removed the dead `theme:` entry from the LOADERS table in packages/app-shell/src/views/metadata-admin/clientValidation.ts (was line 590, reading ThemeSchema off @objectstack/spec/ui) and replaced it with a house-style absence note matching the `workflow` / `approval` notes below it, so the entry cannot be 'helpfully' re-added. The five live table-mates (page, app, dashboard, report, action) are untouched; the whole diff is 3 files, 98 insertions, 1 deletion. All three PM hypotheses were measured. 2a CONFIRMED and does NOT invert: installed @objectstack/spec is 17.1.0 and its ui surface still exports ThemeSchema as a working strict Zod schema (present=true, safeParse=function), with controls PageSchema/FormViewSchema/AppSchema live on the same command — so tsc compiles clean here and the skew is with objectstack main, not with what objectui installs. 2b FALSIFIED on the crash branch and sharpened: getSchemaForType duck-checks the loader result (`typeof schema.safeParse === 'function'`) AND wraps it in try/catch, so a missing export can only degrade to a silent no-op, never throw; moreover that no-op is NOT today's behaviour, because 17.1.0 still ships a working ThemeSchema that would actively judge a draft (proven by ablation). So this is dead-code hygiene, not a latent-crash fix, and the changeset says exactly that. 2c TRUE in practice but NOT structurally guaranteed: ResourceEditPage.tsx:283 keys the table from a route param (`const type = typeProp ?? params.type ?? ''`), resolveResourceConfig is total for unknown types, and the route is defined by the consuming app, so this package cannot close the key set — what makes theme unreachable is the upstream fact that no server registers it, not a guard in this code. One genuine latent defect found and recorded: hasClientValidator answers from key presence alone, so it returned true for theme while the validator behind it judged nothing; per its own docblock that combination makes ResourceEditPage treat live client issues as the error source and SUPPRESS the server's _diagnostics, i.e. a stored item rendering as clean. Unreachable, but it is why the entry was worth removing rather than leaving inert.",
"tests": "All runs from the repo ROOT: package-level `pnpm --filter ... test` is refused by this repo's own guard (objectui#3378 false-green trap, where a package-dir vitest silently runs @object-ui/console's 22 files and reports 'Test Files 22 passed'). Green union re-run at final HEAD 280668a82. (1) New pin `packages/app-shell/src/views/metadata-admin/clientValidation.themeRetired.test.ts`: each negative paired with a live control so a false is a measurement, not a broken import — hasClientValidator('theme') false on both doors while hasClientValidator('page') is true on both; validateMetadataDraft('theme', ...) falls through while the same shape IS rejected for 'page'. It deliberately does NOT pin 'the spec no longer exports ThemeSchema', which would be red today and would flip for unrelated reasons. (2) ABLATION (re-added the entry): mutation confirmed ON DISK by anchored occurrence counts in BOTH directions — 'MUTATION ON DISK: injected-line count 0 -> 1', and restore leg 'injected-line count now = 0, note-anchor count now = 1' plus git status clean; restored under `trap ... EXIT INT TERM` (the trap fired correctly and forced mutation+measurement into one shell invocation). Result ABLATION_TEST_EXIT=1, BOTH legs red: 'AssertionError: expected true to be false' (hasClientValidator flipped true) and 'AssertionError: expected false to be true' (validateMetadataDraft('theme', {nonsense:true}) actively REJECTED the draft — which is itself the proof that ThemeSchema is live in pin 17.1.0). Restore leg re-run green: Tests 2 passed. NO REBUILD LEG REQUIRED and this is stated rather than skipped: the test imports './clientValidation' by relative path from source, not across a package exports boundary, so vitest transforms the mutated file directly — and the behaviour change itself proves the mutated source is what ran. (3) `pnpm exec vitest run packages/app-shell/src/views/metadata-admin/` — Test Files 194 passed, Tests 1977 passed / 1 skipped, exit 0 (run at 6b8f330d6; source tree identical at 280668a82, only the changeset markdown was added after). (4) Targeted re-run at 280668a82 of themeRetired + optOuts + createConformance — Test Files 3 passed, Tests 36 passed, exit 0. createConformance was a real risk (it enumerates authorable types and asserts on hasClientValidator) and is green. (5) `pnpm --filter @object-ui/app-shell type-check` exit 0, output echoed the script name so it was not a zero-match no-op (objectui spells it `type-check`, hyphenated). (6) Gates re-run at 280668a82, exit codes captured BEFORE any pipe: check:spec-symbols exit 0, its own verdict line 'spec symbol derivation: 1296 files scanned against 4966 spec export names'; check:control-bytes exit 0, 'check-control-bytes: OK (scanned 4792 tracked text file(s); skipped 85 binary)'; check:self-import, check:phantom-deps, check:esm-specifiers, check:action-forward-parity all exit 0; changeset presence/no-major/fixed all exit 0, presence reporting '2 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)'. Manual control-byte self-scan of my three files clean. DECLARED NARROWING: lint was run as the affected package's own `pnpm --filter @object-ui/app-shell lint` (exit 0; 0 errors, 2553 pre-existing warnings) rather than the repo-wide `turbo run lint`. The narrowing is safe and measured, not assumed: eslint here is NOT type-aware (no projectService and no project in eslint.config.js), so this diff cannot move the verdict on any file it does not touch. CI runs the full farm regardless.",
"open_questions": [],
"out_of_scope_findings": [
"NOT filed, already tracked — deliberately searched before filing per the file-first-search rule. A controlled repo-wide scan (ThemeSchema 9 hits, ThemeModeSchema 25, defineTheme 0; controls PageSchema 60 and ActionSchema 134 live on the same pipeline) shows packages/types/src/zod/theme.zod.ts holds a NAMED import of ThemeSchema from @objectstack/spec/ui, which unlike my namespace property access WOULD break loudly at the next spec bump. That surface is exactly #5716 (open, decision box: the theme TYPE surface cannot refresh the pin past 17.1.0 until re-homed or dropped) and #5710 (closed). No new issue filed — it would have been a duplicate. Caveat on my instrument: that scan ran against the shared primary checkout at 7138bc129, which is behind origin/main, so it reflects a possibly stale tree and I am not asserting the current state of packages/types."
]
}
Two notes outside the JSON, both PM-actionable:
Base moved. The dispatch cited origin/main at 8689166f6; by the time the worktree was created it was d1ab06f0f, so the branch is off d1ab06f0f. All citations were verified against that tree.
Fence respected. Writes were confined to clientValidation.ts, a new clientValidation.themeRetired.test.ts, and one .changeset/*. packages/auth/**, packages/sdui-parser/** and useConsoleActionRuntime.tsx were never touched. Worktree removed cleanly without--force, which is itself the evidence that nothing uncommitted was left behind.
CI was not waited on, per the dispatch contract — the draft PR is open and gate status is whatever CI reports on 280668a82.
Gates read by name, one call, at 03:59Z (PR started 03:48:00Z): 19 success + 3 skipped = 22. Zero in_progress, zero failure. Eager closure 3916.7 / 3990.2 KB — PASS.
⚠️ Stated so it is not over-read: Build Docs completed in 13 seconds. ci.yml gates that job's steps on git diff … -- 'apps/site/' 'content/' and reports green when empty — this diff touches neither, so the site was not built. Normal and correct for this change; recorded because this seat read exactly that skip as a build an hour ago (#5668).
Fence: clean. Three files, all inside the grant, no governed path:
All three hypotheses measured — and the two that mattered went against the card
2a confirmed, and it does not invert. The installed @objectstack/spec is 17.1.0 and still exports a working ThemeSchema from its ui surface, with PageSchema / FormViewSchema / AppSchema live on the same command as controls. So the skew is with objectstack's main, not with what objectui installs — which is precisely why no gate here ever went red, and why the entry could sit dead for as long as it did.
2b falsified, and the correction is the useful half. I briefed this as possibly a latent crash. It cannot be: getSchemaForType duck-checks the loader result (typeof schema.safeParse === 'function') and wraps the call in try/catch, so a missing export degrades to a silent no-op, never a throw. And that no-op is not even today's behaviour — 17.1.0's ThemeSchema is live and would actively judge a draft, proven by ablation where restoring the entry made validateMetadataDraft('theme', …) reject one.
So this is dead-code hygiene, not a bug fix, and the changeset says exactly that. My Zone-2b instruction was not to upgrade hygiene into a fix it isn't; the report went one better and produced the evidence that forces the honest label.
2c true in practice, not structurally guaranteed — and that distinction is the right one.ResourceEditPage.tsx:283 keys the table from a route param (typeProp ?? params.type ?? ''), resolveResourceConfig is total for unknown types, and the route is defined by the consuming app. What makes theme unreachable is the upstream fact that no server registers it — not a guard in this code. Reporting "unreachable because of a fact I do not control" rather than "unreachable, verified" is the accurate shape.
The genuine finding, which is why removal beats leaving it inert
hasClientValidator answers from key presence alone. While the entry existed it returned true for theme while the schema behind it was on its way to becoming a no-op — and per that function's own docblock, true makes ResourceEditPage treat live client issues as the error source and suppress the server's _diagnostics. A stored item rendering as clean. Unreachable today, but it is the reason an inert entry was not a harmless one, and it is not something the card knew.
ℹ️ One wording note, non-blocking: the inline comment in the new test says "had it ever been reached, a stored item would have rendered as clean". That is the post-bump behaviour; on today's 17.1.0 pin the schema is live and would have judged. The changeset states it correctly in the conditional. The assertions are unaffected — worth tightening if the file is touched again, not worth a push.
The absence note is the deliverable, not the deletion
Zone 3 asked for the house shape rather than a hole, because a bare deletion invites the next reader to "finish the job" by re-adding the entry from the spec — which would type-check and go green against the current pin. The replacement note says so in as many words, and matches the workflow / approval notes below it. The five live table-mates (page, app, dashboard, report, action) are untouched.
The pin's judgement is the part I would highlight to another dev: it deliberately does not assert "the spec no longer exports ThemeSchema" — that would be red today and would flip for reasons unrelated to this module. What is pinned is this module's own behaviour, with each negative paired with a live page control so a false is a measurement rather than a broken import. Ablation re-added the entry and took both legs red, with the disk mutation confirmed by anchored counts in both directions under a trap that is reported as having actually fired.
Declared narrowing on lint (package-scoped rather than the repo farm) is accepted: it is measured, not assumed — eslint.config.js configures no project / projectService, so this diff cannot move any untouched file's verdict, and CI ran the full farm anyway.
Nothing filed out of scope, and the non-filing is itself correct: the packages/types/src/zod/theme.zod.ts named import of ThemeSchema — which unlike a namespace property access would break loudly at the next spec bump — is already #5716 in the decision box. Searched before filing; a duplicate was avoided, and the instrument's staleness caveat (the scan ran against the shared checkout, behind origin/main) was stated rather than glossed.
Activity
os-zhuang commentedon Aug 23, 2026
Triage:
pm:queue,domain:ui, Task. Dead validator entry:clientValidation.ts:590'stheme:readsspec.ThemeSchema, retired upstream (objectstack#10485 / #10695); entry is unreachable today (themewas never a registered metadata type) and invisible to every gate. Scope: remove the entry (precedent #3561). If anyone wants a metadata-admin theme editing surface, that is a capability ruling to request separately — not a reason to keep a pointer at a deleted symbol. Related: the ruled type-surface question is ui#5716 (decision box) — this removal is independent of it and safe either way.Generated by Claude Code
os-zhuang commentedon Aug 23, 2026
Claim:
domain:uiexecution seat (seat post #5560), round 20, slot 2 — replacement for #5702, which returnedneeds_decisionwhen the maintainer ruling's own conditional stop fired (see #5702). This slot is re-filled to hold the seat at concurrency 3.session_01EuPCi56cnGyykygi3z9w4mclaude/issue-5715-drop-dead-theme-validator-entryorigin/mainat8689166f6domain:ui· Tier:claude-opus-5(lane default)clientValidation.tsis internal topackages/app-shell; thethemekey is not a published export and the entry is unreachable (themewas never a registered metadata type). Nothing an author writes changes accept or reject status, and no public surface widens or narrows.File surface granted (write):
Serial constraints — three live fences this round, none overlapping:
packages/auth/**— held by Cross-user client-state pollution: previous user's workspace shown to a new user, and the guided first-run flow suppressed #5664 (slot 1)packages/sdui-parser/**— held by A gauge widget'soptions.inverthas no observable effect, and nothing can say so — it is an undeclared key ridingDashboardWidgetOptionsSchema.passthrough()#5709 (slot 3)packages/app-shell/src/hooks/useConsoleActionRuntime.tsx— held by Metadatatype: 'api'actions send the Bearer token and X-Tenant-ID to absolute third-party URLs — the #2725sameOriginOnlymitigation was never applied to this lane #5702's pushed-but-unlanded branch074121474, pending a maintainer ruling. Same package as your file, different directory; do not touch it.ℹ️
packages/app-shell/src/views/metadata-admin/inspectors/ViewColumnInspector.tsxwas changed by #5344 / PR #5726 (landed 01:2xZ, no live hold) — a sibling directory, not your file, but re-read rather than trusting an older line number.One thing the seat could NOT measure, handed over as a task rather than a reading: the card's claim that this is "invisible to objectstack's Console Pin Gate" rests on objectui's installed
@objectstack/spec17.1.0 pin still publishingThemeSchemawhile objectstack'sorigin/mainhas retired it. The spec package is not installed in the seat's checkout, so the seat has no instrument and therefore reports no reading — verify it yourself in your worktree afterpnpm install, and control the grep against a symbol known to be live (PageSchema,FormViewSchema) so a zero onThemeSchemais a measurement rather than a broken search.Generated by Claude Code
os-zhuang commentedon Aug 23, 2026
os-dev-report
{ "issue": 5715, "status": "done", "branch": "claude/issue-5715-drop-dead-theme-validator-entry", "pr": "https://github.com/objectstack-ai/objectui/pull/5747", "premise_still_valid": true, "summary": "Removed the dead `theme:` entry from the LOADERS table in packages/app-shell/src/views/metadata-admin/clientValidation.ts (was line 590, reading ThemeSchema off @objectstack/spec/ui) and replaced it with a house-style absence note matching the `workflow` / `approval` notes below it, so the entry cannot be 'helpfully' re-added. The five live table-mates (page, app, dashboard, report, action) are untouched; the whole diff is 3 files, 98 insertions, 1 deletion. All three PM hypotheses were measured. 2a CONFIRMED and does NOT invert: installed @objectstack/spec is 17.1.0 and its ui surface still exports ThemeSchema as a working strict Zod schema (present=true, safeParse=function), with controls PageSchema/FormViewSchema/AppSchema live on the same command — so tsc compiles clean here and the skew is with objectstack main, not with what objectui installs. 2b FALSIFIED on the crash branch and sharpened: getSchemaForType duck-checks the loader result (`typeof schema.safeParse === 'function'`) AND wraps it in try/catch, so a missing export can only degrade to a silent no-op, never throw; moreover that no-op is NOT today's behaviour, because 17.1.0 still ships a working ThemeSchema that would actively judge a draft (proven by ablation). So this is dead-code hygiene, not a latent-crash fix, and the changeset says exactly that. 2c TRUE in practice but NOT structurally guaranteed: ResourceEditPage.tsx:283 keys the table from a route param (`const type = typeProp ?? params.type ?? ''`), resolveResourceConfig is total for unknown types, and the route is defined by the consuming app, so this package cannot close the key set — what makes theme unreachable is the upstream fact that no server registers it, not a guard in this code. One genuine latent defect found and recorded: hasClientValidator answers from key presence alone, so it returned true for theme while the validator behind it judged nothing; per its own docblock that combination makes ResourceEditPage treat live client issues as the error source and SUPPRESS the server's _diagnostics, i.e. a stored item rendering as clean. Unreachable, but it is why the entry was worth removing rather than leaving inert.", "tests": "All runs from the repo ROOT: package-level `pnpm --filter ... test` is refused by this repo's own guard (objectui#3378 false-green trap, where a package-dir vitest silently runs @object-ui/console's 22 files and reports 'Test Files 22 passed'). Green union re-run at final HEAD 280668a82. (1) New pin `packages/app-shell/src/views/metadata-admin/clientValidation.themeRetired.test.ts`: each negative paired with a live control so a false is a measurement, not a broken import — hasClientValidator('theme') false on both doors while hasClientValidator('page') is true on both; validateMetadataDraft('theme', ...) falls through while the same shape IS rejected for 'page'. It deliberately does NOT pin 'the spec no longer exports ThemeSchema', which would be red today and would flip for unrelated reasons. (2) ABLATION (re-added the entry): mutation confirmed ON DISK by anchored occurrence counts in BOTH directions — 'MUTATION ON DISK: injected-line count 0 -> 1', and restore leg 'injected-line count now = 0, note-anchor count now = 1' plus git status clean; restored under `trap ... EXIT INT TERM` (the trap fired correctly and forced mutation+measurement into one shell invocation). Result ABLATION_TEST_EXIT=1, BOTH legs red: 'AssertionError: expected true to be false' (hasClientValidator flipped true) and 'AssertionError: expected false to be true' (validateMetadataDraft('theme', {nonsense:true}) actively REJECTED the draft — which is itself the proof that ThemeSchema is live in pin 17.1.0). Restore leg re-run green: Tests 2 passed. NO REBUILD LEG REQUIRED and this is stated rather than skipped: the test imports './clientValidation' by relative path from source, not across a package exports boundary, so vitest transforms the mutated file directly — and the behaviour change itself proves the mutated source is what ran. (3) `pnpm exec vitest run packages/app-shell/src/views/metadata-admin/` — Test Files 194 passed, Tests 1977 passed / 1 skipped, exit 0 (run at 6b8f330d6; source tree identical at 280668a82, only the changeset markdown was added after). (4) Targeted re-run at 280668a82 of themeRetired + optOuts + createConformance — Test Files 3 passed, Tests 36 passed, exit 0. createConformance was a real risk (it enumerates authorable types and asserts on hasClientValidator) and is green. (5) `pnpm --filter @object-ui/app-shell type-check` exit 0, output echoed the script name so it was not a zero-match no-op (objectui spells it `type-check`, hyphenated). (6) Gates re-run at 280668a82, exit codes captured BEFORE any pipe: check:spec-symbols exit 0, its own verdict line 'spec symbol derivation: 1296 files scanned against 4966 spec export names'; check:control-bytes exit 0, 'check-control-bytes: OK (scanned 4792 tracked text file(s); skipped 85 binary)'; check:self-import, check:phantom-deps, check:esm-specifiers, check:action-forward-parity all exit 0; changeset presence/no-major/fixed all exit 0, presence reporting '2 source file(s) of 1 released package(s) changed, and this change declares 1 changeset(s)'. Manual control-byte self-scan of my three files clean. DECLARED NARROWING: lint was run as the affected package's own `pnpm --filter @object-ui/app-shell lint` (exit 0; 0 errors, 2553 pre-existing warnings) rather than the repo-wide `turbo run lint`. The narrowing is safe and measured, not assumed: eslint here is NOT type-aware (no projectService and no project in eslint.config.js), so this diff cannot move the verdict on any file it does not touch. CI runs the full farm regardless.", "open_questions": [], "out_of_scope_findings": [ "NOT filed, already tracked — deliberately searched before filing per the file-first-search rule. A controlled repo-wide scan (ThemeSchema 9 hits, ThemeModeSchema 25, defineTheme 0; controls PageSchema 60 and ActionSchema 134 live on the same pipeline) shows packages/types/src/zod/theme.zod.ts holds a NAMED import of ThemeSchema from @objectstack/spec/ui, which unlike my namespace property access WOULD break loudly at the next spec bump. That surface is exactly #5716 (open, decision box: the theme TYPE surface cannot refresh the pin past 17.1.0 until re-homed or dropped) and #5710 (closed). No new issue filed — it would have been a duplicate. Caveat on my instrument: that scan ran against the shared primary checkout at 7138bc129, which is behind origin/main, so it reflects a possibly stale tree and I am not asserting the current state of packages/types." ] }Two notes outside the JSON, both PM-actionable:
origin/mainat8689166f6; by the time the worktree was created it wasd1ab06f0f, so the branch is offd1ab06f0f. All citations were verified against that tree.clientValidation.ts, a newclientValidation.themeRetired.test.ts, and one.changeset/*.packages/auth/**,packages/sdui-parser/**anduseConsoleActionRuntime.tsxwere never touched. Worktree removed cleanly without--force, which is itself the evidence that nothing uncommitted was left behind.CI was not waited on, per the dispatch contract — the draft PR is open and gate status is whatever CI reports on
280668a82.Generated by Claude Code
os-zhuang commentedon Aug 23, 2026
ACCEPT — landing. PR #5747.
Gates read by name, one call, at 03:59Z (PR started 03:48:00Z): 19
success+ 3skipped= 22. Zeroin_progress, zerofailure. Eager closure 3916.7 / 3990.2 KB — PASS.Build Docscompleted in 13 seconds.ci.ymlgates that job's steps ongit diff … -- 'apps/site/' 'content/'and reports green when empty — this diff touches neither, so the site was not built. Normal and correct for this change; recorded because this seat read exactly that skip as a build an hour ago (#5668).Fence: clean. Three files, all inside the grant, no governed path:
All three hypotheses measured — and the two that mattered went against the card
2a confirmed, and it does not invert. The installed
@objectstack/specis 17.1.0 and still exports a workingThemeSchemafrom itsuisurface, withPageSchema/FormViewSchema/AppSchemalive on the same command as controls. So the skew is with objectstack'smain, not with what objectui installs — which is precisely why no gate here ever went red, and why the entry could sit dead for as long as it did.2b falsified, and the correction is the useful half. I briefed this as possibly a latent crash. It cannot be:
getSchemaForTypeduck-checks the loader result (typeof schema.safeParse === 'function') and wraps the call intry/catch, so a missing export degrades to a silent no-op, never a throw. And that no-op is not even today's behaviour — 17.1.0'sThemeSchemais live and would actively judge a draft, proven by ablation where restoring the entry madevalidateMetadataDraft('theme', …)reject one.So this is dead-code hygiene, not a bug fix, and the changeset says exactly that. My Zone-2b instruction was not to upgrade hygiene into a fix it isn't; the report went one better and produced the evidence that forces the honest label.
2c true in practice, not structurally guaranteed — and that distinction is the right one.
ResourceEditPage.tsx:283keys the table from a route param (typeProp ?? params.type ?? ''),resolveResourceConfigis total for unknown types, and the route is defined by the consuming app. What makesthemeunreachable is the upstream fact that no server registers it — not a guard in this code. Reporting "unreachable because of a fact I do not control" rather than "unreachable, verified" is the accurate shape.The genuine finding, which is why removal beats leaving it inert
hasClientValidatoranswers from key presence alone. While the entry existed it returnedtrueforthemewhile the schema behind it was on its way to becoming a no-op — and per that function's own docblock,truemakesResourceEditPagetreat live client issues as the error source and suppress the server's_diagnostics. A stored item rendering as clean. Unreachable today, but it is the reason an inert entry was not a harmless one, and it is not something the card knew.ℹ️ One wording note, non-blocking: the inline comment in the new test says "had it ever been reached, a stored item would have rendered as clean". That is the post-bump behaviour; on today's 17.1.0 pin the schema is live and would have judged. The changeset states it correctly in the conditional. The assertions are unaffected — worth tightening if the file is touched again, not worth a push.
The absence note is the deliverable, not the deletion
Zone 3 asked for the house shape rather than a hole, because a bare deletion invites the next reader to "finish the job" by re-adding the entry from the spec — which would type-check and go green against the current pin. The replacement note says so in as many words, and matches the
workflow/approvalnotes below it. The five live table-mates (page,app,dashboard,report,action) are untouched.The pin's judgement is the part I would highlight to another dev: it deliberately does not assert "the spec no longer exports
ThemeSchema" — that would be red today and would flip for reasons unrelated to this module. What is pinned is this module's own behaviour, with each negative paired with a livepagecontrol so afalseis a measurement rather than a broken import. Ablation re-added the entry and took both legs red, with the disk mutation confirmed by anchored counts in both directions under atrapthat is reported as having actually fired.Declared narrowing on lint (package-scoped rather than the repo farm) is accepted: it is measured, not assumed —
eslint.config.jsconfigures noproject/projectService, so this diff cannot move any untouched file's verdict, and CI ran the full farm anyway.Nothing filed out of scope, and the non-filing is itself correct: the
packages/types/src/zod/theme.zod.tsnamed import ofThemeSchema— which unlike a namespace property access would break loudly at the next spec bump — is already #5716 in the decision box. Searched before filing; a duplicate was avoided, and the instrument's staleness caveat (the scan ran against the shared checkout, behindorigin/main) was stated rather than glossed.Flipping ready → auto-merge (SQUASH).
Generated by Claude Code