brainclaw 1.16.0 → 1.18.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 (85) hide show
  1. package/README.md +22 -8
  2. package/dist/brainclaw-vscode.vsix +0 -0
  3. package/dist/cli/register-review.js +2 -2
  4. package/dist/commands/code-map.js +4 -1
  5. package/dist/commands/codev.js +61 -30
  6. package/dist/commands/doctor.js +14 -1
  7. package/dist/commands/harvest.js +241 -25
  8. package/dist/commands/inbox.js +10 -4
  9. package/dist/commands/loop.js +2 -2
  10. package/dist/commands/loops-handlers.js +82 -1
  11. package/dist/commands/mcp-catalog.js +12 -4
  12. package/dist/commands/mcp-read-handlers.js +90 -7
  13. package/dist/commands/mcp-schemas.generated.js +3 -0
  14. package/dist/commands/mcp-write-coordination.js +159 -40
  15. package/dist/commands/mcp.js +11 -2
  16. package/dist/core/agent-capability.js +7 -2
  17. package/dist/core/agent-files.js +53 -2
  18. package/dist/core/agent-integrations.js +1 -0
  19. package/dist/core/agentrun-reconciler.js +171 -7
  20. package/dist/core/agentruns.js +6 -1
  21. package/dist/core/code-map/aggregate.js +473 -0
  22. package/dist/core/code-map/backend.js +36 -10
  23. package/dist/core/code-map/freshness.js +36 -1
  24. package/dist/core/code-map/lang/c/imports.scm +12 -0
  25. package/dist/core/code-map/lang/c/index.js +150 -0
  26. package/dist/core/code-map/lang/c/tags.scm +68 -0
  27. package/dist/core/code-map/lang/cpp/imports.scm +14 -0
  28. package/dist/core/code-map/lang/cpp/index.js +149 -0
  29. package/dist/core/code-map/lang/cpp/tags.scm +87 -0
  30. package/dist/core/code-map/lang/csharp/imports.scm +20 -0
  31. package/dist/core/code-map/lang/csharp/index.js +224 -0
  32. package/dist/core/code-map/lang/csharp/tags.scm +63 -0
  33. package/dist/core/code-map/lang/go/imports.scm +13 -0
  34. package/dist/core/code-map/lang/go/index.js +139 -0
  35. package/dist/core/code-map/lang/go/tags.scm +36 -0
  36. package/dist/core/code-map/lang/providers.js +12 -1
  37. package/dist/core/code-map/lang/ruby/imports.scm +24 -0
  38. package/dist/core/code-map/lang/ruby/index.js +198 -0
  39. package/dist/core/code-map/lang/ruby/tags.scm +49 -0
  40. package/dist/core/code-map/lang/rust/imports.scm +44 -0
  41. package/dist/core/code-map/lang/rust/index.js +136 -0
  42. package/dist/core/code-map/lang/rust/tags.scm +47 -0
  43. package/dist/core/code-map/query.js +229 -80
  44. package/dist/core/code-map/types.js +18 -0
  45. package/dist/core/code-map/work-section.js +8 -7
  46. package/dist/core/codev-responses.js +16 -0
  47. package/dist/core/dispatcher.js +209 -29
  48. package/dist/core/execution-adapters.js +29 -3
  49. package/dist/core/ideation-loop-close.js +124 -0
  50. package/dist/core/loops/artifact-resolver.js +197 -0
  51. package/dist/core/loops/attempt-reservation.js +576 -0
  52. package/dist/core/loops/commit-intent.js +494 -0
  53. package/dist/core/loops/facade-schema.js +48 -0
  54. package/dist/core/loops/impl-bind.js +144 -0
  55. package/dist/core/loops/index.js +1 -1
  56. package/dist/core/loops/iteration-engine.js +29 -0
  57. package/dist/core/loops/lock.js +14 -0
  58. package/dist/core/loops/project-resolution.js +157 -0
  59. package/dist/core/loops/reconcile-turn.js +369 -0
  60. package/dist/core/loops/result-reducers.js +88 -0
  61. package/dist/core/loops/store.js +46 -7
  62. package/dist/core/loops/types.js +139 -11
  63. package/dist/core/loops/verbs.js +9 -3
  64. package/dist/core/loops/verify-command.js +209 -0
  65. package/dist/core/messaging.js +58 -5
  66. package/dist/core/review-loop-close.js +106 -34
  67. package/dist/core/review-loop-turn-dispatch.js +445 -0
  68. package/dist/core/runtime-signals.js +68 -0
  69. package/dist/core/schema.js +34 -0
  70. package/dist/core/worktree.js +240 -22
  71. package/dist/facts.js +10 -10
  72. package/dist/facts.json +9 -9
  73. package/dist/wasm/tree-sitter-c.wasm +0 -0
  74. package/dist/wasm/tree-sitter-c_sharp.wasm +0 -0
  75. package/dist/wasm/tree-sitter-cpp.wasm +0 -0
  76. package/dist/wasm/tree-sitter-go.wasm +0 -0
  77. package/dist/wasm/tree-sitter-ruby.wasm +0 -0
  78. package/dist/wasm/tree-sitter-rust.wasm +0 -0
  79. package/docs/cli.md +1 -1
  80. package/docs/code-map.md +22 -6
  81. package/docs/concepts/loop-engine.md +28 -2
  82. package/docs/concepts/observer-protocol.md +22 -0
  83. package/docs/integrations/codex.md +19 -3
  84. package/docs/mcp-schema-changelog.md +43 -1
  85. package/package.json +1 -1
@@ -330,9 +330,11 @@ When `bclaw_coordinate(intent='review', open_loop: true)` is called, it:
330
330
  3. Links the provided handoff/candidate to the loop as an artifact at `change_summary`.
331
331
  4. Advances to `findings` and calls `bclaw_loop(intent: 'turn')` to dispatch to the reviewer.
332
332
  5. On turn completion with a verdict artifact, auto-advances; `reviewer_green` stop closes.
333
- 6. On non-green verdict with `iteration_count < max`, advances to `author_response`, dispatches to author.
333
+ 6. On a `request_changes` verdict, the fix cycle re-dispatches the reviewer into the same worktree until `approve` or the `max_iterations` cap.
334
334
 
335
- **How the verdict reaches the loop (shipped, pln#628 Focus 4B).** A dispatched reviewer worker does not call `bclaw_loop` itself — it writes its outcome to `LANE-RESULT.json` at the worktree root, now including an optional `review_verdict` (`approve` | `request_changes`) and `review_summary`. When the coordinator runs `brainclaw harvest <assignment_id>` (both the report-only path and `--integrate`), a review lane carrying a `review_verdict` is mapped onto its loop: brainclaw records a `verdict` artifact on the reviewer slot (`approve` → an `accepted…` body) and calls `advance`, which **auto-closes the loop on `reviewer_green` for `approve`** — no human driving `complete_turn`/`advance`. `request_changes` records the verdict and advances to `author_response` (the automated fix→re-review cycle is a follow-up). The mapping is idempotent, resolves the reviewer slot strictly by `assignment_id` (so symmetric multi-reviewer loops target the right slot), and runs the `complete_turn`+`advance` pair under the loop lock so an interrupted pass resumes rather than stalls.
335
+ **How the verdict reaches the loop (shipped, pln#628 Focus 4B).** A dispatched reviewer worker does not call `bclaw_loop` itself — it writes its outcome to `LANE-RESULT.json` at the worktree root, including an optional `review_verdict` (`approve` | `request_changes`) and `review_summary`. When the coordinator runs `brainclaw harvest <assignment_id>` (report-only path and `--integrate`), a review lane carrying a `review_verdict` is mapped onto its loop: brainclaw records a `verdict` artifact on the reviewer slot (`approve` → an `accepted…` body) and calls `advance`, which **auto-closes the loop on `reviewer_green` for `approve`** — no human driving `complete_turn`/`advance`.
336
+
337
+ **The autonomous fix cycle (PR2, `--integrate` only).** On `request_changes`, `harvest --integrate` bumps the loop's round counter, **keeps the claim + worktree alive**, and re-dispatches the same reviewer slot into that **same worktree** (symmetric mode) with a findings-aware brief: apply the requested changes in place, then re-review. Commits accumulate on one branch — no fresh worktree per turn, so the branch-per-scope / refuse-unharvested-commits invariants are never tripped. The cycle repeats until `approve` (→ `reviewer_green` close) or the `max_iterations` cap (n=3 → auto-close `blocked`, handed to a human). The report-only harvest path never cycles (it can neither re-dispatch nor retain the claim); it defers `request_changes` to `--integrate` and still closes on `approve`. The mapping is idempotent, resolves the reviewer slot strictly by `assignment_id` (so symmetric multi-reviewer loops target the right slot), and runs the `complete_turn`+`advance` pair under the loop lock so an interrupted pass resumes rather than stalls. Asymmetric (author ≠ reviewer) cross-agent worktree sharing is a planned follow-up.
336
338
 
337
339
  ### Symmetric review-AND-fix mode
338
340
 
@@ -484,6 +486,29 @@ The three rules are independent: `hard_deadline` bounds pathological "heartbeat
484
486
  - Execution loops (`implementation`) route by `claim_id` — preserved from the claim-routed model already in use.
485
487
  - `session_id` is not a routing key; it remains observability-only. This is consistent with `architecture_session_centric_identity` in memory.
486
488
 
489
+ ### Project resolution gate (pln#521 P1)
490
+
491
+ `bclaw_coordinate(intent='review', open_loop=true)` resolves WHICH project the
492
+ loop belongs to before it writes anything. A loop that lands in the wrong store
493
+ persists a candidate, claim, assignment and loop where nobody is watching, and
494
+ spawns the reviewer against the wrong repo.
495
+
496
+ The ladder, in order: an explicit `project` argument; then any selector that
497
+ already won upstream (`--cwd`, `BRAINCLAW_PROJECT`, a session switch, the
498
+ physical child store, the workspace `active-project.json`); then the bare cwd
499
+ fallback. The fallback is accepted in a single-project store — there is exactly
500
+ one answer — and **refused** with `needs_project_selection` when the store can
501
+ host several projects (`project_mode: multi-project`, or a `store_type: workspace`
502
+ parent with nested project stores). The error lists the candidates and creates
503
+ nothing; fix it by passing `project='<name>'` or by making the choice sticky with
504
+ `bclaw_switch`. Ref, scope and path are never used to guess the project (B3
505
+ rejected in `art_e29e88878209`: a wrong guess costs more than an explicit choice).
506
+
507
+ Both `bclaw_coordinate` (open_loop reviews) and `bclaw_dispatch_status` echo the
508
+ decision as `project_name` / `project_cwd`. `dispatch_status` additionally carries
509
+ `_resolution_trace` (`source_cwd`, `effective_cwd`, `active_source`, `project_arg`)
510
+ so a misroute can be diagnosed without reverse-engineering cwd and store state.
511
+
487
512
  ## Open questions (resolved / deferred)
488
513
 
489
514
  Status after Codex schema review (cnd#574 / `dec_be66ccbf`, verdict `needs_revision` → addressed in v8):
@@ -517,6 +542,7 @@ Status after Codex schema review (cnd#574 / `dec_be66ccbf`, verdict `needs_revis
517
542
  The loop surface exposed over MCP is intentionally narrow:
518
543
 
519
544
  - **Review loops** — `bclaw_coordinate(intent="review", open_loop=true, review_mode="asymmetric"|"symmetric", targetAgents=[…])` opens the loop and dispatches the first turn. The reviewer's verdict is then harvested from `LANE-RESULT.json` (`review_verdict`) and **auto-advances/closes the loop on approve** — no manual driving needed for the approve path (pln#628 Focus 4B). `bclaw_loop(intent="turn"|"complete_turn"|"advance"|"close")` remains available to drive turns by hand (e.g. the `request_changes` fix cycle, or a human-operated slot).
545
+ - **Turn-owned exactly-once fix cycle (default, pln#630).** The autonomous `request_changes` fix-cycle re-dispatch runs through the turn-owned attempt state machine (immutable attempt record + atomic launch fence → spawned at most once; `reconcileTurn` finalizes from read-strict, turn-keyed evidence — the ack-wrapper's completion sentinel). It falls back to the legacy closer when a reviewer resolves to inbox/manual (no sentinel) so the loop still converges. **Kill-switch:** set `BRAINCLAW_TURN_OWNED_REVIEW=0` (also `false`/`off`/`no`) to revert review finalization to the legacy presence-based closer.
520
546
  - **Ideation loops** — `bclaw_coordinate(intent="ideate", preset="bootstrap")` opens an ideation loop from a preset.
521
547
 
522
548
  Custom phase lists (`LoopPhase[]`) and bespoke `StopCondition` logic exist in the loop engine internally, but are **not** exposed through the MCP facade today: `CoordinateRequestSchema` accepts only `open_loop`, `review_mode`, `preflight`, `ref`, and `preset` — no `phases` or `stop_condition` — and the standalone `bclaw_loop` tool does not expose an `open` intent. Programmatic construction of ad-hoc loops is therefore internal / future work until the facade is extended.
@@ -213,6 +213,28 @@ the projection rule).
213
213
  > from the seed otherwise. `agents`/`sessions` are never journaled → always seed.
214
214
  > A store that has NOT run the supplement keeps the seed (no regression).
215
215
  >
216
+ > **Section CONTENT cutover (pln#560 completion):** once `registryAuthoritative()`
217
+ > is set, the registry/coordination sections (ATTENTION, IN_PROGRESS, SPRINTS,
218
+ > and the flat claims/assignments/runs/actions/candidates drill-downs) serve
219
+ > their entity content from the projection too — zero MCP display fetches on
220
+ > expand. The non-journaled extras on the composites (server-computed
221
+ > `workflow_hints`, loops via `bclaw_loop(intent='list')`, and the
222
+ > `bclaw_dispatch_status` evidence digests of §6/§7) remain best-effort reads
223
+ > through the observer-flagged client: when no client resolves, the section
224
+ > still renders its entities. SYSTEM keeps its MCP fetch regardless — it mixes
225
+ > private/machine runtime_notes (never journaled, visibility boundary) and
226
+ > cross-project config, neither derivable from the shared journal.
227
+ >
228
+ > Two parity notes: (a) sections whose MCP fetch pre-filtered `status:
229
+ > 'pending'` server-side (actions, candidates) apply the equivalent pure
230
+ > filter on the projection, because renderers admit broader statuses; (b)
231
+ > journal-served sections are **legacy-inclusive** — the genesis backfill
232
+ > journals `provenance.kind='legacy'` records that the MCP default read
233
+ > filter excludes, and the projection trim drops the nested `provenance`
234
+ > object, so parity with the MCP default is not reconstructable client-side.
235
+ > Accepted deliberately: the operator tree already passes `includeLegacy:
236
+ > true` wherever it fetches explicitly.
237
+ >
216
238
  > The historical (pre-pln#568) description below is kept for context.
217
239
 
218
240
  The journal classifies records into five classes (§2). In phase 1 / `dual`
@@ -1,13 +1,13 @@
1
1
  # Codex Integration
2
2
 
3
- brainclaw integrates with OpenAI's Codex CLI through MCP tools and shared instruction files. Codex has MCP access, universal skills support, and headless CLI spawn capability, but no native lifecycle hook surface.
3
+ brainclaw integrates with OpenAI's Codex CLI through MCP tools, shared instruction files, and native lifecycle hooks. Codex has MCP access, universal skills support, headless CLI spawn capability, and a native lifecycle hook surface (added upstream in 2026 — [developers.openai.com/codex/hooks](https://developers.openai.com/codex/hooks)).
4
4
 
5
5
  ## Auto-setup
6
6
 
7
7
  Codex setup is split across machine and project scope:
8
8
 
9
9
  - `brainclaw setup-machine --agents codex --yes` writes the machine-level MCP config at `~/.codex/config.toml`
10
- - `brainclaw init` creates or refreshes the current project's Brainclaw state and writes `AGENTS.md`
10
+ - `brainclaw init` creates or refreshes the current project's Brainclaw state, writes `AGENTS.md`, and writes project-level lifecycle hooks to `.codex/hooks.json` (git-ignored)
11
11
 
12
12
  If the project already has `.brainclaw/`, rerunning `brainclaw init` is safe and refreshes the managed Brainclaw/Codex files for the current machine.
13
13
 
@@ -61,7 +61,7 @@ Since pln#476 (1.0.13+), spawned Codex workers are marked `delivered_and_started
61
61
  |-------|-------|
62
62
  | Tier | A |
63
63
  | MCP | yes |
64
- | Hooks | no |
64
+ | Hooks | yes (`.codex/hooks.json`, project scope) |
65
65
  | Auto-approve | manual (per-tool approval) |
66
66
  | Skills | yes |
67
67
  | CLI spawnable | yes |
@@ -70,6 +70,22 @@ Since pln#476 (1.0.13+), spawned Codex workers are marked `delivered_and_started
70
70
  | MCP config scope | machine |
71
71
  | Prompt delivery | `stdin_pipe` (preferred), `inline_arg` (fallback) |
72
72
 
73
+ ## Lifecycle hooks
74
+
75
+ `brainclaw init` writes project-level hooks to `.codex/hooks.json` (git-ignored, machine-specific command paths). Codex reads hooks from `hooks.json` or an inline `[hooks]` table at user (`~/.codex/`) and project (`<repo>/.codex/`) scope ([Codex hooks docs](https://developers.openai.com/codex/hooks)). brainclaw wires three events:
76
+
77
+ | Event | brainclaw command | Purpose |
78
+ |-------|-------------------|---------|
79
+ | `SessionStart` | `brainclaw session-start --include-context` | Load shared context (constraints, decisions, traps, plans, handoffs) when a session begins |
80
+ | `UserPromptSubmit` | `brainclaw context-diff` | Surface what changed since the last turn |
81
+ | `Stop` | `brainclaw session-end --auto-release --reflect --reflect-handoff --dispatch-review` | Release claims, reflect, and dispatch review at turn end |
82
+
83
+ The file shape is `{ "hooks": { "<Event>": [ { "matcher": "", "hooks": [ { "type": "command", "command": "…" } ] } ] } }` (`matcher: ""` = match all occurrences). brainclaw **owns** these three event arrays: reruns overwrite them (idempotent, no cross-upgrade pile-up) — the same contract as the Cursor / Antigravity hook writers. A user's own hook placed on one of these three events is replaced on the next `init`; hooks on any **other** event are left untouched.
84
+
85
+ **Scope — interactive sessions, not headless dispatch.** These hooks serve an *interactive* Codex session. Non-managed command hooks require a one-time trust in Codex (`/hooks` — inspect and trust) before they run, so a fresh `.codex/hooks.json` is inert until the user trusts it. Headless dispatched workers (`codex exec`, used by `bclaw_dispatch` / `bclaw_coordinate`) do **not** rely on these hooks at all — they receive their context in the dispatch brief and report via `LANE-RESULT.json`; an untrusted project hook is simply skipped there, which is harmless. (A "managed" hook path via `requirements.toml`/MDM could bypass the trust step for fleets — a possible future enhancement.)
86
+
87
+ **Per-event output contract.** `SessionStart` and `UserPromptSubmit` emit their stdout as **model-visible context** — that is exactly the point (inject shared brainclaw state / the context diff). `Stop`, by contrast, expects a **JSON** response from Codex to shape turn-end behavior; brainclaw's `session-end` runs mainly for its side effects (release claims, reflect, dispatch review) and does not emit that JSON, so it does not gate the turn. Emitting a conformant per-event JSON response (notably for `Stop`) is a planned follow-up.
88
+
73
89
  ## Caveats
74
90
 
75
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.
@@ -10,6 +10,33 @@ guarantees this changelog follows.
10
10
 
11
11
  ## Unreleased
12
12
 
13
+ **Added — turn-attempt evidence-correlation fields (pln#630 PR2b-a)**
14
+ - Additive, backward-compatible: `LaneResultSchema` gains optional `turn_id` /
15
+ `run_id` / `nonce`; `RuntimeEventSchema` gains optional `turn_id` / `nonce`
16
+ (`run_id` already present); `LoopSlotSchema` gains optional `current_turn_id`;
17
+ a `turn_reserved` variant joins the loop event journal. All optional/defaulted
18
+ — legacy records parse unchanged; no tool added/removed/renamed.
19
+ - `LoopSlotSchema.current_turn_id` flows into the zod-derived `LoopSlotInput`
20
+ embedded in `bclaw_loop`'s published inputSchema, so it DOES move the public
21
+ MCP surface fingerprint (bumped in the `(current)` section below) and
22
+ regenerates `mcp-schemas.generated.ts`. Additive optional field — no breaking
23
+ change to the tool contract.
24
+
25
+ **Changed — `bclaw_read_inbox` bounded + focused reads (pln#627 Phase A)**
26
+ - Default status filter is now **actionable** (pending + read); acknowledged and
27
+ archived are hidden unless `includeAll=true` or an explicit `status` is passed.
28
+ Previously an unset status returned every message (the "pending by default"
29
+ description was wrong).
30
+ - Results are ordered **newest-first** by `created_at` before pagination, so a
31
+ bounded page serves the most recent messages instead of the oldest debris.
32
+ - Message bodies are **previewed** (~500 chars) with `text_length` + `truncated`;
33
+ the full body is returned only with `full=true`. The page is size-bounded by
34
+ `budget_tokens` (like `bclaw_find` / `bclaw_search`), with `has_more` /
35
+ `next_offset` paging hints — a single read can no longer blow the token budget.
36
+ - Input schema gains `includeAll`, `full`, and `budget_tokens` (additive; moves
37
+ the surface fingerprint — see the current section). `structuredContent.messages`
38
+ now carries `text_length` + `truncated` per message.
39
+
13
40
  **Added — `LaneResultSchema.review_verdict` / `review_summary` (pln#628 Focus 4B)**
14
41
  - `LANE-RESULT.json` (the worktree-root file a dispatched worker writes) gains two
15
42
  optional fields: `review_verdict` (`approve` | `request_changes`) and
@@ -238,7 +265,22 @@ will still succeed. A follow-up PR will strip the dead handler code.
238
265
  changelog records the published MCP surface fingerprint. When a tool
239
266
  name, tier, category, or input schema changes, the test fails until
240
267
  this section is updated.
241
- - MCP public surface fingerprint: `sha256:468f0103414e97e8`
268
+ - MCP public surface fingerprint: `sha256:8241fa50b8cb4805`
269
+ (updated 2026-07-25 for pln#632: `bclaw_loop` gains the `bind` intent — an
270
+ implementation loop dispatches its linked sequence and advances bind→execute — plus
271
+ its typed inputSchema properties `dry_run`, `lanes`, `auto_execute`, `model`, and
272
+ `max_assignments`. Additive — no tool added/removed/renamed; the new enum value + the
273
+ new properties move the fingerprint.)
274
+ Previous: `sha256:f3d49b28d2d366bb`
275
+ (updated 2026-07-24 for pln#630 PR2b-a: `LoopSlotSchema` gains an optional
276
+ `current_turn_id`, which flows through the zod-derived `LoopSlotInput` into
277
+ `bclaw_loop`'s published inputSchema. Additive optional field; regenerates
278
+ `mcp-schemas.generated.ts`.)
279
+ Previous: `sha256:fd8a7e910bf5f751`
280
+ (updated 2026-07-24 for pln#627 Phase A: the `bclaw_read_inbox` input schema
281
+ gains `includeAll`, `full`, and `budget_tokens`. Additive — no tool
282
+ added/removed/renamed; the three new typed properties move the fingerprint.)
283
+ Previous: `sha256:468f0103414e97e8`
242
284
  (updated 2026-07-18 for pln#625 PR #83 + Codex review: `bclaw_list_agents`
243
285
  retired and `bclaw_find(entity='agent')` gains `includeReputation` — now typed
244
286
  as a boolean in `GRAMMAR_FILTER_CONTRACT.booleanKeys` and validated at the MCP
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "brainclaw",
3
- "version": "1.16.0",
3
+ "version": "1.18.0",
4
4
  "description": "Shared project memory for humans and coding agents.",
5
5
  "type": "module",
6
6
  "repository": {