READY-TO-ASSEMBLE-LEGO1-PATCH1 03 — [P0-2] C1 Versioned Identity & Invariants — 2026-06-22
READY-TO-ASSEMBLE-LEGO1-PATCH1 03 — [P0-2] C1 Versioned Identity & Invariants — 2026-06-22
Closes Codex P0-2. Gate: REGISTRATION_HOLD · CAN_PROCEED = NO · 0 runtime mutations. Design-only schema; not created (created later via dot_iu_create_collection / dot-schema-*, file 02).
1. Defect (reconstructed)
Prior file 04 used operation_code text PRIMARY KEY while lookup/history/hash/rollback were version-aware via protocol_version. That model cannot hold the same operation_code across versions; successor_code referenced only operation_code; rollback updated by operation_code alone → could hit the wrong version. Old-version resolvability and non-re-meaning were not enforceable. SUPERSEDED below.
2. Identity model (corrected)
- Surrogate stable id:
vocab_id uuid— immutable, the durable reference target for audit/effect/rollback (so references never depend on a mutable code). - Versioned natural identity (PK):
(operation_code, protocol_version)— the sameoperation_codeexists once perprotocol_version. - Value identity vs version identity: value identity =
operation_code(the governed concept); version identity =(operation_code, protocol_version)(the governed concept as frozen by a version). - Exact version-aware lookup key: historical resolution = exact
(operation_code, protocol_version); new-use resolution = "the active row foroperation_codeunder the current/declaredprotocol_versionforact_type."
3. Field set (design-only)
| Field | Type | Rule |
|---|---|---|
vocab_id |
uuid | immutable surrogate id (reference target) |
operation_code |
text | governed value identity (immutable per row) |
protocol_version |
text | version identity (immutable per row) |
act_type |
text | governed act type (immutable per row) |
semantics_frozen |
jsonb | the immutable meaning bound at this version (no in-place re-meaning) |
status |
text | active / superseded / retired |
successor_operation_code |
text NULL | versioned successor (value part) |
successor_protocol_version |
text NULL | versioned successor (version part) |
governing_authority_ref |
text NOT NULL | each row's own governing authority (provenance; file 04) |
effective_from / effective_to |
timestamptz | half-open [from,to) validity window |
vocab_id_prev |
uuid NULL | links a superseding version to the prior vocab_id |
rollback_ref, created_*, superseded_* |
— | audit/supersession affordances |
4. Uniqueness axes
- PK
(operation_code, protocol_version)— one row per value per version. - UNIQUE
vocab_id— surrogate id never reused. - Partial UNIQUE: at most one
activerow per(operation_code, act_type)(the current resolvable version for new use).
5. Constraints / invariants (enforced by schema + governed handler, file 02)
| Invariant | Constraint |
|---|---|
| Successor exists | if status='superseded' then (successor_operation_code, successor_protocol_version) MUST reference an existing row (composite FK) |
| No self-link | (successor_operation_code, successor_protocol_version) <> (operation_code, protocol_version) |
| No cycle | successor chain is a DAG (governed-handler check; cycle ⇒ reject) |
| Compatible version progression | successor_protocol_version >= this row's protocol_version (monotone) |
| Immutable semantics | operation_code, act_type, protocol_version, semantics_frozen are write-once per row (no UPDATE re-meaning ⇒ would be RBP-5) |
| Lifecycle consistency | retired ⇒ not resolvable for new use (forward-fail-closed, I6/RBP-8); superseded ⇒ successor set |
| Forward-fail-closed | new-use lookup excludes superseded/retired unless an explicit successor maps it |
6. Versioned rollback target (fixes the wrong-version bug)
Rollback/supersession targets the exact version row (operation_code, protocol_version) (or vocab_id), never operation_code alone. Successor binding uses the composite successor key. The corrected rollback contract lives in file 06 (state machine) and supersedes prior file-08 §5.
7. Old-version resolvability (now enforced)
Because PK is (operation_code, protocol_version) and semantics_frozen is write-once, a historical effect that recorded (operation_code, protocol_version) always resolves to the exact frozen meaning; a new version is a new row, never an overwrite ⇒ no silent re-meaning (I4) and no wrong-version rollback.
8. Boundary attestation
Design-only schema/identity model; nothing created. REGISTRATION_HOLD retained; CAN_PROCEED = NO; 0 runtime mutations. Supersedes prior file-04 §1 schema and prior file-08 §5 rollback-by-operation_code.