brainclaw 1.26.1 → 1.27.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.
- package/README.md +41 -12
- package/dist/brainclaw-vscode.vsix +0 -0
- package/dist/cli/register-coordination.js +65 -1
- package/dist/commands/attempt-authority.js +80 -0
- package/dist/commands/harvest.js +140 -61
- package/dist/commands/loop.js +34 -0
- package/dist/commands/loops-handlers.js +87 -14
- package/dist/commands/mcp-catalog.js +42 -18
- package/dist/commands/mcp-schemas.generated.js +44 -0
- package/dist/commands/mcp-write-claims.js +128 -1
- package/dist/commands/mcp-write-coordination.js +146 -76
- package/dist/core/agent-capability.js +1 -1
- package/dist/core/agent-files.js +21 -21
- package/dist/core/agentrun-reconciler.js +148 -22
- package/dist/core/agentruns.js +254 -29
- package/dist/core/assignment-request-schema.js +7 -0
- package/dist/core/assignment-sweeper.js +5 -3
- package/dist/core/assignments.js +131 -33
- package/dist/core/claim-request-schema.js +7 -0
- package/dist/core/claims.js +53 -2
- package/dist/core/dispatch-status.js +16 -6
- package/dist/core/dispatcher.js +51 -51
- package/dist/core/entity-operations.js +20 -0
- package/dist/core/events.js +4 -0
- package/dist/core/execution-adapters.js +160 -14
- package/dist/core/execution-contract.js +345 -0
- package/dist/core/execution.js +130 -16
- package/dist/core/harness-adapters/base.js +150 -0
- package/dist/core/harness-adapters/claude.js +39 -0
- package/dist/core/harness-adapters/codex.js +57 -0
- package/dist/core/harness-adapters/harvest.js +109 -0
- package/dist/core/harness-adapters/index.js +8 -0
- package/dist/core/harness-adapters/prompt-only.js +13 -0
- package/dist/core/harness-adapters/registry.js +48 -0
- package/dist/core/harness-adapters/result.js +33 -0
- package/dist/core/harness-adapters/types.js +2 -0
- package/dist/core/ideation-loop-close.js +25 -2
- package/dist/core/instruction-templates.js +3 -2
- package/dist/core/loop-turn-dispatch.js +207 -0
- package/dist/core/loops/artifact-contract.js +11 -0
- package/dist/core/loops/attempt-authority.js +476 -0
- package/dist/core/loops/attempt-generations.js +509 -0
- package/dist/core/loops/attempt-reservation.js +197 -35
- package/dist/core/loops/attempt-rollout.js +404 -0
- package/dist/core/loops/attempt-takeover.js +155 -0
- package/dist/core/loops/bootstrap-acquire.js +7 -3
- package/dist/core/loops/evidence.js +187 -0
- package/dist/core/loops/facade-schema.js +41 -10
- package/dist/core/loops/gate-policy.js +485 -0
- package/dist/core/loops/impl-bind.js +37 -79
- package/dist/core/loops/index.js +9 -0
- package/dist/core/loops/iteration-engine.js +31 -19
- package/dist/core/loops/kind-policies.js +90 -0
- package/dist/core/loops/lock.js +71 -13
- package/dist/core/loops/reconcile-turn.js +235 -18
- package/dist/core/loops/result-reducers.js +99 -10
- package/dist/core/loops/store.js +30 -3
- package/dist/core/loops/turn-execution.js +480 -0
- package/dist/core/loops/types.js +113 -2
- package/dist/core/loops/verbs.js +332 -99
- package/dist/core/loops/verify-command.js +31 -8
- package/dist/core/loops/workspace-digest.js +54 -0
- package/dist/core/protocol-tool-policy.js +44 -0
- package/dist/core/review-loop-close.js +25 -3
- package/dist/core/review-loop-turn-dispatch.js +210 -161
- package/dist/core/runtime-signals.js +62 -25
- package/dist/core/schema.js +35 -0
- package/dist/core/spawn-check.js +3 -2
- package/dist/core/upgrades/backup.js +27 -4
- package/dist/facts.js +9 -8
- package/dist/facts.json +8 -7
- package/docs/PROTOCOL.md +6 -4
- package/docs/cli.md +49 -1
- package/docs/concepts/attempt-authority.md +407 -0
- package/docs/concepts/evidence-attestations.md +135 -0
- package/docs/concepts/execution-contract.md +166 -0
- package/docs/concepts/harness-adapters.md +166 -0
- package/docs/concepts/ideation-loop.md +5 -4
- package/docs/concepts/loop-engine.md +348 -133
- package/docs/index.md +4 -1
- package/docs/integrations/codex.md +3 -3
- package/docs/integrations/hermes.md +42 -3
- package/docs/integrations/mcp.md +75 -9
- package/docs/loops/debug.md +144 -0
- package/docs/loops/ideation.md +158 -0
- package/docs/loops/implementation.md +154 -0
- package/docs/loops/research.md +136 -0
- package/docs/loops/review.md +200 -0
- package/docs/mcp-schema-changelog.md +14 -5
- package/docs/product/agent-first-model.md +33 -33
- package/package.json +1 -1
package/docs/index.md
CHANGED
|
@@ -28,8 +28,11 @@ Use this page as the entry point into the packaged Markdown documentation.
|
|
|
28
28
|
- [concepts/workspace-bootstrapping.md](concepts/workspace-bootstrapping.md)
|
|
29
29
|
- [concepts/troubleshooting.md](concepts/troubleshooting.md) — runbook for degraded coordination state
|
|
30
30
|
- [concepts/memory-staleness.md](concepts/memory-staleness.md)
|
|
31
|
-
- [concepts/loop-engine.md](concepts/loop-engine.md)
|
|
31
|
+
- [concepts/loop-engine.md](concepts/loop-engine.md) — shared runtime for the five loop protocols
|
|
32
|
+
- [concepts/attempt-authority.md](concepts/attempt-authority.md) — identity, dispatch decisions and spawn authority for every turn
|
|
33
|
+
- [concepts/evidence-attestations.md](concepts/evidence-attestations.md) — server-sealed loop evidence, independent attestations, and protocol gates
|
|
32
34
|
- [concepts/ideation-loop.md](concepts/ideation-loop.md) — memory-confrontation ideation loop (v1.5.0+)
|
|
35
|
+
- Loop protocol guides — [review](loops/review.md), [ideation](loops/ideation.md), [implementation](loops/implementation.md), [research](loops/research.md), [debug](loops/debug.md)
|
|
33
36
|
- [concepts/mcp-governance.md](concepts/mcp-governance.md)
|
|
34
37
|
- [concepts/federation-v2-rfc.md](concepts/federation-v2-rfc.md) — contrat joint core + Cloud pour la fédération chiffrée v2
|
|
35
38
|
|
|
@@ -47,9 +47,9 @@ The `--sandbox workspace-write` setting is required, **not `read-only`** — the
|
|
|
47
47
|
|
|
48
48
|
### Prompt delivery: stdin_pipe (preferred)
|
|
49
49
|
|
|
50
|
-
Since pln#475 (1.0.10+), Codex spawned as a child process receives its prompt via **stdin** rather than as an inline argument. The reason is Windows-specific: `codex.cmd` resolves through `cmd.exe`, where embedded backticks, `#`, or multi-line content can be mis-parsed and raise `unexpected argument`.
|
|
50
|
+
Since pln#475 (1.0.10+), Codex spawned as a child process receives its prompt via **stdin** rather than as an inline argument. The reason is Windows-specific: `codex.cmd` resolves through `cmd.exe`, where embedded backticks, `#`, or multi-line content can be mis-parsed and raise `unexpected argument`. Keeping the prompt out of argv avoids that.
|
|
51
51
|
|
|
52
|
-
When you (or the dispatcher) calls Codex with no positional `[PROMPT]`, Codex reads stdin until EOF
|
|
52
|
+
When you (or the dispatcher) calls Codex with no positional `[PROMPT]`, Codex reads stdin until EOF. A direct spawn pipes the brief normally. On Windows, an ack-wrapped spawn writes the brief to a private per-run file, redirects that file to Codex stdin, and deletes it after the terminal sentinel. This is still `stdin_pipe` at the harness contract: the file is a transport detail that guarantees EOF through `cmd.exe` and keeps prompt content out of shell syntax. `inline_arg` remains a fallback for short prompts on POSIX.
|
|
53
53
|
|
|
54
54
|
### Brief-ack handshake
|
|
55
55
|
|
|
@@ -89,6 +89,6 @@ The file shape is `{ "hooks": { "<Event>": [ { "matcher": "", "hooks": [ { "type
|
|
|
89
89
|
## Caveats
|
|
90
90
|
|
|
91
91
|
- **Sandbox blocks `git commit`, not MCP** (dec#133): a sandboxed Codex run reaches brainclaw MCP (the server is a separate out-of-sandbox process; `approval_policy=never` auto-approves). What the sandbox *does* block is direct writes to paths outside the worktree root — notably `.git`, so the worker cannot `git commit`. Leave fixes uncommitted; the coordinator integrates + commits the worktree diff at harvest. A LANE-RESULT.json / filesystem-direct candidate write remains a valid fallback for reporting.
|
|
92
|
-
- **Windows
|
|
92
|
+
- **Windows prompt transport**: long prompts containing backticks or `#` fail when passed as inline args through `cmd.exe`, while a parent stdin pipe can fail to propagate EOF to a native grandchild. The default ack-wrapped path uses a per-run file redirected to stdin and removes it after the terminal sentinel, avoiding both failure modes.
|
|
93
93
|
- **Sandbox vs review parity**: review runs use the same `workspace-write` sandbox as execution runs (older templates forced `read-only` on reviews; that path blocked PowerShell exec on Windows).
|
|
94
94
|
- **No always-allow**: each MCP tool call still respects per-call approval policy unless explicitly set with `-c approval_policy="never"`.
|
|
@@ -24,8 +24,9 @@ The machine setup writes `~/.hermes/config.yaml`. The project enable step writes
|
|
|
24
24
|
the universal Brainclaw skill into `.agents/skills/brainclaw/SKILL.md` and
|
|
25
25
|
adds the project `.agents/skills` directory to Hermes `skills.external_dirs`.
|
|
26
26
|
|
|
27
|
-
The generated MCP entry is intentionally filtered to the
|
|
28
|
-
|
|
27
|
+
The generated MCP entry is intentionally filtered to the workflow tools Hermes
|
|
28
|
+
is instructed to use. This controls tool discovery only; it does not grant
|
|
29
|
+
headless approval for writes.
|
|
29
30
|
|
|
30
31
|
```yaml
|
|
31
32
|
skills:
|
|
@@ -40,17 +41,55 @@ mcp_servers:
|
|
|
40
41
|
BRAINCLAW_AGENT: hermes
|
|
41
42
|
tools:
|
|
42
43
|
include:
|
|
43
|
-
- bclaw_work
|
|
44
44
|
- bclaw_context
|
|
45
|
+
- bclaw_work
|
|
45
46
|
- bclaw_find
|
|
46
47
|
- bclaw_get
|
|
47
48
|
- bclaw_create
|
|
48
49
|
- bclaw_update
|
|
50
|
+
- bclaw_remove
|
|
49
51
|
- bclaw_transition
|
|
52
|
+
- bclaw_move
|
|
53
|
+
- bclaw_session_start
|
|
54
|
+
- bclaw_session_end
|
|
55
|
+
- bclaw_claim
|
|
56
|
+
- bclaw_release_claim
|
|
57
|
+
- bclaw_add_step
|
|
58
|
+
- bclaw_complete_step
|
|
59
|
+
- bclaw_update_step
|
|
60
|
+
- bclaw_delete_step
|
|
61
|
+
- bclaw_list_sequences
|
|
62
|
+
- bclaw_create_sequence
|
|
63
|
+
- bclaw_update_sequence
|
|
64
|
+
- bclaw_delete_sequence
|
|
65
|
+
- bclaw_read_inbox
|
|
66
|
+
- bclaw_ack_message
|
|
67
|
+
- bclaw_send_message
|
|
68
|
+
- bclaw_correct_handoff
|
|
69
|
+
- bclaw_write_note
|
|
70
|
+
- bclaw_quick_capture
|
|
71
|
+
- bclaw_search
|
|
72
|
+
- bclaw_setup
|
|
73
|
+
- bclaw_bootstrap
|
|
74
|
+
- bclaw_switch
|
|
75
|
+
- bclaw_release_notes
|
|
76
|
+
- bclaw_coordinate
|
|
77
|
+
- bclaw_dispatch
|
|
78
|
+
- bclaw_loop
|
|
79
|
+
- bclaw_dispatch_status
|
|
80
|
+
- bclaw_assignment_update
|
|
81
|
+
- bclaw_code_find
|
|
82
|
+
- bclaw_code_brief
|
|
83
|
+
- bclaw_code_status
|
|
84
|
+
- bclaw_code_refresh
|
|
50
85
|
prompts: false
|
|
51
86
|
resources: false
|
|
52
87
|
```
|
|
53
88
|
|
|
89
|
+
When Brainclaw revisits an existing config, it upgrades the exact historical
|
|
90
|
+
seven-tool managed list. Any other `tools.include` array is treated as a user
|
|
91
|
+
customization and is preserved unchanged.
|
|
92
|
+
|
|
54
93
|
## Memory Boundary
|
|
55
94
|
|
|
56
95
|
Hermes skills are procedural memory: reusable ways to perform work. Brainclaw
|
package/docs/integrations/mcp.md
CHANGED
|
@@ -68,7 +68,7 @@ Each tool also has an `annotations.category` field: `session`, `context`, `memor
|
|
|
68
68
|
| `bclaw_context` | context | Unified context read for memory, execution, board, board summary, and deltas |
|
|
69
69
|
| `bclaw_coordinate` | coordination | Assign, consult, review, ideate, reroute, or summarize across agents |
|
|
70
70
|
| `bclaw_dispatch` | coordination | Analyze, execute, or review dispatch work through one intent-based entry point |
|
|
71
|
-
| `bclaw_loop` | loops | Drive
|
|
71
|
+
| `bclaw_loop` | loops | Drive review, ideation, implementation, research, or debug loops, including fenced physical-run takeover |
|
|
72
72
|
| `bclaw_setup` | session | Agent-driven onboarding wizard |
|
|
73
73
|
|
|
74
74
|
### Standard tools
|
|
@@ -86,7 +86,7 @@ Each tool also has an `annotations.category` field: `session`, `context`, `memor
|
|
|
86
86
|
| `bclaw_write_note` | memory | Record a runtime note |
|
|
87
87
|
| `bclaw_quick_capture` | memory | Capture text and classify it locally as a decision, trap, or runtime note |
|
|
88
88
|
| `bclaw_claim` | coordination | Claim a work scope (advisory lock, auto-worktree) |
|
|
89
|
-
| `bclaw_release_claim` | coordination | Release a claim, optionally updating linked plan status |
|
|
89
|
+
| `bclaw_release_claim` | coordination | Release a legacy/unsettled-independent claim, optionally updating linked plan status; v2 loop claims are released by settlement projections or audited coordinator override |
|
|
90
90
|
| `bclaw_session_start` | session | Start a session explicitly (granular workflow) |
|
|
91
91
|
| `bclaw_session_end` | session | End session, optionally auto-reflect notes or handoffs |
|
|
92
92
|
| `bclaw_add_step` | coordination | Add a sub-step to a plan item |
|
|
@@ -98,7 +98,7 @@ Each tool also has an `annotations.category` field: `session`, `context`, `memor
|
|
|
98
98
|
| `bclaw_update_sequence` | coordination | Update a sequence's status, metadata, or items |
|
|
99
99
|
| `bclaw_delete_sequence` | coordination | Delete a sequence by ID |
|
|
100
100
|
| `bclaw_correct_handoff` | coordination | Write an immutable correction handoff that supersedes an earlier one |
|
|
101
|
-
| `bclaw_assignment_update` | coordination | Report assignment lifecycle status |
|
|
101
|
+
| `bclaw_assignment_update` | coordination | Report assignment lifecycle status; v2 logical Assignments require the full generation fence and accept only accepted/started/progress before settlement |
|
|
102
102
|
| `bclaw_assignment_action` | coordination | Resolve or reject a pending ActionRequired item |
|
|
103
103
|
| `bclaw_harvest_candidates` | coordination | Harvest sandboxed worktree candidate files into the main project store |
|
|
104
104
|
| `bclaw_find` | memory | List canonical entities with filters |
|
|
@@ -399,7 +399,8 @@ bclaw_context({ kind: 'board_summary' })
|
|
|
399
399
|
// Review dispatch with structured loop
|
|
400
400
|
bclaw_dispatch({ intent: 'review', openLoop: true, reviewMode: 'symmetric' })
|
|
401
401
|
|
|
402
|
-
// Open a
|
|
402
|
+
// Open a single-agent ideation loop. Proposal is manual; critique, revision and
|
|
403
|
+
// synthesis are worker phases available through trusted turn(dispatch:true).
|
|
403
404
|
bclaw_coordinate({ intent: 'ideate', task: 'Should we extract the dispatcher into a separate package?' })
|
|
404
405
|
|
|
405
406
|
// Multi-agent ideation: critic gets a context-filtered, BM25-ranked brief auto-dispatched
|
|
@@ -409,15 +410,80 @@ bclaw_coordinate({
|
|
|
409
410
|
targetAgents: ['codex'],
|
|
410
411
|
})
|
|
411
412
|
|
|
413
|
+
// Open a direct implementation loop. The caller owns subsequent bind/turn
|
|
414
|
+
// actions, which is why allow_orphan is explicit. Bind is engine-only; after
|
|
415
|
+
// it advances to execute, turn(dispatch:true) is the worker launch path.
|
|
416
|
+
bclaw_loop({
|
|
417
|
+
intent: 'open',
|
|
418
|
+
kind: 'implementation',
|
|
419
|
+
title: 'Implement the extracted dispatcher',
|
|
420
|
+
allow_orphan: true,
|
|
421
|
+
linked: { plan_ids: ['pln_abc'], sequence_ids: ['seq_abc'] },
|
|
422
|
+
verify: { command: ['npm', 'test'] },
|
|
423
|
+
})
|
|
424
|
+
|
|
425
|
+
bclaw_loop({ intent: 'bind', loop_id: 'lop_abc' })
|
|
426
|
+
bclaw_loop({
|
|
427
|
+
intent: 'turn', loop_id: 'lop_abc', slot_id: 'lsl_worker',
|
|
428
|
+
dispatch: true, target_agents: ['codex', 'claude-code'],
|
|
429
|
+
})
|
|
430
|
+
|
|
431
|
+
// Direct research/debug loops use the same facade. A plain turn records state;
|
|
432
|
+
// trusted dispatch:true actually prepares, fences and launches a worker.
|
|
433
|
+
bclaw_loop({
|
|
434
|
+
intent: 'open',
|
|
435
|
+
kind: 'research',
|
|
436
|
+
title: 'Determine the safe migration boundary',
|
|
437
|
+
goal: 'Produce a sourced synthesis',
|
|
438
|
+
allow_orphan: true,
|
|
439
|
+
})
|
|
440
|
+
bclaw_loop({
|
|
441
|
+
intent: 'turn',
|
|
442
|
+
loop_id: 'lop_research',
|
|
443
|
+
slot_id: 'lsl_investigator',
|
|
444
|
+
dispatch: true,
|
|
445
|
+
target_agents: ['codex', 'claude-code'], // only used when the slot is unbound
|
|
446
|
+
})
|
|
447
|
+
|
|
448
|
+
bclaw_loop({
|
|
449
|
+
intent: 'open',
|
|
450
|
+
kind: 'debug',
|
|
451
|
+
title: 'Reproduce and fix the Windows dispatch failure',
|
|
452
|
+
allow_orphan: true,
|
|
453
|
+
})
|
|
454
|
+
bclaw_loop({ intent: 'turn', loop_id: 'lop_debug', slot_id: 'lsl_reproducer', dispatch: true })
|
|
455
|
+
|
|
456
|
+
// Fence a stale physical generation without changing the logical turn or Assignment.
|
|
457
|
+
// This arms the successor; dispatch the same turn afterwards to contend on launch.
|
|
458
|
+
bclaw_loop({
|
|
459
|
+
intent: 'takeover',
|
|
460
|
+
loop_id: 'lop_abc',
|
|
461
|
+
slot_id: 'lsl_abc',
|
|
462
|
+
turn_id: 'tat_abc',
|
|
463
|
+
expected_epoch: 0,
|
|
464
|
+
cause: 'heartbeat and process evidence are stale',
|
|
465
|
+
liveness_evidence: 'no heartbeat for 30m; wrapper exited',
|
|
466
|
+
external_effect_policy: 'idempotent',
|
|
467
|
+
next_workspace_path: 'C:\\worktrees\\brainclaw-retry-1',
|
|
468
|
+
agent: 'coordinator',
|
|
469
|
+
})
|
|
470
|
+
|
|
412
471
|
// Correct a handoff instead of mutating it
|
|
413
472
|
bclaw_correct_handoff({ originalId: 'hnd_xyz', reason: 'wrong contract', text: '...' })
|
|
414
473
|
```
|
|
415
474
|
|
|
416
|
-
For the full
|
|
417
|
-
|
|
418
|
-
[docs/concepts/ideation-loop.md](../concepts/ideation-loop.md).
|
|
419
|
-
the
|
|
420
|
-
|
|
475
|
+
For the full ideation loop design (phases, context filters, iteration block,
|
|
476
|
+
advance gate, brief assembly, single vs multi-agent UX), see
|
|
477
|
+
[docs/concepts/ideation-loop.md](../concepts/ideation-loop.md). The underlying
|
|
478
|
+
engine supports the five built-in `review`, `ideation`, `implementation`,
|
|
479
|
+
`research`, and `debug` workflows, plus cross-cutting `request_input` /
|
|
480
|
+
`provide_input`; see [docs/concepts/loop-engine.md](../concepts/loop-engine.md).
|
|
481
|
+
Takeover is likewise cross-cutting, not review-specific. Once a turn has an
|
|
482
|
+
AttemptAuthority v2 generation chain, terminal evidence must echo the complete
|
|
483
|
+
`assignment_id`, `turn_id`, `attempt_epoch`, `run_id`, `nonce`,
|
|
484
|
+
`execution_contract_hash`, and `workspace_digest` fence; a stale generation is
|
|
485
|
+
retained for audit but cannot converge loop state. See
|
|
486
|
+
[docs/concepts/attempt-authority.md](../concepts/attempt-authority.md).
|
|
421
487
|
|
|
422
488
|
#### Deprecation status
|
|
423
489
|
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Debug loop
|
|
2
|
+
|
|
3
|
+
> Loop kind: `debug`. One of five equal protocols driven by the shared
|
|
4
|
+
> [Loop Engine](../concepts/loop-engine.md). Identity, dispatch decisions and
|
|
5
|
+
> spawn authority belong to [`AttemptAuthority`](../concepts/attempt-authority.md);
|
|
6
|
+
> nothing on this page overrides them.
|
|
7
|
+
|
|
8
|
+
Worker results use `repro`, `hypothesis`, `isolation_report`, and
|
|
9
|
+
`verify_report` respectively. The mutating `fix` phase remains claimed until
|
|
10
|
+
`harvest --integrate`; the earlier read-only phases may converge on report.
|
|
11
|
+
|
|
12
|
+
## Purpose
|
|
13
|
+
|
|
14
|
+
A `debug` loop drives a broken system back to green. The invariant it
|
|
15
|
+
enforces: "bug fixed" ⟺ "the reproducing command is now green" ⟺ "a passing
|
|
16
|
+
`verify_report`". It mirrors [`implementation`](./implementation.md)'s
|
|
17
|
+
`execute ↔ verify` pattern but starts one step earlier: `reproduce` must
|
|
18
|
+
land a concrete repro before hypothesise-isolate-fix begins.
|
|
19
|
+
|
|
20
|
+
## Default protocol
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
reproduce → hypothesize ↔ isolate ↔ fix → handoff
|
|
24
|
+
└────── iterate (≤3) ─────┘
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
| Phase | Purpose | Artifact | Context filter |
|
|
28
|
+
|---|---|---|---|
|
|
29
|
+
| `reproduce` | Land a reliable repro of the bug | `repro` | `traps`, `runtime_notes`, `handoffs`, `plans` |
|
|
30
|
+
| `hypothesize` | Propose a cause | `hypothesis` | `decisions`, `constraints`, `traps`, `runtime_notes` |
|
|
31
|
+
| `isolate` | Narrow to a single change | `isolation_report` | `decisions`, `constraints`, `traps`, `runtime_notes` |
|
|
32
|
+
| `fix` | Apply the fix; re-run the repro | edits + `verify_report` | `traps`, `runtime_notes`, `constraints` |
|
|
33
|
+
| `handoff` | Ship the diff to review | `handoff` | `handoffs`, `plans` |
|
|
34
|
+
|
|
35
|
+
**Iteration.** `hypothesize ↔ isolate ↔ fix` cycles up to
|
|
36
|
+
`max_iterations: 3`. `exit_when: 'command_green'` — the same predicate
|
|
37
|
+
`implementation` uses — exits early on a passing `verify_report` in the
|
|
38
|
+
current iteration. `advance_when: 'all'` is the default.
|
|
39
|
+
|
|
40
|
+
## Entry points
|
|
41
|
+
|
|
42
|
+
- **Direct open (typical).**
|
|
43
|
+
`bclaw_loop(intent='open', kind='debug', linked={handoff_ids:[…]}, allow_orphan=true)`
|
|
44
|
+
followed by a `turn` for the `reproduce` phase. There is no coordinator
|
|
45
|
+
shortcut for `debug` today. Plain `turn` is state-only; trusted
|
|
46
|
+
`turn(dispatch=true)` launches a worker phase through the common
|
|
47
|
+
AttemptAuthority path.
|
|
48
|
+
- **Referred from `implementation`.** An `implementation` loop that
|
|
49
|
+
closes `blocked` at the cycle cap with a red `verify_report` is a
|
|
50
|
+
natural feeder — open a `debug` loop that links the red report as its
|
|
51
|
+
seed `repro` artifact.
|
|
52
|
+
|
|
53
|
+
## Advance gates
|
|
54
|
+
|
|
55
|
+
Two phases carry gates:
|
|
56
|
+
|
|
57
|
+
**`reproduce`** — cannot start hypothesising without a concrete repro:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
{ kind: 'artifact_produced', phase: 'reproduce', type: 'repro' }
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**`fix`** — cannot leave `fix` without a `verify_report` this iteration
|
|
64
|
+
(same shape as `implementation`'s verify gate):
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
{ kind: 'min_artifacts_by_type', type: 'verify_report', n: 1, scope: 'phase' }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Stop condition
|
|
71
|
+
|
|
72
|
+
```ts
|
|
73
|
+
{ kind: 'any', conditions: [
|
|
74
|
+
{ kind: 'artifact_produced', phase: 'handoff', type: 'handoff' },
|
|
75
|
+
{ kind: 'max_iterations', n: 3 },
|
|
76
|
+
] }
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
- **Handoff produced** → close `completed`. The handoff carries the diff
|
|
80
|
+
for a downstream `review` loop.
|
|
81
|
+
- **Cycle cap** → close `blocked`; the last red `verify_report` stays on
|
|
82
|
+
the loop as evidence. A human picks up.
|
|
83
|
+
|
|
84
|
+
## Artifacts
|
|
85
|
+
|
|
86
|
+
| Type | Phase | Body |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| `repro` | `reproduce` | inline ≤ 4 KB: the command / test / URL that fails, and the exit signature |
|
|
89
|
+
| `hypothesis` | `hypothesize` | inline ≤ 4 KB |
|
|
90
|
+
| `isolation_report` | `isolate` | inline ≤ 4 KB |
|
|
91
|
+
| `verify_report` | `fix` | inline JSON: `{ command, exit_code, passed, duration_ms?, stdout_tail?, stderr_tail? }` |
|
|
92
|
+
| `file_diff` | any phase | ref-based body (`{ref, byte_count, sha256}`) |
|
|
93
|
+
| `handoff` | `handoff` | `ref` to a `handoff` primitive |
|
|
94
|
+
|
|
95
|
+
## Routing
|
|
96
|
+
|
|
97
|
+
`debug` is claim-routed: `slot.claim_id` points at the scope claim the
|
|
98
|
+
fixer slot holds. The scope of the claim should cover the code under
|
|
99
|
+
investigation so the isolation and fix turns can edit freely.
|
|
100
|
+
`session_id` is observability-only.
|
|
101
|
+
|
|
102
|
+
## Recovery
|
|
103
|
+
|
|
104
|
+
- **Fixer worker crashed mid-cycle.** Launch grant lease expires;
|
|
105
|
+
`sweepExpiredLaunchGrants` revokes it; re-dispatch arms a new
|
|
106
|
+
generation at a strictly greater epoch. A prior-iteration
|
|
107
|
+
`verify_report` cannot satisfy the current iteration's gate.
|
|
108
|
+
- **Command-green mid-cycle.** `exit_when: 'command_green'`
|
|
109
|
+
short-circuits the cycle; the driver advances to `handoff` on the next
|
|
110
|
+
`advance`.
|
|
111
|
+
- **Reproduce blocked.** The `phase_advance_blocked` system event records
|
|
112
|
+
the missing `repro`. Add a repro artifact, or narrow the loop scope.
|
|
113
|
+
- **Red `verify_report` at cap.** Loop closes `blocked`; the accumulated
|
|
114
|
+
hypotheses, isolation reports, and red verify reports stay on the loop
|
|
115
|
+
so the next human or agent has the trail.
|
|
116
|
+
|
|
117
|
+
## When NOT to use
|
|
118
|
+
|
|
119
|
+
- **Building something new that doesn't reproduce anything.** Use
|
|
120
|
+
[`implementation`](./implementation.md).
|
|
121
|
+
- **Investigating an open-ended "why?" with no failing command.** Use
|
|
122
|
+
[`research`](./research.md).
|
|
123
|
+
- **Choosing between two architectural fixes.** Use
|
|
124
|
+
[`ideation`](./ideation.md) to pressure the choice against project
|
|
125
|
+
memory first.
|
|
126
|
+
- **Validating a landed fix.** Use [`review`](./review.md); the
|
|
127
|
+
`handoff` a debug loop emits is exactly what a review loop consumes.
|
|
128
|
+
|
|
129
|
+
## Reference implementation
|
|
130
|
+
|
|
131
|
+
| Component | File |
|
|
132
|
+
|---|---|
|
|
133
|
+
| Default protocol | [`src/core/loops/types.ts`](../../src/core/loops/types.ts) (`DEFAULT_PROTOCOLS.debug`) |
|
|
134
|
+
| Iteration FSM (`command_green`) | [`src/core/loops/iteration-engine.ts`](../../src/core/loops/iteration-engine.ts) |
|
|
135
|
+
| Gate evaluator | [`src/core/loops/verbs.ts`](../../src/core/loops/verbs.ts) (`evaluatePhaseAdvanceGate`) |
|
|
136
|
+
| Attempt + execution policy | [`src/core/loops/attempt-authority.ts`](../../src/core/loops/attempt-authority.ts), [`src/core/loops/kind-policies.ts`](../../src/core/loops/kind-policies.ts) |
|
|
137
|
+
| Result reducer | [`src/core/loops/result-reducers.ts`](../../src/core/loops/result-reducers.ts) |
|
|
138
|
+
| Tests | [`tests/unit/loops-iteration-engine.test.ts`](../../tests/unit/loops-iteration-engine.test.ts), [`tests/unit/loops-phase-advance-gate.test.ts`](../../tests/unit/loops-phase-advance-gate.test.ts), [`tests/unit/loops-impl-protocol.test.ts`](../../tests/unit/loops-impl-protocol.test.ts) |
|
|
139
|
+
|
|
140
|
+
## Related
|
|
141
|
+
|
|
142
|
+
- [Loop Engine](../concepts/loop-engine.md)
|
|
143
|
+
- [Attempt authority](../concepts/attempt-authority.md)
|
|
144
|
+
- [dispatch-lifecycle.md](../concepts/dispatch-lifecycle.md)
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
# Ideation loop
|
|
2
|
+
|
|
3
|
+
> Loop kind: `ideation`. One of five equal protocols driven by the shared
|
|
4
|
+
> [Loop Engine](../concepts/loop-engine.md). Identity, dispatch decisions and
|
|
5
|
+
> spawn authority belong to [`AttemptAuthority`](../concepts/attempt-authority.md);
|
|
6
|
+
> nothing on this page overrides them.
|
|
7
|
+
|
|
8
|
+
The automated critic returns `artifact_type: "critique"` with a non-empty
|
|
9
|
+
`body`. A narrative `summary` alone never creates a critique or opens the gate.
|
|
10
|
+
|
|
11
|
+
## Purpose
|
|
12
|
+
|
|
13
|
+
An `ideation` loop stress-tests a proposal **before** it crystallises into a
|
|
14
|
+
plan. Where [`review`](./review.md) validates a finished artifact and asks
|
|
15
|
+
"is this good?", `ideation` takes a fresh proposal and asks "what does our
|
|
16
|
+
accumulated project experience say will go wrong with this?"
|
|
17
|
+
|
|
18
|
+
The adversarial substrate is the project's own memory — traps, feedback
|
|
19
|
+
memos, runtime notes. Even a single-agent run produces useful pressure
|
|
20
|
+
because the phase context filter forces the critic to confront adversarial
|
|
21
|
+
memory rather than the positive context that seeded the proposal. See
|
|
22
|
+
[ideation-loop.md](../concepts/ideation-loop.md) for the full RFC-level
|
|
23
|
+
design; this page is the operator-facing summary.
|
|
24
|
+
|
|
25
|
+
## Default protocol
|
|
26
|
+
|
|
27
|
+
```
|
|
28
|
+
proposal → critique ↔ revision → synthesis
|
|
29
|
+
└─── iterate (≤3) ────┘
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
| Phase | Purpose | Artifact | Context filter |
|
|
33
|
+
|---|---|---|---|
|
|
34
|
+
| `proposal` | Seed: the original idea | `proposal` (text ≤ 4 KB) | `decisions`, `constraints`, `plans`, `project_vision` |
|
|
35
|
+
| `critique` | Adversarial review against project memory | `critique` (repeatable) | `traps`, `feedback`, `runtime_notes`, `critique_history` |
|
|
36
|
+
| `revision` | Champion responds to the critique batch | `revision` | `*` |
|
|
37
|
+
| `synthesis` | Fold the cycle's outputs into a plan draft | `plan_draft` | `*` |
|
|
38
|
+
|
|
39
|
+
**Iteration.** `critique ↔ revision` iterates up to
|
|
40
|
+
`max_iterations: 3`; `exit_when: 'no_new_critique_artifacts'` stops the cycle
|
|
41
|
+
when a full round adds no new critique. `critic_signal` is available for
|
|
42
|
+
explicit early exit.
|
|
43
|
+
|
|
44
|
+
## Entry points
|
|
45
|
+
|
|
46
|
+
- **Coordinator shortcut (recommended).**
|
|
47
|
+
`bclaw_coordinate(intent='ideate', task=…, [targetAgents=[…]])` opens the
|
|
48
|
+
loop with a `champion` slot (caller) and one `critic` slot per target
|
|
49
|
+
agent, stores `task` as the `proposal` artifact, advances to `critique`
|
|
50
|
+
in multi-agent mode, and dispatches the first critic with a brief
|
|
51
|
+
assembled by [`buildIdeationBrief`](../../src/core/loops/brief-assembly.ts).
|
|
52
|
+
- **Single-agent mode** — omit `targetAgents`. The champion drives each
|
|
53
|
+
turn via `bclaw_loop(intent='turn'|'advance')`. A plain `turn` only records
|
|
54
|
+
the assignment; on a worker phase, a trusted caller can set
|
|
55
|
+
`dispatch=true` to launch through AttemptAuthority. Useful when you want the
|
|
56
|
+
loop's structure (memory filter, gate, iteration accounting) without the
|
|
57
|
+
coordinator shortcut.
|
|
58
|
+
- **Direct open.** `bclaw_loop(intent='open', kind='ideation', allow_orphan=true)`.
|
|
59
|
+
|
|
60
|
+
## Advance gates
|
|
61
|
+
|
|
62
|
+
The `critique` phase carries a default `advance_gate`:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
{ kind: 'min_artifacts_by_type', type: 'critique', n: 3, scope: 'phase' }
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Advance to `revision` is refused until at least 3 `critique` artifacts have
|
|
69
|
+
been produced **in the current iteration window**. A previous round's
|
|
70
|
+
critiques do not satisfy the gate for a new round. On gate failure, the
|
|
71
|
+
driver emits a `phase_advance_blocked` system event with a structured
|
|
72
|
+
`gate_reason` and throws an actionable error.
|
|
73
|
+
|
|
74
|
+
## Stop condition
|
|
75
|
+
|
|
76
|
+
```ts
|
|
77
|
+
{ kind: 'artifact_produced', phase: 'synthesis', type: 'plan_draft' }
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The loop closes `completed` on the first `plan_draft` artifact in
|
|
81
|
+
`synthesis`. Override via
|
|
82
|
+
`bclaw_loop(intent='open', stop_condition: …)` — e.g. a
|
|
83
|
+
`min_artifacts_by_type { type: 'critique', n: 5, scope: 'loop' }` stops after
|
|
84
|
+
five critiques have accumulated loop-wide.
|
|
85
|
+
|
|
86
|
+
## Artifacts
|
|
87
|
+
|
|
88
|
+
| Type | Phase | Body |
|
|
89
|
+
|---|---|---|
|
|
90
|
+
| `proposal` | `proposal` | inline text ≤ 4 KB |
|
|
91
|
+
| `critique` | `critique` | inline ≤ 4 KB; must cite memory ids used |
|
|
92
|
+
| `revision` | `revision` | inline ≤ 4 KB |
|
|
93
|
+
| `plan_draft` | `synthesis` | inline ≤ 4 KB; MUST carry `addresses_critique: [artifact_id, …]` |
|
|
94
|
+
| `critic_signal` | `critique` | inline ≤ 4 KB; opts an explicit early cycle exit |
|
|
95
|
+
|
|
96
|
+
`plan_draft` field-presence is enforced at the zod level on
|
|
97
|
+
`LoopArtifactSchema` — a synthesis that omits `addresses_critique` is
|
|
98
|
+
rejected at write time.
|
|
99
|
+
|
|
100
|
+
## Brief assembly
|
|
101
|
+
|
|
102
|
+
Each critic turn ships a size-capped brief (48 KB) with a BM25-ranked
|
|
103
|
+
memory bundle scoped to the phase's `context_filter`. When the bundle
|
|
104
|
+
overflows, the assembler appends a truncation tail and surfaces `truncated`,
|
|
105
|
+
`includedItems`, and `droppedItems` per-slot. This mitigates
|
|
106
|
+
[trp#179](../../src/core/loops/brief-assembly.ts) — oversized bundles push
|
|
107
|
+
agents onto CLI tools instead of MCP semantics.
|
|
108
|
+
|
|
109
|
+
## Routing
|
|
110
|
+
|
|
111
|
+
`ideation` routes turns by `slot_id`; the coordinator shortcut queues a
|
|
112
|
+
message per critic with the brief as body and
|
|
113
|
+
`{intent: 'ideate', loop_id, slot_id, phase, iteration, proposal_artifact_id}`
|
|
114
|
+
as payload. Dispatch failures per slot surface as `partial`; the loop stays
|
|
115
|
+
at the proposal phase and callers can retry manually.
|
|
116
|
+
|
|
117
|
+
## Recovery
|
|
118
|
+
|
|
119
|
+
- **Critic worker crashed mid-turn.** Launch grant lease expires;
|
|
120
|
+
`sweepExpiredLaunchGrants` revokes it; the coordinator can re-dispatch
|
|
121
|
+
with a fresh generation.
|
|
122
|
+
- **Gate blocked at critique.** The `phase_advance_blocked` system event
|
|
123
|
+
records the structured reason. Champion adds more `critique` artifacts,
|
|
124
|
+
or overrides the gate on `open` for a permissive one-shot run.
|
|
125
|
+
- **Cycle cap hit without saturation.** `iteration-engine` emits
|
|
126
|
+
`max_iterations_reached`; the driver moves to `synthesis` regardless.
|
|
127
|
+
- **Synthesis missing `addresses_critique`.** Rejected at
|
|
128
|
+
`complete_turn` — the champion re-emits with the ids populated.
|
|
129
|
+
|
|
130
|
+
## When NOT to use
|
|
131
|
+
|
|
132
|
+
- **Quick clarification.** A 2-turn message thread is cheaper.
|
|
133
|
+
- **Operationally urgent decisions.** The iteration block adds latency —
|
|
134
|
+
use `bclaw_coordinate(intent='consult')` for "the build is broken".
|
|
135
|
+
- **A domain with no accumulated project memory.** The critic will fetch
|
|
136
|
+
nothing and the brief will be a no-op; seed memory first, or run a
|
|
137
|
+
literal multi-agent loop where the critic brings its own perspective.
|
|
138
|
+
- **Validating a change that already exists.** Use
|
|
139
|
+
[`review`](./review.md).
|
|
140
|
+
|
|
141
|
+
## Reference implementation
|
|
142
|
+
|
|
143
|
+
| Component | File |
|
|
144
|
+
|---|---|
|
|
145
|
+
| Default protocol | [`src/core/loops/types.ts`](../../src/core/loops/types.ts) (`DEFAULT_PROTOCOLS.ideation`) |
|
|
146
|
+
| Iteration FSM | [`src/core/loops/iteration-engine.ts`](../../src/core/loops/iteration-engine.ts) |
|
|
147
|
+
| Gate evaluator | [`src/core/loops/verbs.ts`](../../src/core/loops/verbs.ts) (`evaluatePhaseAdvanceGate`) |
|
|
148
|
+
| Brief assembler | [`src/core/loops/brief-assembly.ts`](../../src/core/loops/brief-assembly.ts) |
|
|
149
|
+
| Driver | [`src/commands/mcp-write-coordination.ts`](../../src/commands/mcp-write-coordination.ts) (`req.intent === 'ideate'`) |
|
|
150
|
+
| Attempt + execution policy | [`src/core/loops/attempt-authority.ts`](../../src/core/loops/attempt-authority.ts), [`src/core/loops/kind-policies.ts`](../../src/core/loops/kind-policies.ts) |
|
|
151
|
+
| Result reducer | [`src/core/loops/result-reducers.ts`](../../src/core/loops/result-reducers.ts) |
|
|
152
|
+
| Tests | [`tests/unit/loops-iteration-engine.test.ts`](../../tests/unit/loops-iteration-engine.test.ts), [`tests/unit/loops-phase-advance-gate.test.ts`](../../tests/unit/loops-phase-advance-gate.test.ts), [`tests/unit/loops-brief-assembly.test.ts`](../../tests/unit/loops-brief-assembly.test.ts), [`tests/unit/ideation-loop-e2e.test.ts`](../../tests/unit/ideation-loop-e2e.test.ts) |
|
|
153
|
+
|
|
154
|
+
## Related
|
|
155
|
+
|
|
156
|
+
- [Loop Engine](../concepts/loop-engine.md)
|
|
157
|
+
- [Attempt authority](../concepts/attempt-authority.md)
|
|
158
|
+
- [ideation-loop.md](../concepts/ideation-loop.md) — full RFC
|