Skip to content

docs(ui): document the html and react page authoring tiers - #10281

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-10210-react-page-authoring
Aug 20, 2026
Merged

docs(ui): document the html and react page authoring tiers#10281
os-zhuang merged 1 commit into
mainfrom
claude/issue-10210-react-page-authoring

Conversation

@os-elon

Copy link
Copy Markdown
Collaborator

Fixes#10210 · sub-issue of #10206

What this adds

The react tier is real, shipped and gated, but on the docs site a developer could
find only two generated schema rows, one negatively-phrased bullet, and the validation
rules. The Page Properties table listed neither kind nor source, so the Page guide
read as if regions + components were the only way to author a page.

  • content/docs/ui/pages.mdx — adds the kind and source rows to Page
    Properties, and an Authoring modes section before ## Regions contrasting
    full/slotted vs html vs react, stating plainly that source is authoritative
    over regions, and carrying the ADR-0065 styling warning that applies to both
    source tiers. Cross-links the new page and deployment/validating-metadata.
  • content/docs/ui/react-pages.mdx (new) — the react-tier guide: the trust
    boundary, the react-pages host capability and the OS_PAGE_REACT=off kill switch,
    the injected scope and PascalCase tags, flat props and the Block escape hatch,
    useAdapter query shapes, the ADR-0065 styling rule, accepted source shapes, page
    state, the record:* exclusion, and the real os validate output for each failure
    mode.
  • content/docs/ui/meta.jsonreact-pages immediately after pages.
  • .claude/workflows/docs-accuracy-audit.js — a declared deviation from this card's
    file surface; see the section below for why it is required and not optional.

Per-block prop tables are not restated. The generated contract
(skills/objectstack-ui/references/react-blocks.md, built from REACT_BLOCKS by
packages/spec/scripts/build-react-blocks-contract.ts) is linked as the authority.
No file under packages/spec/**, skills/**, or the objectui repo is touched, and no
file under content/docs/ui/ other than the three above — #10237 owns the rest.

Everything on the page was measured, not recalled

The os validate blocks are real captured output, not composed. os validate was run
against examples/app-showcase with the built CLI, clean and then with deliberate
mistakes injected into renewals-pipeline.page.ts:

runresult
unmodifiedexit 0 · Running author-time rules (41)... · Validation passed (1523ms)
objectName dropped from the ObjectChart blockexit 1 · react-prop-missing-required
onSuccess renamed to onSucces on the ObjectForm blockexit 0 · warning only, confirming the severity split
the ObjectForm view panel swapped for a RecordHighlights blockexit 1 · react-block-needs-record-context

Each mutation was confirmed on disk by grepping for both the removed and the injected
text before the run, and the file was restored to a byte-identical copy afterwards
(sha256 matched, git status clean).

Sources disagreed; here is how each was resolved

objectui/content/docs/guide/react-pages.md was the starting draft. Four of its claims
are contradicted by this repo's sources and were not carried over:

  1. Tailwind styling. The objectui guide styles its react example with
    className="grid grid-cols-2 gap-4" and instructs "compose layout with real HTML and
    Tailwind". ADR-0080 carries an explicit amendment (2026-06-30, ADR-0065 styling
    correction): "Do not author Tailwind classes in page source" — a page's source is
    runtime metadata the console's build-time Tailwind never scans, so utility classes
    silently produce no CSS. The generated contract says the same, and all three real
    kind:'react' pages in examples/app-showcase contain zeroclassName and style
    exclusively with inline style objects plus hsl(var(--token)) colors. This repo's
    sources win; the rule is the page's most prominent callout.
  2. record:* blocks. The objectui guide offers record:details as an in-scope
    example. Those blocks are reachable in the runtime scope, but os validate rejects
    them (react-block-needs-record-context). The page states both halves.
  3. adapter.find options. The objectui guide writes
    adapter.find('x', { filters: [['status','=','open']] }). filters is not a
    QueryParams key — the canonical keys are $filter / $top / $skip / $select /
    $orderby / $search, and the adapter reads $filter. The guide's sample returns
    unfiltered data with no error. The page uses $filter / $top and warns about
    the prefix explicitly.
  4. Block inventory. The objectui guide names ObjectGrid, ObjectKanban and
    ObjectMetric. The curated contract publishes ObjectForm, ListView, ObjectChart and
    Block; a kanban is ListView viewType="kanban" or Block type="object-kanban". The
    page defers to the generated contract and does not list block names of its own.

Filed upstream rather than smoothed over — see the linked findings.

Declared deviation from the file surface, and why this PR is human-merge-only

This card's declared file surface is content/docs/ui/**. One path outside it is in
this diff, deliberately: .claude/workflows/docs-accuracy-audit.js.
It is not a hand
edit — it is exactly what the gate's own --write produced, committed unmodified.

check:docs-audit-scope goes red the moment a hand-written page is added to
content/docs/, and its only remedy is node scripts/docs-audit/check-audit-scope.mjs --write, which regenerates that file (a +1/-0 line). The list has to live inline
there because the workflow runs in a node:vm with no filesystem and cannot enumerate
content/docs itself. .claude/** is on the governed register, so:

$ node scripts/pm/check-governed-merges.mjs --test \
content/docs/ui/pages.mdx content/docs/ui/react-pages.mdx \
content/docs/ui/meta.json .claude/workflows/docs-accuracy-audit.js
governed-surface predicate: 1 of 4 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

This is #9866 exactly, which already measures the same +1/-0 collision on four
page-adding docs PRs. No seat should flip this ready, enqueue it, or arm auto-merge.
The regeneration is not optional — dropping it makes a required lint context red.

Gates

Re-derived with node scripts/pm/dispatch-gates.mjsafter the final commit — the
.claude/ file pulled in three families the dispatch list did not name
(check:pm-governed-merges, check:skill-frame-sync,
@objectstack/lint check:doc-formula-expressions). All 15 run green at c6a62709c:

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 · 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: 254 internal #fragment link(s) across 400 source file(s) all resolve to a real heading
docs-accuracy-audit scope is in sync with content/docs/: 181 hand-written doc(s).
doc authoring guard: 381 files clean — no bare metadata literals.
check-role-word: OK, no new occurrences of the reserved word.
210 prose examples type-check against @objectstack/spec

The new page carries one {/* os:check */} block — a complete definePage({...}) react
page — and check:skill-examples extracted and type-checked it
(content/docs/ui/react-pages.mdx:346 -> docs__ui_react-pages__1.ts), so the sample is
verified against the built spec rather than asserted.

No changeset

Docs-site content plus one generated scope line; this PR publishes no package. Labelled
skip-changeset.


Generated by Claude Code

The react tier is real, shipped and gated, but the docs site only mentioned
it negatively (one bullet saying `record:*` blocks are rejected there) and the
Page Properties table listed neither `kind` nor `source` — so the Page guide
read as if `regions` + `components` were the only way to author a page.
- `ui/pages.mdx`: add the `kind` and `source` rows, and an "Authoring modes"
section before `## Regions` contrasting the three tiers, stating that
`source` is authoritative over `regions`, and carrying the ADR-0065 styling
warning that applies to both source tiers.
- `ui/react-pages.mdx` (new): the full react-tier guide — the trust boundary,
the `react-pages` capability and `OS_PAGE_REACT=off`, the injected scope,
flat props and `<Block>`, `useAdapter` query shapes, the ADR-0065 styling
rule, accepted source shapes, page state, the `record:*` exclusion, and the
real `os validate` output for each failure mode. Per-block prop tables are
linked to the generated contract, never restated.
- `ui/meta.json`: list `react-pages` immediately after `pages`.
- `.claude/workflows/docs-accuracy-audit.js`: regenerated by
`scripts/docs-audit/check-audit-scope.mjs --write`, which `check:docs-audit-scope`
requires whenever a hand-written docs page is added.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GawRwpD44VwBDVy3hs77AX
@os-zhuang
os-zhuang marked this pull request as ready for review August 20, 2026 16:49
@os-zhuang
os-zhuang added this pull request to the merge queueAug 20, 2026
Merged via the queue into main with commit 0bfbeb7Aug 20, 2026
24 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-10210-react-page-authoring branch August 20, 2026 17:27
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): kind:'react' / kind:'html' page authoring has no guide, and the Page Properties table omits kind and source entirely

3 participants

@os-elon@os-zhuang@claude