brainclaw 1.26.2 → 1.28.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 +13 -0
- 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 +143 -15
- package/dist/commands/mcp-catalog.js +52 -18
- package/dist/commands/mcp-schemas.generated.js +64 -0
- package/dist/commands/mcp-write-claims.js +128 -1
- package/dist/commands/mcp-write-coordination.js +149 -76
- package/dist/core/agent-capability.js +1 -1
- 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 +189 -14
- package/dist/core/execution-contract.js +345 -0
- package/dist/core/execution.js +130 -16
- package/dist/core/facade-schema.js +3 -0
- 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 +235 -0
- package/dist/core/loops/artifact-contract.js +11 -0
- package/dist/core/loops/attempt-authority.js +496 -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/brief-assembly.js +21 -4
- package/dist/core/loops/evidence.js +188 -0
- package/dist/core/loops/facade-schema.js +75 -11
- package/dist/core/loops/gate-policy.js +533 -0
- package/dist/core/loops/impl-bind.js +91 -81
- 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 +237 -18
- package/dist/core/loops/result-reducers.js +113 -10
- package/dist/core/loops/store.js +34 -3
- package/dist/core/loops/turn-execution.js +480 -0
- package/dist/core/loops/types.js +127 -3
- package/dist/core/loops/verbs.js +335 -99
- package/dist/core/loops/verify-command.js +105 -20
- package/dist/core/loops/workspace-digest.js +54 -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 +40 -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/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 +302 -113
- package/docs/index.md +4 -1
- package/docs/integrations/codex.md +3 -3
- package/docs/integrations/mcp.md +59 -5
- package/docs/loops/debug.md +144 -0
- package/docs/loops/ideation.md +158 -0
- package/docs/loops/implementation.md +174 -0
- package/docs/loops/research.md +136 -0
- package/docs/loops/review.md +200 -0
- package/docs/mcp-schema-changelog.md +18 -5
- 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"`.
|
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
|
|
@@ -410,7 +411,8 @@ bclaw_coordinate({
|
|
|
410
411
|
})
|
|
411
412
|
|
|
412
413
|
// Open a direct implementation loop. The caller owns subsequent bind/turn
|
|
413
|
-
// actions, which is why allow_orphan is explicit.
|
|
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.
|
|
414
416
|
bclaw_loop({
|
|
415
417
|
intent: 'open',
|
|
416
418
|
kind: 'implementation',
|
|
@@ -420,6 +422,52 @@ bclaw_loop({
|
|
|
420
422
|
verify: { command: ['npm', 'test'] },
|
|
421
423
|
})
|
|
422
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
|
+
|
|
423
471
|
// Correct a handoff instead of mutating it
|
|
424
472
|
bclaw_correct_handoff({ originalId: 'hnd_xyz', reason: 'wrong contract', text: '...' })
|
|
425
473
|
```
|
|
@@ -430,6 +478,12 @@ advance gate, brief assembly, single vs multi-agent UX), see
|
|
|
430
478
|
engine supports the five built-in `review`, `ideation`, `implementation`,
|
|
431
479
|
`research`, and `debug` workflows, plus cross-cutting `request_input` /
|
|
432
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).
|
|
433
487
|
|
|
434
488
|
#### Deprecation status
|
|
435
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
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Implementation loop
|
|
2
|
+
|
|
3
|
+
> Loop kind: `implementation`. 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 `execute` worker returns `artifact_type: "execute_report"`. Because this
|
|
9
|
+
phase edits its worktree, report-only harvest does not settle the turn or
|
|
10
|
+
release its claim; convergence happens after `harvest --integrate`.
|
|
11
|
+
|
|
12
|
+
## Purpose
|
|
13
|
+
|
|
14
|
+
An `implementation` loop drives a bound plan+sequence to a green
|
|
15
|
+
verification command. It ADDS to the dispatch pipeline what that pipeline
|
|
16
|
+
lacked: a deterministic `command_green` gate, a bounded `execute ↔ verify`
|
|
17
|
+
cycle, and per-phase context sculpting. `bind` is an engine-only action: it
|
|
18
|
+
validates the plan/sequence link and advances to `execute`. It never launches
|
|
19
|
+
a worker. `execute ↔ verify` iterates until the verify command is green or
|
|
20
|
+
the cycle cap is hit.
|
|
21
|
+
|
|
22
|
+
Binding validates the complete graph: every sequence item must reference a
|
|
23
|
+
linked, existing plan (and an existing step when `stepId` is present). Explicit
|
|
24
|
+
sequence lanes are paired deterministically with worker slots, one slot per
|
|
25
|
+
lane. Each slot then carries its lane, plan/step ids, and `scope_hint`.
|
|
26
|
+
|
|
27
|
+
## Default protocol
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
bind → execute ↔ verify → handoff_ready
|
|
31
|
+
└── iterate (≤3) ───┘
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
| Phase | Purpose | Artifact | Context filter |
|
|
35
|
+
|---|---|---|---|
|
|
36
|
+
| `bind` | Validate the linked plan + sequence; advance to `execute` | link already stored on the loop | `plans`, `decisions`, `constraints`, `project_vision` |
|
|
37
|
+
| `execute` | Apply the sequence's steps in the worktree | edits + `execute_report` | `decisions`, `constraints`, `traps`, `runtime_notes` |
|
|
38
|
+
| `verify` | Run the declared verify command | `verify_report` | `traps`, `runtime_notes` |
|
|
39
|
+
| `handoff_ready` | Produce the handoff for downstream review | `handoff` | `handoffs`, `plans` |
|
|
40
|
+
|
|
41
|
+
**Iteration.** `execute ↔ verify` cycles up to `max_iterations: 3`.
|
|
42
|
+
`exit_when: 'command_green'` exits early on a passing `verify_report` in the
|
|
43
|
+
current iteration. `advance_when: 'all'` on each phase means every
|
|
44
|
+
participating slot must produce its expected artifact before advance fires.
|
|
45
|
+
|
|
46
|
+
## Entry points
|
|
47
|
+
|
|
48
|
+
- **Direct open (typical).**
|
|
49
|
+
`bclaw_loop(intent='open', kind='implementation', slots=[…], linked={plan_ids:[…], sequence_ids:[…]}, allow_orphan=true)`
|
|
50
|
+
followed by `bind`. `allow_orphan=true` acknowledges that the caller will
|
|
51
|
+
drive worker turns.
|
|
52
|
+
- **Via bind.** `bclaw_loop(intent='bind', loop_id=…)` validates the linked
|
|
53
|
+
sequence and advances `bind → execute`. Historical launch options
|
|
54
|
+
(`lanes`, `auto_execute`, `model`, `max_assignments`) remain accepted
|
|
55
|
+
during rollout but are ignored; the response carries a migration warning.
|
|
56
|
+
- **Explicit worker turn.** In `execute`, trusted
|
|
57
|
+
`bclaw_loop(intent='turn', loop_id=…, slot_id=…, dispatch=true)` is the only
|
|
58
|
+
worker launch path and uses the common AttemptAuthority fence. Independent
|
|
59
|
+
slots may be dispatched concurrently. Without `dispatch=true`, `turn` is
|
|
60
|
+
state-only and never starts a process.
|
|
61
|
+
|
|
62
|
+
## Advance gates
|
|
63
|
+
|
|
64
|
+
`verify` carries an `advance_gate`:
|
|
65
|
+
|
|
66
|
+
```ts
|
|
67
|
+
{ kind: 'min_artifacts_by_type', type: 'verify_report', n: 1, scope: 'phase' }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Advance cannot leave `verify` without a `verify_report` artifact **this
|
|
71
|
+
iteration** — this guards the narrated-verify anti-pattern where a slot
|
|
72
|
+
claims it verified without actually running the command. `command_green` in
|
|
73
|
+
the iteration engine reads the reports produced against this gate.
|
|
74
|
+
|
|
75
|
+
For bound lanes, call `bclaw_loop(intent='verify', slot_id=…)`. The command
|
|
76
|
+
runs in that slot assignment's worktree. Omitting `slot_id` when several lane
|
|
77
|
+
worktrees exist fails closed, and `command_green` requires a current-iteration
|
|
78
|
+
green report from every bound lane.
|
|
79
|
+
|
|
80
|
+
## Stop condition
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
{ kind: 'any', conditions: [
|
|
84
|
+
{ kind: 'artifact_produced', phase: 'handoff_ready', type: 'handoff' },
|
|
85
|
+
{ kind: 'max_iterations', n: 3 },
|
|
86
|
+
] }
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- **Handoff produced** → close `completed`. The handoff is the downstream
|
|
90
|
+
consumer's entry point.
|
|
91
|
+
- **Cycle cap** → close `blocked`; the last red `verify_report` is
|
|
92
|
+
attached so a human or a `debug` loop can pick up.
|
|
93
|
+
|
|
94
|
+
## Artifacts
|
|
95
|
+
|
|
96
|
+
| Type | Phase | Body |
|
|
97
|
+
|---|---|---|
|
|
98
|
+
| `execute_report` | `execute` | inline text ≤ 4 KB, or ref-based when large |
|
|
99
|
+
| `verify_report` | `verify` | inline JSON: `{ command, exit_code, passed, duration_ms?, stdout_tail?, stderr_tail? }` |
|
|
100
|
+
| `file_diff` | any phase | ref-based body (`{ref, byte_count, sha256}`) |
|
|
101
|
+
| `handoff` | `handoff_ready` | `ref` to a `handoff` primitive |
|
|
102
|
+
|
|
103
|
+
## Routing
|
|
104
|
+
|
|
105
|
+
`implementation` is claim-routed: each worker `slot.claim_id` points at the
|
|
106
|
+
scope claim created by `turn(dispatch=true)`, and the common driver runs in
|
|
107
|
+
the worktree bound to that claim. `bind` creates neither claim nor assignment.
|
|
108
|
+
`session_id` is observability-only.
|
|
109
|
+
Dispatch also uses the bound `scope_hint` to retrieve only path-related
|
|
110
|
+
decisions, constraints, traps and runtime context (while retaining unscoped
|
|
111
|
+
project-wide memory).
|
|
112
|
+
[Attempt authority](../concepts/attempt-authority.md#ordered-dispatch)
|
|
113
|
+
mints a deterministic `turn_id` from `(loop_id, slot_id, iteration)` on
|
|
114
|
+
every dispatch, so a concurrent re-dispatch hits `reservation_exists` and
|
|
115
|
+
adopts the existing attempt. If a reusable slot has already spent that legacy
|
|
116
|
+
identity in another worker phase of the same iteration, the common resolver
|
|
117
|
+
uses `(loop_id, slot_id, phase, iteration)` for a versioned successor logical
|
|
118
|
+
turn. This is a Loop Engine rule shared by every kind, not implementation-loop
|
|
119
|
+
special handling.
|
|
120
|
+
|
|
121
|
+
At `handoff_ready`, the facade emits a structured `next_actions` call for
|
|
122
|
+
`bclaw_coordinate(intent='review', open_loop=true)`. It remains explicit: the
|
|
123
|
+
engine does not invent a reviewer or silently mutate external state. The
|
|
124
|
+
created review loop persists `linked.source_loop_id`, while the implementation
|
|
125
|
+
loop received the same provenance from its ideation source, so `list/get`
|
|
126
|
+
surfaces the pipeline chain without a separate registry.
|
|
127
|
+
|
|
128
|
+
## Recovery
|
|
129
|
+
|
|
130
|
+
- **Execute worker crashed mid-iteration.** Launch grant lease expires;
|
|
131
|
+
`sweepExpiredLaunchGrants` revokes it; a re-dispatch arms a new
|
|
132
|
+
generation at a strictly greater epoch. Because `execute_report` and
|
|
133
|
+
`verify_report` are per-iteration, a prior-iteration report never
|
|
134
|
+
satisfies the current iteration's gate.
|
|
135
|
+
- **`verify_report` red at cap.** Loop closes `blocked`; the last red
|
|
136
|
+
`verify_report` and the accumulated `execute_report`s stay on the loop
|
|
137
|
+
as evidence.
|
|
138
|
+
- **Command-green mid-cycle.** `exit_when: 'command_green'` short-circuits
|
|
139
|
+
the cycle; the driver advances to `handoff_ready` on the next `advance`.
|
|
140
|
+
- **Stale worker LANE-RESULT resurfaces after a cycle bump.**
|
|
141
|
+
`evidenceMatchesAttempt` rejects it — the current-generation nonce no
|
|
142
|
+
longer matches the stale token.
|
|
143
|
+
|
|
144
|
+
## When NOT to use
|
|
145
|
+
|
|
146
|
+
- **Debugging an already-broken build.** Use [`debug`](./debug.md) — its
|
|
147
|
+
`reproduce` phase gives you a repro artifact the fix rides on, and its
|
|
148
|
+
`command_green` gate is the same shape.
|
|
149
|
+
- **Validating a change that already exists.** Use
|
|
150
|
+
[`review`](./review.md).
|
|
151
|
+
- **Choosing between architectural options.** Use
|
|
152
|
+
[`ideation`](./ideation.md) — an implementation loop with no plan is
|
|
153
|
+
empty.
|
|
154
|
+
- **Open-ended discovery.** Use [`research`](./research.md).
|
|
155
|
+
|
|
156
|
+
## Reference implementation
|
|
157
|
+
|
|
158
|
+
| Component | File |
|
|
159
|
+
|---|---|
|
|
160
|
+
| Default protocol | [`src/core/loops/types.ts`](../../src/core/loops/types.ts) (`DEFAULT_PROTOCOLS.implementation`) |
|
|
161
|
+
| Bind action | [`src/core/loops/impl-bind.ts`](../../src/core/loops/impl-bind.ts) (`runImplBind`) |
|
|
162
|
+
| Common worker driver | [`src/core/loop-turn-dispatch.ts`](../../src/core/loop-turn-dispatch.ts) (`dispatchLoopTurn`) |
|
|
163
|
+
| Iteration FSM (command_green) | [`src/core/loops/iteration-engine.ts`](../../src/core/loops/iteration-engine.ts) |
|
|
164
|
+
| Attempt authority | [`src/core/loops/attempt-authority.ts`](../../src/core/loops/attempt-authority.ts) |
|
|
165
|
+
| Turn execution policy | [`src/core/loops/kind-policies.ts`](../../src/core/loops/kind-policies.ts), [`src/core/loops/turn-execution.ts`](../../src/core/loops/turn-execution.ts) |
|
|
166
|
+
| Result reducer | [`src/core/loops/result-reducers.ts`](../../src/core/loops/result-reducers.ts) |
|
|
167
|
+
| Tests | [`tests/unit/loops-impl-bind.test.ts`](../../tests/unit/loops-impl-bind.test.ts), [`tests/unit/loops-impl-protocol.test.ts`](../../tests/unit/loops-impl-protocol.test.ts), [`tests/unit/loops-gate-content-integrity.test.ts`](../../tests/unit/loops-gate-content-integrity.test.ts) |
|
|
168
|
+
|
|
169
|
+
## Related
|
|
170
|
+
|
|
171
|
+
- [Loop Engine](../concepts/loop-engine.md)
|
|
172
|
+
- [Attempt authority](../concepts/attempt-authority.md)
|
|
173
|
+
- [plans-and-claims.md](../concepts/plans-and-claims.md)
|
|
174
|
+
- [dispatch-lifecycle.md](../concepts/dispatch-lifecycle.md)
|