ADR-0009 — The status ladder: development, committed, validated; forward only; medallion words stay in the lake
Status: accepted design · 2026-10-29
Context
A workarea mirrors a crew's work, and that work matures: it is explored, then governed, then finished. A single terminal "archived" or "retired" state cannot express that arc; OML needs three stages a lifecycle with only an end cannot say: a stage where a tenant may deliberately relax review inside a bounded, marked exception (ADR-0001 d5); a working stage with full review; and a frozen stage that an auditor can rely on — "what this area held when it froze is what it holds now, minus journalled demotions and erasures". This record decides the ladder. Its rules, the transition matrix and the per-status refusal matrix are declared on architecture/workareas.md; this record states the decisions and what was rejected. Nothing here is built; every refusal named below is a design commitment with a typed error in the taxonomy (api/errors.md), not a property of running software.
Decision
-
d1 — Three statuses, and no others.
development,committed,validated(frozen).development: review runs as everywhere, and tenant policy MAY additionally permit markedself_signedrows under the one bounded constitutional exception, scoped in ADR-0001 d5 and widened nowhere.committed: full non-author review required; promotions allowed; the permanent status of the universe root.validated: frozen — refuses new writes, promotions into it, reassignment in or out, child creation and re-parenting; serves reads. -
d2 — One write-eligibility rule across all statuses. Who may write into a workarea is decided by effective access (ADR-0008 d4) and by nothing else. Status changes only the review policy applied to what is submitted — never grant resolution.
validated's write refusal is the admission policy of that status, received identically by every holder of write access as a typed error, not an edit to anyone's grants. Audit questions about access are answered from grants and permission epochs alone; audit questions about a refused write are answered from status and policy snapshots alone. -
d3 — Transitions are forward only, proposed and ratified by different identities.
development→committed→validated, proposed by an admin or a dreamer with effective access on the node, ratified by a second, non-proposing dreamer or admin — R2 applies to transitions — and journalled with a snapshot of the review policy in force, so any later promotion audit is answered against the policy that actually governed it. Backward transitions do not exist: no verb, journalled or otherwise, moves a workarea down the ladder. Work that must continue after validation is a new child elsewhere in the tree, typically with acontinuesedge. -
d4 — The child-status constraint. An area may become
validatedonly when every child is alreadyvalidated, and creating a new child under avalidatedarea is refused. Together these make "frozen" mean the whole subtree, by construction rather than by patrol: a validated node can never acquire an unfrozen descendant. -
d5 — A frozen area admits exactly three mutations, all journalled. Demote, erasure (crypto-shred, ADR-0005) and crew-metadata update (ADR-0008 d7). The first two exist because governance and legal reality do not freeze — a claim found wrong is demoted, a claim that must go is erased, each under its own journal event — and the third because freeze covers claim content and promotions, not workarea metadata. Everything else a frozen area is asked to do is refused.
-
d6 — Medallion words name physical lake zones only.
bronze,silver,goldare the names of Delta Lake zones, declared in architecture/storage.md and data/delta-tables.md, and nothing else. The status ladder keeps its own words. No page, error, log line or CLI output may call a workarea "gold" or a lake zone "validated". The two vocabularies touch at exactly one point, stated where the lake is declared: unreviewed content never enters a consumer-readable zone.
Consequences
statusis one column onworkareas(data/postgres-schema.md), and every refusal in d1 is a typed error naming the status rule it enforces (api/errors.md). Transition events with policy snapshots join the event catalog (data/event-catalog.md).- d2 keeps a single source of access truth. Nothing recomputes grants on transition, so freezing a large subtree is a metadata act, not a permission migration — and conversely, revoking a crew's access to a frozen area is an ordinary grant act, unrelated to status.
- d3's second ratifier makes a status change cost two identities. A one-admin tenant cannot freeze an area alone; that is the same liveness cost R2 imposes on promotion (ADR-0001) and it is accepted for the same reason: a frozen area is an evidence claim, and an evidence claim signed by one identity that also proposed it is worth less to the auditor reading the export (architecture/audit-and-lineage.md).
- d4 orders the freeze of a deep tree leaves-first. An admin freezing a branch performs the transitions bottom-up; the CLI previews the affected set under its mass-operation dry-run default (cli/reference.md).
- d5 commits the lake path: demote and erasure in a frozen area still flow through the outbox as retract operations (architecture/storage.md), so gold tables curated per validated workarea are not immutable snapshots — they are current state under journalled demotion and erasure, and the reconciler checks them as such (architecture/reconciliation.md).
- d6 is a standing documentation and review obligation under the fixed vocabulary of ADR-0018: a surface that leaks "gold" for a workarea or "validated" for a zone is a defect.
Rejected alternatives
- Per-status grant models — a second grant table or modifier set per status, so that
validatedareas would carry their own, narrower grants. Rejected because it creates two sources of access truth: every check would reconcile the grant state with the status-local state, every audit answer would depend on which table the checker consulted, and a transition would become a permission migration with its own failure modes. d2 keeps one truth — ADR-0008 d4 decides access, status decides policy — and the cost is thatvalidated's refusals must be implemented as admission policy rather than falling out of grant resolution. - Reversible freezing — an unfreeze verb, journalled like any other act. Rejected because it
voids the guarantee that is the point of freezing: "this area was validated on date D" is worth
something to an auditor only if nothing promoted into it afterwards, and a journalled thaw
window still forces every consumer of the export to verify that no thaw occurred — the
guarantee degrades from a structural property into a query. Work that must continue gets a new
child and a
continuesedge (d3); the frozen node stays frozen. - A fourth
archivedstatus — a terminal state aftervalidatedfor areas nobody should read anymore. Rejected because its two candidate meanings are already covered: stop serving the content — that is demotion of the rows, journalled and reversible per row; make the content cease to exist — that is erasure by crypto-shredding (ADR-0005). Both are among d5's permitted mutations insidevalidated. A status that hides an entire area without doing either would be a read-path visibility switch with no journalled per-row account — exactly the silent disappearance R4 exists to prevent.