← Docs

Workflow execution

This page is the execution contract for workflows: what each node kind does, what a run freezes, how ready nodes are scheduled, and what every control and state means.

Node kinds

KindBehavior
From ideaAuthoring-only. Captures the initial exploration; never dispatched by a run.
SpecAuthoring-only. Produces or represents the specification; never dispatched by a run.
Task breakdownAuthoring-only. Shapes the executable graph; never dispatched by a run.
ImplementationStarts an agent-backed workflow session.
ReviewStarts an agent-backed session and must return a typed review result.
RevisionStarts an agent-backed session when its paired review requests changes.
RecoveryStarts a recovery agent to finish blocked work so the existing graph can advance.
MergeRuns Brisal’s worktree merge operation; it never falls through to an agent prompt.
CommitRuns Brisal’s commit operation on the node’s bound worktree.
Tool callRuns its configured domain tool operation.
GatePauses for your explicit Approve or Reject decision.

Disabled nodes remain visible but do not execute. Declared inputs are artifact references; they do not establish ordering. Use dependencies for ordering.

Execution policy

Open Settings → Workflows to edit the selected workspace’s defaults:

SettingEffect
Provider capsMaximum concurrent attempts per provider, per run. An empty map means no provider cap.
Agent poolsOrdered candidate agent ids by workflow role. The scheduler tries them in order.
Thinking defaultsReasoning level by node kind. A node override wins.
TimeoutsDefault timeout plus per-kind overrides, in seconds. A node override wins.
RetryMaximum retries and recovery rounds.
RecoveryTrigger timing, ordered recovery-agent pool, and maximum rounds.

New workflows copy these defaults at creation; existing workflows do not track later settings changes. In a workflow’s Run setup, select Apply current defaults to replace that workflow’s policy. Node-level overrides and existing runs remain unchanged.

Scheduling

A run starts every graph-ready node for which it can acquire provider capacity. When demand exceeds a cap, ready nodes become Queued until a slot opens. Deterministic ordering only decides which ready node gets a scarce slot first; it does not turn slices into phases.

Caps are scoped to one run. There is no hidden workspace-wide or global governor, and separate runs do not serialize access to the same worktree.

Agent pools are ordered fallbacks. A run freezes the ids and order, but resolves each chosen agent’s current provider, model, and behavior at attempt start.

Run controls

ControlAvailability and result
Start RunStarts a fresh run when no run is active and validation has no blocking errors.
Stop RunAvailable while running. Cancels active attempts and makes the run terminal after cancellation settles.
Resume RunAvailable for a paused run. Continues that run from its existing snapshot.
Rerun RemainingCreates a new run based on a prior run and carries forward matching completed work.
Rerun AllCreates a fresh run with no completion carryover.

Rerun Remaining inherits a completed, recovered, or skipped node only when its kind and semantic content still match. Semantic content includes its prompt, declared inputs, instructions, and parameters. Changes to title, slice placement, dependencies, agent pool, thinking, execution policy, or worktree binding do not by themselves invalidate that carryover. Historical attempts and their sessions remain evidence; they are never reused as active attempts.

Run states

StateMeaning
PendingCreated but not yet dispatching work.
RunningScheduling or executing nodes.
PausedResumable, with no automatic continuation.
CompletedAll required work reached a successful terminal state.
FailedThe run exhausted a terminal execution or recovery path.
CancelledStopped by the user.

Completed, Failed, and Cancelled are terminal. Starting or rerunning creates a new run except Resume, which continues the paused one.

Node and attempt states

StateMeaning
PendingNot ready or awaiting dispatch.
QueuedDependencies are satisfied, but provider capacity is unavailable.
RunningThe attempt is in progress.
CompletedFinished successfully.
RecoveredRecovery completed the blocked work.
SkippedDeliberately bypassed, such as a Revision after its Review passed.
BlockedCannot proceed without a policy or user-level resolution.
FailedAn execution/system failure that may still enter retry or recovery.

A blocked or failed attempt carries a reason, such as app restart, cancellation, no eligible agent, exhausted retries or recovery, gate rejection, timeout, or a missing review result.

Reviews and revisions

Every Review writes a Markdown report and one typed result:

  • Passed skips the paired Revision.
  • Needs revision queues the paired Revision with the report as context.
  • Blocked also queues the paired Revision; the review finding itself does not block the workflow.

A missing or invalid typed result fails the Review attempt. A Review that needs revision must have a valid paired Revision node or graph validation blocks the run from starting.

Retry and recovery

A timeout fails the attempt. Retry policy decides whether to try the node again. When recovery is enabled, each eligible recovery-pool agent is tried once in declared order before another retry round.

Recovery completes blocked node work so the current DAG can continue; it does not rewrite the graph. If all recovery candidates and permitted rounds are exhausted, the run becomes Failed. Recovery never recursively recovers itself.

Snapshots, edits, and restart

At start, a run snapshots the graph, prompt content, disabled state, worktree bindings and base commit, agent-pool ids/order, caps, thinking, timeouts, retry, and recovery policy. Workflow edits made afterward apply only to a future run.

The root worktree binding becomes immutable after the first run. Slice worktree overrides are also part of each run’s snapshot. Merge and Commit nodes use Brisal’s normal worktree operations, including the standard paused-conflict flow described in Worktrees.

If Brisal restarts with a nonterminal attempt, that attempt becomes Blocked with reason App restarted, and the run becomes Paused. Nothing auto-resumes; inspect the run, then use Resume Run deliberately.