Forks and regions
fork awl 8 Runs work concurrently inside one step: `fork item in items` one branch per item, or a bare `fork` for named branches.
-
formstatement -
positionsstep-body
//! One branch per repo, checked in parallel, joined in input order.
workflow sweep_repos
input repos: [String]
outcome done: type [Verdict], route success
type Verdict { ok: Bool }
worker ci
action check(repo: String) -> Verdict
step sweep
fork repo in repos
check(repo: repo)
join -> verdicts
route done(verdicts) join awl 8 Closes a `fork`, binding a collection fork's results in input order.
-
formstatement -
positionsstep-body
//! `join` closes the fork, binding the branches' results in input order.
workflow gather_reports
input repos: [String]
outcome done: type [Report], route success
type Report { summary: String }
worker inspectors
action inspect(repo: String) -> Report
step gather
fork repo in repos
inspect(repo: repo)
join -> reports
route done(reports) sequential awl 8 Runs a collection `fork` one item at a time in input order instead of in parallel.
-
formstatement -
positionsstep-body
//! `sequential` publishes one target at a time, in input order.
workflow publish_targets
input targets: [String]
outcome done: type [Receipt], route success
type Receipt { target: String }
worker publisher
action publish(target: String) -> Receipt
step publish_all
fork target in targets sequential
publish(target: target)
join -> receipts
route done(receipts) distribute awl 8 Opens a multi-step region that runs one item track per element in parallel.
-
formstatement -
positionsstep-body
//! Every host gets its own step track; the tracks run in parallel.
workflow inspect_fleet
input hosts: [String]
outcome done: type [Report], route success
type Report { host: String }
worker ops
action inspect(host: String) -> Report
step open
distribute host in hosts
step work
inspect(host: host) -> report
step close
collect report -> reports
route done(reports) sequence awl 8 Opens a multi-step region that runs one item track at a time in collection order.
-
formstatement -
positionsstep-body
//! One host at a time, in collection order, each through its own track.
workflow roll_out
input hosts: [String]
outcome done: type [Attempt], route success
type Attempt { host: String, ok: Bool }
worker ops
action deploy(host: String) -> Attempt
step ordered
sequence host in hosts
step push
deploy(host: host) -> attempt
step settle
collect attempt -> attempts
route done(attempts) collect awl 8 Closes the nearest region as the first statement of its close step, binding results in input order.
-
formstatement -
positionsstep-body
//! `collect` opens the close step, folding the region's results back in.
workflow check_services
input services: [String]
outcome done: type Int, route success
type Health { ok: Bool }
worker probes
action probe(service: String) -> Health
step open
distribute service in services
step probe_one
probe(service: service) -> health
step close
collect health -> results
results |> count -> total
route done(total) in awl 8 Names the per-item binding of a fork or a region opener, as in `fork item in items`.
-
formstatement -
positionsstep-body
//! `in` names the per-item binding: each branch sees one `name`.
workflow greet_everyone
input names: [String]
outcome done: type [Greeting], route success
type Greeting { text: String }
worker greeter
action greet(name: String) -> Greeting
step greet_each
fork name in names
greet(name: name)
join -> greetings
route done(greetings) A collection fork body compiles as one unbound action or child call. Each named fork branch compiles as one action call. Join collects the declared results.
Per-item distribute tracks are concurrent; sequence tracks run in order. A collected optional result preserves a failed track as an absent value rather than pretending all tracks succeeded.
Bounded iteration
loop awl 9 Runs a bounded value-threading loop whose body runs at least once and must rebind the threaded value.
-
formstatement -
positionsstep-body
//! Improve the draft until it is ready, at most three passes.
workflow refine_draft
input topic: String
outcome done: type Draft, route success
outcome stuck: type String, route failure
type Draft { body: String, ready: Bool }
worker writers
action improve(topic: String, prior: Draft) -> Draft
step refine
loop draft = Draft(body: "", ready: false)
improve(topic: topic, prior: draft) -> draft
until draft.ready
max 3
outcome ready: if draft.ready, route done(draft)
outcome exhausted: else, route stuck("the draft never settled") counting awl 9 Binds the number of completed iterations of a `loop`.
-
formstatement -
positionsstep-body
//! `counting` binds how many iterations the loop completed.
workflow poll_job
input job: String
outcome done: type Int, route success
outcome stuck: type String, route failure
type Status { ready: Bool }
worker jobs
action poll(job: String, prior: Status) -> Status
step watch
loop status = Status(ready: false) counting polls
poll(job: job, prior: status) -> status
until status.ready
max 10
outcome ready: if status.ready, route done(polls)
outcome gave_up: else, route stuck(job) until awl 9 States the condition that ends a `loop`, tested after the body has run.
-
formstatement -
positionsstep-body
//! `until` ends the loop, tested after each pass of the body.
workflow stabilize_build
input tag: String
outcome done: type Build, route success
outcome stuck: type String, route failure
type Build { green: Bool }
worker ci
action rebuild(tag: String, prior: Build) -> Build
step converge
loop build = Build(green: false)
rebuild(tag: tag, prior: build) -> build
until build.green
max 5
outcome green: if build.green, route done(build)
outcome exhausted: else, route stuck(tag) max awl 9 Bounds iteration: the mandatory ceiling on a `loop`, or `max N visits` on a step inside a flow loop.
-
formstatement -
positionsstep-body
//! `max` is the mandatory ceiling; exhaustion is a distinct outcome.
workflow negotiate_quote
input request: String
outcome done: type Offer, route success
outcome stuck: type String, route failure
type Offer { accepted: Bool }
worker brokers
action haggle(request: String, prior: Offer) -> Offer
step negotiate
loop offer = Offer(accepted: false)
haggle(request: request, prior: offer) -> offer
until offer.accepted
max 4
outcome agreed: if offer.accepted, route done(offer)
outcome exhausted: else, route stuck(request) visits awl 9 Completes a step's `max N visits` bound, and reads as the visit count inside that step's guards.
-
formstatement -
positionsstep-body
//! `max 3 visits` bounds the flow loop; `visits` reads the count in guards.
workflow recheck_repo
input repo: String
outcome done: type Verdict, route success
type Verdict { ok: Bool }
worker ci
action check(repo: String) -> Verdict
step attempt
check(repo: repo) -> verdict
step judge
outcome again: if not verdict.ok and visits < 3, route attempt
outcome settled: else, route done(verdict)
max 3 visits A value-threading loop runs its body at least once and must rebind its threaded value. Counting optionally binds completed iterations; until tests after the body, and max is mandatory. A visit bound limits re-entry to a step. Bindings and result routes must remain valid on every path.
Parallel bodies have stricter bytecode compilation rules than sequential bodies. In particular, literal indexing is refused in a parallel branch or per-item track. See compiler boundaries.