The spec describes *what the procedure is*: structure, data, actors, gates and
order. It carries no presentation. Rendering (layout, theme, dark mode, the
questionnaire and the dimension view) is the renderer's job and must follow from
the semantics alone. If a UI feature needs a new spec field, that field has to be
justified as meaning, not appearance.
## The model
```text
pack
|- framing what to keep in mind (shown first)
|- actors who does or approves what, with privileges
|- datapoints the non-secret facts collected and applied -> state nil/set/err/ok
|- stages hierarchy of the procedure
| |- steps the work -> state todo/running/done/failed
| |- gates QA checks tied to the stage and to goals -> state open/passed/failed/waived
|- artefacts what a run produces and where it lives (non-secret references)
```
### Two states, two things
| Thing | States | Meaning |
| --- | --- | --- |
| **Datapoint** (parameter, role assignment, artefact location, custody reference) | `nil` no value, `set` value given, `err` invalid or rejected, `ok` confirmed in the real system | Is the data known and right? |
| **Step** | `todo`, `running`, `done`, `failed` (`skipped` for read-only) | Has it been applied? |
| **Gate** | `open`, `passed`, `failed`, `waived` | Is the quality condition met? |
A v0.1 `parameter` is a datapoint that has a value type and is asked as a
question. Steps `uses:` datapoints; steps may `produces:` datapoints
(for example an artefact location).
### Hierarchy and order
-`stages` nest to at most three levels. A stage has `title`, `goal`, `steps`, and
optional child `stages`.
- Every step and stage may declare `requires:` (ids of steps, stages, gates,
or datapoints in state `ok`). This forms a dependency graph, so alternatives and
parallel work are expressible. `one_of:` groups declare alternatives: any one
satisfies the group.
- **Canonical serialization.** The order in which the pack lists things is the
recommended order. The engine computes: *ready* = every requirement met;
*recommended next* = the first ready item in canonical order. Operators may take
any other ready item. A pack that lists no `requires` behaves as a linear
sequence, which is exactly a v0.1 pack.
### Gates
A gate is a QA condition, not a step.
```yaml
gates:
- id: custody-approved
title: Custody strategy approved
stage: custody # exit gate of this stage
goal: platform-root-custody # quality objective; canon standard id where one exists
blocking: true # blocks dependents and the stage exit