# 15 · Target Architecture for 2.0: Schemas, Surfaces, Invariants `docs/09` did this job for the road to 1.0, and it is the reason that road was iterable: five releases built against one schema authority instead of five implementers' guesses. This document is the same instrument for [`14-roadmap-to-2.0.md`](14-roadmap-to-2.0.md): every field, payload, and command the work orders name is given here in full, with its default, its self-heal behavior, and the invariant that guards it. **How to read it.** A delta over `docs/03` (as built) and `docs/09` (the 1.0 target, now shipped). Where 14 and 15 disagree, **15 is the schema authority** — and two such disagreements already exist and are resolved here, deliberately (§2.3 receipt stamping; §2.2 retirement), because writing schemas is how prose bugs get caught. Sections marked **[BINDING]** are settled for v1.3–v1.6; sections marked **[RE-ANCHOR]** (v1.7–v2.0 surfaces) give the target shape but must be re-read against accumulated telemetry before their release builds — the shape is a commitment, the details are not yet. --- ## 1 · Invariants ### 1.1 Carried forward whole (docs/09 §2 — unchanged, still outranking everything) Stdlib-only, no network code · the engine owns every number · receipts append-only, never rewritten · state advances only through receipts · the assessor never sees the dialogue · confidence picked or null · learner text never on a command line · mutating commands take the lock · defaults backward-compatible and self-healing · every engine change ships a selftest that fails without it. ### 1.2 New invariants (the 2.0 additions, numbered continuing docs/09) 11. **Read-only commands stay read-only under temptation.** `propose`, `due --cap`, `adherence`, `adjudication-stats`, `grader-health` never write and never take the lock. (`stats.proposals_pending` re-runs the deterministic proposal computation — nothing persists a pending queue.) 12. **A canary audit can never mint a `pass`.** Its verdict domain is `{canary-pass, canary-fail}`; only a full-set audit can certify. Any code path that lets a canary satisfy the export gate on its own is a defect. 13. **`relearn` rows are excluded from every retention-family population by the shared predicates** (`_review_receipts` and friends), never by per-caller filters — one predicate change, every reader inherits it (the v0.6.4 lesson, made law). 14. **Every model-derived number carries its label in the payload** (`order_basis`, `schedule_policy`, `basis` on fits, `grade` on proposals). A payload a skill can read without seeing the label is a defect (doctrine 14 §0.5). 15. **Adaptation is proposed–consented–logged–reversible** (Article 12, v1.8): the only writer of a learner-model change offered by the system is the consent flow, and it writes `adaptations.jsonl` in the same transaction. 16. **Retirement is a learner decision, not a mastery event.** It is exempt from "state advances only through receipts" because it advances nothing; it is recorded on the node it governs (§2.2) and — once the ledger exists — there too. The engine never proposes retiring a specific node. --- ## 2 · State schema deltas (all additive; every field self-heals) ### 2.1 `learner-model.json` — additions **[BINDING through v1.6; v1.8 fields RE-ANCHOR]** ```jsonc { "schema": 1, "memory": { "desired_retention": 0.90, "interval_multiplier": 1.0, // RESET to 1.0 by the v1.6 migration (§5.2) "last_refit": null, "fsrs_params": null, // v1.6 tier-2 fit writes {w: [...17], basis: "