CX · Reference guideflow
PlaygroundDownloadsAboutv0.18.0-pre.1

flow

General workflow on the saga substrate: flows as documents, runs as journaled records, and a runner that is a pure function rather than an engine. A flow is an ordinary CX document in a CLOSED vocabulary of nineteen words (§2.3), of which nineteen are implemented — flow, step, branch, map, until, pivot=, when=, needs=, deadline=, escalate, the [notify] rung, by=, quorum=, attempts=, every=, flow=, calendar=, [compute …], [ack …] — whose steps carry their act in the canonical form [do 'ns/verb' [field value]…], or COMPUTE a value with [compute 'ns/def' [field value]…], the transform step. needs= names the PRECEDING SIBLINGS a construct waits for, relaxing document order into a DAG so siblings whose needs are met activate together (RULED: 789-WF-20a). attempts=N on a step bounds the re-attempts of a FAILED act and is admitted only where the resolved command declares [idempotent] (RULED: 789-WF-26a): the record carries attempt=K, a failed attempt with the bound unspent is :retrying and is re-offered on the next drive, and exhaustion is :failed reason=:attempts-exhausted into the path below; every= is the WAIT between attempts, a durable timer named <run id>:<step>:wait so it cannot displace the step's deadline (RULED: 1314-c1), armed on-missed :coalesce and re-offering the step when it fires (RULED: 1314-c2). A step's intent BINDS from the run record at activation (RULED: WF-42): a [do …] or [compute …] field may hold a CXPath over $args and $steps — a guard's own domain, refused with a guard's own code outside it, and refused CXER4952 on a step the order does not place first — and the RESOLVED intent is what the :running transition and the folded record carry, so the record is the only truth an act was made from; [compute 'ns/def' …] stands where an act stands, runs a Ring-1 PURE def read off the resolver row's pure= under the same absent-means-no rule idempotent= carries, records its result like any step's, and is never the pivot. [until … attempts=N] is BOUNDED repetition, do then test (RULED: WF-18): the body runs, then the when= EXIT guard is read over the record, and while it is false the body runs again after the every= wait (the same durable wait timer a step's re-attempt uses, armed on-missed :coalesce) until attempts= — MANDATORY — is spent, which is :failed reason=:attempts-exhausted into the path below; each iteration's rows are recorded IN THE PARENT with iteration=N, $steps/<name> reading the latest and $steps/<name>[iteration=N] an earlier one, until inside until is refused and the pivot may sit in one only when its attempts= is 1. flow=<address> on a step is a SUB-FLOW by content address (RULED: WF-22): the reference resolves at validation against a [flow …] document the resolver carries, whose address IS its content address — a cycle, an unresolvable address or a run tree deeper than 32 refuse CXER4967, the step's [args …] is checked against the referenced declaration, and the pivot rule counts through the reference — and at run time the step starts a CHILD RUN of that document in its own stream, correlated by run id (parent= on the child, child= on the step), completing when the child does and compensating the child in reverse when the parent unwinds; a [flow] nested inside a [flow] stays refused. calendar=<address> names a [business-calendar] (time.md §3.11) that every duration in its scope is measured against in OPEN time (RULED: WF-24): the document's calendar= is the default and the innermost one on a step, branch, map, until or rung wins; the address resolves at validation against a [business-calendar …] row the resolver carries, whose address IS its content address, and an address that does not resolve, is not a calendar, or names one time refuses is CXER4968; each deadline=, every= wait and rung within= in scope is computed ONCE at activation as time's add-open-duration from the activation instant and recorded on the activating transition (deadline-at=, wait-until=, rungs-at=), the durable timer armed AT that instant, so a 4h deadline armed at 15:00 Friday under a 09:00–17:00 Mon–Fri calendar is due at 11:00 Monday and a replay reads the instant it was armed with; flow keeps no clock, so the activation instant arrives as data — a start's opts.at, an advance's event at= (a timer's own, a courier's tick at= or an act's at=) — and a document with a calendar= started or advanced without one is refused CXER4965 before anything is performed; a run is the fold over its [flow-transition …] entries in one journal stream; and advance(document, record, event) yields the transitions to append plus at most one side effect, so any process may advance a run, racing advancers are serialized by the stream's own commit lock, and a crashed advancer leaves nothing to clean up. Wave 1 ships validate (the whole grammar, the applicability matrix, the refusals register, the pivot rules, the guard domain and act resolution, all as values), simulate (the same runner law over a supplied result table — a deterministic dry run that needs no journal), fold-record (the pinned fold identity from transitions to the [flow-run …] record), and the impure verbs start / advance / status / rearm / claim / release / reassign / cancel / pause / resume / skip / retry-now / resolve / migrate: start derives the run's content-addressed id, journals its :started transition with the authority basis it will be admitted against, and drives the run until it parks or terminates; advance performs the ONE effect the law names, applies its outcome on the same call, and appends both under the home stream's expect-pos CAS; status is the fold at head, or at a position for a bitemporal read. A map fans out over its over= set into CHILD RUNS — a derived document per item, with $item bound and the parent's args visible read-only, in the child's own home stream whose id is the content address over (parent id, map name, item index) — and the parent carries only counts: one :fanned-out transition, then a claim and a completion per item, bounded by max-parallel= in-flight children, with tolerate= the number (or percent) of item failures the set absorbs and a failed child compensating itself. A child run is an ordinary run: advance and status on it behave as on any run. Compensation runs in reverse before the pivot and forward-only after it with the incomplete count visible; a failing compensator yields the one [conflict kind=:uncompensatable] value; every deadline is a durable sched timer whose callback is advance, armed on-missed :fire-all so an expired one-shot is never dropped, and rearm is the restore half a live runner calls at boot — it folds the journal to the pending [sched-intent …] set, derives each registry entry from the timer's own name and calls sched restore, so a deadline that elapsed while the process was down fires once carrying its ORIGINAL instant; and a completed run answers [deduped …], because the record IS the durable step-dedup. The PERFORMER AXIS (RULED: WF-4, WF-12, WF-21, WF-23; W3): by= other than :runner OFFERS a step — the runner journals :pending with offered-to= and parks, and the step completes on an ADMITTED correlated act: for :principal an [approval] of the recorded cx:propose proposal (its address is the step's proposal=, and the approval that completes it is committed through authz), or the act itself with its empty fields filled, admitted at the PEP against the performer's own authority; for :agent the outcome of the stream-18 tool the offer records (scoped to the run, requiring a delegation attenuated from the run's basis by the step's [bounds]), or an explicit [hand-back] into the ladder with the handoff brief; for :peer the acknowledgment an adapter presents with the run id as the callback token; and a decline for any of them. quorum=N completes a principal step on N distinct actors' approvals of its one proposal (quorum-met=, [concurrence …], :quorum-unreachable, :quorum-unsatisfiable); the [escalate] ladder's [to] rungs transfer the offer and its [notify] rungs append :reminded, every rung a durable timer, and a deadline that fires with no rung left parks the run :stalled; claim, release and reassign are the work-management acts, each a transition under the run's CAS (CXER4959 for the losing claimer). MIGRATE (RULED: WF-6; W5) moves an in-flight run onto a new version of its document, and only on a Lane-2 [flow-lineage [from] [to] [relation] [map step= to=]…] claim covering exactly that pair (CXER4960) and mapping every COMPLETED step (CXER4961): its dry run classifies the run :clean, :drifted — with the diff of its pending step's neighborhood — or :refused, presented to its owner as a decision, and commits nothing, and with an empty run id it classifies every in-flight run of the old version fleet reads, the fleet preflight; a committed move appends one :migrated transition carrying the claim's address and re-pins flow=, the run's durable timers following the pin; and an ops agent's migrate is floored at approval. The OPERATOR ACTS (RULED: WF-19, WF-25, 1265-PB-8; W7) are six verbs on the RUN, each admitted against the operator's own authority and each a recorded transition carrying actor=, authority= and its reason: cancel appends :cancelling, withdraws what the run never reached, lets a :running step's outcome land and then unwinds from where the run stands to :cancelled (cancelled-by= on the record), cascading to map children and sub-flows, and is refused past a :done pivot; pause parks the run :paused with each armed timer's REMAINING duration recorded ([suspended …], measured from the act's own instant opts.at) and resume re-arms exactly those, so paused time does not count; skip records a step :skipped reason=:operator and activates its successors, refusing a :done step, a pre-pivot step the pivot waits on and any step past a :done pivot; retry-now re-attempts the :incomplete tail or a step waiting on its every= wait now, which the empty advance tick does not; and resolve consumes the one [conflict] value with a [resolution kind=:retry-compensation|:accept-forward|:abandon], floored at approval for an ops agent — an agent's resolve is refused on its own authority (CXER4700), and a principal resolves. A state an act does not admit is CXER4966; an act that finds nothing to do answers the record unchanged. The OPERATOR ACTS (RULED: WF-19, WF-25, 1265-PB-8; W7) are six verbs on the RUN, each admitted against the operator's own authority and each a recorded transition carrying actor=, authority= and its reason: cancel appends :cancelling, withdraws what the run never reached, lets a :running step's outcome land and then unwinds from where the run stands to :cancelled (cancelled-by= on the record), cascading to map children and sub-flows, and is refused past a :done pivot; pause parks the run :paused with each armed timer's REMAINING duration recorded ([suspended …], measured from the act's own instant opts.at) and resume re-arms exactly those, so paused time does not count; skip records a step :skipped reason=:operator and activates its successors, refusing a :done step, a pre-pivot step the pivot waits on and any step past a :done pivot; retry-now re-attempts the :incomplete tail or a step waiting on its every= wait now, which the empty advance tick does not; and resolve consumes the one [conflict] value with a [resolution kind=:retry-compensation|:accept-forward|:abandon], floored at approval for an ops agent — an agent's resolve is refused on its own authority (CXER4700), and a principal resolves. A state an act does not admit is CXER4966; an act that finds nothing to do answers the record unchanged. fleet is the per-party LIVE readout (RULED: WF-7): one live materialize per stream of the journal — checkpointed, incremental, rebuildable from the journal — joined at the cut its head-sets name, counting runs by status and by flow version, naming the :stalled runs by a PURE predicate over the record (:running, no durable timer pending, and the newest transition older than the active step's deadline, else the flow's stall-after=, else seven days — never a heartbeat), the :conflict and :incomplete ones, child completion per map and each run's age since its last transition, filtered by a CXPath over records (opts.where) and paged (opts.limit, opts.cursor); its :inbox lens answers the offered principal steps one actor may take (RULED: 1265-PW-2), its [steps …] rows are the fleet overlay on the flow's one picture, and a build without the live pack refuses it CXER4964. The CROSS-COMPANY profile (RULED: WF-8; W6): a :peer step offered to=peer:did:… is a DELEGATED INTENT over the federation seam — validate refuses a counterparty whose authenticated XSP session, the resolver's [peer [xsp-auth-established …] [fn …]] row, did not confirm the transcript-covered flow token (CXER4962); the runner emits the act over that session with the initiator's own locator it emitted at, and the step completes — or, on a wind-back, is compensated through a second intent to the paired compensator — only on the counterparty's signed [step-ack …], verified fail-closed (the run and step correlation, [by] the delegated DID, a signed tier, the recorded locator, Ed25519 over the claim's canonical form under the DID's own key — or, for a did:web, under the key the session's attach resolved, recorded as kid= and doc-hash= on the completing transition (RULED: XCO-1); CXER4963) — and a step whose [ack tier=:t2 by= m=] states a co-signature set completes on m distinct named co-signers verified over one canonical claim (RULED: XCO-2), each party's journal holding its half and the run id a correlation key, never an authority input. It composes journal, authz, sched, live, cx, did and diagram, and adds no engine process, no second timer, no second approval mechanism and no capability of its own.

flow:pipeline-check

[$flow:pipeline-check] ($pipeline::element $flow::element $env::element) -> element — Check a [pipeline name= flow= [extract step=]… [transform step= in= out=]… [load step=]… [park step=]] against the flow it declares (flow.md §4.27): [pipeline-ok …], or CXER4965 naming every defect — the flow's address or validity, a missing step, an extract/load/park that is not a [do …] act, a transform that is not a [compute …] step, an in=/out= that is not a content address.

flow:job-check

[$flow:job-check] ($job::element $flow::element $env::element) -> element — Check a [job name= flow= [run step= pipeline=]…] against the flow it declares (flow.md §4.27): [job-ok …], or CXER4965 when the address or validity is wrong or a [run] names a step that does not exist or is not a sub-flow step.

flow:job-readout

[$flow:job-readout] ($journal::element $id::string $job::element $pipelines::any $opts::map) -> element — A job run's readout (flow.md §4.27): its status and, per [run …] step, the child pipeline run's id and status with [stage step= role= status=] by the roles of the pipeline declaration its pipeline= address names.

flow:iac-state

[$flow:iac-state] ($journal::element $stack::string) -> element — The observed infrastructure of a stack (flow.md §4.28): [observed stack= [resource type= name= pos= field=…]*], the fold of every iac:<stack>/<name> stream (one per resource), secret references resolved to the sealed values the journal still holds.

flow:iac-plan

[$flow:iac-plan] ($contracts::element $desired::element $observed::element $opts::map) -> element — The plan (flow.md §4.28): the field diff of a [stack …] against the observed state projected through the [contracts [resource-type …]…] — create/update/replace in dependency order, deletes in reverse, [set field= from= to=] rows (a secret's row carries no value), the stream positions read, the masked desired/observed hashes; CXER4965 naming every defect (an undeclared or computed field, an immutable change, a cycle, a refusing opts.policy closure).

flow:iac-apply

[$flow:iac-apply] ($plan::element $contracts::element $provider::map $journal::element $attribution::map $opts::map) -> element — Run a plan through the provider closures (flow.md §4.28): CXER1114 when a stream moved since the plan; else each step's effect, readiness or finalizer wait, secret seal and journaled entry under expect-pos; the first failure compensates every completed step in reverse. [apply-report status=applied|compensated|refused …] with the rotated secrets it shredded.

flow:iac-read

[$flow:iac-read] ($contracts::element $provider::map $observed::element) -> element — What the provider reads back for every recorded resource (flow.md §4.28): [live stack= [resource …]* [missing …]* [unmanaged …]*], unmanaged from a provider's optional list closure.

flow:iac-drift

[$flow:iac-drift] ($contracts::element $observed::element $live::element) -> element — The snapshot-diff rung over infrastructure (flow.md §4.28): [drift rung=snapshot-diff [changed resource= field= recorded= live=]* [missing …]* [unmanaged …]*] over the declared, non-computed, non-secret fields.

flow:hermetic-identity

[$flow:hermetic-identity] ($step::element $opts::map) -> any — A [hermetic-step …]'s identity (flow.md §4.26): step: + the content address of the step document, its program and every input by content (under opts.root), and the cx build that runs it; CXER4965 for a malformed step.

flow:hermetic-run

[$flow:hermetic-run] ($step::element $opts::map) -> any — Run a [hermetic-step …] under the :cx executor (flow.md §4.26): a fresh cx granted read/write of a work directory holding only the copied inputs; a hermetic step whose identity is indexed in opts.cache is served from it without executing. Answers [hermetic-result status= cached= identity= …] with its [attestation …] (inputs and outputs by content address); :failed with reason=:exit / :output-missing / :output-undeclared is the failure channel. An effectful step always runs and is never cached.

flow:promote

[$flow:promote] ($journal::element $artifact::element $opts::map) -> any — Move an [artifact name= addr=] into the environment opts.to (flow.md §4.26): admitted on opts.attestation, a signed attestation that verifies (opts.trust honoured) and names the address among its outputs, and — with opts.from — only for the address that environment holds. Appends one actor-stamped [promoted …] to the journal stream promote:<name> under its compare-and-swap; answers [promotion name= env= addr= seq=]. Refusals are CXER4965.

flow:rollback

[$flow:rollback] ($journal::element $name::string $env::string $addr::string $opts::map) -> any — Move an environment's pointer back to an address that was promoted to it before (flow.md §4.26): one more [promoted … rollback=true]; the history is never rewritten. CXER4965 for an address the environment never held.

flow:promotion-status

[$flow:promotion-status] ($journal::element $name::string) -> element — Where each environment points now (flow.md §4.26): [promotion-status name= moves= [env name= addr=]…], folded from the journal stream promote:<name>.

flow:attestation-sign

[$flow:attestation-sign] ($att::element $signer::map) -> any — Sign an [attestation …] (flow.md §4.26): Ed25519 over its canonical bytes without the signature, under signer {did: <did:key:…>, key: <private key>}, whose key must control its DID (else CXER4965). Answers the attestation with one [signature suite=ed25519 by=<did> 'z<base58btc>'].

flow:attestation-verify

[$flow:attestation-verify] ($att::element $opts::map {}) -> element — Check a signed [attestation …] (flow.md §4.26): [attestation-check verified=true by= identity=], or verified=false reason=:unsigned / :malformed / :suite / :signature (tampered, or another key) / :untrusted (opts.trust names other DIDs). A failure is the answer, not an err.

flow:validate

[$flow:validate] -> element — Check a flow document against the closed vocabulary, the applicability matrix, the pivot rules and the guard domain, resolving every step's act through the executing environment's resolver. Answers [valid flow= steps= words= [act …]…]; every refusal is an [err] VALUE in CXER4952-4955.

      [?lib 'cx-platform/flow']
[?let [= $f [flow name="approve"
  [args [order::string]]
  [step name="place" pivot=true [do 'orders/place' [order "o-1"]]]]]
[= $e [resolver [act name='orders/place' resolved='sha2-256:aa']]]
  [$flow:validate $f $e]]
    
      [valid flow='sha2-256:7df435e0a77707eb1cf87ba3c5887d22fb7f970f63ea1cd961f8eeb99728c21e' steps=1 words='flow step pivot' [act name='orders/place' resolved=sha2-256:aa]]
    

flow:simulate

[$flow:simulate] -> element — Run the pure runner law from a fresh record over a supplied [results …] table and answer [simulation [flow-run …] [transitions …]] — the record the run WOULD reach and the transitions it would append. A construct with no supplied result parks, exactly as it would live, and the simulation goes on driving whatever the record still admits — under document order that is nothing, and under needs= it is every sibling that did not name the parked construct. Never touches a journal.

      [?lib 'cx-platform/flow']
[?let [= $f [flow name="approve"
  [args [order::string]]
  [step name="place" pivot=true [do 'orders/place' [order "o-1"]]]]]
[= $r [$flow:simulate $f [args [order "o-1"]] [results [step name="place" status=:done [result [placed order="o-1"]]]]]]
  $r/flow-run@status]
    
      :done
    

flow:fold-record

[$flow:fold-record] -> any — Fold a run's [flow-transition …] entries into its [flow-run …] record — the pinned fold identity of §2.2/§4.11, so replay is byte-identical and a long run is read from its last snapshot. An empty sequence is the absence channel.

      [?lib 'cx-platform/flow']
[?let [= $ts ([flow-transition run="flow:r1" status=:started flow="sha2-256:aa" version=1 [args [order "o-1"]] [step name="place" pivot=true]],
              [flow-transition run="flow:r1" step="place" status=:done [result [placed order="o-1"]]],
              [flow-transition run="flow:r1" status=:done])]
  [$flow:fold-record $ts]]
    
      [flow-run id=flow:r1 flow=sha2-256:aa version=1 status=:done [args [order o-1]] [step name=place status=:done pivot=true ord=2 activated=2 [result [placed order=o-1]]]]
    

flow:start

[$flow:start] -> element — Validate a flow document against opts.env, check the run's [args …] record against its declaration, derive the run's content-addressed id from (the document's Tier-1 address, opts.actor, a ≥128-bit nonce), journal the :started transition with the authority basis to the home stream (opts.stream, default the run id itself), then advance until the run parks or terminates. Answers the [flow-run …] record — or [deduped <record>] when a run with that id is already terminal, because the record IS the durable step-dedup. opts.actor and opts.authority are MANDATORY (CXER4965); opts.nonce names the nonce for a test. A pre-pivot failure compensates in reverse and lands :compensated; a post-pivot failure is forward-only and lands :incomplete with the count visible, and the next start re-attempts only that tail with resumed=N visible. A map fans out into child runs as it drives: each item's child is an ordinary run in its own home stream, the parent carries one :fanned-out transition and then a claim and a completion per item, and tolerate= decides whether the set's failures fail the map.

      [?lib 'cx-platform/flow']
[?lib 'cx-platform/journal']
[?def unreserve impure [effects] ($sku='') [unreserved sku=$sku]]
[?def reserve impure [effects] [compensates unreserve] ($sku='') [reserved sku=$sku]]
[?def place-order impure [effects] ($order='') [placed order=$order]]
[?let [= $j [$journal:open "mem://flow-doc-start" "acme"]]
[= $f [$cx:parse "[flow name='checkout' [args [sku::string] [order::string]] [step name='reserve' [do 'inventory/reserve' [sku $args/sku]]] [step name='place' pivot=true [do 'orders/place' [order $args/order]]]]"]]
[= $e [resolver [act name='inventory/reserve' resolved='sha2-256:11' compensates='inventory/unreserve' [fn $reserve]]
                [act name='orders/place' resolved='sha2-256:22' [fn $place-order]]]]
[= $o {env: $e flow: $f actor: "did:key:z6Mk" authority: "cap:sha2-256:c1" nonce: "n1" stream: "order:o-1"}]
[= $r1 [$flow:start $j $f [args [sku "88"] [order "o-1"]] $o]]
[= $r2 [$flow:start $j $f [args [sku "88"] [order "o-1"]] $o]]
  [probe [status $r1@status] [steps [?splice $r1/step]] [replay [$name $r2]]]]
    
      [probe [status :done] [steps [step name=reserve status=:done ord=3 activated=2 [result [reserved sku='88']] [do 'inventory/reserve' [sku '88']]] [step name=place status=:done pivot=true ord=5 activated=4 [result [placed order=o-1]] [do 'orders/place' [order o-1]]]] [replay deduped]]
    

flow:advance

[$flow:advance] -> element — Evaluate the runner law over the run's folded record and ONE event, perform the ONE effect it names through the shipped command path, apply that outcome as the correlated act on the SAME call, and append both under the home stream's expect-pos CAS. The event is empty (a courier tick) or a [timer-fired run= step= at=]; opts.flow is the document the run pinned at start and opts.env its resolver. Answers the record after the transitions it appended, possibly none — a terminal run answers its record unchanged, and a courier that loses the CAS re-reads and re-evaluates rather than performing a second effect (CXER1114 reaches the caller only when opts.expect-pos was the caller's own). An unknown id is CXER4956.

      [?lib 'cx-platform/flow']
[?lib 'cx-platform/journal']
[?def place-order impure [effects] ($order='') [placed order=$order]]
[?let [= $j [$journal:open "mem://flow-doc-advance" "acme"]]
[= $f [$cx:parse "[flow name='approve' [args [order::string]] [step name='place' pivot=true [do 'orders/place' [order $args/order]]]]"]]
[= $e [resolver [act name='orders/place' resolved='sha2-256:22' [fn $place-order]]]]
[= $o {env: $e flow: $f actor: "did:key:z6Mk" authority: "cap:sha2-256:c1" stream: "order:o-1"}]
[= $id [$concat "flow:" [$cx:hash [flow-run-id [flow [$cx:hash $f]] [actor "did:key:z6Mk"] [nonce "n1"]]]]]
[= $t0 [flow-transition run=$id status=:started flow=[$cx:hash $f] version=1 stream="order:o-1"
          actor="did:key:z6Mk" authority="cap:sha2-256:c1" [args [order "o-1"]] [step name="place" pivot=true]]]
[= $seed [$journal:append $j $t0 {actor: "did:key:z6Mk" authority: "cap:sha2-256:c1" stream: "order:o-1"}]]
[= $r1 [$flow:advance $j $id () $o]]
[= $r2 [$flow:advance $j $id () $o]]
[= $unknown [$flow:advance $j "flow:sha2-256:00" () $o]]
  [probe [status $r1@status] [step $r1/step/@status] [again [= [$cx:hash $r2] [$cx:hash $r1]]] [unknown $unknown@code]]]
    
      [probe [status :done] [step :done] [again true] [unknown cx-err:CXER4956]]
    

flow:rearm

[$flow:rearm] -> element — The restore half of durable timers, and the one call that makes a live runner honest about liveness (RULED: 789-WF-27a). Folds the journal to its still-pending flow [sched-intent …] set and derives the registry entry each one needs — the fire value is always advance with [timer-fired run= step= at=] (RULED: 1265-PB-5) and the timer's name IS <run id>:<step>, so the entry is COMPUTED from the name and nothing extra is persisted — then calls sched restore with it. Every entry carries the RUN'S OWN recorded basis, home stream and document pin, all read from its record — the pin its :started transition took, or the one its latest :migrated transition re-pinned (§4.10) — and never the booting runner's (RULED: 1313-b) — one call re-arms every pending timer THE JOURNAL carries, so the runs it re-arms are not the caller's. Answers sched's [restore-report rearmed= skipped= orphaned=]: an empty journal is rearmed=0, a value; a durable intent this journal holds that flow did not arm stays orphaned rather than being re-armed by a runner that does not own it; and so does a flow timer whose run pins a DIFFERENT document than opts.flow — a migrated run's timer under the document it left, too — or has no readable :started, because advance refuses a document it did not pin and a refusal inside a timer callback reaches no record. A deadline that elapsed while the process was down fires carrying its ORIGINAL instant, read from the intent, not the boot instant. opts.flow, opts.env and the authority basis are advance's, because every entry it builds is a call to advance.

      [?lib 'cx-platform/flow']
[?lib 'cx-platform/journal']
[?def release-stock impure [effects] ($sku='') [released sku=$sku]]
[?def reserve-stock impure [effects] [compensates release-stock] ($sku='') [reserved sku=$sku]]
[?def place-order impure [effects] ($order='') [placed order=$order]]
[?let [= $j [$journal:open "mem://flow-doc-rearm" "acme"]]
[= $j2 [$journal:open "mem://flow-doc-rearm-empty" "acme"]]
[= $f [$cx:parse "[flow name='dl' [args [order::string]] [step name='reserve' deadline=1d [do 'stock/reserve' [sku '88']]] [step name='place' pivot=true [do 'orders/place' [order $args/order]]]]"]]
[= $e [resolver [act name='stock/reserve' resolved='sha2-256:33' compensates='stock/release' [fn $reserve-stock]] [act name='orders/place' resolved='sha2-256:44' [fn $place-order]]]]
[= $o {env: $e flow: $f actor: "did:key:z6Mk" authority: "cap:sha2-256:c1" nonce: "n1" stream: "order:o-1"}]
[= $r [$flow:start $j $f [args [order "o-1"]] $o]]
[= $rep [$flow:rearm $j $o]]
[= $none [$flow:rearm $j2 $o]]
  [probe [rearmed $rep@rearmed] [orphaned $rep@orphaned] [empty $none@rearmed]]]
    
      [probe [rearmed 1] [orphaned 0] [empty 0]]
    

flow:migrate

[$flow:migrate] -> element — Move an in-flight run onto a new version of its document (§4.10, RULED: WF-6). A run pins its document's Tier-1 address at start; moving it takes a Lane-2 [flow-lineage [from <the run's pin>] [to <the target's address>] [relation :additive|:narrowing|:split|:merge] [map step= to=]…] claim covering EXACTLY that pair (CXER4960 otherwise) and mapping every COMPLETED step onto a construct of the target (CXER4961 for one with no image); a step that has not completed is carried by name. With opts.dry-run true it classifies the run and commits nothing — [migration run= dry-run=true from= to= lineage= relation= class=:clean|:drifted|:refused], a drifted run carrying the [diff …] of its pending step's neighborhood and a refused one the [decision owner= [unmapped step=]…] it is presented to its owner as. Committed, it appends one :migrated transition carrying the claim's address, re-pins the record's flow=, re-arms the run's durable timers under the new pin and drives the run on under its own basis, answering the record; advance then refuses the old document. opts.flow is the document the run pins and opts.env the resolver the target validates against; opts.actor/opts.authority are the OPERATOR's (CXER4965 when absent), and an ops AGENT's migrate is floored at approval — refused (CXER4700), appending nothing. CXER4956 for an unknown run, CXER4957 for a terminal one. With an EMPTY $id and opts.dry-run true it is the FLEET preflight: every non-terminal run fleet lists for the caller that pins the claim's [from], each classified as its own dry run would, in [migrations total= clean= drifted= refused= [migration …]…] — it reads through fleet, so it needs fleet's eval (and the clock unless opts.now is given); an empty id with no dry run is CXER4965, because a fleet is moved run by run.

      [?lib 'cx-platform/flow']
[?lib 'cx-platform/journal']
[?def approve impure [effects] ($order='' $decision='') [approved order=$order decision=$decision]]
[?def ship impure [effects] ($order='') [shipped order=$order]]
[?let [= $j [$journal:open "mem://flow-doc-migrate" "acme"]]
[= $v1 [$cx:parse "[flow name='o' [args [order::string]] [step name='decide' by=:principal to=role:desk pivot=true [do 'orders/approve' [order $args/order] [decision]]]]"]]
[= $v2 [$cx:parse "[flow name='o' [args [order::string]] [step name='decide' by=:principal to=role:desk pivot=true [do 'orders/approve' [order $args/order] [decision]]] [step name='ship' [do 'orders/ship' [order $args/order]]]]"]]
[= $e [resolver [act name='orders/approve' resolved='sha2-256:22' [fn $approve]] [act name='orders/ship' resolved='sha2-256:33' [fn $ship]]]]
[= $o {env: $e flow: $v1 actor: "did:key:z6Mk" authority: "cap:sha2-256:c1" nonce: "n1" roles: {desk: ('dana',)}}]
[= $r [$flow:start $j $v1 [args [order "o-1"]] $o]]
[= $claim [flow-lineage [from [$cx:hash $v1]] [to [$cx:hash $v2]] [relation :additive]]]
[= $dry [$flow:migrate $j [$string $r@id] $v2 $claim [$map-put $o "dry-run" true]]]
[= $m [$flow:migrate $j [$string $r@id] $v2 $claim $o]]
  [probe [class $dry@class] [?splice $dry/*] [re-pinned [= [$string $m@flow] [$cx:hash $v2]]]]]
    
      [probe [class :drifted] [diff [added name=ship]] [re-pinned true]]
    

flow:status

[$flow:status] -> element — The run record: the fold over the run's [flow-transition …] entries in its home stream (opts.stream, default the run id), read at head — or at a position with opts.at, which is the ordinary bitemporal read of the same fold. An unknown id is CXER4956; the read never mutates a run.

      [?lib 'cx-platform/flow']
[?lib 'cx-platform/journal']
[?def place-order impure [effects] ($order='') [placed order=$order]]
[?let [= $j [$journal:open "mem://flow-doc-status" "acme"]]
[= $f [$cx:parse "[flow name='approve' [args [order::string]] [step name='place' pivot=true [do 'orders/place' [order $args/order]]]]"]]
[= $e [resolver [act name='orders/place' resolved='sha2-256:22' [fn $place-order]]]]
[= $o {env: $e flow: $f actor: "did:key:z6Mk" authority: "cap:sha2-256:c1" nonce: "n1" stream: "order:o-1"}]
[= $r [$flow:start $j $f [args [order "o-1"]] $o]]
[= $now [$flow:status $j [$string $r@id] $o]]
[= $then [$flow:status $j [$string $r@id] {stream: "order:o-1" at: 1}]]
  [probe [now $now@status] [at-1 $then@status] [step-at-1 $then/step/@status]]]
    
      [probe [now :done] [at-1 :running] [step-at-1 :waiting]]
    

flow:fleet

[$flow:fleet] -> element — The per-party LIVE readout over the journal's run records (§4.12a, RULED: WF-7): each stream of the journal is a live materialize — checkpointed in opts.store (default a store of this process), incremental, rebuildable from the journal — and the fleet is their order-independent join at the cut its [head-set …] names. Answers [fleet as-of= total= [head-set …] [by-status …] [by-flow …] [stalled …] [conflicts …] [incomplete …] [runs …]]: counts by status and by flow version (the pinned address), the :stalled runs — the PURE predicate: :running, no durable timer pending, and the newest transition older than the active step's deadline=, else the flow's stall-after=, else seven days, beside the runs a ladder left :stalled — the :conflict and :incomplete runs, child completion per map, and each run's age since its last transition at opts.now (else the clock). opts.where is a CXPath over each record and its args; opts.limit / opts.cursor page [runs …]; opts.authz with opts.actor WITHHOLDS the streams the actor may not read (withheld=N); opts.lens :inbox answers the offered principal steps opts.actor may take (RULED: 1265-PW-2); opts.flow adds the fleet overlay's [steps …] rows. An empty fleet is [fleet total=0]; a malformed option is CXER4965; a build without the live pack is CXER4964; it needs the eval capability live does. It appends nothing and drives nothing (RULED: WF-32).

      [?lib 'cx-platform/flow']
[?lib 'cx-platform/journal']
[?def approve impure [effects] ($order='' $decision='') [approved order=$order decision=$decision]]
[?def place-order impure [effects] ($order='') [placed order=$order]]
[?let [= $j [$journal:open "mem://flow-doc-fleet" "acme"]]
[= $ship [$cx:parse "[flow name='ship' [args [order::string]] [step name='place' pivot=true [do 'orders/place' [order $args/order]]]]"]]
[= $review [$cx:parse "[flow name='review' stall-after=1d [args [order::string]] [step name='decide' by=:principal to=role:finance pivot=true [do 'orders/approve' [order $args/order] [decision]]]]"]]
[= $e [resolver [act name='orders/place' resolved='sha2-256:22' [fn $place-order]] [act name='orders/approve' resolved='sha2-256:33' [fn $approve]]]]
[= $o {env: $e actor: "did:key:z6Mk" authority: "cap:sha2-256:c1"}]
[= $r1 [$flow:start $j $ship [args [order "o-1"]] [$map-put [$map-put $o "flow" $ship] "nonce" "n1"]]]
[= $r2 [$flow:start $j $review [args [order "o-2"]] [$map-put [$map-put $o "flow" $review] "nonce" "n2"]]]
[= $f [$flow:fleet $j {now: "1970-01-03T00:00:00Z" env: [resolver $ship $review]}]]
  [probe [total $f@total] [by-status [?splice $f/by-status/*]] [stalled $f/stalled/@total $f/stalled/run/@step]]]
    
      [probe [total 2] [by-status [status name=:done n=1] [status name=:running n=1]] [stalled 1 'decide']]
    

flow:claim

[$flow:claim] -> element — Claim an offered step for opts.actor — EXCLUSIVE assignment (§4.13, RULED: WF-12), recorded as a claimed-by= transition under the run's own CAS, so two claimers race and one wins. Answers the record. The claimer must be inside the offer (to=principal:<id> is that actor; to=role:<name> a member of the role as opts.roles resolves it) — CXER4958 otherwise, and for a step that is not a :pending offer; a step another actor holds is CXER4959; a terminal run is CXER4957. The claim binds the step: only the claimant completes it until it is released or reassigned.

      [?lib 'cx-platform/flow']
[?lib 'cx-platform/journal']
[?def approve impure [effects] ($order='' $decision='') [approved order=$order decision=$decision]]
[?let [= $j [$journal:open "mem://flow-doc-claim" "acme"]]
[= $f [$cx:parse "[flow name='review' [args [order::string]] [step name='decide' by=:principal to=role:finance pivot=true [do 'orders/approve' [order $args/order] [decision]]]]"]]
[= $e [resolver [act name='orders/approve' resolved='sha2-256:22' [fn $approve]]]]
[= $o {env: $e flow: $f actor: "did:key:z6Mk" authority: "cap:sha2-256:c1" nonce: "n1" stream: "order:o-1" roles: {finance: ('dana', 'erin')}}]
[= $r [$flow:start $j $f [args [order "o-1"]] $o]]
[= $won [$flow:claim $j [$string $r@id] "decide" [$map-put $o "actor" "dana"]]]
[= $lost [$flow:claim $j [$string $r@id] "decide" [$map-put $o "actor" "erin"]]]
  [probe [claimed-by $won/step/@claimed-by] [loser $lost@code]]]
    
      [probe [claimed-by dana] [loser cx-err:CXER4959]]
    

flow:release

[$flow:release] -> element — Release opts.actor's OWN claim on an offered step (§4.13, RULED: WF-12): a transition clearing claimed-by=, after which any member of the offer may claim or complete it. Answers the record. Releasing a claim another actor holds, or a step no one has claimed, is CXER4958; a terminal run is CXER4957.

      [?lib 'cx-platform/flow']
[?lib 'cx-platform/journal']
[?def approve impure [effects] ($order='' $decision='') [approved order=$order decision=$decision]]
[?let [= $j [$journal:open "mem://flow-doc-release" "acme"]]
[= $f [$cx:parse "[flow name='review' [args [order::string]] [step name='decide' by=:principal to=role:finance pivot=true [do 'orders/approve' [order $args/order] [decision]]]]"]]
[= $e [resolver [act name='orders/approve' resolved='sha2-256:22' [fn $approve]]]]
[= $o {env: $e flow: $f actor: "did:key:z6Mk" authority: "cap:sha2-256:c1" nonce: "n1" stream: "order:o-1" roles: {finance: ('dana', 'erin')}}]
[= $r [$flow:start $j $f [args [order "o-1"]] $o]]
[= $held [$flow:claim $j [$string $r@id] "decide" [$map-put $o "actor" "dana"]]]
[= $freed [$flow:release $j [$string $r@id] "decide" [$map-put $o "actor" "dana"]]]
  [probe [held $held/step/@claimed-by] [released [$empty $freed/step/@claimed-by]]]]
    
      [probe [held dana] [released true]]
    

flow:reassign

[$flow:reassign] -> element — Move an offered step to another principal or role, $to (§4.13, RULED: WF-12). It needs AUTHORITY OVER THE STEP'S to= SCOPE: opts.actor must be inside the offer it moves (CXER4958 otherwise). The move is a transition: offered-to= names the new scope, its membership is resolved afresh from opts.roles, and any claim is dropped — a claim is on an offer, and this is a new one. A standing out-of-office is a reassign delegation, not a feature. Answers the record; a terminal run is CXER4957.

      [?lib 'cx-platform/flow']
[?lib 'cx-platform/journal']
[?def approve impure [effects] ($order='' $decision='') [approved order=$order decision=$decision]]
[?let [= $j [$journal:open "mem://flow-doc-reassign" "acme"]]
[= $f [$cx:parse "[flow name='review' [args [order::string]] [step name='decide' by=:principal to=role:finance pivot=true [do 'orders/approve' [order $args/order] [decision]]]]"]]
[= $e [resolver [act name='orders/approve' resolved='sha2-256:22' [fn $approve]]]]
[= $o {env: $e flow: $f actor: "did:key:z6Mk" authority: "cap:sha2-256:c1" nonce: "n1" stream: "order:o-1" roles: {finance: ('dana', 'erin') ops: ('oscar')}}]
[= $r [$flow:start $j $f [args [order "o-1"]] $o]]
[= $refused [$flow:reassign $j [$string $r@id] "decide" "role:ops" [$map-put $o "actor" "mallory"]]]
[= $moved [$flow:reassign $j [$string $r@id] "decide" "role:ops" [$map-put $o "actor" "dana"]]]
  [probe [refused $refused@code] [offered-to $moved/step/@offered-to]]]
    
      [probe [refused cx-err:CXER4958] [offered-to role:ops]]
    

flow:cancel

[$flow:cancel] -> element — Cancel a run — an act on the RUN admitted against the OPERATOR's own authority (opts.actor, opts.authority; CXER4965 when absent), never the run's recorded basis (§4.21, RULED: WF-19). Appends :cancelling carrying the operator's actor, authority and the reason; every construct the run never reached is :cancelled; a step already :running is not killed — its outcome is recorded when it lands — and the run then unwinds from where it stands through §4.8's compensation (each compensator under the run's own basis) to :cancelled, with cancelled-by= on the record. Live child runs — a map's claimed items and a flow= step's child — are cancelled by the same rule. REFUSED past a :done pivot (CXER4966); a terminal run answers its record unchanged; an unknown run is CXER4956. Answers the record once the run parks or terminates.

      [?lib 'cx-platform/flow']
[?lib 'cx-platform/journal']
[?def unreserve impure [effects] ($sku='') [unreserved sku=$sku]]
[?def reserve impure [effects] [compensates unreserve] ($sku='') [reserved sku=$sku]]
[?def unhold impure [effects] ($order='') [released order=$order]]
[?def hold impure [effects] [compensates unhold] ($order='') [held order=$order]]
[?let [= $j [$journal:open "mem://flow-doc-cancel" "acme"]]
[= $f [$cx:parse "[flow name='c' [args [order::string]] [step name='reserve' [do 'inventory/reserve' [sku '88']]] [step name='hold' by=:peer to=peer:bank [do 'bank/hold' [order $args/order]]]]"]]
[= $e [resolver [act name='inventory/reserve' resolved='sha2-256:11' compensates='inventory/unreserve' [fn $reserve]]
                [act name='bank/hold' resolved='sha2-256:22' compensates='bank/unhold' [fn $hold]]]]
[= $o {env: $e flow: $f actor: "did:key:z6Mk" authority: "cap:sha2-256:c1" nonce: "n1" stream: "order:o-1"}]
[= $r [$flow:start $j $f [args [order "o-1"]] $o]]
[= $c [$flow:cancel $j [$string $r@id] [reason "withdrawn"] [$map-put $o "actor" "principal:ops"]]]
  [probe [status $c@status] [by $c@cancelled-by] [steps [?splice [?for [in $s $c/step] [yield [row name=[$string $s@name] status=$s@status]]]]]]]
    
      [probe [status :cancelled] [by principal:ops] [steps [row name=reserve status=:compensated] [row name=hold status=:cancelled]]]
    

flow:pause

[$flow:pause] -> element — Pause a run going forward (:running or :stalled) under the operator's own authority (§4.21, RULED: WF-25): the run is :paused, nothing activates, and an in-flight step's outcome is still recorded. TIMERS SUSPEND: each armed timer's REMAINING duration — its persisted deadline less the act's own instant, opts.at, because the verb reads no clock — is recorded on the record as [suspended [timer name= step= kind= remaining=]…], and a timer that fires while the run is paused changes nothing. CXER4966 for a terminal, an already-paused or an unwinding run; CXER4965 when timers are armed and opts.at is absent. Answers the record.

      [?lib 'cx-platform/flow']
[?lib 'cx-platform/journal']
[?def unhold impure [effects] ($order='') [released order=$order]]
[?def hold impure [effects] [compensates unhold] ($order='') [held order=$order]]
[?let [= $j [$journal:open "mem://flow-doc-pause" "acme"]]
[= $f [$cx:parse "[flow name='p' [args [order::string]] [step name='hold' by=:peer to=peer:bank deadline=1h [do 'bank/hold' [order $args/order]]]]"]]
[= $e [resolver [act name='bank/hold' resolved='sha2-256:22' compensates='bank/unhold' [fn $hold]]]]
[= $o {env: $e flow: $f actor: "did:key:z6Mk" authority: "cap:sha2-256:c1" nonce: "n1" stream: "order:o-1"}]
[= $r [$flow:start $j $f [args [order "o-1"]] $o]]
[= $p [$flow:pause $j [$string $r@id] [reason "audit"] [$map-merge ($o, {actor: "principal:ops" at: [$time-datetime 1970 1 1 0 15 0]})]]]
  [probe [status $p@status] [suspended [?splice [?for [in $t $p/suspended/timer] [yield [timer step=[$string $t@step] kind=$t@kind remaining=[$string $t@remaining]]]]]]]]
    
      [probe [status :paused] [suspended [timer step=hold kind=:deadline remaining='45m']]]
    

flow:resume

[$flow:resume] -> element — Lift a pause (§4.21, RULED: WF-25): the run returns to :running under the operator's act, every suspended timer is RE-ARMED under its own name for exactly its recorded remainder — so paused time counted against no deadline, rung or wait — and the run is driven on until it parks or terminates. CXER4966 when the run is not :paused. Answers the record.

      [?lib 'cx-platform/flow']
[?lib 'cx-platform/journal']
[?def unhold impure [effects] ($order='') [released order=$order]]
[?def hold impure [effects] [compensates unhold] ($order='') [held order=$order]]
[?let [= $j [$journal:open "mem://flow-doc-resume" "acme"]]
[= $f [$cx:parse "[flow name='p' [args [order::string]] [step name='hold' by=:peer to=peer:bank [do 'bank/hold' [order $args/order]]]]"]]
[= $e [resolver [act name='bank/hold' resolved='sha2-256:22' compensates='bank/unhold' [fn $hold]]]]
[= $o {env: $e flow: $f actor: "did:key:z6Mk" authority: "cap:sha2-256:c1" nonce: "n1" stream: "order:o-1"}]
[= $r [$flow:start $j $f [args [order "o-1"]] $o]]
[= $op [$map-put $o "actor" "principal:ops"]]
[= $p [$flow:pause $j [$string $r@id] [reason "audit"] $op]]
[= $q [$flow:resume $j [$string $r@id] $op]]
[= $again [$flow:resume $j [$string $r@id] $op]]
  [probe [paused $p@status] [resumed $q@status] [not-paused $again@code]]]
    
      [probe [paused :paused] [resumed :running] [not-paused cx-err:CXER4966]]
    

flow:skip

[$flow:skip] -> element — Skip a step (§4.21, RULED: WF-25): the step is recorded :skipped reason=:operator under the operator's actor, authority and reason, and its successors activate. REFUSED (CXER4966) for a :done step, for a pre-pivot step the pivot waits on — skipping what the pivot's compensability argument rests on would silently break §4.7 — for any step once the pivot is :done, and on an unwinding run; a step the run's record does not hold is CXER4965; a terminal run, or a step already skipped, answers the record unchanged.

      [?lib 'cx-platform/flow']
[?lib 'cx-platform/journal']
[?def unsurvey impure [effects] ($order='') [recalled order=$order]]
[?def survey impure [effects] [compensates unsurvey] ($order='') [surveyed order=$order]]
[?def unnotify impure [effects] ($order='') [retracted order=$order]]
[?def notify impure [effects] [compensates unnotify] ($order='') [notified order=$order]]
[?let [= $j [$journal:open "mem://flow-doc-skip" "acme"]]
[= $f [$cx:parse "[flow name='s' [args [order::string]] [step name='survey' by=:peer to=peer:crm [do 'crm/survey' [order $args/order]]] [step name='notify' [do 'mail/notify' [order $args/order]]]]"]]
[= $e [resolver [act name='crm/survey' resolved='sha2-256:11' compensates='crm/unsurvey' [fn $survey]] [act name='mail/notify' resolved='sha2-256:22' compensates='mail/unnotify' [fn $notify]]]]
[= $o {env: $e flow: $f actor: "did:key:z6Mk" authority: "cap:sha2-256:c1" nonce: "n1" stream: "order:o-1"}]
[= $r [$flow:start $j $f [args [order "o-1"]] $o]]
[= $s [$flow:skip $j [$string $r@id] "survey" [reason "never answered"] [$map-put $o "actor" "principal:ops"]]]
  [probe [status $s@status] [steps [?splice [?for [in $x $s/step] [yield [row name=[$string $x@name] status=$x@status]]]]]]]
    
      [probe [status :done] [steps [row name=survey status=:skipped] [row name=notify status=:done]]]
    

flow:retry-now

[$flow:retry-now] -> element — Re-attempt the failed or incomplete tail NOW (§4.21, RULED: WF-25), which the empty advance tick does not: an :incomplete run resumes with resumed=N visible and its failed tail re-attempted, and a step waiting on its every= re-attempt timer is re-offered at once. The act is a transition carrying the operator's actor and authority. A run with nothing failed or incomplete is a value — its record, unchanged; a paused run is CXER4966.

      [?lib 'cx-platform/flow']
[?lib 'cx-platform/journal']
[?def place impure [effects] ($order='') [placed order=$order]]
[?def notify impure [effects] [idempotent] ($order='') [?test-err-then-ok err-count=1 ok-value=[notified]]]
[?let [= $j [$journal:open "mem://flow-doc-retry-now" "acme"]]
[= $f [$cx:parse "[flow name='t' [args [order::string]] [step name='place' pivot=true [do 'orders/place' [order $args/order]]] [step name='notify' [do 'mail/notify' [order $args/order]]]]"]]
[= $e [resolver [act name='orders/place' resolved='sha2-256:11' [fn $place]] [act name='mail/notify' resolved='sha2-256:22' idempotent=true [fn $notify]]]]
[= $o {env: $e flow: $f actor: "did:key:z6Mk" authority: "cap:sha2-256:c1" nonce: "n1" stream: "order:o-1"}]
[= $r [$flow:start $j $f [args [order "o-1"]] $o]]
[= $x [$flow:retry-now $j [$string $r@id] [$map-put $o "actor" "principal:ops"]]]
  [probe [before $r@status] [after $x@status] [resumed $x@resumed]]]
    
      [probe [before :incomplete] [after :done] [resumed 1]]
    

flow:resolve

[$flow:resolve] -> element — The operator's act on the ONE [conflict kind=:uncompensatable] value of a :conflict run (§4.8, RULED: 1265-PB-8): a [resolution kind= subject=?] consumes it — :retry-compensation returns the step to :done and the unwind goes on, :accept-forward marks the step :done on a recorded external fact whose locator [effect stream= seq= hash=] it carries, and :abandon ends the run :failed with the resolution recorded. CXER4957 unless the run is :conflict; CXER4965 for a malformed resolution. Irreversible, so for an ops AGENT (opts.actor agent:…) it is floored at approval (§4.12a, X3): the agent's own resolve is refused (CXER4700) and appends nothing; a principal operator resolves.

      [?lib 'cx-platform/flow']
[?lib 'cx-platform/journal']
[?def void impure [effects] ($order='') [?test-err-then-ok err-count=1 ok-value=[voided]]]
[?def print impure [effects] [compensates void] ($order='') [printed order=$order]]
[?def charge impure [effects] ($order='') [?test-always-err]]
[?let [= $j [$journal:open "mem://flow-doc-resolve" "acme"]]
[= $f [$cx:parse "[flow name='r' [args [order::string]] [step name='label' [do 'label/print' [order $args/order]]] [step name='charge' pivot=true [do 'bill/charge' [order $args/order]]]]"]]
[= $e [resolver [act name='label/print' resolved='sha2-256:11' compensates='label/void' [fn $print]] [act name='bill/charge' resolved='sha2-256:22' [fn $charge]]]]
[= $o {env: $e flow: $f actor: "did:key:z6Mk" authority: "cap:sha2-256:c1" nonce: "n1" stream: "order:o-1"}]
[= $r [$flow:start $j $f [args [order "o-1"]] $o]]
[= $x [$flow:resolve $j [$string $r@id] [resolution kind=:retry-compensation] [$map-put $o "actor" "principal:ops"]]]
  [probe [before $r@status] [after $x@status] [conflicts [$count $x/conflict]]]]
    
      [probe [before :conflict] [after :compensated] [conflicts 0]]
    

flow:fill

[$flow:fill] -> any — Fill an automation skeleton (composition.md §3.10, RULED: AA-1, AA-3, AA-7) from an [answers [<slot> <value>]…] document: every [slot name= kind=] marker in the skeleton's [flow …] and [on …] templates is replaced by its answer, and the value is the flow document and its [on …] row with no slot open — the row carrying start=, the filled flow's Tier-1 address, and as=, the binder opts.as names (RULED: AA-8). An act is 'ns/verb', a field a lower-case name, a role role:<name>, a principal principal:<id>, a duration a literal such as 1d, a value a scalar. A slot unanswered or answered with a value of the wrong kind, an answer naming no slot, an answer given twice and a missing binder are ONE CXER4965 refusal naming every one of them — never the first alone, never a partial fill. Pure: the four skeletons ship as data (data/skeletons/), and cx xap scaffold <skeleton> --answers FILE --as P and the studio call this same def.

      [?lib 'cx-platform/flow']
[?let [= $sk [skeleton name=nightly trigger=schedule
  [flow "[flow name='nightly' [step name='sweep' [do [slot name=act kind=act]]]]"]
  [on "[on kind=schedule every=[slot name=every kind=duration]]"]]]
[= $as {as: "principal:did:key:z6MkOps"}]
[= $no [$flow:fill $sk [answers [act 'sweep'] [evry 1d]] $as]]
  [probe
   [filled [?splice [$flow:fill $sk [answers [act 'store/sweep'] [every 1d]] $as]]]
   [refused [$string $no@code]]
   [why [$string $no@message]]]]
    
      [probe [filled [flow name=nightly [step name=sweep [do store/sweep]]] [on kind=schedule every::duration=1d start=sha2-256:fc2ba0c572378301ea7f27f6b6431ebd865ea6757249f0a617441a8582f050b2 as=principal:did:key:z6MkOps]] [refused cx-err:CXER4965] [why "E_COORD_ARG_INVALID: fill: nightly is not filled — `act` (act) is answered `sweep`, not a qualified act name — write 'ns/verb'; `every` (duration) is unanswered; `evry` answers no slot of nightly (composition.md §3.10: every open or wrongly-kinded slot, in one refusal)"]]