You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 9a33cdd
Browse filesBrowse the repository at this point in the historyBrowse files
refactor(spec,skills): gen:react-blocks emits one artifact — the markdown is the single AI-facing rendering (#15257)
The generator wrote the same table twice: a machine-readable JSON rendering
(5,352 tokens) and a markdown one (3,153 tokens) — same four blocks, same prop
counts, byte-identical `note`. The JSON had zero consumers in this repo beyond
the register rows that named it, and zero in objectui. It is retired: the
writer is dropped, the file is deleted, `--check` verifies one artifact, and
every reference that named the path moves with it — the merge-driver row and
its comment, the regeneration orchestrator entry, the governed-merge register's
candidate and its self-test fixtures, the skills token ratchet's boundary
fixture and pinned exclusion set, ADR-0082, and the one skill-body link.
Measured: the published skill bundle drops from 156,787 to 151,426 tokens
(-5,361, -3.4%); the generator-owned population goes 11 files to 10 and the
published-file population 47 to 46.
Claude-Session: https://claude.ai/code/session_01H2oQebDDxYKfWZusyd8GXk
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/adr/0082-react-component-contract-governance.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -36,7 +36,7 @@ They drift silently: a component can accept a prop the spec never declared (an u
36
36
37
37
`packages/spec/src/ui/react-blocks.ts` is a **block→schema index**: each curated public block (`<ObjectForm>` → `FormViewSchema`, `<ListView>` → `ListViewSchema`, `<RecordDetails>` → `RecordDetailsProps`, `<ObjectChart>` → `ChartConfigSchema`, …) names its spec schema, plus a per-block `dataProps` allowlist that curates *which* schema props to surface (ADR-0080: capability ≠ contract — `ListView` has 45 schema props; the contract surfaces ~10 high-signal ones).
38
38
39
-
`scripts/build-react-blocks-contract.ts` generates the AI-facing contract (`skills/objectstack-ui/contracts/react-blocks.contract.json` + `references/react-blocks.md`) by reading the spec schemas (`z.toJSONSchema`, with `OS_EAGER_SCHEMAS=1` to resolve lazy schemas), taking each prop's spec-authored `.describe()`, and merging the React overlay. **Hand-authoring is rejected** — a hand-written contract drifts into fiction; a generated one is zero-drift by construction.
39
+
`scripts/build-react-blocks-contract.ts` generates the AI-facing contract (`skills/objectstack-ui/references/react-blocks.md`) by reading the spec schemas (`z.toJSONSchema`, with `OS_EAGER_SCHEMAS=1` to resolve lazy schemas), taking each prop's spec-authored `.describe()`, and merging the React overlay. **Hand-authoring is rejected** — a hand-written contract drifts into fiction; a generated one is zero-drift by construction.*(#14296 item 3 = A, 2026-09-02: this generator also emitted a second, machine-readable rendering of the same table at `contracts/react-blocks.contract.json` — same four blocks, same prop counts, byte-identical `note`. It had zero consumers in either repo and charged the published skill bundle for a second copy of one table, so it is retired: the markdown is the single AI-facing output, and `check:react-blocks` verifies one artifact.)*
40
40
41
41
### 2. Registry `inputs` are a projection, not the protocol
// The contract, as the ONE rendering below prints it. `version` and `source`
134
+
// were the retired JSON envelope's own fields and went with it: the markdown
135
+
// states its provenance in the frontmatter `description` it emits instead.
129
136
constcontract={
130
-
version: 2,
131
137
adr: 'ADR-0081',
132
-
source: "GENERATED from the REACT_BLOCKS definition in the '@objectstack/spec/ui' module — data props from the spec zod schemas, binding/controlled/callback from the React overlay.",
133
138
note: "Props each component accepts in kind:'react' page source. Reference blocks by their PascalCase tag. kind: data=declarative config (from the spec schema) · binding=connects to data · controlled=React state · callback=React function. These blocks are for DATA. Live data: const adapter = useAdapter(); adapter.find/findOne/create/update. STYLING (ADR-0065) — a page's source is runtime metadata, so the console's build-time Tailwind NEVER scans it: utility classNAMES silently produce no CSS. Do NOT use Tailwind className in page source. (a) Layout/chrome: inline style={} with hsl(var(--token)) theme colors — e.g. color:'hsl(var(--foreground))', background:'hsl(var(--card))', border:'1px solid hsl(var(--border))', and px/flex for layout. (b) Overlays: render <ObjectForm formType='drawer'|'modal' open onOpenChange> (a pre-styled Sheet/Dialog) — never hand-roll a fixed inset-0 backdrop.",
0 commit comments