-
Notifications
You must be signed in to change notification settings - Fork 0
Add optional CMUX multi-agent orchestration runbooks #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| --- | ||
| type: job | ||
| domain: kb-meta | ||
| trigger: an initiative/task is ready to run in its own repo context, delegated from the main workspace | ||
| frequency: per-initiative | ||
| tools: cmux, Claude Code, git, Initiatives/ | ||
| owner: {{NAME}} | ||
| status: active | ||
| tags: [job, kb-meta] | ||
| aliases: [Delegate to a workspace, Spin up a CMUX workspace, Delegate an initiative] | ||
| --- | ||
|
|
||
| # Job — Delegate an initiative to a CMUX workspace | ||
|
|
||
| > **When:** the main workspace needs to hand a whole task/initiative to its own | ||
| > CMUX workspace (own repo/worktree, own agent) · **Frequency:** per-initiative · | ||
| > **Tools:** `cmux` CLI, Claude Code, git, the initiative note | ||
| > **Outcome:** a dedicated, colour-coded CMUX workspace running its own Claude | ||
| > Code on the right `--cwd`, kicked off against an `Initiatives/<slug>.md` note | ||
| > that is the shared source of truth — with the dispatch recorded back in that note. | ||
| > **Model:** orchestrator — a capable model (Claude Code lead); delegated | ||
| > workspace agent — a capable or cheaper model by task weight. | ||
|
|
||
| ## When to run this | ||
| The unit of work is a **whole workstream** that wants its own repo context and | ||
| lifecycle — not a fan-out of sub-tasks within one session (that's | ||
| [[Spawn subagent panes in a CMUX workspace]]). You're operating from the **main | ||
| workspace** (Claude Code orchestrator, cwd = your vault root). This is an | ||
| **optional extension** — see `meta/AGENTS.md` § Optional extensions for the | ||
| two-interface model behind it (vault = memory/durable, CMUX = runtime/ephemeral; | ||
| state round-trips through the vault). **Precondition:** the initiative has a note | ||
| in `Initiatives/` (if not, run [[Run an initiative]] first) — that note is the | ||
| delegated workspace's `backlog.md`. | ||
|
|
||
| ## Steps | ||
| 1. **Preflight the socket.** `cmux identify --json` should succeed. If not, launch | ||
| CMUX and poll: | ||
| ```bash | ||
| cmux identify --json >/dev/null 2>&1 || { open -a cmux; \ | ||
| for i in $(seq 1 30); do cmux identify --json >/dev/null 2>&1 && break; sleep 0.5; done; } | ||
| ``` | ||
| (`cmux` = `/Applications/cmux.app/Contents/Resources/bin/cmux` — symlink it onto PATH once.) | ||
| 2. **Pick the window.** Reuse the current one: `WIN=$(cmux list-windows --json | jq -r '.[0].id')`. | ||
| 3. **Create the workspace on the initiative's cwd** — a repo checkout or a | ||
| worktree. Capture the refs: | ||
| ```bash | ||
| read WS LEAD < <(cmux workspace create --window "$WIN" --name "<slug>" \ | ||
| --cwd "$HOME/dev/<repo-or-worktree>" --focus true --json \ | ||
| | jq -r '[.workspace_ref,.surface_ref]|@tsv') | ||
| ``` | ||
| Add `--env-file ./.env` when the workspace needs credentials injected. | ||
| 4. **Make it legible** — colour + status so it's scannable in the sidebar: | ||
| ```bash | ||
| cmux rename-tab --workspace "$WS" --surface "$LEAD" "🎯 <slug>" | ||
| cmux workspace-action --action set-color --workspace "$WS" --color <Colour> | ||
| cmux set-status initiative "<slug>" --workspace "$WS" | ||
| ``` | ||
| 5. **Launch the delegated Claude Code** into the lead surface (pick the model by | ||
| task weight — a cheaper model for well-scoped execution, a more capable one | ||
| for heavy reasoning): | ||
| ```bash | ||
| cmux send --surface "$LEAD" "claude --model <model-id>" | ||
| cmux send-key --surface "$LEAD" enter | ||
| sleep 4 | ||
| ``` | ||
| 6. **Kick it off with a one-line brief** that points at the vault note as its | ||
| source of truth and demands a sentinel on completion. **One line, no newlines:** | ||
| ```bash | ||
| cmux send --surface "$LEAD" "Read <vault>/Initiatives/<slug>.md; execute its Now-and-next; write decisions/actions back to that note; end with: DONE: <slug> | <summary>" | ||
| cmux send-key --surface "$LEAD" enter | ||
| ``` | ||
| 7. **Record the dispatch in the vault** *(this is the round-trip — do not skip)* — | ||
| in `Initiatives/<slug>.md` add a dated Milestone ("delegated to CMUX workspace | ||
| `<slug>` on `<cwd>`, <date>") and any `#action`s you're now waiting on. | ||
| 8. **Coordinate to completion** (event-driven, not busy-poll): | ||
| ```bash | ||
| cmux events --category notification --reconnect | grep -m1 "$WS" >/dev/null | ||
| cmux read-screen --surface "$LEAD" --scrollback --lines 60 | tail -30 | ||
| ``` | ||
| **Confirm the `DONE:` sentinel actually printed** before trusting it — a wake | ||
| can mean "needs input", not "finished". If it's asking for input, `send` the | ||
| answer + `send-key enter`. | ||
| 9. **Close out.** When the initiative note reflects the outcome (results, decisions, | ||
| next actions written back), tear the workspace down: `cmux workspace close | ||
| --workspace "$WS"` (or keep it if work continues). The vault, not CMUX, is the record. | ||
|
|
||
| ## Gotchas / rules | ||
| - **State lives in the vault, not the workspace.** A CMUX workspace is disposable; | ||
| if the plan/result isn't written into `Initiatives/<slug>.md`, it's lost on | ||
| teardown. Step 7 + step 9 are the whole point. | ||
| - **`send` types; `send-key enter` submits.** A `send` with no follow-up `enter` | ||
| leaves the prompt unsent. **Never put a `\n` inside a `send`** — each newline | ||
| fires a half-finished turn; keep briefs to one line and split if long. | ||
| - **Thread the refs.** Always capture `workspace_ref`/`surface_ref` from `--json` | ||
| and reuse them — never guess a surface address. | ||
| - **Notify ≠ done.** Always `read-screen` and confirm the sentinel; agents notify | ||
| when they need input too. | ||
| - **`socketControlMode: cmuxOnly` is fine** for an orchestrator running inside a | ||
| CMUX pane (the default). Only raise to `allowAll` if you drive from outside CMUX. | ||
| - **One workspace = one repo context.** If the "delegation" is really N concurrent | ||
| sub-tasks sharing one context, use panes instead → [[Spawn subagent panes in a CMUX workspace]]. | ||
|
|
||
| ## Done when | ||
| - [ ] A dedicated CMUX workspace is running its own Claude Code on the right `--cwd`, kicked off against the initiative note. | ||
| - [ ] The dispatch (and, at close, the outcome) is written back into `Initiatives/<slug>.md`. | ||
| - [ ] The `DONE:` sentinel was confirmed via `read-screen` (not assumed from a notification). | ||
|
|
||
| ## Related | ||
| - `meta/AGENTS.md` § Optional extensions — the model + why (the two-interface split, the round-trip rule). | ||
| - [[Spawn subagent panes in a CMUX workspace]] — sibling runbook for pane-level fan-out. | ||
| - [[Run an initiative]] — creates/maintains the `Initiatives/` note this delegates against. | ||
| - [[AGENTS]] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,101 @@ | ||
| --- | ||
| type: job | ||
| domain: kb-meta | ||
| trigger: one task decomposes into concurrent sub-tasks you want to run and watch as panes | ||
| frequency: ad-hoc | ||
| tools: cmux, Claude Code | ||
| owner: {{NAME}} | ||
| status: active | ||
| tags: [job, kb-meta] | ||
| aliases: [Spawn subagent panes, Fan out subagents, Subagent panes, Spawn workers in panes] | ||
| --- | ||
|
|
||
| # Job — Spawn subagent panes in a CMUX workspace | ||
|
|
||
| > **When:** a single task fans out into concurrent sub-tasks you want visible and | ||
| > drivable as panes in the current workspace · **Frequency:** ad-hoc · | ||
| > **Tools:** `cmux` CLI, Claude Code | ||
| > **Outcome:** N worker agents running in split panes, each driven by the session | ||
| > lead through the four-verb loop, each reporting a `DONE:` sentinel — torn down | ||
| > when finished. | ||
| > **Model:** lead — a capable model (coordinates, doesn't do the heavy edits); | ||
| > worker panes — a cheaper/faster model where appropriate. | ||
|
|
||
| ## When to run this | ||
| The work is **one task with concurrent legs that share a context** (e.g. | ||
| research three sources at once; build + test in parallel), not a whole workstream | ||
| needing its own repo (that's [[Delegate an initiative to a CMUX workspace]]). | ||
| You're the **lead** in an existing workspace. This is an **optional extension** — | ||
| see `meta/AGENTS.md` § Optional extensions for the model + why (the two-interface | ||
| split, the four-verb loop, model policy). **The lead coordinates — it does not do | ||
| the heavy editing itself once workers exist.** | ||
|
|
||
| ## Steps | ||
| 1. **Know your own surface.** From the lead pane, `cmux identify --json` (socket | ||
| check) and `cmux list-pane-surfaces` to see the workspace + your surface ref. | ||
| Set `WS=<workspace_ref>` and `LEAD=<your surface_ref>`. | ||
| 2. **Split off worker panes** — anchor each split on an existing surface; capture | ||
| each new ref. E.g. three workers: | ||
| ```bash | ||
| W1=$(cmux new-split right --workspace "$WS" --surface "$LEAD" --json | jq -r .surface_ref) | ||
| W2=$(cmux new-split down --workspace "$WS" --surface "$W1" --json | jq -r .surface_ref) | ||
| W3=$(cmux new-split down --workspace "$WS" --surface "$LEAD" --json | jq -r .surface_ref) | ||
| ``` | ||
| 3. **Label them** so the grid is scannable: `cmux rename-tab --workspace "$WS" | ||
| --surface "$W1" "🔬 research-A"` (repeat per worker); optional `cmux | ||
| trigger-flash --surface "$W1"` to point at one. | ||
| 4. **Launch an agent in each pane** (a cheaper/faster model for well-scoped legs). | ||
| `send` the CLI line, then `send-key enter`, and give it a moment to boot: | ||
| ```bash | ||
| for S in "$W1" "$W2" "$W3"; do | ||
| cmux send --surface "$S" "claude --model <model-id>" | ||
| cmux send-key --surface "$S" enter | ||
| done | ||
| sleep 4 | ||
| ``` | ||
| 5. **Dispatch one single-line task per worker**, each ending in a sentinel. **One | ||
| line, no embedded newlines:** | ||
| ```bash | ||
| cmux send --surface "$W1" "<worker A's task>. End with exactly: DONE: research-A | <summary>" | ||
| cmux send-key --surface "$W1" enter | ||
| # repeat for W2, W3 | ||
| ``` | ||
| 6. **Wait on the doorbell, then confirm** — block on the notification stream, then | ||
| read the pane and check the sentinel actually printed: | ||
| ```bash | ||
| cmux events --category notification --reconnect | grep -m1 "$W1" >/dev/null | ||
| cmux read-screen --surface "$W1" --scrollback --lines 80 | tail -30 | ||
| ``` | ||
| One event stream serves all workers for parallel dispatch. A wake can mean | ||
| "needs input" — if so, `send` the answer + `send-key enter`, don't mark it done. | ||
| 7. **Integrate + write back.** The lead collects each worker's result and folds it | ||
| into the deliverable / the relevant vault note (concept, initiative, daily | ||
| note). Route any failure back to the responsible worker with a follow-up `send`. | ||
| 8. **Tear down** finished panes: `cmux close-surface --surface "$W1"` (repeat). | ||
| Close a runaway the same way. | ||
|
|
||
| ## Gotchas / rules | ||
| - **`send` types, `send-key enter` submits; never embed `\n`** — each newline | ||
| fires a separate half-finished turn. One line per `send`. | ||
| - **Thread refs from `--json`** — capture every `surface_ref` at creation; never | ||
| guess an address. | ||
| - **Notify ≠ done** — always `read-screen` and confirm the `DONE:` sentinel; agents | ||
| notify when they need input too. Wait on events; **don't busy-poll**. | ||
| - **Lead doesn't do the heavy lifting** once workers exist — it decomposes, | ||
| dispatches, integrates, reports. Keep its own edits to integration. | ||
| - **Panes share the workspace cwd/context** — if a leg needs a different repo, it's | ||
| a workspace-level delegation instead → [[Delegate an initiative to a CMUX workspace]]. | ||
| - **Claude Code's own Task/Agent subagents are in-process**, not CMUX panes. This | ||
| runbook is the explicit-pane path (visible, drivable). Some CMUX versions can | ||
| surface native subagents as panes automatically — untested; prefer explicit | ||
| `new-split` for now. | ||
|
|
||
| ## Done when | ||
| - [ ] N worker panes launched, labelled, and each dispatched a one-line task with a sentinel. | ||
| - [ ] Every worker's `DONE:` sentinel confirmed via `read-screen`; results integrated by the lead and written to the right vault note. | ||
| - [ ] Finished panes torn down with `close-surface`. | ||
|
|
||
| ## Related | ||
| - `meta/AGENTS.md` § Optional extensions — the model + why (the four-verb loop, coordination patterns, model policy). | ||
| - [[Delegate an initiative to a CMUX workspace]] — sibling runbook for workspace-level (whole-task) delegation. | ||
| - [[AGENTS]] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Schema consistency: this Job adds a new note with
aliases:, butmeta/link-map.mdwasn't regenerated (meta/bin/build-link-map.sh). Permeta/AGENTS.md§ Conventions: "Regenerate after adding/renaming any concept, person, or job." Right now none of this job's aliases (or the siblingSpawn subagent panes...job's aliases) resolve via the link map. Same applies toJobs/Spawn subagent panes in a CMUX workspace.md.