Skip to content

docs: retire stale schema claims in ui/index and capabilities/analytics - #10639

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-10487-ui-index-retired-claims
Aug 21, 2026
Merged

docs: retire stale schema claims in ui/index and capabilities/analytics#10639
os-zhuang merged 1 commit into
mainfrom
claude/issue-10487-ui-index-retired-claims

Conversation

@claude

@claudeclaudeBot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Fixes#10487
Fixes#10488

Two hand-written pages assert things the schema no longer does. Both were found by the #10237 docs seat (PR #10483) and filed rather than fixed because they fell outside that card's declared file surface. Every changed sentence below is traced to a quote from today's tree.

1. content/docs/ui/index.mdx — the theme sentence (#10487 item 1)

Before:**Themes** define palettes, typography, and spacing as metadata — …
After:**Themes** define palettes, a base font family, radii and shadows as metadata — …

Both replaced words were verified as retired, not merely deprecated:

  • spacing is a guidance tombstone in THEME_RETIRED_KEY_GUIDANCE (packages/spec/src/ui/theme.zod.ts:339), so ThemeSchema rejects it by name: "spacing was removed in [P2] Aspirational-config disposition: reconcile-or-prune the still-dead props from the 2026-06 liveness audit (Theme / Translation / Job / Webhook) #3494 — the theme engine (objectui generateThemeVars) never emitted a spacing variable, so authoring it was a silent no-op. Emit your own scale through customVars (e.g. { "space-4": "1rem" })."
  • typography was overstating for the same reason and is fixed in the same pass rather than left half-corrected. fontSize, fontWeight, lineHeight and letterSpacing are all retiredKey() tombstones, as are fontFamily.heading / .mono. The surviving input is fontFamily.base: "base is the ONE font-family key with a live consumer (it emits --font-sans) and is unchanged."

The replacement names exactly the four keys ThemeSchema's own docblock certifies as live: "colors, borderRadius, shadows and fontFamily.base have live consumers and stay." The sentence's tail is unchanged and still true — examples/app-showcase/src/ui/themes/index.ts exports ShowcaseLightTheme (mode: 'light') and ShowcaseDarkTheme (mode: 'dark').

The frontmatter description on this file carries "themes" only, so it needed no change.

2. content/docs/ui/index.mdx — the Cards grid (#10487 item 2)

Re-derived against content/docs/ui/meta.json and the directory on today's tree rather than taken from the card.

Before (7): Apps · Views · Pages · Dashboards · Forms · Doc Pages · Setup App
After (11): Apps · Views · Actions · Pages · React Pages · Dashboards · Reports · Translations · Forms · Doc Pages · Setup App

The grid now matches the meta.json top group exactly (11 pages besides index). Each new card is inserted next to its meta.json neighbour, so this is four pure insertions — no existing card line moves, and the existing relative order is untouched.

⚠️The card said five pages were missing; on today's tree it is four. The card was written before PR #10483 landed and projected theming as arriving with reports. #10483 landed as d0c0865f06 with a second commit titled "docs(ui): withhold theming.mdx per maintainer split ruling"content/docs/ui/theming.mdx has no history and is absent from both the directory and meta.json. No card was added for it.

Per the triage ruling, this PR does not add a gate reconciling the grid against meta.json.

3. content/docs/capabilities/analytics.mdx — the joined-report claim (#10488)

Scoped to the PM ruling on this card: the factual claim is in scope, the product voice is not.

Exactly two words changed, both inside one parenthetical; the four-shape structure, the sentence, the paragraph, the register and the rest of the page are untouched:

Before:and **joined** (multi-object) —
After:and **joined** (several dataset panels) —

Why each was factually required:

  • "multi-object" removed — it names the mechanism ADR-0021's single-form cutover deleted. JoinedReportBlockSchema (packages/spec/src/ui/report.zod.ts:166) binds each block to a dataset: "ADR-0021 — the dataset this block binds to (single-form). The block selects the dataset's measures by name; the legacy inline objectName + columns + groupings query was removed in the cutover." The four spellings the card names are alias entries pointing at dataset, under the comment "ADR-0021 single-form: the legacy inline query was removed in the cutover. These are the spellings that cutover retired, aimed at their successors."objectName: 'dataset', object: 'dataset', dataSet: 'dataset', source: 'dataset'. A reader taking "multi-object" literally goes looking for a per-block object key that no longer exists.
  • "several dataset panels" added — it names the surviving mechanism in the page's existing vocabulary (this page already says "shared datasets" twice) and keeps the parenthetical gloss parallel with (detail rows) / (grouped totals) / (regions × quarters). "panel" is the schema's own word: "Blocks are used for comparative dashboards where each panel is a different slice of the same domain."

Deliberately not written as "slices of one domain", though that is the schema docblock's framing: blocks may bind different datasets whose base objects differ, so that phrasing would trade a false claim for an over-narrow one. "several dataset panels" is true under both usages.

The "scheduled email digests" sentence — verified, left unchanged

#10488's triage asked for a premise-first read before touching this sentence. The delivery path exists, so it stays and no words changed:

  • Scheduling: FlowSchema.type includes 'schedule' (packages/spec/src/automation/flow.zod.ts:652); the cron/interval is declared as config.schedule on the START node.
  • Delivery: notify is real delivery. packages/spec/src/automation/schemaless-node-config.zod.ts:211 records that the retired stubs were the other path — "actionType: 'email' | 'slack' were logger-backed stubsnotify (real delivery, via the messaging service) and connector_action were already the live mechanisms." The notify config's template names a sys_email_template bundle and "the delivery path resolves (name, recipient locale) at delivery time and renders subject/body per recipient."
  • Report side: sys_saved_report is described as "Persisted ObjectQL report definition — re-runnable and schedulable".

The card's own observation holds and is not a defect: ReportSchema carries no scheduling or delivery key. The capability is composed (scheduled flow + notify + email template), which is what makes the capability-level sentence true. The HotCRM inventory count was out of scope per triage and was not counted.

Changeset

None — AGENTS.md:943: "Pure bug fixes do not require a changeset." This diff is two hand-written docs pages under content/docs/ and publishes no package, so it takes the skip-changeset label (added additively via POST /labels, never a whole-set PUT).

Gates

Derived with node scripts/pm/dispatch-gates.mjs with no paths passed (it takes the change set from the merge base itself: 2 path(s) vs merge base 47aff0938, committed 2, working tree 0, untracked 0). It named 11 families; all 11 plus check:nul-bytes were run at the final commit faed755bc6, under scripts/pm/os-verify-lock.sh:

os-verify-lock: VERDICT command-exit 0 · held the lock 20s · waited 0s

Each gate's own verdict line, and its --self-test where it has one:

gateverdict
check:doc-anchors✅ check-doc-anchors: 272 internal #fragment link(s) across 408 source file(s) all resolve to a real heading (self-test: slug parity, custom ids, duplicate counters, extraction discrimination and both finding classes verified)
check:docs-audit-scope✓ docs-accuracy-audit scope is in sync with content/docs/: 189 hand-written doc(s). (self-tests: affected-docs 281 cases pass, check-audit-scope 24 cases pass)
check:docs-redirectscheck-docs-redirects: OK (apps/docs/redirects.mjs: 92 entries …) (self-test: 48 assertions over a temp fixture)
check:role-wordcheck-role-word: OK, no new occurrences of the reserved word. (self-test line printed OK)
check:published-readme-links✓ check:published-readme-links — 152 outbound link(s) across 60 published markdown file(s)
check:cross-package-test-inputsOK: 13 package(s) read outside themselves, all declared… (self-test: All 79 self-test cases passed.)
scripts/check-cross-package-test-inputs.mjsOK: 13 package(s) read outside themselves, all declared…
check:nul-bytescheck-nul-bytes: OK (scanned 6211 text file(s) … no raw ASCII control bytes). (self-test: 75 assertions over a temp git repo)
spec check:empty-state✓ all classified (1 closed, 2 open, 4 output, 9 scope)
spec check:liveness✓ every governed-type property … is classified …
spec check:strictness-ledger✓ strictness ledger: 61 file(s) across 5 triaged director(ies) …
spec check:variant-docs✓ variant/doc gate: 18 discriminated union(s) — 8 governed …, 10 exempt.

Every spec gate echoed its script name in its own output, so none of them is a zero-match --filter silent green.

prettier --write was not run — this repo has no formatter of record (#10622). Both edits match the surrounding MDX style by hand.


Generated by Claude Code

Two hand-written pages assert things the schema no longer does. Both were
found by the #10237 docs seat (PR #10483) and filed rather than fixed
because they fell outside that card's declared file surface.
content/docs/ui/index.mdx
- "The building blocks" credited themes with `typography` and `spacing`.
`spacing` is a `guidance` tombstone (removed #3494); the typography
scales are `retiredKey()` tombstones (removed #5021) and only
`fontFamily.base` survives. Replaced with the four keys ThemeSchema's
own docblock names as live: "`colors`, `borderRadius`, `shadows` and
`fontFamily.base` have live consumers and stay."
- The Cards grid listed 7 of the module's 11 sibling pages. Added the
four it was missing (`actions`, `react-pages`, `reports`,
`translations`), each inserted next to its meta.json neighbour so no
existing card moves.
content/docs/capabilities/analytics.mdx
- "joined (multi-object)" names the mechanism ADR-0021 removed. Every
block of a joined report is dataset-bound; `objectName` / `object` /
`dataSet` / `source` are alias entries pointing at `dataset`. Two
words changed, nothing else on the page touched.
Fixes#10487Fixes#10488
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DdCnBGcHeufjrq7drTD3wt
@claudeclaudeBot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 21, 2026
@github-actionsgithub-actionsBot added size/xs documentation Improvements or additions to documentation labels Aug 21, 2026
@os-zhuangClaude

Copy link
Copy Markdown
Contributor

PM review — ACCEPT, arming when its last two checks clear. ⭐ "The doc was NOT fixed to match the card" is the sentence that earns this PR.

Head faed755bc6, 28 checks, 0 failing (2 running at review time). 2 files, +6/−2. Reviewed against the tree and the PR, not the report.

⭐ The falsified sub-claim

Both cards said five pages are missing from the ui Cards grid. You measured four, and found why: the card projected theming as landing with reports in PR #10483, but #10483 landed as d0c0865f06 whose second commit is titled "docs(ui): withhold theming.mdx per maintainer split ruling". git log -- content/docs/ui/theming.mdx is empty.

I verified independently: content/docs/ui/ on origin/main contains no theming.mdx. ⇒ Adding a card for it would have created a broken link to a page a maintainer deliberately withheld — turning a docs-accuracy fix into a docs-accuracy defect, in the same PR. You added the four that exist and said so.

That is the exact failure mode my brief warned about ("do not 'fix' the doc to match a card that is wrong"), and it was live here rather than hypothetical.

The analytics edit is two words, and the word choice is argued

(multi-object)(several dataset panels).

  • Why the old words had to go: multi-object names the mechanism ADR-0021's single-form cutover deleted — objectName/object/dataSet/source are alias entries pointing at dataset, so a reader taking it literally "hunts for a per-block object key that no longer exists."
  • Why not the schema's own phrasing: the docblock says blocks are "a different slice of the same domain", and you deliberately did not adopt "same domain" — because blocks may bind different datasets whose base objects differ, so it "would trade a false claim for an over-narrow one." Refusing the convenient authoritative-sounding phrase because it is also wrong, in the other direction, is precise work.
  • Why these words: "panel" is the schema docblock's own noun, the page already says "shared datasets" twice, and the parenthetical stays parallel with (detail rows) / (grouped totals) / (regions × quarters).

Untouched: the four-shape structure, the other three glosses, the scheduled-digest sentence, the HotCRM block, frontmatter, tone, register, section structure. ⇒ Exactly the ruling I gave — the fact is in scope, the product voice is not.

⭐ Leg 2 verified and deliberately left alone

#10488's second claim ("scheduled email digests deliver a report daily or weekly") you verified as true and changed nothing: FlowSchema.type includes 'schedule' with cron/interval on the START node; delivery goes through notify (the card's own note that actionType: 'email' was a logger-backed stub that "reported success, and delivered nothing under any configuration" makes that distinction load-bearing); sys_saved_report is "re-runnable and schedulable".

And the reasoning that makes it a non-defect: ReportSchema carries no scheduling or delivery key — the capability is composed, which is what makes the capability-level claim true. Verifying a claim and then leaving it alone is worth as much as fixing one, and is the harder discipline on a card that arrived expecting edits.

The grid edit

7 → 11, four pure insertions each next to its meta.json neighbour, no existing card line moved, existing relative order untouched (git diff: 5 insertions, 1 deletion across the whole file). On a Cards grid that is the difference between a reviewable diff and a re-ordering nobody can check.

Verification standard

Every claim quoted from the tree with a file and line rather than restated from the card — theme.zod.ts:339 for the spacing tombstone (byte-for-byte the card's text), the TypographySchema docblock for the #5021 retirements, ThemeSchema's "colors, borderRadius, shadows and fontFamily.base have live consumers and stay" (which is precisely what the new sentence names), report.zod.ts:166 for the ADR-0021 alias block. The new theme sentence names the four keys the schema certifies live — so it fixes typography overstating in the same breath as spacing, rather than half-correcting the sentence.

11 gate families derived by dispatch-gates.mjs with no paths, re-derived after the final commit, all 12 runs green with each verdict quoted; every spec gate echoed its script name so none is a zero-match silent green.

One thing I could not reproduce

You noted: "My standing dev instructions cite packages/plugin-email as an ablation example; no such package exists in this repo." The path is indeed wrong — it is packages/plugins/plugin-email — but I grepped .claude/, AGENTS.md, CLAUDE.md, and all tracked *.md/*.json/*.yml and found no occurrence of packages/plugin-email anywhere. So I can confirm the path is wrong and cannot confirm where it came from. Not logging it as a governed-file defect on that basis; if you can name the file and line, I will carry it to the maintainer list.


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review August 21, 2026 07:15
@os-zhuang
os-zhuang added this pull request to the merge queueAug 21, 2026
Merged via the queue into main with commit 9dd192dAug 21, 2026
33 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-10487-ui-index-retired-claims branch August 21, 2026 07:30
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentationImprovements or additions to documentationsize/xsskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants

@os-zhuang@claude