pub enum CompositionNode {
Stage {
id: StageId,
pinning: Pinning,
config: Option<BTreeMap<String, Value>>,
},
RemoteStage {
url: String,
input: NType,
output: NType,
},
Const {
value: Value,
},
Sequential {
stages: Vec<CompositionNode>,
},
Parallel {
branches: BTreeMap<String, CompositionNode>,
},
Branch {
predicate: Box<CompositionNode>,
if_true: Box<CompositionNode>,
if_false: Box<CompositionNode>,
},
Fanout {
source: Box<CompositionNode>,
targets: Vec<CompositionNode>,
},
Merge {
sources: Vec<CompositionNode>,
target: Box<CompositionNode>,
},
Retry {
stage: Box<CompositionNode>,
max_attempts: u32,
delay_ms: Option<u64>,
},
Let {
bindings: BTreeMap<String, CompositionNode>,
body: Box<CompositionNode>,
},
}Expand description
A composition graph node. The core AST for Noether’s composition language.
Variants§
Stage
Leaf node: reference to a stage in the store.
The id field is interpreted according to pinning:
Pinning::Signature(default):idis a signature-level hash (SignatureId) and the resolver returns the currently Active implementation with that signature.Pinning::Both:idis an implementation-inclusive hash (ImplementationId/StageId) and the resolver requires an exact match. No fallback.
The optional config provides static parameter values merged
with the pipeline input before the stage executes.
Use CompositionNode::stage to construct a node with default
pinning; use the struct literal only when you need a non-default
pinning or a config.
§Known gap in M2 (v0.6.0)
resolve_stage_ref is only wired into the type checker and
executor runner. Other passes (effect inference, Ed25519
verify, planner cost/parallel grouping, budget, grid-broker
splitter) still look up by StageId directly, which means
a Pinning::Signature node may type-check but fail at those
downstream passes. The resolver-normalisation pass lands as a
follow-up: it rewrites graph nodes to implementation IDs before
any downstream pass runs, so the rest of the engine keeps
operating on concrete implementation hashes.
RemoteStage
Call a remote Noether API endpoint over HTTP.
The declared input and output types are verified by the type checker
at build time — the remote server does not need to be running during
noether build. In native builds, execution uses reqwest. In browser
builds, the JS runtime makes a fetch() call.
Fields
Const
Emits a constant JSON value, ignoring its input entirely. Used to inject literal strings, numbers, or objects into a pipeline.
Sequential
A >> B >> C: output of each stage feeds the next.
Fields
stages: Vec<CompositionNode>Parallel
Execute branches concurrently, merge outputs into a Record keyed by
branch name. Each branch receives input[branch_name] if the input is
a Record containing that key; otherwise it receives the full input.
Const branches ignore their input entirely — use them for literals.
Fields
branches: BTreeMap<String, CompositionNode>Branch
Conditional routing based on a predicate stage.
Fanout
Source output sent to all targets concurrently.
Merge
Multiple sources merge into a single target.
Retry
Retry a stage up to max_attempts times on failure.
Let
Bind named intermediate computations and reference them in body.
Each binding sub-node receives the outer Let input (the same value
passed to the Let node). After all bindings have produced a value, the
body runs against an augmented input record:
{ ...outer-input fields, <binding-name>: <binding-output>, ... }
Bindings with the same name as an outer-input field shadow it. This
makes it possible to carry original-input fields into stages later in a
Sequential pipeline — the canonical example is scan → hash → diff,
where diff needs state_path from the original input but hash
would otherwise erase it.
All bindings are scheduled concurrently — there are no inter-binding
references. If you need a binding to depend on another, wrap it in a
nested Sequential.
Implementations§
Source§impl CompositionNode
impl CompositionNode
Sourcepub fn stage(id: impl Into<String>) -> Self
pub fn stage(id: impl Into<String>) -> Self
Build a Stage node with default pinning (Signature) and no
config. Use this in place of the struct literal when you don’t
need to set pinning or config explicitly.
Sourcepub fn stage_pinned(id: impl Into<String>) -> Self
pub fn stage_pinned(id: impl Into<String>) -> Self
Build a Stage node with an explicit Both pinning — the
resolver will require the exact implementation named by id.
Trait Implementations§
Source§impl Clone for CompositionNode
impl Clone for CompositionNode
Source§fn clone(&self) -> CompositionNode
fn clone(&self) -> CompositionNode
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more