# Lifecycle State Model M12 adds a lifecycle control layer without collapsing the existing domain identities. `Model`, `ModelRevision`, `ModelArtifact`, `ArtifactSet`, `RuntimeProfile`, `RuntimeProbe`, `DeploymentCandidate`, `CapabilityDeployment` and `ProjectBinding` remain separate records. ## Independent dimensions Readiness is expressed as independent evidence, never inferred from one status: | Dimension | Values used by lifecycle evidence | | --- | --- | | Integrity | `UNKNOWN`, `VERIFIED`, `CORRUPT` | | Security | `UNREVIEWED`, `APPROVED`, `BLOCKED` | | Runtime | `UNPROBED`, `PROVEN`, `INCOMPATIBLE` | | Evaluation | `NOT_EVALUATED`, `EVALUATED`, `REGRESSED`, `PROMOTION_ELIGIBLE` | | Project fit | `UNKNOWN`, `REQUIRES_MORE_EVIDENCE`, `ELIGIBLE`, `BLOCKED`, `DEFERRED_EXTERNAL_VALIDATION`, `KEEP_LAB` | | Deployment | `CANDIDATE`, `LAB_READY`, `PROMOTION_ELIGIBLE`, `CANARY`, `LAB_STABLE`, `STABLE`, `DRAINING`, `DEPRECATED`, `ARCHIVED` | `LAB_READY`, engineering `PASS`, Advisor `PROMOTION_ELIGIBLE` and an approved request are not synonyms for production. Production is an explicit environment on a lifecycle subject and requires an evidence-bound approval, immutable plan, rollback snapshot and separate execution. ## Transition graph and concurrency The typed graph in `domain/lifecycle_contracts.py` rejects shortcuts. Production follows `STABLE → DRAINING → DEPRECATED → ARCHIVED`; restoration from deprecated requires a new explicit promotion path, not mutation. LAB supports bounded canary and a separate `LAB_STABLE` state. Every subject has a monotonically increasing `version`. Execution compares the operator's expected version before journaling a change. The database also permits only one production/stable deployment per capability contract. Conflicts return typed 409 responses; retries use a unique idempotency key. Every transition creates an append-only `LifecycleEvent` containing object, before/after state, actor and role, policy revision, evidence IDs, reason, time and change ID. No inference payload or secret is stored. M13 adds an independent migration state graph. It does not collapse backfill or external cutover truth into deployment lifecycle state; production cutover remains subordinate to a current M12 approval and matching approved `requires_reindex` promotion plan. ## M14 operational integration Lifecycle failures and rollback failures feed bounded operational metrics/alerts from the existing operation journal. Alert acknowledgement is not lifecycle approval, promotion authority or rollback authority. M14 never executes lifecycle remediation; all production changes still require the M12 evidence-bound policy, immutable plan and explicit actor separation. ## M16 reconciliation under fault An incomplete lifecycle operation is rolled back conservatively from its immutable snapshot on the next control-plane start, exactly once. Restart storms do not accumulate: four consecutive restarts under load produced no authoritative drift. The `lifecycle_commit_has_evidence` and `no_hidden_auto_promotion` invariants assert that no operation reaches `COMMITTED` without its plan, approver and executor, and that no production deployment exists without a recorded production approval.