The declared outcome
An outcome lives in the held target’s output schema, on the flow’s single result surface. The schema wraps the value in the run’s result envelope — astatus string and a result object keyed by the collector’s id — with the
outcome field carrying an enum of its values:
collect and the outcome field is outcome, with two
values. A flow that flags exactly one result surface can declare one outcome; a flow
that flags none, or more than one, declares none.
The synthesized conditional
Wiring the outcome adds oneconditional node. Its id is the wired node’s id with
__outcomes appended, and it carries one branch per wired value. Each branch’s key
is the conditional’s id with __<value> appended, its condition reads the wired
node’s result at the pinned path, and its path is the target node the value routes
to:
gate; the conditional is gate__outcomes, with a branch
for each wired value. The graph gains one edge from the wired node into the
conditional and one edge from the conditional to each branch target:
The pinned condition path
Every branch condition reads the wired node’s recorded result at one fixed shape:<node> is the wired node’s id, <collectorId> and <outcomeField> are the two
names from the declared outcome, and <value> is the wired value. A branch that
reads this exact path is a wired outcome; a branch that reads anything else is a
plain hand-authored decision on the same field, and stays one.
The ui marker is optional
The ui marker names the wired node and its outcome so the editor folds the
conditional back into chips when it loads the flow. The engine ignores it: it reads
the wire form structurally — the conditional’s id, its branch keys, and each
branch’s condition path — and drops the marker when it builds the flow. A
hand-authored flow that follows the id, branch-key, and condition-path shape above
is read and routed identically with or without the marker. Add the marker only
if you want the editor to render the wiring as chips.
Expiry follows the wiring
An ask holder whose held target has anexpired
outcome earns its expiry behaviour from the wiring, never from an authored value.
When the expired value is wired downstream — the conditional carries a
<node>__outcomes__expired branch — the ask is started with on_expiry set to
resume, so a lapsed deadline resumes the run down the expired branch. Leave
the expired value unwired and the ask keeps the door’s kill default: a lapsed
deadline ends the held chain. The behaviour is a pure function of whether the
branch is present, so a hand-authored flow that wires the branch gets the resume
behaviour with nothing else to set.
See also
- Calling another flow: cancel, resume, start — the holder node the outcome sits on.
- Expiry in a flow — what the derived
on_expirydoes at run time. - The flows editor — wiring an outcome as chips instead of by hand.

