ADR 0025 - Configured Executor Values

Defines reusable configured executor values as inert Wire source values that can be applied only in explicit node executor-call positions.


On this page
  1. Status
  2. Context
  3. Decision
  4. Syntax
  5. Scoping And Export
  6. Config Evaluation
  7. Port Matching
  8. Alternatives considered
  9. Consequences
  10. Positive
  11. Negative
  12. Obligations
  13. Related

ADR 0025 - Configured Executor Values

Status

Proposed - fills the reusable-config gap left by ADR 0024 after configured executors stopped being graph vertices. ADR 0030 defines the node implementation positions where configured executor values may be applied.

Context

ADR 0024 intentionally rejects the older partial-node model. A configured executor value may name registered authority and carry reusable configuration, but it is not a graph vertex and cannot derive a port boundary from surrounding topology.

That leaves a useful authoring question: what does this mean?

let analyst = @review.analyst { temperature = 0.2 } ;

Without a source-level answer, authors must either repeat executor config at every call site or fall back to the old partial-node intuition that ADR 0024 rejects.

Decision

Wire should support configured executor values as inert source values.

let analyst = @review.analyst {
  temperature = 0.2 ;
  model = "gpt-5.4" ;
} ;

node analyze
  <- evidence: EvidenceSet ;
  -> analysis: AnalysisRecord ;
  = analyst (evidence) ;

A configured executor value has an executor kind, not a CorePure value type and not a circuit type. Conceptually it carries:

  • the executor id;
  • a statically elaborated config value;
  • the registered executor projection used for admission;
  • effect and validation metadata from the projection registry.

It carries no runnable host action, provider credential, tool handle, or Pulse StageAction.

Syntax

The reusable form is:

let <name> = @<executor> { <config> } ;

The direct call form is:

-> output: T = @<executor> { <config> } (<input-expr>) ;

The empty-config shorthand remains valid:

-> output: T = @<executor> (<input-expr>) ;

and is equivalent to:

-> output: T = @<executor> {} (<input-expr>) ;

Applying a configured executor value is valid only in the executor-call implementation positions defined by ADR 0030: a node-level executor body after the output boundary has been declared.

node analyze
  <- input: AnalysisInput ;
  -> output: AnalysisRecord ;
  = analyst (input) ;

The single-output inline shorthand is reserved for registered executor authority with @. It is not valid for configured executor values because analyst (input) is also ordinary CorePure function application syntax after ADR 0050.

It is not valid inside CorePure, so this output equation is rejected:

-> output: T = analyst input ;

Scoping And Export

File-level let may bind configured executor values. The binding is private unless written with export let.

export let analyst = @review.analyst { temperature = 0.2 } ;

Exporting a configured executor value exports inert source data only. It does not grant authority. An importing host still needs a registered projection and Capability binding for the referenced executor id.

Node-local where <record-expr> ; clauses remain CorePure-only. They may depend on input values and are subject to the pure evaluator’s determinism and authority-freedom rules. Allowing executor values there would mix input-dependent pure computation with authority selection.

Config Evaluation

Executor config must be statically elaborable. It may use file-level static pure-data values, but it may not depend on node input ports, runtime values, memory, time, IO, imports with authority, or host callbacks.

Config admission happens before the graph vertex is admitted. Invalid config is a Wire admission failure, not a runtime executor failure.

Port Matching

A configured executor value is applied to one input expression. If the registered projection has one input port, the expression must validate against that port’s contract. If the projection has several input ports, the expression must be a record whose fields match the projected input port labels.

The result boundary must match the node implementation form from ADR 0030. Single-output shorthand is valid only when exactly one output is declared. Multi-output and zero-output configured executor calls use node-level executor bodies.

Alternatives considered

  • Keep configured executors as partial graph nodes. Rejected because ADR 0024 requires every admitted vertex to have an explicit typed boundary from a node declaration.
  • Make executor config host-only. Rejected because repeated inline config is poor authoring and hides useful reusable policy from Wire review.
  • Allow executor values inside CorePure. Rejected because CorePure is authority-free and deterministic. Executor selection is a topology/binding concern, not pure computation.
  • Require inline config at every call site. Rejected because it preserves the semantics but creates noisy source and encourages drift between nominally identical executor uses.

Consequences

Positive

  • ADR 0024’s reusable-config story gets a concrete syntax.
  • Reusable executor policy can be reviewed, exported, and reused without becoming topology.
  • Host authority remains in Capability binding rather than in Wire source.
  • Node declarations remain the only authored graph vertices.

Negative

  • Wire needs kind checking for ordinary pure-data values, configured executor values, and graph values.
  • The parser distinguishes configured executor application by node-level executor-body position; direct output equations are CorePure.
  • Configured executor application depends on the node implementation-form checks from ADR 0030.

Obligations

  • Add parser and kind-checker tests for configured executor bindings and node-level body applications.
  • Reject configured executor calls inside CorePure output equations.
  • Reject input-dependent executor config.
  • Update executor reference docs to replace partial-node wording with configured executor values.
  • Ensure imported configured executor values still require host projection and Capability binding.