Recipes

Tasks from start to finish. Every command is real, and every output below was captured from a demo daemon running the synthetic lighthouse project, so your IDs and timestamps will differ.

  1. 01Hand a task to an agent

    File a bead, place a worker, land its branch.

    caco bd dispatch
  2. 02Plan a feature as a graph

    Dependencies decide what is ready to start.

    caco bd update --dependencies
  3. 03Prove a change

    Queued per project, with bounded concurrency.

    caco test run --wait
  4. 04Answer the fleet

    Questions wait for you on every surface.

    caco decision resolve
  5. 05Steer a running agent

    Message, pause or take the keyboard.

    caco msg send --target
  6. 06Find anything

    Beads, messages, feed and files, ranked.

    caco search
  7. 07Add a machine

    One trust domain, agents placed anywhere.

    caco node join
  8. 08Run a typed flow

    Agents and actions as a checked graph.

    caco flow run
Before you start

You need a running node: Quickstart gets you there. The commands pass --project explicitly; with default_project set in your config, or CACO_PROJECT in the environment, you can leave it out.

Hand a task to an agent

Work starts as a bead. Dispatch claims it, picks a node and starts a worker in its own checkout; completing the worker lands its branch through the project's gate.

  1. File the bead

    caco bd create --project lighthouse --type task --priority 1 \
        --title "Expose the latest build result over the API" \
        --description "Add a read-only endpoint that returns the newest build's status, duration and log URL for the footer to poll."
    created: bd-a00001 — Expose the latest build result over the API

    For anything longer than a sentence, write the description to a file and pass --description-file: Markdown with backticks and $ survives intact.

  2. Preview where it would go

    caco bd dispatch --project lighthouse --bead-id bd-a00001 --profile dev --dry-run
    caco bd dispatch placement dry-run (metadata only)
      bead: bd-a00001
      project: lighthouse
      daemon request: not sent
      bead claimed: no
      agent spawned: no
      preflight: would run when a target node is resolved
      would_request:
        {
          "goal": "Implement bead bd-a00001 (title/description resolved at dispatch time)",
          "profile": "dev"
        }
    No bead was claimed and no agent was spawned. Re-run without --dry-run / --preview to dispatch.
  3. Dispatch it

    caco bd dispatch --project lighthouse --bead-id bd-a00001 --profile dev

    Dispatch streams its phases as it goes: it reserves the bead for a node, creates the agent there, starts the runtime and adopts the reservation as the agent's claim. If the response is lost, retrying returns the same agent from the durable handoff receipt; it never spawns twice. Add --node vega to choose the machine yourself. The full sequence

  4. Watch it, or join in

    caco agent list --project lighthouse
    # the agent's own pane; --raw attaches to the bare Herdr or tmux terminal
    caco agent attach --id AGENT_ID

    The same agent appears in the terminal UI, the web dashboard and on your phone.

  5. Land it

    caco agent complete --id AGENT_ID --dry-run   # the exact steps it would take
    caco agent complete --id AGENT_ID

    Whether that means a squash-merge or a pull request comes from the agent's profile and the project; --mode overrides it for one landing. How work lands

Plan a feature as a graph

Split a feature into beads and say which depend on which. Only beads with nothing open in front of them are ready, so dispatchers and auto-claiming workers start them in a safe order.

  1. File the feature and make it wait

    caco bd create --project lighthouse --type feature --priority 1 \
        --title "Show build status in the footer" \
        --description "The footer should show the latest build result and link to its log, so a broken main is visible without opening CI."
    created: bd-a0000b — Show build status in the footer
    caco bd update --project lighthouse --bead-id bd-a0000b --dependencies bd-a00001
    updated: bd-a0000b (fields: dependencies)
  2. See what is ready

    caco bd list --project lighthouse
    ID           PRI  TYPE     STATUS       AGE        LABELS           ASSIGNEE             TITLE
    bd-a0000b    P1   feature  open         just now   -                -                    Show build status in the footer
    bd-a00001    P1   task     open         just now   -                -                    Expose the latest build result over the API
    caco bd list --project lighthouse --ready
    ID           PRI  TYPE     STATUS       AGE        LABELS           ASSIGNEE             TITLE
    bd-a00001    P1   task     open         just now   -                -                    Expose the latest build result over the API
  3. Draw the graph

    caco bd graph --project lighthouse --format ascii
    # legend: [open] [in_progress] (closed) {draft} <permanent>
    
    [bd-a0000b open] Show build status in the footer
        < blocked-by: bd-a00001 Expose the latest build result over t...
    [bd-a00001 open] Expose the latest build result over the API

    --format mermaid or dot renders the same graph for documents. To burn a whole graph down automatically, run the std.feature.burndown flow, which dispatches each ready layer as the one before it lands.

Prove a change

Tests run through the daemon's per-project queue with bounded concurrency, instead of each agent starting the suite in its own shell. The command comes from projects[].test.command; --auto fills in the project, directory and command from where you are.

caco test run --project lighthouse --auto --wait
job_id=tj-274341ca
caco test run
  Job ID:       tj-274341ca
  State:        passed
  Command:      ./scripts/test.sh
  Project:      lighthouse
  Exit Code:    0
  Started:      2026-10-14T00:11:24.455410854Z
  Finished:     2026-10-14T00:11:24.468723809Z

--- stdout ---
4 passed

Without --wait you get the job ID straight away; caco build run queues builds the same way. A run that matches no tests fails rather than passing. Reintegration's own gate is a queued job too, admitted ahead of ordinary ones, and it survives a daemon restart. Testing

Answer the fleet

When an agent or controller needs a person but not right now, it files a decision with options and a recommendation. Decisions batch for later and resolve from any surface: terminal, web, phone or watch.

  1. A question arrives

    caco decision file --project lighthouse --question "Ship the footer behind a flag first?" \
        --option "Flag it" --option "Ship it on" --recommend "Flag it" --context bd-a0000b
    filed decision decision-01a137bf-ed73-7df3-8179-e1570eb98ffb for the operator (project lighthouse)
    parsed options:
      [0] Flag it
      [1] Ship it on
  2. See what is waiting

    caco decision list --project lighthouse
    decision-01a137bf-ed73-7df3-8179-e1570eb98ffb  [active]  Ship the footer behind a flag first?  (filer=, age=0s)
      * [0] Flag it
        [1] Ship it on
      context: bd-a0000b

    The * marks the recommendation. In the terminal UI they wait in a Decisions section beside Choices.

  3. Answer it

    caco decision resolve --id decision-01a137bf-ed73-7df3-8179-e1570eb98ffb --option "Flag it"
    resolved decision decision-01a137bf-ed73-7df3-8179-e1570eb98ffb: Flag it

    The first answer wins and the filer is told. An urgent question from a running agent is a choice instead: one at a time per agent, with a recommended default, listed by caco choices current and answered in the same places. Messaging and choices

Steer a running agent

Agents take direction while they work. A message lands in the agent's session as [caco-msg from …] and stays in its inbox; the short name works when it is unambiguous in the project.

caco msg send --project lighthouse --target wren --body "Reuse the existing /api/v1 router; no new server."
# --wake=false batches it for the agent's next turn
caco msg send --project lighthouse --target wren --body-file review.md --wake=false
caco agent pause --id AGENT_ID     # keeps the session for inspection
caco agent resume --id AGENT_ID
caco agent attach --id AGENT_ID    # take the keyboard yourself
Always name the agent

Without --id, caco agent pause pauses every live agent that matches its --node and --project filters.

Find anything

One full-text index covers beads, scratchpads, messages, the feed, files, summaries, links and the commit history of every configured project, ranked by relevance and tagged by where each hit lives. Use --surface commit to search only commit subjects, bodies and authors; the daemon indexes each project's newest 2,000 commits from its canonical checkout every five minutes.

caco search footer --project lighthouse --surface bead
unified search (FTS5, BM25-ranked, surface-tagged) for: footer

[bead] bd-a0000b  Show build status in the footer  The footer should show the latest build result and link to its log, so a broken main is visible without opening CI.
[bead] bd-a00001  Expose the latest build result over the API  Add a read-only endpoint that returns the newest build's status, duration and log URL for the footer to poll.

Drop --surface to search everything, or bound it in time with --since 2d. caco msg history and caco bd search search one surface in more depth.

Add a machine

Every machine runs its own daemon; they trust each other through one cluster certificate authority. Clients only ever talk to their local daemon, which forwards to peers over mutual TLS.

  1. Bring it into the trust domain

    # on the authority, for a node listed in the shared config
    caco cert issue --node vega
    caco cert distribute --node vega        # over the node's configured SSH
    
    # or let the new machine request its own certificate
    caco node join --node-name vega --bootstrap-url AUTHORITY_URL --token JOIN_TOKEN

    Either way the new node never creates a certificate authority of its own. PKI & certificates

  2. Start it and check the mesh

    caco up                       # on vega
    caco node list
    NAME             HOST                 TYPE     LIVENESS       VERSION    HASH
    atlas            127.0.0.1            static   self           1.2.1882   5bbb3b75d378
    
    1 node(s)   # the demo is one node; each peer adds a row
  3. Use it

    caco bd dispatch --project lighthouse --bead-id bd-a00001 --node vega
    caco @vega agent list          # run a command on another node

    Without --node, the project's node selector places work. Networking & security

Run a typed flow

A flow wires agents, actions and other flows into a graph whose ports carry checked types. It is compiled and validated before anything runs, and every run is durable: it survives restarts, suspends for your input and keeps its outputs.

  1. Scaffold one

    caco flow scaffold --name lighthouse.triage --output-dir .cacophony/flows
    Created flow scaffold .cacophony/flows/triage.flow.yaml and .cacophony/flows/types.jtd.yaml.
    # .cacophony/flows/triage.flow.yaml
    flow: lighthouse.triage
    imports:
      t: ./types.jtd.yaml
    in:
      request: t.Request
    out:
      result: t.Result
    nodes:
      work:
        action: lighthouse.triage.work
        in:
          request: t.Request
        out:
          result: t.Result
    edges:
      - from: in.request
        to: work.request
      - from: work.result
        to: out.result

    Swap the action node for an agent node, fan out with a map, or suspend for a human review; Flows covers each node type.

  2. Check it

    caco flow validate --file .cacophony/flows/triage.flow.yaml
    Flow validation passed: lighthouse.triage at sha256:e257eadc41d4… from .cacophony/flows/triage.flow.yaml.
    caco flow explain --file .cacophony/flows/triage.flow.yaml
    Flow lighthouse.triage (sha256:e257eadc41d4…)
    Source: triage.flow.yaml
    Inputs: 1  Outputs: 1
    Nodes: 1  Edges: 2  Imports: 1
      work  executor=action  requires=0  suspends=false
  3. Commit it, then find it in the registry

    caco flow list --project lighthouse
    Flows (47):
      lighthouse.triage  e257eadc41d4  1 nodes / 2 edges / 0 activations
      std.bead.create-graph  8ac97fac1059  1 nodes / 2 edges / 0 activations
      …

    Flows register from the project's default branch. The 46 std.* flows ship with Cacophony: feature delivery, research, maintenance and burndown.

  4. Run it

    caco flow run --flow lighthouse.triage --project lighthouse --prompt "Why does the nightly build time out?" --dry-run
    {
      "mode": "prepare_start",
      "project": "lighthouse",
      "request": {
        "flow": "lighthouse.triage",
        "inputs": { "request": { "text": "Why does the nightly build time out?" } },
        …
      }
    }
    caco flow run --flow lighthouse.triage --project lighthouse --prompt "Why does the nightly build time out?"
    caco flow watch --run latest --project lighthouse

    --prompt fills the flow's standard text input. A suspended node waits for caco flow input or an answer in the inbox; caco flow stop and resume keep its agents and sessions.