Layer 1: The JSON Schema (as you type)
rx/_schema/unoverse.schema.json validates every definition in your editor (wiring in 01). Structural, zero false positives. It catches:
- missing envelope fields (
unoverse,kind,name,root; components also needcategory: discovery meta lives in the manifest) - an unknown primitive
type(the closed set is encoded) - broken primitives:
Switchwithoutcases,Eachwithouttemplate+ a list (literalitemsorbind.items),Refwithoutref,ComponentSlotwithoutselect - illegal conditions: only
eq/ne/in/ truthy exist;and/or/arithmetic are rejected by design (derive in the node, 03)
unoverse field) and bare node partials (layouts/, states/, components/, atoms).
One-off sweep of everything from the CLI, if you want it (needs ajv once: npm i -D ajv at the repo root; Studio runs the same schema as you type):
Layer 2: The lint rules (Studio, at publish)
The same rules the platformβs guard tests enforce in CI, run by Studio before anything publishes:
The platformβs own CI additionally runs the theme-contract and discoverability-meta guards, and the SDK build enforces the closed set at the renderer level: you canβt drift past them even if a rule were missed at publish.
Layer 3: Your judgment (the conformance checklist)
What no linter can decide: audit every artifact against this before calling it done: Structure- Structure is earned: flat if it can be;
components//states//layouts/only when the shape demands them - Few shallow discriminants, not boolean soup; same-shape states collapsed into one data-driven state
- No self-guarding states; mutually exclusive views in ONE
Switch
- Every
bindhas a prop/state key with a default - Derived values computed in the node, sent as plain fields: no logic simulated in the definition
- Reaction contract respected: a component writes only its own slice; template surfaces react via
select.where;setTemplateValueonly for the templateβs own chrome - Locked state respected: lifecycle from derived flags, voice via
callState, host chrome viaprops
- No component-type rules in slots; reaction surfaces select by
where; components own their size and faces - Manifest binds the workflow;
whenToUseoutcome-first, disqualifies by property
- Semantic tokens only; no invented component-named tokens
Ship
Publishing happens in Studio and nowhere else: assets never deploy through the core platform:- Preview, mock: prop defaults + the state picker; exercise every state fixture.
- Preview, live (07): stream real data through it, watch the stream log stay clean. The preview runs the production path, so it is the release test.
- Publish: Studio lints (Layer 2 blocks on any error) and publishes to your universe over the API, authenticated by your sign-in to that universe (publishing is a specific permission on your account). The item is live in every canvas immediately: no build, no restart, no deploy.
Next: 09, Troubleshooting.

