pub enum OperationKind {
Show 16 variants
AddFunction {
sig_id: SigId,
stage_id: StageId,
effects: EffectSet,
budget_cost: Option<u64>,
},
RemoveFunction {
sig_id: SigId,
last_stage_id: StageId,
},
ModifyBody {
sig_id: SigId,
from_stage_id: StageId,
to_stage_id: StageId,
from_budget: Option<u64>,
to_budget: Option<u64>,
},
RenameSymbol {
from: SigId,
to: SigId,
body_stage_id: StageId,
},
ChangeEffectSig {
sig_id: SigId,
from_stage_id: StageId,
to_stage_id: StageId,
from_effects: EffectSet,
to_effects: EffectSet,
from_budget: Option<u64>,
to_budget: Option<u64>,
},
AddImport {
in_file: String,
module: ModuleRef,
},
RemoveImport {
in_file: String,
module: ModuleRef,
},
AddType {
sig_id: SigId,
stage_id: StageId,
},
RemoveType {
sig_id: SigId,
last_stage_id: StageId,
},
ModifyType {
sig_id: SigId,
from_stage_id: StageId,
to_stage_id: StageId,
},
Merge {
resolved: usize,
},
InlineLet {
sig_id: SigId,
from_stage_id: StageId,
to_stage_id: StageId,
let_node: String,
binding_name: String,
from_budget: Option<u64>,
to_budget: Option<u64>,
},
RenameLocal {
sig_id: SigId,
from_stage_id: StageId,
to_stage_id: StageId,
let_node: String,
old_name: String,
new_name: String,
from_budget: Option<u64>,
to_budget: Option<u64>,
},
ReplaceMatchArm {
sig_id: SigId,
from_stage_id: StageId,
to_stage_id: StageId,
match_node: String,
arm_index: usize,
from_budget: Option<u64>,
to_budget: Option<u64>,
},
Candidate {
sig_id: SigId,
stage_id: StageId,
},
Promote {
sig_id: SigId,
winner_candidate: OpId,
winner_stage_id: StageId,
supersedes: Vec<OpId>,
from_stage_id: Option<StageId>,
from_budget: Option<u64>,
to_budget: Option<u64>,
},
}Expand description
The kinds of operations that produce stage transitions. Mirrors
the initial set in #129; new kinds (MoveBetweenFiles,
SplitFunction, ExtractType) can be added later as long as
they’re appended at the end of this enum or use explicit
#[serde(rename = "...")] tags so existing OpIds stay stable.
Variants§
AddFunction
New function published. effects is the effect set declared
in the signature; tracked here (not just inside the stage)
so #130’s write-time gate has a cheap path to check effect
changes without rehydrating the AST.
budget_cost (#247) records the function’s declared
[budget(N)] cost. Optional with skip_serializing_if, so
pre-#247 ops without a declared budget continue to hash to
their original OpId (additive serialization, same trick
intent_id uses). None means the function declared no
budget effect; Some(n) is the literal n from
[budget(n)].
RemoveFunction
Function removed; last_stage_id is the head before the
remove (so blame can walk the predecessor without scanning).
ModifyBody
Function body changed; signature unchanged.
from_budget / to_budget (#247) record the declared
[budget(N)] on each side. Same Option + skip discipline
as AddFunction.budget_cost — pre-#247 ops keep their
OpIds. The pair is what lex op log --budget-drift reads
to surface “budget grew/shrank” diffs without rehydrating
stages.
Fields
RenameSymbol
Symbol renamed. The body hash is preserved (body_stage_id)
so two renames of the same body collapse to the same OpId
and lex blame walks the rename as a single causal event
rather than delete + add.
ChangeEffectSig
Effect signature changed. Captures both old and new effect sets so the write-time gate (#130) can verify importers haven’t silently broken.
from_budget / to_budget (#247) capture the declared
[budget(N)] on each side. ChangeEffectSig usually fires
because the effect list changed; #247 makes budget drift
visible without forcing a full effect-set diff.
Fields
AddImport
Import added to a file. in_file is the canonical path
(relative to the repo root, forward-slashes) so two
machines hashing the same edit get the same OpId.
RemoveImport
AddType
RemoveType
ModifyType
Merge
Merge of two branch heads. Carries only an informational count
of resolved sigs so two structurally identical merges of
different sizes don’t collide on op_id; the per-sig deltas live
in OperationRecord::produces (StageTransition::Merge).
InlineLet
Typed transform: inlined a let x := v; body by
substituting v for every unshadowed x in body, then
replacing the entire Let node with the substituted body
(#280). The op records the let-binding’s position and the
inlined name; the actual substituted value lives in the
content-addressed to_stage_id so the op_id stays compact.
Fields
RenameLocal
Typed transform: renamed a let-bound local within a fn
body (#280). Records the old/new identifiers and the position
of the let-binding in the AST. Body-shape-stable: the renamed
stage typically hashes near the original.
Fields
ReplaceMatchArm
Typed transform: replaced one arm’s body in a Match
expression (#280). Semantically a ModifyBody, but the op
records which arm changed and where in the AST — so the
op log reads as a semantic edit history rather than as
opaque hash-to-hash bytes.
match_node is the lex_ast::ids::NodeId of the Match
expression at the time of the transform. NodeIds aren’t
stable across structural edits — they’re audit-trail metadata,
not re-derivation keys. The authoritative record of the new
stage is to_stage_id (content-addressed).
from_budget/to_budget follow the same skip_if_none
discipline as Self::ModifyBody: pre-#280 ops continue
hashing to their original OpIds.
Fields
match_node: StringPath-style NodeId of the Match expression that was
modified, captured at transform time. See
lex_ast::ids::NodeId for the format.
Candidate
Multi-agent coordination: a stage proposed for a sig
without advancing the branch (#294). Multiple agents can
land Candidate ops on the same sig concurrently without
contention — they all chain off the current head and don’t
move it. Used together with Self::Promote to model
bake-offs: several agents propose, one is promoted.
The Operation’s intent_id is expected to be set so
downstream consumers can distinguish proposals by author.
(The schema doesn’t enforce this; the gate does.)
Promote
Multi-agent coordination: promotes a previously-landed
Self::Candidate op as the new head for its sig (#294).
Carries the list of other candidates this Promote
supersedes so the op log explicitly records the bake-off
shape.
Acts as a ModifyBody (or AddFunction when the sig has
no head) for branch-head purposes — transition_for_kind
returns the appropriate StageTransition.
Fields
winner_candidate: OpIdOp id of the Self::Candidate being promoted.
winner_stage_id: StageIdStage id of the winner (duplicates the candidate’s
stage_id for fast lookup; saves a log round-trip
for lex op show).
supersedes: Vec<OpId>Every other live Candidate for sig_id at the time
of promotion. Sorted by op_id for canonical-form
stability. After this Promote lands, none of these
op_ids appear in [Store::list_candidates].
Implementations§
Source§impl OperationKind
impl OperationKind
Sourcepub fn merge_target(&self) -> Option<(SigId, Option<StageId>)>
pub fn merge_target(&self) -> Option<(SigId, Option<StageId>)>
The (SigId, Option<StageId>) an op kind targets, as used by
StageTransition::Merge::entries. Used by the merge-commit
path (#134) to translate a Resolution::Custom { op } into
the head-map delta the merge op records:
- Adds →
(sig, Some(stage_id)) - Modifies →
(sig, Some(to_stage_id)) - Removes →
(sig, None) - Renames →
(to_sig, Some(body_stage_id)) AddImport/RemoveImport/ nestedMerge→None(no single sig→stage delta)
Sourcepub fn budget_delta(&self) -> (Option<u64>, Option<u64>)
pub fn budget_delta(&self) -> (Option<u64>, Option<u64>)
(from_budget, to_budget) for ops that carry a budget delta
(#247). (None, None) for ops where the budget isn’t part
of the canonical payload — RemoveFunction, RenameSymbol,
imports, and merges. AddFunction reports (None, Some(cost)) for “this is the initial cost.” Used by lex op show, lex op log --budget-drift, and lex audit --budget.
Sourcepub fn budget_sig(&self) -> Option<&SigId>
pub fn budget_sig(&self) -> Option<&SigId>
The SigId an op touches if it carries a budget — used for
per-sig audit rollups in lex audit --budget. Returns None
for ops without a relevant budget (the same set as the
_ => (None, None) arm of Self::budget_delta).
Trait Implementations§
Source§impl Clone for OperationKind
impl Clone for OperationKind
Source§fn clone(&self) -> OperationKind
fn clone(&self) -> OperationKind
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for OperationKind
impl Debug for OperationKind
Source§impl<'de> Deserialize<'de> for OperationKind
impl<'de> Deserialize<'de> for OperationKind
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl PartialEq for OperationKind
impl PartialEq for OperationKind
Source§fn eq(&self, other: &OperationKind) -> bool
fn eq(&self, other: &OperationKind) -> bool
self and other values to be equal, and is used by ==.Source§impl Serialize for OperationKind
impl Serialize for OperationKind
impl Eq for OperationKind
impl StructuralPartialEq for OperationKind
Auto Trait Implementations§
impl Freeze for OperationKind
impl RefUnwindSafe for OperationKind
impl Send for OperationKind
impl Sync for OperationKind
impl Unpin for OperationKind
impl UnsafeUnpin for OperationKind
impl UnwindSafe for OperationKind
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.