{"version":"0.1","rui":{"description":"A RUI is a JSON document describing an app — its screens, blocks, and data bindings.","fileExtension":".rui.json"},"layouts":[{"type":"Page","description":"Screen container — one per routable screen","props":[{"name":"id","type":"string","required":true},{"name":"type","type":"literal","value":"Page","required":true},{"name":"title","type":"string","required":true},{"name":"description","type":"string","required":false},{"name":"children","type":"Section[]","required":true}]},{"type":"Section","description":"Grouping container for blocks","props":[{"name":"id","type":"string","required":true},{"name":"type","type":"literal","value":"Section","required":true},{"name":"title","type":"string","required":false},{"name":"direction","type":"enum","values":["stack","row"],"required":true},{"name":"children","type":"Block[]","required":true}]}],"blocks":[{"type":"Metric","description":"Single numeric or text KPI","props":[{"name":"id","type":"string","required":true},{"name":"type","type":"literal","value":"Metric","required":true},{"name":"label","type":"string","required":true},{"name":"binding","type":"ReadBinding","required":true,"notes":"valuePath required"},{"name":"format","type":"enum","values":["number","text"],"required":false}]},{"type":"Table","description":"Tabular list with optional static filter","props":[{"name":"id","type":"string","required":true},{"name":"type","type":"literal","value":"Table","required":true},{"name":"title","type":"string","required":false},{"name":"binding","type":"ReadBinding","required":true},{"name":"columns","type":"Column[]","required":true},{"name":"filter","type":"TableFilter","required":false}]},{"type":"Text","description":"Static copy","props":[{"name":"id","type":"string","required":true},{"name":"type","type":"literal","value":"Text","required":true},{"name":"content","type":"string","required":true}]}],"bindings":[{"type":"read","description":"Fetch data via GET","props":[{"name":"type","type":"literal","value":"read","required":true},{"name":"method","type":"literal","value":"GET","required":true},{"name":"path","type":"string","required":true,"notes":"Must start with /"},{"name":"valuePath","type":"string","required":false,"notes":"Dot-path into JSON response; required for Metric"}]}],"rules":[{"id":"R0","code":"INVALID_JSON","description":"Payload must be valid JSON"},{"id":"R1","code":"VERSION_MISMATCH","description":"version must equal registry version (\"0.1\")"},{"id":"R2","code":"MISSING_REQUIRED_PROP","description":"Required top-level keys version, meta, navigation, pages must be present"},{"id":"R3","code":"DUPLICATE_ID","description":"Every node id must be globally unique across the RUI"},{"id":"R4","code":"INVALID_ID_FORMAT","description":"Every node id must match ^[a-z][a-z0-9-]*$ (1–64 chars)"},{"id":"R5","code":"UNKNOWN_TYPE","description":"Node type must be a registered layout or block"},{"id":"R6","code":"MISSING_REQUIRED_PROP","description":"Required props must be present per type"},{"id":"R7","code":"UNKNOWN_PROP","description":"No unknown properties (strict mode)"},{"id":"R7b","code":"INVALID_PROP_TYPE","description":"Prop types must match registry"},{"id":"R8","code":"EMPTY_PAGES","description":"pages.length must be >= 1"},{"id":"R9","code":"EMPTY_NAVIGATION","description":"navigation.items.length must be >= 1"},{"id":"R10","code":"INVALID_NAV_PAGE_ID","description":"Every navigation.items[].pageId must match a pages[].id"},{"id":"R11","code":"ORPHAN_PAGE","description":"Every pages[].id must appear in at least one navigation item"},{"id":"R12","code":"INVALID_PAGE_CHILD","description":"Page.children must contain only Section nodes"},{"id":"R13","code":"INVALID_SECTION_CHILD","description":"Section.children must contain only block nodes"},{"id":"R14","code":"INVALID_NESTING","description":"No Section-in-Section nesting"},{"id":"R15","code":"EMPTY_PAGE","description":"Page.children.length must be >= 1"},{"id":"R16","code":"EMPTY_SECTION","description":"Section.children.length must be >= 1"},{"id":"R17","code":"INVALID_COLUMNS","description":"Table.columns.length >= 1; column key unique within table"},{"id":"R18","code":"MISSING_BINDING","description":"Table.binding and Metric.binding are required"},{"id":"R19","code":"MISSING_VALUE_PATH","description":"Metric.binding.valuePath is required"},{"id":"R20","code":"INVALID_BINDING","description":"Binding type must be \"read\"; method must be \"GET\""},{"id":"R21","code":"INVALID_FILTER_FIELD","description":"Table.filter.field must match a column key"},{"id":"R22","code":"PLANNED_NOT_SUPPORTED","description":"Planned block/binding types are not supported in v0.1"},{"id":"R23","code":"INVALID_VALUE_PATH","description":"valuePath must be valid dot-segments"},{"id":"R24","code":"INVALID_BINDING","description":"ReadBinding.path must start with /"}],"planned":{"blocks":["Form","Button"],"bindings":["write","action"]},"ids":{"pattern":"^[a-z][a-z0-9-]*$","minLength":1,"maxLength":64,"assignedBy":"agent"}}