Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .github/workflows/lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4637,6 +4637,24 @@ jobs:
- name: Check docs object examples pass the os validate security posture
run: pnpm --filter @objectstack/lint run check:doc-security-posture

# The YAML half of the same surface (#13086, ruled 2026-08-29).
# check:skill-examples reads only ts/tsx fences — while metadata
# AUTHORING examples are written in YAML, so the format carrying most of
# what an author copies was in no gate's population at all
# (layout-dsl.mdx taught a phantom field-level `visible` map through two
# hand sweeps of the same page, #8251/#8306/#12935). Each ```yaml block
# tagged `os:check-yaml <schema>` is safeParsed against the LIVE spec
# schema it declares — resolved through the same registry
# `PUT /api/v1/meta/:type/:name` validates with — so a rejection here is
# the one a runtime save would print, rename hint included. Also prints
# the tagged/untagged fence census so opt-in adoption stays visible
# rather than becoming a permanent excuse. Reads src/ through tsx (no
# dist), so its place in this job is cohesion with the example-gate
# cluster above, not a build dependency. Self-tests first, like its
# neighbours.
- name: Check docs YAML examples parse against live spec schemas
run: pnpm --filter @objectstack/spec run check:yaml-examples

# Same anti-drift class as the gates above, for the generated translation
# bundles in packages/platform-objects/src/apps/translations/. Nothing
# regenerated them either, so they rotted three ways at once (#3670):
Expand Down
6 changes: 6 additions & 0 deletions content/docs/protocol/objectui/layout-dsl.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -224,6 +224,7 @@ All layouts use a responsive grid that divides space into 12 columns.

### Basic Grid Layout

{/* os:check-yaml FormSectionSchema key=section */}
```yaml
section:
label: Contact Information
Expand Down Expand Up @@ -279,6 +280,7 @@ section:

Grid automatically collapses on smaller screens:

{/* os:check-yaml FormSectionSchema key=section */}
```yaml
section:
columns: 3 # Desktop: 3 columns, Tablet: 2 columns, Mobile: 1 column
Expand Down Expand Up @@ -328,6 +330,7 @@ Sections are collapsible containers for related fields.

### Basic Section

{/* os:check-yaml FormSectionSchema[] key=sections */}
```yaml
sections:
- label: Contact Information
Expand Down Expand Up @@ -355,6 +358,7 @@ sections:
Show sections based on field values. The key is **`visibleWhen`** and its value is a
**CEL predicate string** — never a `{ field, value }` rule object:

{/* os:check-yaml FormSectionSchema[] key=sections */}
```yaml
sections:
- label: Basic Info
Expand Down Expand Up @@ -468,6 +472,7 @@ strip.

### Basic Tabs

{/* os:check-yaml FormViewSchema */}
```yaml
type: tabbed
tabPosition: top # top | bottom | left | right
Expand Down Expand Up @@ -550,6 +555,7 @@ Breakpoint-driven show/hide and per-breakpoint layout live one tier up, on a
([ADR-0065](https://github.com/objectstack-ai/objectstack/blob/main/docs/adr/0065-sdui-styling-model.md)) — desktop-first buckets compiled to id-scoped CSS at
render:

{/* os:check-yaml ResponsiveStylesSchema key=responsiveStyles */}
```yaml
# On a page component (*.page.ts) — NOT on a form field or a form section
responsiveStyles:
Expand Down
4 changes: 3 additions & 1 deletion packages/spec/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@
"check:react-blocks": "tsx scripts/build-react-blocks-contract.ts --check",
"check:react-declaration-parity": "tsx scripts/check-react-blocks-declaration-parity.ts",
"check:skill-examples": "tsx scripts/check-skill-examples.ts --self-test && tsx scripts/check-skill-examples.ts",
"check:yaml-examples": "tsx scripts/check-yaml-examples.ts --self-test && tsx scripts/check-yaml-examples.ts",
"check:template-manifests": "tsx scripts/check-template-manifests.ts --self-test && tsx scripts/check-template-manifests.ts",
"check:test-typecheck": "tsx ../../scripts/check-test-typecheck.mts --self-test && tsx ../../scripts/check-test-typecheck.mts --package packages/spec --project tsconfig.test.json",
"gen:test-typecheck-debt": "tsx ../../scripts/check-test-typecheck.mts --update --package packages/spec --project tsconfig.test.json",
Expand All @@ -310,7 +311,8 @@
"ai": "^7.0.66",
"tsx": "^4.23.12",
"typescript": "^6.0.3",
"vitest": "^4.1.10"
"vitest": "^4.1.10",
"yaml": "^2.9.0"
},
"dependencies": {
"pg-connection-string": "^2.14.0",
Expand Down
6 changes: 6 additions & 0 deletions packages/spec/scripts/check-generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,12 @@ const NO_GENERATOR: ReadonlyArray<{ check: string; why: string }> = [
// above. The audit half is unchanged and is still the bulk of what it reports.
{ check: 'check:empty-state', why: 'audits empty-state coverage — no artifact' },
{ check: 'check:skill-examples', why: 'validates skill examples parse — no artifact' },
// #13086 — the YAML half of the surface `check:skill-examples` covers for
// TypeScript: tagged ```yaml blocks in skills/ + content/docs/ are safeParsed
// against the live spec schemas. Reads src/ through tsx (no dist), writes
// nothing: a failure is a doc example to fix or a marker to move, never a
// `gen:` to run.
{ check: 'check:yaml-examples', why: 'validates tagged prose YAML examples against live spec schemas — no artifact' },
// #7319. Reads `src/` and the shipped template trees and writes nothing: a
// failure is either a manifest to fix or a schema to fix, never a `gen:` to
// run. It audits the inverse direction from everything in GATED — those
Expand Down
Loading
Loading