open-standards/joule-ui/conformance/lang/README.md
Transaction Science 8a0f6073f7 joule-ui: the line language (SPEC §11), a streaming ingest into validated widget trees
joule-ui takes in OpenUI Lang 1.0 the way it takes in A2UI: a model writes a
surface as a program, one widget a line, and joule-ui-lang builds a widget tree
against the host's registry as the program streams. After every chunk a snapshot
holds the tree as far as it can be built, each widget checked by joule-ui's own
validate, and every error with its source line and reason code. State, queries,
operators, conditionals, built-in functions and sequences of actions are parsed
and refused not-declarative. A canonical writer turns a tree back into the
language; it parses back to the same tree.

- joule-ui-core: WidgetSchema::positional, the order a positional call passes
  props in (SPEC §3); absent from the wire form when undeclared.
- joule-ui-interaction: begin_interaction and Pending::finish, the lifecycle's
  three phases in two steps for a host whose handler is asynchronous (SPEC §6);
  run_interaction is built on them and seals what it sealed before.
- conformance/lang/v1: L1 statements, L2 ingest, L3 streaming, L4 the canonical
  form, L5 refusals, with an independent Python verifier written from §11.
- docs/create.md: the design of Create.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-27 04:46:19 -04:00

34 lines
2 KiB
Markdown

# joule-ui line language conformance — v1
The pack of SPEC §11.9: the line language (OpenUI Lang 1.0, taken in as joule-ui
widget trees) against the pack's own library. Regenerate with:
```
cargo run -p joule-ui-lang --bin gen_lang_vectors
```
and verify, from the specification alone, with the independent verifier:
```
python3 -I conformance/lang_verify.py # every case recomputed and compared
python3 -I conformance/lang_verify.py --mutations # changed vectors are refused
```
`cargo test -p joule-ui-lang --test pack` checks that the committed files are exactly
what the reference implementation gives.
| File | Class | What a conforming ingest reproduces |
|---|---|---|
| `library.json` | — | the library: each widget's props, children rule and positional order (written out), and the root widget |
| `l1-statements.json` | **L1** | each text's statements (name, source line, kind, complete) and whether it ended open |
| `l2-ingest.json` | **L2** | each text's snapshot at the end of the stream: the tree, its nodes (key, line, statement), the errors (line, statement, code, widget, prop, warning), the unresolved names, the orphans, whether it ended open |
| `l3-stream.json` | **L3** | each case's snapshot after every chunk and at the end; the end equals the batch parse of the joined chunks |
| `l4-write.json` | **L4** | each tree's canonical text, which parses back to the tree |
| `l5-refusals.json` | **L5** | negative controls: each refused with its code at its line, and its whole snapshot |
| `MANIFEST.json` | — | each file's SHA-256 |
The tree and its values are in joule-ui's wire form (§2): a widget is
`{"name", "props", "children"}` (`children` absent when empty); a prop value is
`{"type": "text" | "number" | "bool" | "list" | "object", "value": ...}`, `{"type": "null"}`,
or `{"type": "action", "value": {"id", "payload"}}` with `payload` null or a prop value.
Errors carry no message: messages are for a person or a model, and not normative.