Distributed Workflow Demo

Run a durable workflow that hands work between local embed-agent participants through Astrorun or the work-item CLI.

Overview

This demo proves the current durable workflow path:

  1. An automation invokes a WorkflowGraph.
  2. Server-side workflow steps run through Oban.
  3. WorkflowEmbedAgent nodes create durable work items for assigned agents.
  4. Local harnesses discover, claim, start, and submit those work items.
  5. The workflow resumes from the journal and eventually completes.

Use Astrorun for the product experience. Use the manual work-item commands when you want to debug the state machine one transition at a time.

The executable reference is the CLI synthetic scenario:

  • tests/synthetics/cli/tests/65_distributed_workflow.yaml
  • tests/synthetics/cli/fixtures/distributed-workflow-graph.json

That scenario creates three agents, uploads a workflow graph, invokes an automation, settles two embed-agent handoffs, verifies the durable journal, and confirms the final thread message.


Prerequisites

From a linked project:

archagent init
archagent auth status

You also need:

  • an app you can create agents, configs, automations, and threads in;
  • a local harness available to Astrorun, such as AstroDev, Claude Code, Codex, or Rovo Dev;
  • jq if you use the manual command snippets below;
  • tmux only if you want Astrorun live sessions.

Demo Shape

The workflow graph is:

trigger -> triage script -> investigate embed agent -> evaluate embed agent -> announce script

The important handoffs are:

  • investigate is assigned to the investigator agent.
  • evaluate is assigned to the evaluator agent.
  • announce is a server script that posts the evaluator's verdict back to a thread.

The invoke payload carries the free-form bug input. The invoke participants map binds workflow participant names to concrete agent ids.


Set Up The Run

The setup mirrors tests/synthetics/cli/tests/65_distributed_workflow.yaml. That executable scenario uses same-app assignees. Cross-company participant access is a separate policy concern; this runbook focuses on proving the durable work-item handoff and journal resume path end to end.

Create participants:

REPORTER=$(archagent create agent -n "DWF Reporter" --lookup-key demo-dwf-reporter --json | jq -r '.id')
INVESTIGATOR=$(archagent create agent -n "DWF Investigator" --lookup-key demo-dwf-investigator --json | jq -r '.id')
EVALUATOR=$(archagent create agent -n "DWF Evaluator" --lookup-key demo-dwf-evaluator --json | jq -r '.id')

Create the announcement thread:

THREAD_ID=$(archagent create thread \
  --title "DWF Investigation Verdicts" \
  --owner-type agent \
  --owner-id "$REPORTER" \
  --skip-welcome-message \
  --json | jq -r '.id')

Create the workflow graph file:

cp tests/synthetics/cli/fixtures/distributed-workflow-graph.json ./dwf-graph.json
sed -i.bak "s/__THREAD_ID__/$THREAD_ID/g" ./dwf-graph.json

Upload the workflow config:

WORKFLOW_CONFIG_ID=$(archagent create config \
  -k WorkflowGraph \
  --mime-type application/json \
  -f ./dwf-graph.json \
  --lookup-key demo-dwf-graph \
  --json | jq -r '.id')

Create and activate the automation:

AUTOMATION_ID=$(archagent create automation \
  -n "DWF Embed Investigation" \
  -t invoked \
  --config "$WORKFLOW_CONFIG_ID" \
  --run-as-agent "$REPORTER" \
  --invoke-auth secret_key \
  --json | jq -r '.id')

archagent activate automation "$AUTOMATION_ID"

Invoke the run:

RUN_ID=$(archagent invoke automation "$AUTOMATION_ID" \
  --payload '{"bug":"upload fails"}' \
  --participants "{\"investigator\":\"$INVESTIGATOR\",\"evaluator\":\"$EVALUATOR\"}" \
  --json | jq -r '.id')

echo "$RUN_ID"

At this point the server should advance until the workflow parks on the investigate embed-agent node.


Product Path: Astrorun

Launch Astrorun from the linked project:

archagent astrorun

In the dashboard:

  1. Look under Candidates for the workflow work item.
  2. Select the item and press Enter to enqueue it.
  3. Let the selected harness produce a JSON result.
  4. Approve the result when the item reaches Review.
  5. Wait for the next participant work item to appear.
  6. Repeat for the evaluator handoff.

The result submitted for a workflow work item must be a JSON object. For the investigator step, a useful shape is:

{"summary":"Large uploads exceed the picker limit"}

For the evaluator step:

{"message":"accept: summary looks solid"}

After the evaluator result is submitted, the server should run the announce script and complete the automation run.


Debug Path: Manual Work-Item CLI

Use this path when you want deterministic control over each lease transition.

Wait for investigator work:

archagent list workitems --agent "$INVESTIGATOR" --json

Claim it:

CLAIM_JSON=$(archagent claim workitem \
  --agent "$INVESTIGATOR" \
  --execution "$RUN_ID" \
  --json)

INV_ITEM_ID=$(echo "$CLAIM_JSON" | jq -r '.data.work_item.id')
INV_LEASE=$(echo "$CLAIM_JSON" | jq -r '.data.lease_owner')

Start and submit:

archagent start workitem "$INV_ITEM_ID" --lease-owner "$INV_LEASE"

archagent submit workitem "$INV_ITEM_ID" \
  --lease-owner "$INV_LEASE" \
  --result '{"summary":"Large uploads exceed the picker limit"}'

Wait for evaluator work:

archagent list workitems --agent "$EVALUATOR" --json

Claim it:

CLAIM_JSON=$(archagent claim workitem \
  --agent "$EVALUATOR" \
  --execution "$RUN_ID" \
  --json)

EVAL_ITEM_ID=$(echo "$CLAIM_JSON" | jq -r '.data.work_item.id')
EVAL_LEASE=$(echo "$CLAIM_JSON" | jq -r '.data.lease_owner')

Start and submit:

archagent start workitem "$EVAL_ITEM_ID" --lease-owner "$EVAL_LEASE"

archagent submit workitem "$EVAL_ITEM_ID" \
  --lease-owner "$EVAL_LEASE" \
  --result '{"message":"accept: summary looks solid"}'

Verify The Run

Check the automation run:

archagent describe automationrun "$RUN_ID" --json

Inspect the durable journal:

archagent describe automationrun "$RUN_ID" --journal

The journal should include:

  • execution_started
  • node_started
  • command_requested
  • command_completed
  • node_completed
  • execution_completed

The thread should include the announce script's final message:

archagent list threadmessages --thread "$THREAD_ID"

Run The Executable Synthetic

To validate this flow against a local platform stack, use the CLI synthetic harness:

cd tests/synthetics/cli

export ARCHASTRO_SYNTH_PLATFORM_URL=http://localhost:4000
export ARCHASTRO_SYNTH_GRPC_ADDR=localhost:50052
export ARCHASTRO_SYNTH_CLI_BIN=archagent

go test -tags synthetics -v -count=1 -run 'TestCLISynthetics/distributed-workflow'

The exact test selector may vary with the Go test name generated by the harness. If the selector does not match, run the CLI synthetic suite and filter for distributed-workflow in the output.


Cleanup

archagent delete automation "$AUTOMATION_ID"
archagent delete config "$WORKFLOW_CONFIG_ID"
archagent delete thread "$THREAD_ID"
archagent delete agent "$REPORTER"
archagent delete agent "$INVESTIGATOR"
archagent delete agent "$EVALUATOR"
rm -f ./dwf-graph.json ./dwf-graph.json.bak