Skip to content

feat(spec): declare record:details section headerColor as a closed six-token enum - #12616

Merged
os-zhuang merged 4 commits into
mainfrom
claude/issue-12126-headercolor-enum
Aug 26, 2026
Merged

feat(spec): declare record:details section headerColor as a closed six-token enum#12616
os-zhuang merged 4 commits into
mainfrom
claude/issue-12126-headercolor-enum

Conversation

@os-zhuang

@os-zhuangos-zhuang commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Fixes#12126

Implements maintainer ruling A (2026-08-26, issue comment 5419726057, verbatim provenance 「其他接受你的建议」): declare headerColor on the strict record:details section schema as a closed z.enum over exactly the six tokens objectui#6294 ships.

What changed

Sanity check the ruling delegated

Read objectui/packages/plugin-detail/src/headerColor.ts at objectui origin/main (read-only): its HEADER_COLOR_CLASSES lookup ships exactly muted, muted/50, accent, primary/10, secondary/10, destructive/10 — the enum matches the module one-to-one, and the module's own header states the tints-only reasoning (CardHeader sets no foreground; solids would need a paired text-foreground class, left to the pass-through). No vocabulary adjustment needed, no shape question raised.

The renderer's bg-* pass-through is deliberately NOT declared: it renders only when the host app's Tailwind build happens to generate the class — the capability-illusion shape the old refusal existed to prevent, and ruling A explicitly rejects option B (open string).

Guidance/alias machinery

Checked per the dispatch card: the strict section schema carries NO curated headerColor guidance or alias entry (grep over packages/spec/src — the only headerColor occurrences were the zod comment and the pin test), so there is nothing to remove for the #5013 alias-integrity audit; pnpm check:spec-parsed-alias is green (its verdict line: "ADR-0122 type-alias convention: ... OK").

Verification (union re-run at final head 342070617, tree clean; every command through scripts/pm/os-verify-lock.sh, exit codes captured before any pipe)

  • pnpm --filter @objectstack/spec build — green (check-dts-emitted: 34/34 declared declaration file(s) present).
  • pnpm --filter @objectstack/spec test435 files / 11525 tests passed (vitest summary line: Tests 11525 passed (11525)).
  • pnpm --filter @objectstack/spec typecheck — green, including the test layer: check:test-typecheck: OK — @objectstack/spec's test layer compiles under packages/spec/tsconfig.test.json (the edited test file is covered by that program and is not a debt-ledger entry).
  • Reverse verification (from the committed state at 410f85825; restore via git checkout HEAD -- path, proven by empty git diff HEAD): with component.zod.ts reverted to base d7b3963c2 (mutation confirmed on disk: grep -c "headerColor: z.enum" = 0) and the new tests kept, both new pins turned RED as predicted — the accept test on the unrecognized key, the reject test on the issue-code mismatch — and back green on restore. Direction observed: turned red (the normal direction).
  • pnpm --filter @objectstack/spec check:authorable-surface — green at 342070617; its own verdict: authorable-defaults/ verified against upstream 7a25e7d606b7 — 1255 default(s) unchanged; the base-anchor lag line is printed by the check as informational, not an error.
  • pnpm --filter @objectstack/spec check:generated — green at 342070617: ✓ All 14 generated artifacts are up to date. (An earlier run pre-merge proved api-surface/ stale — dist mtime vs the reverse-verification leg, the same shape the record:details sections: five more renderer-honoured keys remain undeclared by the strict section schema (title / defaultCollapsed / icon / description / headerColor) #11661 batch recorded; rebuilt and regenerated byte-identical, zero tracked-file diff.)
  • Derived gates (node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack, change set taken by the script from merge-base), re-run at 342070617: check:spec-parsed-alias (ADR-0122 ... OK), check:engine-double-contract (OK — 689 pinned, 134 in the DEBT ledger, 3 exempt), check:where-matcher (303 matcher(s) ... answer the combinator battery correctly or refuse it loudly), check:query-options-erasure (ratchet holds ... none new), check-nul-bytes (OK — scanned 6978 text file(s)). Declared narrowing: the remaining derived families (docs-family checks, CI-filter parity, etc.) are left to CI, which runs the farm on every PR; check:type-check-debt needs the full workspace closure built and the edited test file sits in an existing tsc program with no ledger entry, so the edit cannot move its per-entry counts.

Landing-watch

Both watched PRs landed mid-flight and were merged in, each followed by a full union re-run (build, full spec suite, typecheck, check:generated, check:authorable-surface, ratchet gates): #12614 (spec ui/action.zod.ts + plugin-security) merged at 533fc01b1, then #12613 (kernel CLICommandContributionSchema retirement) merged at final head 342070617. origin/main re-fetched after the final push: no further commits.

The @object-ui/types mirror narrowing is the objectui leg — zero objectui edits here; the PM files that follow-up card.

Stops at DRAFT per the dispatch contract (clause-② contract review; no ready-flip, no auto-merge).

Generated by Claude Code

…x-token enum
The #11661 refusal's recorded reason (template-literal Tailwind read
generating no CSS) was repaired by objectui#6294's literal-class lookup;
maintainer ruling A (2026-08-26) declares the key as z.enum over
exactly the six tokens that lookup ships: muted, muted/50, accent,
primary/10, secondary/10, destructive/10. Declared = enforced — values
outside the enum (including bg-* pass-through spellings) are refused at
authoring time instead of shipping a header that silently does not paint.
Optional, no schema default; the title withhold stands and its pin flips
consciously, as its own comment anticipated.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012xGvxcwPRTJfA7RfjXEYA4
gen:docs wrote this page; gen:schema produced no tracked-file changes
(authorable-surface.base.json lags by design — baseRev allowance).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012xGvxcwPRTJfA7RfjXEYA4
@github-actions

github-actionsBot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

1 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to listnot a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run.

What this run could not see
  • 1 name(s) were too generic to anchor anything (single lowercase words)
  • 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.

Coarse fallback — 126 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 7a25e7d606b7694f6bbd6bcc226bec33f546c370packageMentionDocs.

Which tree this was computed on

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

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

@github-actionsgithub-actionsBot added documentation Improvements or additions to documentation protocol:ui tests tooling labels Aug 26, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationprotocol:uisize/mteststooling

Projects

None yet

2 participants

@os-zhuang@claude