@@ -15,19 +15,26 @@ import (
1515// through OperationFormatHistory; it is a property of the store, not of one
1616// row.
1717const (
18+ OperationRegistryMetadataVersion = 1
19+
20+ OperationModeTransition OperationMode = "transition"
21+ OperationModeReconcile OperationMode = "reconcile"
22+
1823 // OperationFormatLegacy is the shape written before registry-owned
19- // provenance: operations carry no provenance fields, and an ns.dependency
20- // entry states its deployment root through Entry.DependencyRoot. Such a
21- // store also holds updates for entries the current baseline no longer
22- // declares, which replay applies as upserts.
24+ // provenance. Such a store also holds updates for entries the current
25+ // baseline no longer declares, which replay applies as upserts.
2326 OperationFormatLegacy = 1
2427 // OperationFormatProvenance is the shape written by a runtime that owns
2528 // provenance: every operation carries its own record, so replay holds the
2629 // same total-map invariant a live transition holds.
2730 OperationFormatProvenance = 2
31+ // OperationFormatRegistryMetadata stores registry-owned state in its own
32+ // versioned operation block instead of adding fields to the entry or the
33+ // operation envelope.
34+ OperationFormatRegistryMetadata = 3
2835 // OperationFormatCurrent is the format this runtime writes. A wire-format
2936 // change bumps it together with the migration that re-stamps the store.
30- OperationFormatCurrent = OperationFormatProvenance
37+ OperationFormatCurrent = OperationFormatRegistryMetadata
3138)
3239
3340// OperationFormatSnapshot is the complete, source-verified view a semantic
@@ -74,6 +81,60 @@ var ErrOperationFormatMigrationConflict = errors.New("operation format migration
7481// until all branches have been rewritten.
7582var ErrOperationFormatMigrationIncomplete = errors .New ("operation format migration does not cover complete history" )
7683
84+ // NewOperationRegistryMetadata creates the versioned registry-owned portion
85+ // of an operation. The records are copied so callers retain no mutable alias.
86+ func NewOperationRegistryMetadata (current , previous * EntryProvenance ) * OperationRegistryMetadata {
87+ if current == nil && previous == nil {
88+ return nil
89+ }
90+ return NewOperationRegistryMetadataWithMode (OperationModeTransition , current , previous )
91+ }
92+
93+ // NewOperationRegistryMetadataWithMode creates registry-owned operation state
94+ // with explicit application semantics.
95+ func NewOperationRegistryMetadataWithMode (mode OperationMode , current , previous * EntryProvenance ) * OperationRegistryMetadata {
96+ metadata := & OperationRegistryMetadata {Version : OperationRegistryMetadataVersion , Mode : mode }
97+ if current != nil {
98+ copy := * current
99+ metadata .Current = & copy
100+ }
101+ if previous != nil {
102+ copy := * previous
103+ metadata .Previous = & copy
104+ }
105+ return metadata
106+ }
107+
108+ // OperationMode returns the registry application semantics carried by the
109+ // operation. An empty value is invalid in the current operation format.
110+ func (o Operation ) OperationMode () OperationMode {
111+ if o .Registry == nil {
112+ return ""
113+ }
114+ return o .Registry .Mode
115+ }
116+
117+ // CurrentProvenance returns the registry state produced by the operation.
118+ func (o Operation ) CurrentProvenance () * EntryProvenance {
119+ if o .Registry == nil {
120+ return nil
121+ }
122+ return o .Registry .Current
123+ }
124+
125+ // PreviousProvenance returns the registry state replaced by the operation.
126+ func (o Operation ) PreviousProvenance () * EntryProvenance {
127+ if o .Registry == nil {
128+ return nil
129+ }
130+ return o .Registry .Previous
131+ }
132+
133+ // SetRegistryMetadata replaces the registry-owned portion of an operation.
134+ func (o * Operation ) SetRegistryMetadata (current , previous * EntryProvenance ) {
135+ o .Registry = NewOperationRegistryMetadata (current , previous )
136+ }
137+
77138// ErrMissingProvenance reports a state entry without a provenance record — a
78139// violation of the ProvenanceMap total-map invariant.
79140var ErrMissingProvenance = errors .New ("entry has no provenance record" )
0 commit comments