Skip to content

docs(objectui): layout-dsl teaches only shapes the live schemas accept - #13337

Merged
os-project-manager merged 2 commits into
mainfrom
claude/issue-13266-layout-dsl-untrue-fences
Aug 30, 2026
Merged

docs(objectui): layout-dsl teaches only shapes the live schemas accept#13337
os-project-manager merged 2 commits into
mainfrom
claude/issue-13266-layout-dsl-untrue-fences

Conversation

@claude

@claude claude Bot commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Brings content/docs/protocol/objectui/layout-dsl.mdx down to the shapes the live
schemas actually accept, and pins every example so it cannot drift again.

Census (from the gate's own output, not counted by hand):
content/docs/protocol/objectui/layout-dsl.mdx: 6 tagged / 17 untagged
18 tagged / 0 untagged. Corpus-wide, check:yaml-examples goes from
6 tagged / 147 untagged to 18 tagged / 130 untagged.

Premise re-derived on this base, before editing

The card's readings were measured on the #13086 branch. Re-derived here on
origin/main @ 2fc11958 (which contains the merged checker, 2ebfe7e9) by
extracting all 23 YAML fences and running safeParse against every schema each
could plausibly claim — PageSchema, PageRegionSchema, PageComponentSchema,
FormViewSchema, FormSectionSchema, FormFieldSchema, ListViewSchema, plus
wrapper-unwrapped (key=section / sections / layout / steps) variants.

Result: 6 tagged, 17 untagged, and zero of the 17 was accepted by any candidate
schema.
The card's premise holds in full; no section had been repaired in the
interim. Every grouping in the card reproduced verbatim.

Section × disposition

Default per triage is DELETE/rewrite — bring the docs to the spec. Nothing here
widens the accepted set, and no packages/spec source is touched.

Fence (old line) Section Disposition Basis
75 Standard Template rewrite + tag page context: is on no schema; name/label required. page:section carries only children, so the field body is record:details
126 Console Template rewrite + tag page same context: defect; record:list is not a component type — the list block is object-grid
187 Wizard Template DELETE + Callout steps exists on no schema. template: wizard parses (free string) while naming a template no renderer provides
250 Custom Span Widths rewrite + tag FormSectionSchema key=section no section-level layout:; field span is the enum auto/full, colSpan is 1–4 — there is no span: 6
395 Section Variants DELETE + Callout variant is a phantom key on FormSectionSchema
417 Inline Field Group DELETE, replaced field_group is a type on no schema; section columns + per-field span already express it
442 Address Field Group DELETE, folded into the same replacement ditto; a genuinely composite value is a field of type address/composite
593 Basic Related List rewrite + tag PageComponentSchema a related list is a page component, not a form section; objectName/relationshipField, and actions is a list of ids
623 Inline Editing Related List DELETE + Callout RecordRelatedListProps declares no mode, and its columns is field-name strings, never column objects
655 Metric Widget rewrite + tag PageComponentSchema the real block is object-metric; it aggregates its object and has no literal value:; colorVariant, not color
680 Activity Feed Widget rewrite + tag PageComponentSchema record:activity, bound to the page's record — no object/filter of its own
693 Custom Widget rewrite + tag PageComponentSchema a custom.* type is a legitimate open extension point; the type: widget + component:/config: wrapper is not
706 Master-Detail Split View DELETE as written, replaced + tag no page-level layout: block (layout aliases to template); the declared block is object-master-detail-form
723 Grid of Cards DELETE + Callout no schema, and its per-breakpoint columns map is the same breakpoint-map class already removed from this page
744 Kanban Board rewrite + tag PageComponentSchema the declared block is object-kanban; columns are swimlane definitions, not a field projection
934 Customer 360 rewrite + tag page regions is an array, not a map; label was missing; inner type: section/widget/related_list spellings corrected
990 Multi-Step Wizard DELETE, replaced + tag FormViewSchema same steps defect; the declared staged-form shape is a tabbed form view

Two further corrections in the same class, found while re-anchoring and fixed
here because they teach the same refused structure on the same page: the
Layout Hierarchy diagram nested "Field Group", "Widget" and "Related List"
under a Section (regions hold components; only a form-shaped component holds
sections), and it carried span: 6. The 12-Column Grid System heading now
opens with a Callout stating what is actually authorable (columns 1–4, span: auto|full) — "12 columns" describes the renderer's internal grid, never an
authorable span vocabulary.

Escalations — reported, not built

Per the triage ruling, implementing a documented-but-undeclared surface is a
Feature on the manual floor. Two deleted sections describe capabilities that may
deserve a decision card rather than permanent removal; neither is built here:

  1. Multi-step / wizard authoring (two fences). No steps surface exists at
    any tier. The nearest declared shapes are a tabbed form view (no progress
    model, no per-step validation gate) and a flow. This is the larger of the two.
  2. Section presentation variants (compact / spacious / danger). Purely
    cosmetic and nothing reads it today; lower value, recorded for completeness.

card_grid, field_group, related-list mode: inline_edit and the split_view
/ list_view / detail_view types are not escalated — each is either a
duplicate of a declared shape or a defect class this page has already removed.

Verification

Gate families derived from the diff with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack (26 matched; the 2 changeset-triggered ones do
not apply — see below). All re-run at 92d1a709, the final commit; each exit code
captured before any pipe.

Green, quoting each gate's own verdict line:

  • check:yaml-examples✅ 18 tagged YAML example(s) across 1 file(s) validate against their declared live spec schemas
  • check:docs✅ 230 generated files in sync with packages/spec
  • check:doc-anchors✅ check-doc-anchors: 282 internal #fragment link(s) across 409 source file(s) all resolve to a real heading (this is what pins the two new in-page links)
  • check:skill-examples✅ 260 prose examples type-check across 3 surface(s)
  • check:doc-security-posture✅ 26 ObjectSchema.create example(s) … carry an os validate-clean security posture
  • check:doc-formula-expressions, check:doc-authoring, check:docs-single-h1,
    check:docs-audit-scope, check:docs-redirects, check:role-word,
    check:nul-bytes, check:published-readme-links,
    check:react-page-adapter-contract, check:cross-package-test-inputs,
    check:liveness, check:empty-state, check:strictness-ledger,
    check:variant-docs, and the five scripts/check-doc* / check-docs* /
    check-section-landing-index / check-ci-filter-parity families — all exit 0.

Two CI reds on 943e9216; one real, one an artifact. Check Documentation Links failed on
943e9216: the replacement wizard Callout linked /docs/protocol/automation/flow, a
route that does not exist — the page is content/docs/automation/flows.mdx, spelled
/docs/automation/flows by 18 existing links. Fixed in 92d1a709. Worth recording why
the local sweep missed it
: check:doc-anchors judges in-page #fragment targets, not
route destinations, so it was green on both commits; the job that catches this is lychee
--offline resolving root-relative links against content/, and lychee is not installed
in the dev container. Every root-relative link on the page now resolves (10/10, checked
against the same content/ + .mdx/.md fallback rule lychee uses), and nothing
anywhere links into an anchor this PR deleted (grep -rn 'layout-dsl#' finds none).

TypeScript Type Check also showed red on 943e9216, and that one is not a defect in
this diff
. Run 33291367599's own conclusion is cancelled: lint.yml sets
cancel-in-progress: true keyed on the PR, so pushing the link fix superseded the
in-flight run, and all four member lanes (workspace, consumer gates, debt ledger,
plus Lint & Repo Gates) were CANCELLED rather than failed. TypeScript Type Check is
an aggregator whose final step asserts every needs: lane succeeded, so cancelled lanes
make it report failure. Nothing was changed for it, and it is green on the new head.
pnpm --filter @objectstack/spec check:generated was run locally against the same tree
to make sure nothing generated had gone stale behind it — exit 0.

Final state on 92d1a709: 27 success, 6 skipped, zero non-green, including
Check Documentation Links, TypeScript Type Check and all four Type Check lanes.
Check Changeset is among the skipped — the skip-changeset label doing its job.

check:skill-examples, check:doc-formula-expressions and
check:doc-security-posture each first returned PREREQUISITE NOT MET /
"package is not built" — not measurements. They were re-run green after
turbo run build --filter=@objectstack/lint --filter=@objectstack/formula --filter=@objectstack/client-react --filter=@objectstack/client.

Beyond the tags — a limit worth stating. PageComponentSchema.properties is
an open record of string to unknown, so an os:check-yaml PageComponentSchema tag
validates the component node's own keys and not the props bag. Every rewritten
component's properties was therefore additionally dispatched through
ComponentPropsMap by hand, and all of them are accepted (custom.approval_timeline
excepted by design — an unregistered type has no entry). That audit caught one real
defect the tag could not: record:details.columns is the string enum "1"|"2"|"3"|"4",
so columns: 2 is refused; the Customer 360 example writes columns: '2'. Filed as
a follow-up finding, since the gap is the gate's, not this page's.

Changeset

None, and skip-changeset is applied: the diff is a single file under
content/docs/**, which no package publishes, so this PR declares no release of
its own — the exemption's stated meaning in pr-automation.yml. Same shape as the
recent docs/tooling PRs #13199 and #13202, which landed without one.

Fixes #13266


Generated by Claude Code


Generated by Claude Code

Every YAML fence on the page is now validated by check:yaml-examples: 18
tagged / 0 untagged, up from 6 tagged / 17 untagged. Each of the 17 untagged
fences was refused by every live schema it could plausibly claim (re-derived
by safeParse on this base); each is now either rewritten to the declared shape
and tagged, or removed with a Callout recording what it taught and why it is
gone.

Rewritten and tagged: the two page templates (no `context:` key; `name` +
`label` are required), custom span widths (`span: auto|full`, not twelfths),
the field-group examples (section `columns` + per-field `span`), related lists
and widgets (page components with `properties`, not form sections), the
master-detail and kanban blocks (`object-master-detail-form` / `object-kanban`,
not a page-level `layout:` mapping), Customer 360 (`regions` is an array), and
the onboarding wizard (a `tabbed` form view).

Removed rather than implemented, per ADR-0049 enforce-or-remove in the docs
direction: the `steps:` wizard template, section `variant:`, related-list
`mode: inline_edit`, and the `card_grid` block (whose per-breakpoint `columns`
map is the same defect class already removed from this page).

No packages/spec source is touched — the docs move to the spec, not the
reverse.
@claude claude Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 30, 2026
@github-actions github-actions Bot added the documentation Improvements or additions to documentation label Aug 30, 2026
The replacement Callout linked /docs/protocol/automation/flow, a route that
does not exist — the page is content/docs/automation/flows.mdx, which 18 other
links already spell /docs/automation/flows. Caught by the Check Documentation
Links job (lychee --offline resolves root-relative links against content/);
check:doc-anchors did not, because it judges in-page #fragments rather than
route destinations.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/l skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[finding] layout-dsl.mdx: most of the 17 still-untagged YAML fences teach shapes the live schemas refuse (per-fence readings attached)

2 participants