Skip to content

docs(ui): add the report and theming guides, and the book spine half of doc-pages - #10483

Merged
os-zhuang merged 2 commits into
mainfrom
claude/issue-10237-ui-reports-theming-book
Aug 21, 2026
Merged

docs(ui): add the report and theming guides, and the book spine half of doc-pages#10483
os-zhuang merged 2 commits into
mainfrom
claude/issue-10237-ui-reports-theming-book

Conversation

@os-elon

Copy link
Copy Markdown
Collaborator

Fixes#10237 · sub-issue of #10206 · last card of the epic

What this adds

Three authorable surfaces each had a generated schema reference and no page teaching
them. Same defect shape, same directory, one meta.json — landed together, but written
as three independently checkable pieces.

  • content/docs/ui/reports.mdx (new) — leads with the distinction that sends a
    reader here (report vs list view vs dashboard widget), then the four report types with
    worked summary / matrix / joined examples, ordering rules, drill-through, the
    embedded chart, app-nav reachability, and what the schema does and does not say about
    access. Dataset authoring, ordering semantics and filter placeholders are cross-linked
    to data-modeling/analytics.mdx, not restated.
  • content/docs/ui/theming.mdx (new) — what a theme declares, the schema-key to
    CSS-variable rename table, the two-theme light/dark idiom the showcase actually ships,
    extends / customVars / mode resolution, and the bare-HSL-triple token contract.
    Opens with a warn callout stating what authoring a theme does and does not wire up
    today (see below).
  • content/docs/ui/doc-pages.mdx — adds the book half. The existing doc content
    is untouched; the new section states precisely what derives group membership, the three
    per-doc keys the spine reads, identity and audience, a worked defineBook example, and
    how doc and book compose on the tree endpoint.
  • content/docs/ui/meta.jsonreports after dashboards, theming after
    reports. Exactly two insertions; nothing else re-ordered.
  • .claude/workflows/docs-accuracy-audit.js — the mechanical regeneration, committed
    exactly as the tool produced it. See the human-merge section.

Nothing under packages/spec/** is touched, and no file under content/docs/ui/ other
than the four above — pages.mdx and react-pages.mdx are read-only here.

Three PM premises were measured. One of them is false.

1. ReportSchema is live — confirmed.report is in MetadataType, in
DEFAULT_METADATA_TYPE_REGISTRY (**/*.report.ts, loadOrder: 60) and in
BUILTIN_METADATA_TYPE_SCHEMAS, so the runtime REST door validates a stored report.
App nav type: 'report' is cross-ref-validated in stack.zod.ts and routes to
/report/ plus the report name, which objectui renders through ReportView and
DatasetReportRenderer. No warn callout needed.

2. ThemeSchema parses but nothing applies it — FALSIFIED as "live and enforced".
This is the stack.tools shape the dispatch warned about, and the page says so in a warn
callout rather than reading as if authoring a theme wires something up:

LayerState
Authoring gatelivedefineStack({ themes }) / defineTheme() parse strictly (ADR-0078)
Artifact ingestliveARTIFACT_FIELD_TO_TYPE maps themes -> theme, items are registered
Metadata type registryabsenttheme appears zero times in metadata-plugin.zod.ts; not in MetadataType, not in the registry, not in BUILTIN_METADATA_TYPE_SCHEMAS, so there is no runtime REST validation door
CSS emission enginelivegenerateThemeVars in @object-ui/core, applied by the ThemeProvider in @object-ui/react via its themes prop
The last hopmissing — no first-party surface reads a stored theme item back, and no key selects one

Measured, not inferred: no framework package under core / runtime / rest /
services / plugins reads .themes or a 'theme' metadata item; the only
ThemeProvider mounted in objectui is ConsoleShell.tsx mounting
app-shell/chrome/ThemeProvider (a light/dark/system class toggle unrelated to
ThemeSchema), and the console never fetches theme metadata. AppSchema has no
theme key either — theme there is an alias onto branding.

What does colour a running console is app.branding.primaryColor / accentColor, read by
packages/layout/src/AppShell.tsx and written onto --primary,
--primary-foreground, --ring, --sidebar-primary, --sidebar-ring, --accent,
--accent-foreground. The page points there for "recolour the shipped console" and keeps
the theme surface for host apps that mount the provider. Filed as a finding.

3. BookSchema + ADR-0046 §6 describe a live derived-membership mechanism — confirmed,
and the page describes the resolver rather than the ADR.
resolveBookTree /
deriveImplicitPackageBook / resolveDocAudiences / docAudienceAllows are all called
from packages/rest/src/rest-server.ts on GET /meta/book/:name/tree. The page states
the actual four-step derivation (group order, first-claim-wins over include-or-group,
doc.order then label within a group, orphans into a synthetic Uncategorized group),
the two include forms, pages overrides with '---' / '...', and the two-stage
audience filter. One ADR/code divergence is noted inline: §6.7 sketches the gate as
{ profile }; the shipped key is { permissionSet } per ADR-0090.

Cross-page consistency with react-pages.mdx

theming.mdx is the other end of the token system react-pages.mdx describes, so the
two were made to agree on measurement, not by matching wording:

  • Why the hsl(…) wrapper exists.toCSSColor converts an authored hex to a bare
    HSL triple
    #7C3AED becomes 262 83% 58%. The variable holds the inside of a
    colour, so hsl(var(--card)) is required rather than stylistic. theming.mdx says this
    and links react-pages.mdx#styling; non-colour tokens (var(--radius),
    var(--shadow-md)) take no wrapper, matching that page's own examples.
  • Token ownership, stated so the two pages do not contradict each other.
    react-pages.mdx lists --primary-foreground and --space-* among usable tokens.
    Neither is theme-authorable — both come from the console base stylesheet
    (@object-ui/components/src/index.css, which wraps every colour token as
    hsl(var(--token))). theming.mdx therefore says a theme overrides a subset of the
    base token set rather than defining it, so a page may legitimately reference a token no
    theme can set.
  • The retracted framing is not propagated. Neither new page repeats the
    "constrained JSX/HTML+Tailwind" wording that ADR-0080's 2026-06-30 amendment retracted
    and that PageSchema's describe() strings still carry (spec: PageSchema's kind/source descriptions still teach "JSX/HTML+Tailwind", which ADR-0080's 2026-06-30 amendment retracted — and the generated reference publishes it verbatim #10286). theming.mdx
    describes theme tokens only and does not restate the page-styling rule it links to.

Everything on the pages was read from source

  • ReportsReportSchema / JoinedReportBlockSchema / ReportSortSchema and the
    four showcase reports in examples/app-showcase/src/ui/reports/index.ts. The
    report-vs-view distinction is the showcase's own recorded conversion (its former
    TaskListReport became the tabular list view on showcase_task, because a flat
    record list is an object-bound row lens under ADR-0017), not an invented framing.
  • Themes — the emitted-variable table is COLOR_TO_CSS_MAP plus the radius/shadow
    maps in @object-ui/core's ThemeEngine.ts, key by key. The light/dark idiom is
    examples/app-showcase/src/ui/themes/index.ts — two theme items sharing a palette base,
    which is what the schema supports (mode is a scalar; there is no nested dark block).
  • BooksBookSchema and the resolveBookTree resolver, plus the REST route.

One PM lead corrected: the report "two data paths"

The card asks for "the two data paths: object-bound and dataset-bound". There is one.
Under the ADR-0021 single-form cutover the legacy inline objectName + columns +
groupings query was removed; ReportSchema.superRefine requires dataset + values for
every non-joined report, and objectName / object / source / dataSet are alias
entries pointing at dataset. The page documents one path and says so in an info callout,
and analytics.mdx is cross-linked for the dataset side as instructed. The two pages agree.

Human-merge-only, expected, not a failure

check:docs-audit-scope went red the moment the two new pages existed:

✗ .claude/workflows/docs-accuracy-audit.js: ALL_HANDWRITTEN has drifted from content/docs/.
+ content/docs/ui/reports.mdx
+ content/docs/ui/theming.mdx

Its only remedy is node scripts/docs-audit/check-audit-scope.mjs --write, which produced
a +2/-0 edit to that file — committed unmodified. .claude/** is on the governed
register:

$ node scripts/pm/check-governed-merges.mjs --test ...the five paths...
governed-surface predicate: 1 of 5 path(s) hit the register (5 surfaces, repo-agnostic).
GOVERNED — a human merge is the review record for this PR (#9495 regime).
.claude/** x1 — the agent instruction tree (skills, agents, hooks, settings)
- .claude/workflows/docs-accuracy-audit.js
exit 3

No seat should flip this ready, enqueue it, or arm auto-merge. Dropping the
regeneration is not an option — it makes a required lint context red. This is #9866, the
same collision all five sibling docs PRs in this epic hit.

Gates

Re-derived with node scripts/pm/dispatch-gates.mjs (no path args — it derives its own
change set) after the final commit, and the whole union re-run at that commit,
72e1a98f2. All 15 derived families green, plus check:nul-bytes and
check:skill-examples:

check:doc-anchors · check:doc-authoring · check:docs-audit-scope ·
check:docs-redirects · check:published-readme-links · check:role-word ·
check:cross-package-test-inputs (both spellings) · check:pm-governed-merges ·
check:skill-frame-sync · @objectstack/lint check:doc-formula-expressions · and the
spec set check:empty-state · check:liveness · check:strictness-ledger ·
check:variant-docs · check:skill-examples.

Verdict lines, as the gates printed them:

check-doc-anchors: 259 internal #fragment link(s) across 402 source file(s) all resolve to a real heading
docs-accuracy-audit scope is in sync with content/docs/: 183 hand-written doc(s).
doc authoring guard: 383 files clean — no bare metadata literals.
check-role-word: OK, no new occurrences of the reserved word.
219 prose examples type-check against @objectstack/spec
check:doc-formula-expressions: 22 record-scoped formula example(s) across 409 files / 1425 TS blocks judged clean
OK: 12 package(s) read outside themselves, all declared, and turbo.json hashes every declared glob.

check:doc-formula-expressions needs @objectstack/formula built on a fresh worktree —
built alongside @objectstack/spec before the run, so no ERR_MODULE_NOT_FOUND.

The nine {/* os:check */} blocks these pages add were confirmed extracted from the
gate's own log rather than assumed — five in reports.mdx, three in theming.mdx, one in
doc-pages.mdx:

content/docs/ui/doc-pages.mdx:252 → docs__ui_doc-pages__1.ts
content/docs/ui/reports.mdx:69,88,114,185,208 → docs__ui_reports__1..5.ts
content/docs/ui/theming.mdx:44,112,144 → docs__ui_theming__1..3.ts

No changeset

Docs-site content plus one generated scope line; this PR publishes no package. Labelled
skip-changeset, matching sibling #10281.

Out-of-scope findings, filed not fixed

Listed in the report comment on #10237.


Generated by Claude Code

…of doc-pages
Three authorable surfaces had a generated schema reference and no page teaching
them. Same defect shape, same directory, one meta.json — landed together.
- content/docs/ui/reports.mdx (new) — leads with the distinction that sends a
reader here (report vs list view vs dashboard widget), then the four report
types, drill-through, the embedded chart, app-nav reachability, and what the
schema does and does not say about access. Dataset authoring, ordering
semantics and filter placeholders are cross-linked to
data-modeling/analytics.mdx rather than restated.
- content/docs/ui/theming.mdx (new) — the palette/typography/radius/shadow
surface, the schema-key -> CSS-variable rename table, the two-theme light/dark
idiom the showcase actually ships, and the bare-HSL-triple token contract that
makes ui/react-pages.mdx's `hsl(var(--token))` rule what it is. Carries a warn
callout stating what authoring a theme does and does not wire up today.
- content/docs/ui/doc-pages.mdx — adds the `book` half. The existing `doc`
content is untouched; the new section states precisely what derives group
membership, the three per-doc keys the spine reads, identity and audience, a
worked example, and how `doc` and `book` compose on the tree endpoint.
- content/docs/ui/meta.json — `reports` after `dashboards`, `theming` after
`reports`. Two insertions; nothing else re-ordered.
- .claude/workflows/docs-accuracy-audit.js — the mechanical `--write`
regeneration `check:docs-audit-scope` requires when a hand-written page is
added, committed exactly as the tool produced it (+2/-0). `.claude/**` is a
governed surface, so this PR is human-merge-only.
Claude-Session: https://claude.ai/code/session_01GawRwpD44VwBDVy3hs77AX
Co-authored-by: Claude <sales@objectstack.ai>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
@os-zhuang
os-zhuang marked this pull request as ready for review August 21, 2026 03:21
@os-zhuang
os-zhuang added this pull request to the merge queueAug 21, 2026
@os-elonClaude

Copy link
Copy Markdown
CollaboratorAuthor

Maintainer ruling: this PR is split — theming.mdx is withheld, the other two guides land

Ruled live in the PM session, 2026-08-21, after the #10485 enforce-or-remove ruling (option B: retire the themes authoring surface) landed between this PR's writing and its merge. The maintainer's reasoning, verbatim (untranslated):

那几段"怎么写"的示例,是在给一个已裁定要拆掉的面做推广。……一个有完整示例的文档页对 AI 作者的信号强度,远高于一段警告对它的劝阻。

and the chosen disposition: 「路 2:拆开合reports.mdxbook 那半(都不受裁决影响,质量也没问题)现在就合;theming.mdx 扣住,让退役卡一并处置 theming 的文档终局。」

What changes on this branch (an appended commit — no history rewrite; a dev is dispatched for the mechanical edit):

  • remove content/docs/ui/theming.mdx
  • remove the "theming" entry from content/docs/ui/meta.json (the "reports" entry stays)
  • re-run node scripts/docs-audit/check-audit-scope.mjs --write so ALL_HANDWRITTEN drops the withheld page (committed as the tool produces it)

reports.mdx, doc-pages.mdx and everything else in this PR are untouched. The PR body is deliberately not edited — it records what was true when written; this comment is the record of the split (same convention as prior mid-flight corrections).

The withheld theming.mdx content stays recoverable in this branch's history. Its endgame — deletion vs. a short app.branding pointer page, and where the still-true token-contract facts (bare-HSL-triple values, the base-stylesheet-owned token set) migrate — is owned by the retirement card #10485, which was updated accordingly. Note the page's warn callout framing ("declaring the palette now so it is ready when the hop lands") presupposed the enforce direction and is inaccurate under ruling B — one more reason it does not ship in the window.

This PR remains governed-surface (.claude/**) — human merge only, after the split commit lands and CI re-converges.


Generated by Claude Code

Per the maintainer ruling on PR #10483 (issue comment
#10483 (comment)),
issue #10485 retired the `themes` authoring surface (option B) between this
PR's writing and its merge, so its theming guide must not ship while
reports.mdx and the doc-pages book half land as planned.
- remove content/docs/ui/theming.mdx
- drop the "theming" entry from content/docs/ui/meta.json ("reports" stays)
- regenerate .claude/workflows/docs-accuracy-audit.js via
node scripts/docs-audit/check-audit-scope.mjs --write (ALL_HANDWRITTEN -1)
The withheld content stays recoverable in this branch's history; its
disposition (deletion vs. a short app.branding pointer page) is owned by
the retirement card #10485.
@os-elonClaude

Copy link
Copy Markdown
CollaboratorAuthor

os-dev-report

Mechanical split-commit is prepared and verified locally but could not be pushed — the PR's head branch has been added to a merge queue, and GitHub's protected-branch hook refuses the push:

remote: error: GH006: Protected branch update failed for refs/heads/claude/issue-10237-ui-reports-theming-book.
remote: - A pull request for this branch has been added to a merge queue. Branches that
remote: are queued for merging cannot be updated. To modify this branch, dequeue the
remote: associated pull request.

This PR touches .claude/workflows/docs-accuracy-audit.js — a governed surface (AGENTS.md Prime Directive #14). Per that directive it should never have entered the merge queue, and the PR's own body (written by the prior dev) says as much: "No seat should flip this ready, enqueue it, or arm auto-merge." At the time I read it, pull_request_read reported draft: false (queue membership doesn't show there — this only surfaced via the rejected push).

Per my dispatch's basic rules, dequeuing / flipping this PR to draft is explicitly not my call — that state was set by another actor and reversing a ready/queue flip is reserved for the PM or maintainer. I am stopping here rather than touching it.

Work completed and verified, sitting as a local unpushed commit (a746b55, one commit appended on top of the PR's then-head 72e1a98f2, no rebase/amend):

  • git rm content/docs/ui/theming.mdx
  • content/docs/ui/meta.json: removed the "theming" entry only ("reports" untouched)
  • node scripts/docs-audit/check-audit-scope.mjs --write.claude/workflows/docs-accuracy-audit.js regenerated, -1 line (the theming.mdx entry), reports.mdx entry untouched

Diffstat vs the PR's origin/claude/issue-10237-ui-reports-theming-book (pre-commit head 72e1a98f2) — exactly 3 files:

 .claude/workflows/docs-accuracy-audit.js | 1 -
content/docs/ui/meta.json | 1 -
content/docs/ui/theming.mdx | 227 -------------------------------
3 files changed, 229 deletions(-)

Confirmed no dangling inbound links into the removed page before deleting (content/docs/references/ui/dashboard.mdx and content/docs/protocol/objectui/widget-contract.mdx only mention the word "theming" in prose, no markdown link into theming.mdx; no ](.../theming) link anywhere in content/).

Gates run against the actual diff (node scripts/pm/dispatch-gates.mjs, no path args), all green at commit a746b55:

  • check:doc-authoring — exit 0 — "doc authoring guard: 382 files clean"
  • check:doc-anchors — exit 0 — "256 internal #fragment link(s) across 401 source file(s) all resolve to a real heading"
  • check:docs-audit-scope — exit 0 — "docs-accuracy-audit scope is in sync with content/docs/: 182 hand-written doc(s)"
  • check:docs-redirects — exit 0
  • check:role-word — exit 0
  • check:skill-frame-sync — exit 0
  • check:pm-governed-merges (self-test) — exit 0
  • check:cross-package-test-inputs — exit 0
  • check:published-readme-links — exit 0
  • @objectstack/spec check:empty-state — exit 0
  • @objectstack/spec check:liveness — exit 0 ("every governed-type property ... classified")
  • @objectstack/spec check:strictness-ledger — exit 0
  • @objectstack/spec check:variant-docs — exit 0
  • @objectstack/lint check:doc-formula-expressions — exit 0
  • check:nul-bytes — exit 0 (self-scan, files touched)

node scripts/pm/check-governed-merges.mjs --test against the diff still correctly reports GOVERNED (the .claude/** hit, as before) — unchanged from the PR's existing state, confirming this commit doesn't change the governed classification.

Needed from the PM/maintainer: dequeue this PR (or confirm it should stay queued and tell me why, since that reads as a Prime Directive #14 violation) so the branch accepts a push, then I can land this commit as-is — no rework needed, just a re-push once the branch is writable. The commit is sitting locally in my worktree (/home/user/objectstack-pr10483-theming-split, branch claude/issue-10237-ui-reports-theming-book, HEAD a746b55) ready to push the moment the branch is unblocked.


Generated by Claude Code

@os-elon
os-elon removed this pull request from the merge queue due to a manual request Aug 21, 2026
@os-elonClaude

Copy link
Copy Markdown
CollaboratorAuthor

os-dev-report

Split commit pushed successfully. The prior GH006 rejection (PR was in a merge queue, an incident being tracked separately by the maintainer) is resolved — the remote branch was confirmed still at the unmoved head 72e1a98f2, so the previously-prepared local commit was pushed as-is, no re-application needed, no rebase, no force.

Commit:a746b55 (one ordinary commit appended on top of the PR's original head 72e1a98f2), pushed to claude/issue-10237-ui-reports-theming-book.

Diffstat vs the prior head (72e1a98f2..a746b55) — exactly 3 files:

 .claude/workflows/docs-accuracy-audit.js | 1 -
content/docs/ui/meta.json | 1 -
content/docs/ui/theming.mdx | 227 -------------------------------
3 files changed, 229 deletions(-)
  • git rm content/docs/ui/theming.mdx
  • content/docs/ui/meta.json: removed the "theming" entry only ("reports" untouched)
  • node scripts/docs-audit/check-audit-scope.mjs --write: .claude/workflows/docs-accuracy-audit.js regenerated as produced, ALL_HANDWRITTEN-1 (the theming.mdx line; reports.mdx stays)

Gates run against this diff (node scripts/pm/dispatch-gates.mjs, no path args, derived the 15 families below), all green:

  • check:doc-authoring — exit 0 — "doc authoring guard: 382 files clean"
  • check:doc-anchors — exit 0 — "256 internal #fragment link(s) across 401 source file(s) all resolve to a real heading"
  • check:docs-audit-scope — exit 0 — "docs-accuracy-audit scope is in sync with content/docs/: 182 hand-written doc(s)"
  • check:docs-redirects — exit 0
  • check:role-word — exit 0
  • check:skill-frame-sync — exit 0
  • check:pm-governed-merges (self-test) — exit 0
  • check:cross-package-test-inputs — exit 0
  • check:published-readme-links — exit 0
  • @objectstack/spec check:empty-state — exit 0
  • @objectstack/spec check:liveness — exit 0
  • @objectstack/spec check:strictness-ledger — exit 0
  • @objectstack/spec check:variant-docs — exit 0
  • @objectstack/lint check:doc-formula-expressions — exit 0
  • check:nul-bytes — exit 0

node scripts/pm/check-governed-merges.mjs --test still correctly reports GOVERNED for this diff (the .claude/** hit is unchanged by this commit).

Not flipped ready, not armed for auto-merge, not touched by me at all — that state remains the maintainer's / PM's to set. Awaiting CI re-convergence and human merge.


Generated by Claude Code

@os-elon
os-elon marked this pull request as draft August 21, 2026 03:59
@os-zhuang
os-zhuang marked this pull request as ready for review August 21, 2026 04:05
@os-zhuang
os-zhuang added this pull request to the merge queueAug 21, 2026
Merged via the queue into main with commit d0c0865Aug 21, 2026
30 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-10237-ui-reports-theming-book branch August 21, 2026 04:36
os-zhuang pushed a commit that referenced this pull request Aug 21, 2026
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
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs(ui): report and theme have generated references and no guide, and doc-pages.mdx never mentions book

3 participants

@os-elon@os-zhuang@claude