# Deployment Mode and Conversion Contract (D3) Status: DRAFT — awaiting ratification (webui-audit S2, contract 6 of 9). Authority: PRD D3 (Part I §3) — two modes chosen at install time, Standalone and Enterprise, with the mode table (brains, user-data isolation, secrets, conversion); Standalone → Enterprise conversion is **one-way** and Enterprise is a **terminal state**. PRD D14 (Part I §7) — the per-user brain split is optional in Standalone and keeping it is the recommended default because it preserves forward-compatibility with the one-way conversion. PRD D11 (Part I §9) — v1 ships the Standalone flow only; Enterprise conversion is explicitly deferred. PRD D3 federation clause — federation is intentionally not fully designed, deferred, and nothing in v1 may foreclose it. This contract binds the mode as a canonical platform property (§2), the per-mode obligations and which contract owns each (§3), the conversion transition (§4), the v1 non-foreclosure obligations (§5), and their witnesses (§6). Domain semantics stay with their owning contracts: wizard mode choice and branching (contract 3 §2), identity/SSO (`identity-lifecycle.md`), custody and per-user brain mechanics (contract 7), tool mapping (`tool-gateway-mapping.md`). ## 1. Definitions 1. **Mode**: the platform-wide deployment mode, exactly one of `standalone` or `enterprise`. The vocabulary is closed in v1; extension (e.g. a federation mode) is by amendment to this contract, never ad hoc. 2. **Conversion**: the one-way transition `standalone → enterprise`. No other mode transition exists. 3. **Conversion preconditions**: the verifiable conditions of §4.2 that must all hold before the mode record may change. ## 2. Mode is a canonical recorded property 1. Mode is recorded canonically in the platform database at bootstrap, as the explicit operator choice contract 3 §2.3 requires. It is never derived from feature state (presence of Vault, count of brains, count of users), and no component may infer a different mode than the record states. 2. The record is readable through the Gateway (and CLI, D8) by any authenticated user; components branch on the read value only. 3. The record is immutable except by the §4 conversion transition. Editing it by direct database access, config file, environment variable, or wizard re-run is non-conformant (contract 3 §2.3: changing mode later is conversion, not a wizard re-run). ## 3. Per-mode obligations (owner map) The PRD mode table binds four rows; this contract assigns each an owning contract so no obligation is unowned and none is bound twice: | Obligation | Standalone | Enterprise | Owner | | ------------------- | -------------------------------------- | -------------------------------------------------- | --------------------------------------------- | | Brains | one mosaic-brain (system + user files) | system brain for config + one brain per user | contract 7 (custody/brain mechanics) | | User-data isolation | single user | no user-data leakage between users; sharing opt-in | contract 7 (enforced by architecture, D14) | | Secrets | OpenBao/Vault or flat files | OpenBao/Vault REQUIRED | this contract (§4.2 gate; steady-state check) | | Conversion | may convert to Enterprise, one-way | terminal state | this contract (§4) | In Enterprise steady state, a flat-file secrets backend is non-conformant; the platform refuses to start Enterprise-mode components against a flat-file secrets configuration (fail-closed, not warn-and-run). ## 4. Conversion transition 1. **Direction and terminality.** The only transition is `standalone → enterprise`. `enterprise → standalone` does not exist: there is no command, no admin override, and no support path. An attempt is refused with the precondition/state error class of the command envelope (`tool-gateway-mapping.md` §4.2). 2. **Preconditions (all verified before the record changes):** - Secrets: OpenBao/Vault is configured and reachable, and no required secret is served from a flat-file backend. Secret migration completes before conversion; this contract does not define the migration tooling, only the gate. - Brains: the per-user brain split required by the Enterprise row of §3 is established for every existing user (or the deployment already kept the split, the D14 recommended default). Brain partitioning mechanics are contract 7; this contract binds only that the split is complete before the mode flips. - Identity: at least one platform administrator account exists and the identity contract's registration controls are in a deliberately chosen state (`identity-lifecycle.md` §2) — recorded as re-affirmed at conversion, since Enterprise changes their consequences. 3. **Atomicity of the flip.** The mode record changes in one transaction, only after every §4.2 precondition verifies. An interrupted or failed conversion leaves the record `standalone` and the platform fully operational in Standalone semantics; there is no intermediate mode and no half-converted state observable through the record. Preparatory work (secret migration, brain partitioning) is re-runnable and may complete across multiple attempts, in the same at-most-once, keyed style contract 3 §4 binds for wizard seeding. 4. **Authority and audit.** Conversion is a platform-administrator command carrying an explicit irreversibility acknowledgment in its request. It is an official Gateway/CLI command (D8): when built, it is added to the tool↔Gateway mapping by amendment (`tool-gateway-mapping.md` §3.3). The transition emits an audit event (actor, prior mode, new mode, precondition evidence reference) in the same transaction as the record change; the event survives indefinitely. ## 5. v1 obligations (non-foreclosure) v1 ships Standalone only (D11); the conversion command is deferred work. v1 still MUST: 1. Record the mode per §2 (the wizard already binds the choice, contract 3 §3.2) with `enterprise` a reserved, refused value for bootstrap — v1 bootstrap accepts `standalone` only. 2. Keep the §2.3 immutability rule: no v1 surface mutates the mode record. 3. Not foreclose conversion: v1 data layouts follow the custody contract's pointer/consent structure (contract 7) so the per-user brain split remains establishable, matching the D14 recommendation. 4. Not foreclose federation: the closed mode vocabulary is extensible by amendment, and no v1 component may treat the mode enum as exhaustive in a way that fails closed against a future added value at parse time (unknown mode values are a refused configuration, not undefined behavior). ## 6. Verification requirements Binding on the implementing PRs: 1. **Mode-record witness (v1):** the mode is readable via Gateway and CLI after bootstrap and equals the wizard-recorded choice; bootstrap with mode `enterprise` is refused; no other write path to the record exists (covered by a writer assertion in the style of contract 1 §6.3, scoped to the mode record). 2. **Immutability witness (v1):** every mutation surface shipped in v1 leaves the mode record unchanged (asserted over the Gateway command inventory); direct-write attempts through shipped code paths do not exist. 3. **No-downgrade witness (conversion milestone):** with mode `enterprise`, a conversion request to `standalone` (and any crafted mode-write) is refused with the precondition/state error class and no record change. 4. **Precondition witnesses (conversion milestone):** conversion with (a) an unreachable Vault, (b) a required secret still flat-file backed, or (c) an unpartitioned user brain is refused with no record change and no partial mode effect. 5. **Interruption witness (conversion milestone):** fault injection aborting conversion after preparatory work leaves the record `standalone`, the platform operational, and a re-attempt able to complete without duplicating prepared state. 6. **Audit witness (conversion milestone):** a completed conversion has exactly one audit event, same-transaction with the record change; a failed attempt has a refusal event and no mode-change event. ## Ruling request Ratify sections 1–6 as written, with one decision embedded: - Decision (§5): v1 implements the **mode record and its immutability only** — bootstrap records `standalone`, the `enterprise` value is reserved and refused, and the conversion command itself is deferred to the Enterprise milestone, consistent with D11's deferred list. Alternative if rejected: build the conversion command inside v1 — rejected because D11 scopes v1 to the Standalone slice and conversion depends on contract 7 custody mechanics that are themselves not in the v1 slice.