brainclaw 1.5.4 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/README.md +52 -28
  2. package/dist/brainclaw-vscode.vsix +0 -0
  3. package/dist/cli.js +159 -12
  4. package/dist/commands/assignment-resource.js +182 -0
  5. package/dist/commands/bootstrap-loop.js +206 -0
  6. package/dist/commands/init.js +158 -22
  7. package/dist/commands/loop.js +156 -0
  8. package/dist/commands/loops-handlers.js +110 -55
  9. package/dist/commands/mcp-read-handlers.js +45 -4
  10. package/dist/commands/mcp.js +628 -205
  11. package/dist/commands/questions.js +180 -0
  12. package/dist/commands/reply.js +190 -0
  13. package/dist/commands/session-end.js +105 -3
  14. package/dist/commands/session-start.js +32 -53
  15. package/dist/commands/setup.js +87 -48
  16. package/dist/commands/switch.js +21 -1
  17. package/dist/core/agentrun-reconciler.js +65 -0
  18. package/dist/core/agentruns.js +10 -0
  19. package/dist/core/assignments.js +29 -10
  20. package/dist/core/claims.js +29 -0
  21. package/dist/core/context.js +1 -1
  22. package/dist/core/coordination.js +1 -1
  23. package/dist/core/dispatch-status.js +219 -0
  24. package/dist/core/entity-operations.js +166 -10
  25. package/dist/core/entity-registry.js +11 -10
  26. package/dist/core/execution-adapters.js +38 -2
  27. package/dist/core/facade-schema.js +55 -0
  28. package/dist/core/federation-cloud.js +27 -12
  29. package/dist/core/federation-materialize.js +57 -0
  30. package/dist/core/instruction-templates.js +2 -0
  31. package/dist/core/loops/bootstrap-acquire.js +195 -0
  32. package/dist/core/loops/facade-schema.js +68 -1
  33. package/dist/core/loops/hooks/bootstrap-write.js +144 -0
  34. package/dist/core/loops/hooks/notify-operator.js +148 -0
  35. package/dist/core/loops/hooks/survey-source-reader.js +256 -0
  36. package/dist/core/loops/index.js +8 -2
  37. package/dist/core/loops/next-expected.js +63 -0
  38. package/dist/core/loops/presets/bootstrap.js +75 -0
  39. package/dist/core/loops/presets/index.js +16 -0
  40. package/dist/core/loops/store.js +224 -4
  41. package/dist/core/loops/types.js +346 -1
  42. package/dist/core/loops/verbs.js +739 -6
  43. package/dist/core/schema.js +31 -2
  44. package/dist/core/state.js +62 -0
  45. package/dist/core/store-resolution.js +26 -16
  46. package/dist/facts.js +7 -5
  47. package/dist/facts.json +6 -4
  48. package/docs/cli.md +115 -30
  49. package/docs/concepts/dispatch-lifecycle.md +228 -0
  50. package/docs/concepts/loop-engine.md +55 -0
  51. package/docs/concepts/multi-agent-workflows.md +167 -166
  52. package/docs/concepts/troubleshooting.md +10 -2
  53. package/docs/integrations/agents.md +14 -14
  54. package/docs/integrations/codex.md +15 -12
  55. package/docs/integrations/mcp.md +10 -4
  56. package/docs/integrations/overview.md +11 -0
  57. package/docs/playbooks/productivity/index.md +3 -3
  58. package/docs/quickstart-existing-project.md +48 -28
  59. package/docs/quickstart.md +42 -28
  60. package/package.json +1 -1
@@ -0,0 +1,228 @@
1
+ # Dispatch lifecycle
2
+
3
+ When brainclaw routes work to another agent — `bclaw_coordinate(intent="assign"|"review"|"consult")`, `bclaw_dispatch(intent="execute")`, or a multi-turn `bclaw_loop` — it spins up **up to six related entities** plus an on-disk **brief-ack sentinel** and (since pln#504) **per-assignment stdout/stderr log files**. Knowing what each one means lets you tell at a glance whether a dispatch is alive, dead, or merely slow.
4
+
5
+ This doc is the consolidated reference. It complements:
6
+ - [multi-agent-workflows.md](multi-agent-workflows.md) — happy-path coordination patterns
7
+ - [troubleshooting.md](troubleshooting.md) — symptom-driven diagnostic playbooks
8
+ - [loop-engine.md](loop-engine.md) — multi-turn loop protocol details
9
+ - [../integrations/codex.md](../integrations/codex.md), [../integrations/claude-code.md](../integrations/claude-code.md), etc. — per-agent spawn semantics
10
+
11
+ ---
12
+
13
+ ## The six entities
14
+
15
+ A single `bclaw_coordinate(intent="review", open_loop=true, targetAgents=[codex])` creates:
16
+
17
+ ```
18
+ ┌─────────────────┐
19
+ │ candidate │ cnd_… (review payload)
20
+ └────────┬────────┘
21
+ │ references
22
+ ┌───────────────────┼──────────────────┐
23
+ ▼ ▼ ▼
24
+ ┌──────────┐ ┌─────────────┐ ┌──────────┐
25
+ │ loop │ ◄────►│ assignment │ │ message │
26
+ │ lop_… │ │ asgn_… │ │ msg_… │
27
+ └──────────┘ └──────┬──────┘ └──────────┘
28
+
29
+ │ owned-by
30
+
31
+ ┌──────────────┐
32
+ │ claim │ clm_… (worktree lock)
33
+ └──────┬───────┘
34
+ │ triggers
35
+
36
+ ┌──────────────┐
37
+ │ agent_run │ run_… (the OS-level spawn)
38
+ └──────┬───────┘
39
+
40
+ ┌───────────────────┼─────────────────┐
41
+ ▼ ▼ ▼
42
+ ┌──────────┐ ┌─────────────┐ ┌────────────┐
43
+ │ ack file │ │ stdout log │ │ stderr log │
44
+ │ .ack │ │ .stdout.log │ │ .stderr.log│
45
+ └──────────┘ └─────────────┘ └────────────┘
46
+ (pln#476) (pln#504) (pln#504)
47
+ ```
48
+
49
+ | Entity | Prefix | Created by | Owner | Purpose |
50
+ |---|---|---|---|---|
51
+ | `candidate` | `cnd_` | the coordinate facade (review/ideate) | the dispatcher agent | Review payload that the loop references. Stays after the loop closes. |
52
+ | `loop` | `lop_` | `bclaw_coordinate(open_loop=true)` or `bclaw_loop(intent="open")` | the dispatcher | Multi-turn thread of structured work. Has its own FSM. |
53
+ | `assignment` | `asgn_` | dispatcher when targeting an agent | the **target** agent | Lifecycle event for that agent's turn. The only entity whose FSM tracks the WORKER's progress. |
54
+ | `message` | `msg_` | dispatcher | the dispatcher | The brief delivered to the target's inbox. |
55
+ | `claim` | `clm_` | dispatcher (or `bclaw_claim` directly) | the target agent | Worktree advisory lock. Released when the work is done or the agent gives up. |
56
+ | `agent_run` | `run_` | the CLI execution adapter, only when an OS-level spawn actually happens | the target agent | OS-level subprocess record. Status FSM tracks the LIFETIME of the process — but only the parts brainclaw can observe (see [§Liveness limits](#liveness-limits) below). |
57
+
58
+ Plus two filesystem-only artefacts created by the worker shell wrapper:
59
+
60
+ - **Brief-ack sentinel**: `.brainclaw/coordination/runtime/ack/<assignment_id>.ack` — touched by the spawn wrapper BEFORE the agent binary runs (pln#476). Proves the spawn shell got far enough to execute `touch`. Does NOT prove the agent binary itself succeeded.
61
+ - **stdout/stderr logs** (pln#504): `.brainclaw/coordination/runtime/log/<assignment_id>.{stdout,stderr}.log` — opened by the parent before the spawn, the child inherits dup'd fds and writes its streams there. This is the only window onto what a sandboxed worker actually said before dying.
62
+
63
+ ---
64
+
65
+ ## FSM cheatsheet
66
+
67
+ ### `loop.status`
68
+
69
+ ```
70
+ open ──▶ paused ──▶ open (pause / resume)
71
+
72
+ ├──▶ completed (stop_condition met)
73
+ ├──▶ cancelled (manual close — use when the loop dies abnormally)
74
+ └──▶ blocked (external blocker; intent to resume later)
75
+ ```
76
+
77
+ `bclaw_loop(intent="close")` accepts **only** `completed | cancelled | blocked` as `status`. **Not `failed`** — map crashed/dead loops to `cancelled` with a `reason`.
78
+
79
+ ### `assignment.status`
80
+
81
+ ```
82
+ created ──▶ offered ──▶ accepted ──▶ started ──▶ completed
83
+ │ │ │ │
84
+ │ │ │ └──▶ failed (worker self-reported)
85
+ │ │ │ └──▶ blocked (worker needs supervisor)
86
+ │ │ │ └──▶ cancelled (rerouted away)
87
+ │ │ └──▶ acceptance_ttl expired (default 15min) → cancelled
88
+ │ └──▶ heartbeat_ttl expired (default 30min while running) → cancelled
89
+ └──▶ removed by `bclaw_assignment_admin` (rare)
90
+ ```
91
+
92
+ Transitions past `offered` require the assigned agent itself (or `bclaw_assignment_admin`). A coordinator that didn't create the assignment **cannot** update it — `Agent X cannot update assignment owned by Y` is the canonical rejection.
93
+
94
+ ### `agent_run.status`
95
+
96
+ ```
97
+ launching ──▶ running ──▶ completed
98
+ │ ──▶ failed (non-zero exit, worker reported)
99
+ │ ──▶ interrupted (TTL/heartbeat expiry, see below)
100
+
101
+ └──▶ failed (spawn returned no pid, brief-ack timeout)
102
+ ```
103
+
104
+ **Liveness limits** {#liveness-limits}: `last_event_at` is bumped only when the worker writes a lifecycle event (via MCP or via the wrap shell). A worker that crashes before its first output keeps `status=running` and `last_event_at == launched_at` until reconciled. Since pln#503 phase 3.2, **any read of `agent_run` via `bclaw_find` / `bclaw_get` triggers a lazy reconciliation pass**: open runs past the 60s grace window get their pid checked, and dead workers transition to `failed` (`status_reason='silent_termination_no_evidence'`) once past the 30min stale threshold.
105
+
106
+ For a single consolidated check (run + assignment + claim + loop + pid + log tails + verdict in one response), use **`bclaw_dispatch_status(target_id)`** (pln#503 phase 3.1).
107
+
108
+ ### `claim.status`
109
+
110
+ ```
111
+ active ──▶ released
112
+
113
+ └──▶ adopted (another session inherited the claim, e.g. reconnect)
114
+ ```
115
+
116
+ Releasing a claim does NOT cancel its assignment / agent_run / loop — those are independent entities. You generally need to clean up all of them together when aborting a dispatch.
117
+
118
+ ---
119
+
120
+ ## Observability decision tree
121
+
122
+ You called `bclaw_coordinate(intent="review", open_loop=true, …)` and got back `execution_status: "delivered_and_started"`. What does that actually mean?
123
+
124
+ **Fast path** (recommended since pln#503 phase 3.1): call `bclaw_dispatch_status(target_id="<asgn_…>")` and read its `diagnosis.health` + `diagnosis.recommended_next_action`. The tool consolidates the steps below into a single response — entity fan-out, pid liveness, log tails, verdict, recommended next action.
125
+
126
+ **Long path** (for understanding or when the tool isn't available):
127
+
128
+ ```
129
+ 1. execution_status = "delivered_and_started"
130
+ ├──▶ Means: the spawn wrapper touched the brief-ack sentinel
131
+ └──▶ Does NOT mean: the worker is doing useful work
132
+
133
+ 2. Verify the spawn is alive — check the agent_run record
134
+ bclaw_find(entity="agent_run", filter={assignment_id: "<asgn>"})
135
+ ├──▶ status="running" AND pid alive on OS AND last_event_at < 5min ago → healthy
136
+ ├──▶ status="running" AND pid alive AND last_event_at == launched_at → stalled (worker never produced output)
137
+ ├──▶ status="running" AND pid dead → silently died (see logs)
138
+ └──▶ status="completed" / "failed" / "interrupted" → terminal, read status_reason
139
+
140
+ 3. If silent, read the logs (pln#504)
141
+ cat .brainclaw/coordination/runtime/log/<asgn>.stderr.log
142
+ cat .brainclaw/coordination/runtime/log/<asgn>.stdout.log
143
+ ├──▶ Contains an error → root cause found
144
+ └──▶ Empty → worker died before any write OR launched without log capture (legacy path)
145
+
146
+ 4. If the worker is alive but doing nothing useful for 15+ min
147
+ → most likely sandbox / MCP / capability mismatch with the brief
148
+ → see ../integrations/<agent>.md "Caveats" for per-agent gotchas
149
+ ```
150
+
151
+ ---
152
+
153
+ ## Diagnostic playbook
154
+
155
+ When a dispatch hangs, work top-down through these checks. For the symptom-driven variant see [troubleshooting.md#inbox-messages-stuck--brief-ack-never-arrived](troubleshooting.md#inbox-messages-stuck--brief-ack-never-arrived).
156
+
157
+ ### Quick triage (≤5s)
158
+
159
+ ```bash
160
+ # Single call covers process liveness + ack + log tails + entity state + verdict
161
+ bclaw_dispatch_status(target_id="<asgn>") # or clm_/lop_/run_
162
+ ```
163
+
164
+ Read `diagnosis.health` (`healthy` | `stalled` | `silent_death` | `terminal` | `not_dispatched` | `unknown`) and `diagnosis.recommended_next_action` — usually that's all you need.
165
+
166
+ ### Manual triage (≤30s — when `bclaw_dispatch_status` isn't available)
167
+
168
+ ```bash
169
+ # 1. Is the OS-level process alive?
170
+ Get-Process -Id <pid> # Windows
171
+ ps -p <pid> # POSIX
172
+
173
+ # 2. Did the spawn wrapper actually run?
174
+ ls .brainclaw/coordination/runtime/ack/<asgn>.ack
175
+
176
+ # 3. What did the worker say? (pln#504)
177
+ cat .brainclaw/coordination/runtime/log/<asgn>.stderr.log
178
+ cat .brainclaw/coordination/runtime/log/<asgn>.stdout.log
179
+ ```
180
+
181
+ ### Deeper (1-5min)
182
+
183
+ ```bash
184
+ # Full entity state — same fan-out bclaw_dispatch_status does for you
185
+ bclaw_get(entity="assignment", id="<asgn>") # owner, ttls, status_reason
186
+ bclaw_get(entity="agent_run", id="<run>") # pid, started_at, last_event_at
187
+ bclaw_get(entity="claim", id="<clm>") # worktree, agent
188
+ bclaw_get(entity="loop", id="<lop>") # current_phase, slot states
189
+
190
+ # Worktree activity
191
+ git -C <worktree> log --oneline -5 # any new commits?
192
+ git -C <worktree> status # uncommitted work?
193
+ ls <worktree>/REVIEW_FINDINGS.md # for review loops
194
+ ```
195
+
196
+ ### Abort a dispatch cleanly
197
+
198
+ A dead dispatch needs four cleanup steps (no single facade does all of them today):
199
+
200
+ ```text
201
+ 1. Stop-Process -Id <pid> # if pid still alive
202
+ 2. bclaw_loop(intent="close", loop_id="<lop>", status="cancelled", reason="...")
203
+ 3. bclaw_release_claim(id="<clm>")
204
+ 4. (optional) bclaw_assignment_admin or leave assignment as `offered`
205
+ — only the owning agent can transition assignment.status, and a
206
+ released claim already makes it effectively orphan
207
+ ```
208
+
209
+ ---
210
+
211
+ ## Per-agent spawn semantics
212
+
213
+ Spawn behaviour varies by agent. The capability profile in `src/core/agent-capability.ts` describes each agent's prompt delivery, sandbox model, and MCP availability. Per-agent caveats:
214
+
215
+ - [codex.md](../integrations/codex.md#caveats) — `--sandbox workspace-write` required; spawned codex may not have brainclaw MCP wired; stdin_pipe prompt delivery; brief-ack required for headless dispatch detection.
216
+ - [claude-code.md](../integrations/claude-code.md) — interactive vs `-p` headless modes; tools whitelist.
217
+ - [copilot.md](../integrations/copilot.md), [windsurf.md](../integrations/windsurf.md), [cline.md](../integrations/cline.md), [opencode.md](../integrations/opencode.md), [roo.md](../integrations/roo.md), [kilocode.md](../integrations/kilocode.md), [continue.md](../integrations/continue.md) — per-agent specifics.
218
+ - [mistral-vibe.md](../integrations/mistral-vibe.md) — EU/GDPR self-hosted option.
219
+
220
+ ---
221
+
222
+ ## See also
223
+
224
+ - [troubleshooting.md](troubleshooting.md) — symptom-driven diagnostic playbooks
225
+ - [loop-engine.md](loop-engine.md) — multi-turn loop protocol, locks, advance gates
226
+ - [multi-agent-workflows.md](multi-agent-workflows.md) — high-level coordination scenarios
227
+ - [../integrations/overview.md](../integrations/overview.md) — index of supported agents
228
+ - [../integrations/mcp.md](../integrations/mcp.md) — full MCP tool catalog
@@ -163,6 +163,60 @@ interface LoopConflictRecord {
163
163
  }
164
164
  ```
165
165
 
166
+ ## Artifact body shapes
167
+
168
+ `LoopArtifact.body` has two known shape categories. Ref-based bodies keep large
169
+ content out of the loop thread JSON and store only file metadata in `body`.
170
+ Inline bodies keep the whole structured payload in `body` for small artifacts
171
+ such as operator questions and answers.
172
+
173
+ Ref-based bodies are JSON encoded as `RefBasedArtifactBody`:
174
+
175
+ - `ref`: string filename within the loop's `artifacts/` directory.
176
+ - `byte_count`: exact byte length of the referenced file at attach time.
177
+ - `sha256`: lowercase hex SHA-256 digest of the referenced file content.
178
+
179
+ The referenced file lives at
180
+ `.brainclaw/loops/threads/<loop_id>/artifacts/<ref>`. The champion or driver
181
+ code that calls `complete_turn` / `add_artifact` is responsible for writing the
182
+ file before or during the attach call, then attaching only
183
+ `JSON.stringify({ ref, byte_count, sha256 })` as the artifact body.
184
+
185
+ These artifact types use the ref-based shape:
186
+
187
+ - `signals_report`: structured discovery or bootstrap signals, often larger
188
+ than the inline body cap.
189
+ - `project_md_draft`: draft `PROJECT.md` content prepared by a loop slot.
190
+ - `project_md_final`: final `PROJECT.md` content accepted by the loop.
191
+ - `file_diff`: unified diff or patch content produced for review or apply.
192
+
193
+ Typical attach flow:
194
+
195
+ ```ts
196
+ const body = '<content>';
197
+ const ref = `<artifact-id>.<ext>`;
198
+ const artifactsDir = path.join(memoryDir(cwd), 'loops', 'threads', loopId, 'artifacts');
199
+ fs.mkdirSync(artifactsDir, { recursive: true });
200
+ fs.writeFileSync(path.join(artifactsDir, ref), body, 'utf8');
201
+ const byte_count = Buffer.byteLength(body, 'utf8');
202
+ const sha256 = crypto.createHash('sha256').update(body, 'utf8').digest('hex');
203
+ complete_turn(
204
+ {
205
+ ...,
206
+ artifact: {
207
+ phase,
208
+ type,
209
+ body: JSON.stringify({ ref, byte_count, sha256 }),
210
+ },
211
+ },
212
+ cwd,
213
+ );
214
+ ```
215
+
216
+ `RefBasedArtifactBodySchema` in `src/core/loops/types.ts` is the authoritative
217
+ validator for this metadata shape. `KNOWN_ARTIFACT_BODY_SCHEMAS` in the same
218
+ file lists which artifact types are ref-based and which use inline JSON bodies.
219
+
166
220
  ## Lifecycle verbs
167
221
 
168
222
  The engine exposes four active verbs. Each one mutates state, appends an event, and returns the updated `LoopThread`. **All verbs are strictly synchronous-on-state and asynchronous-on-work**: any downstream dispatch (spawning a CLI, calling another MCP tool) is fire-and-forget from the commit window, so the per-loop lock is always released quickly.
@@ -450,6 +504,7 @@ Status after Codex schema review (cnd#574 / `dec_be66ccbf`, verdict `needs_revis
450
504
 
451
505
  - [plans-and-claims.md](plans-and-claims.md)
452
506
  - [coordination.md](coordination.md)
507
+ - [dispatch-lifecycle.md](dispatch-lifecycle.md) — entity FSMs (loop / assignment / agent_run / claim), brief-ack semantics, log-file diagnostic playbook
453
508
  - [runtime-notes.md](runtime-notes.md)
454
509
  - pln#394 `feat/loop-engine-mvp`
455
510
  - pln#395 `feat/review-loop-protocol`
@@ -1,166 +1,167 @@
1
- # Multi-Agent Workflows
2
-
3
- brainclaw is built around a small set of memory primitives — **plans**, **claims**, **handoffs**, **decisions**, **traps**, and **runtime notes** — that work the same way whether you're orchestrating multiple agents in parallel right now or letting the next agent (or the next you) pick up the work next week.
4
-
5
- This doc walks through four concrete scenarios. Pick the one that matches what you're doing.
6
-
7
- ---
8
-
9
- ## 1. Active orchestration — parallel work across agent instances
10
-
11
- **Scenario** — you have a sequence of independent lanes and want several agents (same agent, different instances, or several different agents) to work on them in parallel.
12
-
13
- **Walkthrough**:
14
-
15
- 1. Capture the work as plans, then group them into a sequence with explicit lane labels and dependencies:
16
-
17
- ```text
18
- bclaw_create(entity="plan", data={ text: "Refactor auth module", … })
19
- bclaw_create(entity="plan", data={ text: "Add e2e tests", … })
20
-
21
- # Then, via CLI or a follow-up call:
22
- brainclaw sequence create "auth-refactor-cycle" --items '[
23
- {"planId":"pln_aaa","rank":1,"lane":"refactor"},
24
- {"planId":"pln_bbb","rank":2,"lane":"tests","hard_after":["pln_aaa"]}
25
- ]' --status active
26
- ```
27
-
28
- 2. Dispatch the sequence — the dispatcher picks up the ready lanes (no `hard_after` blocking), creates one claim + worktree per lane, and routes inbox messages by `claim_id`:
29
-
30
- ```text
31
- bclaw_dispatch(intent="execute", agents=[<your agents>])
32
- ```
33
-
34
- 3. Each spawned worker runs in its own worktree (so concurrent edits don't collide), reads its inbox, and progresses the plan. Coordinator polls `bclaw_context(kind="board")` to follow progress.
35
-
36
- 4. As each lane lands a commit, merge it into master and release the claim. Lanes with `hard_after` unblock automatically once their predecessors are `done`.
37
-
38
- **What the primitives do here**: claims isolate scope per lane, the sequence's `hard_after` graph orders the work, and worktrees give Git-level isolation so parallel commits don't conflict.
39
-
40
- ---
41
-
42
- ## 2. Agent switching — when an agent runs out of credits mid-task
43
-
44
- **Scenario** — your active agent hits a credit/quota limit while a task is half-done. You want the next agent (a different model, a fresh instance, anything you have available) to resume cleanly without re-explaining the whole project.
45
-
46
- **Walkthrough**:
47
-
48
- 1. Before the active agent shuts down, close out properly:
49
-
50
- ```text
51
- bclaw_session_end(narrative="Implemented X. Need to finish Y. Tests for Z still pending.")
52
- ```
53
-
54
- This snapshots the session, releases the active claims, and writes a handoff with the narrative + commit list.
55
-
56
- 2. Bring up the next agent (any compatible one). Its first call is `bclaw_work(intent="resume")`:
57
-
58
- ```text
59
- bclaw_work(intent="resume")
60
- ```
61
-
62
- This returns the session context: open plans, recent decisions, active constraints, known traps, the latest handoff narrative, and any unfinished claims it can adopt.
63
-
64
- 3. The new agent reads the handoff, picks up the right plan, and either creates a fresh claim on the same scope or adopts the existing one:
65
-
66
- ```text
67
- bclaw_work(intent="execute", planId="pln_…", scope="src/...")
68
- ```
69
-
70
- 4. From here on it's a normal session — the new agent has all the context the previous one had.
71
-
72
- **What the primitives do here**: the handoff carries the narrative and the file delta, the session record carries the runtime context, and shared memory (decisions, constraints, traps) means the new agent doesn't relearn what the previous one already knows.
73
-
74
- ---
75
-
76
- ## 3. Project recovery — returning to a project after weeks
77
-
78
- **Scenario** — you (or an agent on your behalf) come back to a project after a couple of weeks. You don't remember exactly where things stood. You want to ramp back up in a few minutes, not an afternoon.
79
-
80
- **Walkthrough**:
81
-
82
- 1. From the project root, ask any compatible agent to load context with the canonical facade:
83
-
84
- ```text
85
- bclaw_work(intent="resume")
86
- ```
87
-
88
- You get back: in-progress plans, blocked plans, decisions taken since you left, active constraints, known traps, recent handoffs, and a session continuity hint (where the last session left off).
89
-
90
- 2. If you want a narrower view focused on one area:
91
-
92
- ```text
93
- bclaw_context(kind="memory", path="src/auth", profile="briefing")
94
- ```
95
-
96
- 3. Capture the things you remember in the moment — even rough — as runtime notes. They live in memory and can be promoted later to durable decisions or traps:
97
-
98
- ```text
99
- bclaw_create(entity="runtime_note", data={ text: "Token rotation logic was the next thing to ship" })
100
- ```
101
-
102
- 4. Pick the next plan, claim its scope, and start working. The agent has everything it needs.
103
-
104
- **What the primitives do here**: durable memory means decisions and constraints survive long absences, the session continuity record bridges the gap between runs, and runtime notes give a low-friction way to capture half-formed ideas as they come back to you.
105
-
106
- ---
107
-
108
- ## 4. Team async — multiple humans and agents on the same project
109
-
110
- **Scenario** — two or more people work on the same project, possibly with their own agents. Everyone needs to see the same plans, the same constraints, the same decisions, without constant Slack pings.
111
-
112
- **Walkthrough**:
113
-
114
- 1. Whenever someone takes a non-trivial decision (architecture, library choice, naming convention), capture it once:
115
-
116
- ```text
117
- bclaw_create(entity="decision", data={ text: "Use OAuth 2.0 with PKCE", outcome: "approved" })
118
- bclaw_create(entity="constraint", data={ text: "All auth endpoints must rate-limit", category: "security" })
119
- bclaw_create(entity="trap", data={ text: "Don't import from src/legacy/", severity: "high" })
120
- ```
121
-
122
- These become visible to every agent (and every teammate's agent) on the next `bclaw_context` call.
123
-
124
- 2. When someone starts a non-trivial chunk of work, claim its scope so others can see it:
125
-
126
- ```text
127
- bclaw_work(intent="execute", scope="src/auth", task="Token rotation rework")
128
- ```
129
-
130
- The agent board (`bclaw_context(kind="board")` or `brainclaw agent-board`) now shows that scope as taken — anyone considering the same area sees the claim and either coordinates or picks something else.
131
-
132
- 3. When work is ready for review, hand it off explicitly. The handoff includes the file delta, the narrative, and any open questions:
133
-
134
- ```text
135
- bclaw_coordinate(intent="review", task="Auth refactor ready for review", scope="src/auth")
136
- ```
137
-
138
- 4. Reviewers pick up the handoff via inbox (`bclaw_read_inbox`) and respond either by accepting + closing it, or by sending back fixes through the same coordination loop.
139
-
140
- **What the primitives do here**: shared memory means every teammate's agent operates with the same constraints and traps, claims prevent double-work even without coordination meetings, and handoffs replace ad-hoc "hey, can you look at this?" pings with auditable artifacts.
141
-
142
- ---
143
-
144
- ## How the four scenarios share the same model
145
-
146
- Notice that the four walkthroughs above use the **same primitives**, just composed differently:
147
-
148
- | Primitive | Active orchestration | Agent switching | Project recovery | Team async |
149
- |---|---|---|---|---|
150
- | **plan** | unit of work in a lane | what the next agent picks up | what you ramp back into | what teammates see in the board |
151
- | **claim** | scope lock per lane | snapshotted on session_end, adoptable later | shows what was in flight | prevents teammates from double-editing |
152
- | **handoff** | between sequential lanes | carries the narrative + delta | bridges across the gap | replaces "ping me when ready" |
153
- | **decision / constraint / trap** | guides every spawned worker | survives the credit-limit cutover | reminds you of past choices | propagates team knowledge |
154
- | **runtime_note** | per-lane observations | quick captures before shutdown | half-formed thoughts on return | informal observations to share |
155
-
156
- You don't pick a "mode" up front. You compose the primitives in whatever way fits the moment, and brainclaw keeps them durable across all of it.
157
-
158
- ---
159
-
160
- ## Next reads
161
-
162
- - [memory.md](memory.md) — what counts as memory and how it's organized
163
- - [plans-and-claims.md](plans-and-claims.md) — coordination layer in depth
164
- - [loop-engine.md](loop-engine.md) — structured multi-turn protocols (review loops, ideation, etc.)
165
- - [memory-staleness.md](memory-staleness.md) — how brainclaw signals when stored items may be outdated
166
- - [../integrations/overview.md](../integrations/overview.md) — connecting your specific agent
1
+ # Multi-Agent Workflows
2
+
3
+ brainclaw is built around a small set of memory primitives — **plans**, **claims**, **handoffs**, **decisions**, **traps**, and **runtime notes** — that work the same way whether you're orchestrating multiple agents in parallel right now or letting the next agent (or the next you) pick up the work next week.
4
+
5
+ This doc walks through four concrete scenarios. Pick the one that matches what you're doing.
6
+
7
+ ---
8
+
9
+ ## 1. Active orchestration — parallel work across agent instances
10
+
11
+ **Scenario** — you have a sequence of independent lanes and want several agents (same agent, different instances, or several different agents) to work on them in parallel.
12
+
13
+ **Walkthrough**:
14
+
15
+ 1. Capture the work as plans, then group them into a sequence with explicit lane labels and dependencies:
16
+
17
+ ```text
18
+ bclaw_create(entity="plan", data={ text: "Refactor auth module", … })
19
+ bclaw_create(entity="plan", data={ text: "Add e2e tests", … })
20
+
21
+ # Then, via CLI or a follow-up call:
22
+ brainclaw sequence create "auth-refactor-cycle" --items '[
23
+ {"planId":"pln_aaa","rank":1,"lane":"refactor"},
24
+ {"planId":"pln_bbb","rank":2,"lane":"tests","hard_after":["pln_aaa"]}
25
+ ]' --status active
26
+ ```
27
+
28
+ 2. Dispatch the sequence — the dispatcher picks up the ready lanes (no `hard_after` blocking), creates one claim + worktree per lane, and routes inbox messages by `claim_id`:
29
+
30
+ ```text
31
+ bclaw_dispatch(intent="execute", agents=[<your agents>])
32
+ ```
33
+
34
+ 3. Each spawned worker runs in its own worktree (so concurrent edits don't collide), reads its inbox, and progresses the plan. Coordinator polls `bclaw_context(kind="board")` to follow progress.
35
+
36
+ 4. As each lane lands a commit, merge it into master and release the claim. Lanes with `hard_after` unblock automatically once their predecessors are `done`.
37
+
38
+ **What the primitives do here**: claims isolate scope per lane, the sequence's `hard_after` graph orders the work, and worktrees give Git-level isolation so parallel commits don't conflict.
39
+
40
+ ---
41
+
42
+ ## 2. Agent switching — when an agent runs out of credits mid-task
43
+
44
+ **Scenario** — your active agent hits a credit/quota limit while a task is half-done. You want the next agent (a different model, a fresh instance, anything you have available) to resume cleanly without re-explaining the whole project.
45
+
46
+ **Walkthrough**:
47
+
48
+ 1. Before the active agent shuts down, close out properly:
49
+
50
+ ```text
51
+ bclaw_session_end(narrative="Implemented X. Need to finish Y. Tests for Z still pending.")
52
+ ```
53
+
54
+ This snapshots the session, releases the active claims, and writes a handoff with the narrative + commit list.
55
+
56
+ 2. Bring up the next agent (any compatible one). Its first call is `bclaw_work(intent="resume")`:
57
+
58
+ ```text
59
+ bclaw_work(intent="resume")
60
+ ```
61
+
62
+ This returns the session context: open plans, recent decisions, active constraints, known traps, the latest handoff narrative, and any unfinished claims it can adopt.
63
+
64
+ 3. The new agent reads the handoff, picks up the right plan, and either creates a fresh claim on the same scope or adopts the existing one:
65
+
66
+ ```text
67
+ bclaw_work(intent="execute", planId="pln_…", scope="src/...")
68
+ ```
69
+
70
+ 4. From here on it's a normal session — the new agent has all the context the previous one had.
71
+
72
+ **What the primitives do here**: the handoff carries the narrative and the file delta, the session record carries the runtime context, and shared memory (decisions, constraints, traps) means the new agent doesn't relearn what the previous one already knows.
73
+
74
+ ---
75
+
76
+ ## 3. Project recovery — returning to a project after weeks
77
+
78
+ **Scenario** — you (or an agent on your behalf) come back to a project after a couple of weeks. You don't remember exactly where things stood. You want to ramp back up in a few minutes, not an afternoon.
79
+
80
+ **Walkthrough**:
81
+
82
+ 1. From the project root, ask any compatible agent to load context with the canonical facade:
83
+
84
+ ```text
85
+ bclaw_work(intent="resume")
86
+ ```
87
+
88
+ You get back: in-progress plans, blocked plans, decisions taken since you left, active constraints, known traps, recent handoffs, and a session continuity hint (where the last session left off).
89
+
90
+ 2. If you want a narrower view focused on one area:
91
+
92
+ ```text
93
+ bclaw_context(kind="memory", path="src/auth", profile="briefing")
94
+ ```
95
+
96
+ 3. Capture the things you remember in the moment — even rough — as runtime notes. They live in memory and can be promoted later to durable decisions or traps:
97
+
98
+ ```text
99
+ bclaw_create(entity="runtime_note", data={ text: "Token rotation logic was the next thing to ship" })
100
+ ```
101
+
102
+ 4. Pick the next plan, claim its scope, and start working. The agent has everything it needs.
103
+
104
+ **What the primitives do here**: durable memory means decisions and constraints survive long absences, the session continuity record bridges the gap between runs, and runtime notes give a low-friction way to capture half-formed ideas as they come back to you.
105
+
106
+ ---
107
+
108
+ ## 4. Team async — multiple humans and agents on the same project
109
+
110
+ **Scenario** — two or more people work on the same project, possibly with their own agents. Everyone needs to see the same plans, the same constraints, the same decisions, without constant Slack pings.
111
+
112
+ **Walkthrough**:
113
+
114
+ 1. Whenever someone takes a non-trivial decision (architecture, library choice, naming convention), capture it once:
115
+
116
+ ```text
117
+ bclaw_create(entity="decision", data={ text: "Use OAuth 2.0 with PKCE", outcome: "approved" })
118
+ bclaw_create(entity="constraint", data={ text: "All auth endpoints must rate-limit", category: "security" })
119
+ bclaw_create(entity="trap", data={ text: "Don't import from src/legacy/", severity: "high" })
120
+ ```
121
+
122
+ These become visible to every agent (and every teammate's agent) on the next `bclaw_context` call.
123
+
124
+ 2. When someone starts a non-trivial chunk of work, claim its scope so others can see it:
125
+
126
+ ```text
127
+ bclaw_work(intent="execute", scope="src/auth", task="Token rotation rework")
128
+ ```
129
+
130
+ The agent board (`bclaw_context(kind="board")` or `brainclaw agent-board`) now shows that scope as taken — anyone considering the same area sees the claim and either coordinates or picks something else.
131
+
132
+ 3. When work is ready for review, hand it off explicitly. The handoff includes the file delta, the narrative, and any open questions:
133
+
134
+ ```text
135
+ bclaw_coordinate(intent="review", task="Auth refactor ready for review", scope="src/auth")
136
+ ```
137
+
138
+ 4. Reviewers pick up the handoff via inbox (`bclaw_read_inbox`) and respond either by accepting + closing it, or by sending back fixes through the same coordination loop.
139
+
140
+ **What the primitives do here**: shared memory means every teammate's agent operates with the same constraints and traps, claims prevent double-work even without coordination meetings, and handoffs replace ad-hoc "hey, can you look at this?" pings with auditable artifacts.
141
+
142
+ ---
143
+
144
+ ## How the four scenarios share the same model
145
+
146
+ Notice that the four walkthroughs above use the **same primitives**, just composed differently:
147
+
148
+ | Primitive | Active orchestration | Agent switching | Project recovery | Team async |
149
+ |---|---|---|---|---|
150
+ | **plan** | unit of work in a lane | what the next agent picks up | what you ramp back into | what teammates see in the board |
151
+ | **claim** | scope lock per lane | snapshotted on session_end, adoptable later | shows what was in flight | prevents teammates from double-editing |
152
+ | **handoff** | between sequential lanes | carries the narrative + delta | bridges across the gap | replaces "ping me when ready" |
153
+ | **decision / constraint / trap** | guides every spawned worker | survives the credit-limit cutover | reminds you of past choices | propagates team knowledge |
154
+ | **runtime_note** | per-lane observations | quick captures before shutdown | half-formed thoughts on return | informal observations to share |
155
+
156
+ You don't pick a "mode" up front. You compose the primitives in whatever way fits the moment, and brainclaw keeps them durable across all of it.
157
+
158
+ ---
159
+
160
+ ## Next reads
161
+
162
+ - [memory.md](memory.md) — what counts as memory and how it's organized
163
+ - [plans-and-claims.md](plans-and-claims.md) — coordination layer in depth
164
+ - [loop-engine.md](loop-engine.md) — structured multi-turn protocols (review loops, ideation, etc.)
165
+ - [dispatch-lifecycle.md](dispatch-lifecycle.md) — what actually happens when a dispatch goes wrong: 6-entity dance, brief-ack sentinel, stdout/stderr logs, observability decision tree
166
+ - [memory-staleness.md](memory-staleness.md) — how brainclaw signals when stored items may be outdated
167
+ - [../integrations/overview.md](../integrations/overview.md) — connecting your specific agent