brainclaw 0.29.2 → 1.5.4

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 (197) hide show
  1. package/LICENSE +21 -74
  2. package/README.md +199 -176
  3. package/dist/brainclaw-vscode.vsix +0 -0
  4. package/dist/cli.js +710 -25
  5. package/dist/commands/accept.js +3 -0
  6. package/dist/commands/add-step.js +11 -26
  7. package/dist/commands/agent-board.js +70 -3
  8. package/dist/commands/audit.js +19 -0
  9. package/dist/commands/check-policy.js +54 -0
  10. package/dist/commands/check-security-mcp.js +145 -0
  11. package/dist/commands/check-security.js +106 -0
  12. package/dist/commands/claim-resource.js +1 -0
  13. package/dist/commands/codev.js +672 -0
  14. package/dist/commands/compact.js +74 -0
  15. package/dist/commands/complete-step.js +16 -26
  16. package/dist/commands/constraint.js +8 -20
  17. package/dist/commands/decision.js +9 -20
  18. package/dist/commands/delete-plan.js +10 -12
  19. package/dist/commands/delete-step.js +16 -0
  20. package/dist/commands/dispatch.js +163 -0
  21. package/dist/commands/doctor.js +1122 -49
  22. package/dist/commands/enable-agent.js +1 -0
  23. package/dist/commands/export.js +280 -22
  24. package/dist/commands/handoff.js +33 -0
  25. package/dist/commands/harvest.js +189 -0
  26. package/dist/commands/hooks.js +82 -25
  27. package/dist/commands/inbox.js +169 -0
  28. package/dist/commands/init.js +38 -31
  29. package/dist/commands/install-hooks.js +71 -44
  30. package/dist/commands/link.js +89 -0
  31. package/dist/commands/list-claims.js +48 -3
  32. package/dist/commands/list-plans.js +129 -25
  33. package/dist/commands/loops-handlers.js +409 -0
  34. package/dist/commands/mcp-read-handlers.js +1628 -0
  35. package/dist/commands/mcp-schemas.generated.js +269 -0
  36. package/dist/commands/mcp.js +4224 -1501
  37. package/dist/commands/plan-resource.js +64 -0
  38. package/dist/commands/plan.js +12 -26
  39. package/dist/commands/prune.js +37 -2
  40. package/dist/commands/reflect.js +20 -7
  41. package/dist/commands/release-claim.js +11 -6
  42. package/dist/commands/release-notes.js +170 -0
  43. package/dist/commands/repair.js +210 -0
  44. package/dist/commands/run-profile.js +57 -0
  45. package/dist/commands/sequence.js +113 -0
  46. package/dist/commands/session-end.js +423 -14
  47. package/dist/commands/session-start.js +214 -41
  48. package/dist/commands/setup-security.js +103 -0
  49. package/dist/commands/setup.js +42 -4
  50. package/dist/commands/stale.js +109 -0
  51. package/dist/commands/switch.js +100 -2
  52. package/dist/commands/trap.js +14 -31
  53. package/dist/commands/update-handoff.js +63 -4
  54. package/dist/commands/update-plan.js +21 -28
  55. package/dist/commands/update-step.js +37 -0
  56. package/dist/commands/upgrade.js +313 -6
  57. package/dist/commands/usage.js +102 -0
  58. package/dist/commands/version.js +20 -0
  59. package/dist/commands/who.js +33 -5
  60. package/dist/commands/worktree.js +105 -0
  61. package/dist/core/actions.js +315 -0
  62. package/dist/core/agent-capability.js +610 -17
  63. package/dist/core/agent-context.js +7 -1
  64. package/dist/core/agent-files.js +1169 -85
  65. package/dist/core/agent-integrations.js +160 -5
  66. package/dist/core/agent-inventory.js +2 -0
  67. package/dist/core/agent-profiles.js +93 -0
  68. package/dist/core/agent-registry.js +162 -30
  69. package/dist/core/agentrun-reconciler.js +345 -0
  70. package/dist/core/agentruns.js +424 -0
  71. package/dist/core/ai-agent-detection.js +31 -10
  72. package/dist/core/archival.js +77 -0
  73. package/dist/core/assignment-sweeper.js +82 -0
  74. package/dist/core/assignments.js +367 -0
  75. package/dist/core/audit.js +30 -0
  76. package/dist/core/brainclaw-version.js +94 -2
  77. package/dist/core/candidates.js +93 -2
  78. package/dist/core/claims.js +419 -0
  79. package/dist/core/codev-metrics.js +77 -0
  80. package/dist/core/codev-personas.js +31 -0
  81. package/dist/core/codev-plan-gen.js +35 -0
  82. package/dist/core/codev-prompts.js +74 -0
  83. package/dist/core/codev-responses.js +62 -0
  84. package/dist/core/codev-rounds.js +218 -0
  85. package/dist/core/config.js +4 -0
  86. package/dist/core/context.js +381 -34
  87. package/dist/core/coordination.js +201 -6
  88. package/dist/core/cross-project.js +230 -16
  89. package/dist/core/default-profiles/doctor.yaml +11 -0
  90. package/dist/core/default-profiles/janitor.yaml +11 -0
  91. package/dist/core/default-profiles/onboarder.yaml +11 -0
  92. package/dist/core/default-profiles/reviewer.yaml +13 -0
  93. package/dist/core/dispatcher.js +1189 -0
  94. package/dist/core/duplicates.js +2 -2
  95. package/dist/core/entity-operations.js +450 -0
  96. package/dist/core/entity-registry.js +344 -0
  97. package/dist/core/events.js +106 -2
  98. package/dist/core/execution-adapters.js +154 -0
  99. package/dist/core/execution-context.js +63 -0
  100. package/dist/core/execution-profile.js +270 -0
  101. package/dist/core/execution.js +255 -0
  102. package/dist/core/facade-schema.js +81 -0
  103. package/dist/core/federation-cloud.js +99 -0
  104. package/dist/core/federation-message.js +52 -0
  105. package/dist/core/federation-transport.js +65 -0
  106. package/dist/core/gc-semantic.js +482 -0
  107. package/dist/core/governance.js +247 -0
  108. package/dist/core/guards.js +19 -0
  109. package/dist/core/ideation.js +72 -0
  110. package/dist/core/identity.js +110 -25
  111. package/dist/core/ids.js +6 -0
  112. package/dist/core/input-validation.js +2 -2
  113. package/dist/core/instruction-templates.js +344 -136
  114. package/dist/core/io.js +90 -11
  115. package/dist/core/lock.js +6 -2
  116. package/dist/core/loops/brief-assembly.js +213 -0
  117. package/dist/core/loops/facade-schema.js +148 -0
  118. package/dist/core/loops/index.js +7 -0
  119. package/dist/core/loops/iteration-engine.js +139 -0
  120. package/dist/core/loops/lock.js +385 -0
  121. package/dist/core/loops/store.js +201 -0
  122. package/dist/core/loops/types.js +403 -0
  123. package/dist/core/loops/verbs.js +534 -0
  124. package/dist/core/markdown.js +15 -3
  125. package/dist/core/memory-compactor.js +432 -0
  126. package/dist/core/memory-git.js +152 -8
  127. package/dist/core/messaging.js +278 -0
  128. package/dist/core/migration.js +32 -1
  129. package/dist/core/mutation-pipeline.js +4 -2
  130. package/dist/core/operations/memory-mutation.js +129 -0
  131. package/dist/core/operations/memory-write.js +78 -0
  132. package/dist/core/operations/plan.js +190 -0
  133. package/dist/core/policy.js +169 -0
  134. package/dist/core/reputation.js +9 -3
  135. package/dist/core/schema.js +491 -6
  136. package/dist/core/search.js +21 -2
  137. package/dist/core/security-cache.js +71 -0
  138. package/dist/core/security-guard.js +152 -0
  139. package/dist/core/security-scoring.js +86 -0
  140. package/dist/core/sequence.js +130 -0
  141. package/dist/core/socket-client.js +113 -0
  142. package/dist/core/staleness.js +246 -0
  143. package/dist/core/state.js +98 -22
  144. package/dist/core/store-resolution.js +43 -11
  145. package/dist/core/toml-writer.js +76 -0
  146. package/dist/core/upgrades/backup.js +232 -0
  147. package/dist/core/upgrades/health-check.js +169 -0
  148. package/dist/core/upgrades/patches/candidate-archive.js +145 -0
  149. package/dist/core/upgrades/patches/handoff-review-strip.js +128 -0
  150. package/dist/core/upgrades/patches/provenance-rollout.js +136 -0
  151. package/dist/core/upgrades/schema-version.js +97 -0
  152. package/dist/core/worktree.js +606 -0
  153. package/dist/facts.js +114 -0
  154. package/dist/facts.json +111 -0
  155. package/docs/architecture/project-refs.md +5 -1
  156. package/docs/cli.md +690 -43
  157. package/docs/concepts/ideation-loop.md +317 -0
  158. package/docs/concepts/loop-engine.md +456 -0
  159. package/docs/concepts/mcp-governance.md +268 -0
  160. package/docs/concepts/memory-staleness.md +122 -0
  161. package/docs/concepts/multi-agent-workflows.md +166 -0
  162. package/docs/concepts/plans-and-claims.md +31 -6
  163. package/docs/concepts/project-md-convention.md +35 -0
  164. package/docs/concepts/troubleshooting.md +220 -0
  165. package/docs/concepts/upgrade-cli.md +202 -0
  166. package/docs/concepts/upgrade-dogfood-procedure.md +114 -0
  167. package/docs/context-format-changelog.md +2 -2
  168. package/docs/context-format.md +2 -2
  169. package/docs/index.md +68 -0
  170. package/docs/integrations/agents.md +15 -16
  171. package/docs/integrations/cline.md +88 -0
  172. package/docs/integrations/codex.md +75 -23
  173. package/docs/integrations/continue.md +60 -0
  174. package/docs/integrations/copilot.md +67 -9
  175. package/docs/integrations/kilocode.md +72 -0
  176. package/docs/integrations/mcp.md +304 -21
  177. package/docs/integrations/mistral-vibe.md +122 -0
  178. package/docs/integrations/opencode.md +84 -0
  179. package/docs/integrations/overview.md +23 -8
  180. package/docs/integrations/roo.md +74 -0
  181. package/docs/integrations/windsurf.md +83 -0
  182. package/docs/mcp-schema-changelog.md +191 -1
  183. package/docs/playbooks/integration/index.md +121 -0
  184. package/docs/playbooks/productivity/index.md +102 -0
  185. package/docs/playbooks/team/index.md +122 -0
  186. package/docs/product/agent-first-model.md +184 -0
  187. package/docs/product/entity-model-audit.md +462 -0
  188. package/docs/product/positioning.md +10 -10
  189. package/docs/quickstart-existing-project.md +135 -0
  190. package/docs/quickstart.md +124 -37
  191. package/docs/release-maintenance.md +79 -0
  192. package/docs/review.md +2 -0
  193. package/docs/server-operations.md +118 -0
  194. package/package.json +21 -13
  195. package/dist/commands/claude-desktop-extension.js +0 -18
  196. package/dist/commands/diff.js +0 -99
  197. package/dist/core/claude-desktop-extension.js +0 -224
@@ -0,0 +1,268 @@
1
+ # MCP surface governance
2
+
3
+ How the brainclaw MCP server evolves — catalog tiers, breaking-change
4
+ policy, versioning, deprecation cadence, and changelog discipline.
5
+
6
+ Operator-facing. Agents that cache tool catalogs use this to know when
7
+ to invalidate and what to expect when we change things. Source of
8
+ truth for `pln_aaf94588` (doc/mcp-versioning-and-surface-governance).
9
+
10
+ ## Tiers
11
+
12
+ The MCP surface is split into four tiers. Callers filter via the
13
+ `tools/list` params `catalog`, `include`, `advanced`, or `tier` (see
14
+ [docs/integrations/mcp.md](../integrations/mcp.md)).
15
+
16
+ | Tier | Use | Stability guarantee |
17
+ |--------------|-----------------------------------------|----------------------------------------------------------|
18
+ | `facade` | `bclaw_work`, `bclaw_coordinate`, `bclaw_loop`, … | **Public, stable.** Breaking changes require a schema major bump. |
19
+ | `standard` | Common CRUD + read tools | **Public, stable.** Same rules as facade. |
20
+ | `advanced` | Low-level ops used by specialised flows | **Public, evolving.** Breaking changes require a minor bump + deprecation warning. |
21
+ | `internal` | Build-only, test fixtures, experimental | **Unstable.** No compatibility guarantees — can change between patch releases. |
22
+
23
+ `facade + standard` are the default `tools/list` output. `advanced`
24
+ must be opted-into. `internal` is never returned by `tools/list`.
25
+
26
+ A tool's tier is declared at registration time in
27
+ `src/commands/mcp.ts`. Moving a tool between tiers is itself a
28
+ contract change — moving *up* (e.g., advanced → standard) is safe,
29
+ moving *down* (standard → advanced) requires a deprecation window.
30
+
31
+ ## What counts as a breaking change
32
+
33
+ Anything that can cause a previously-working MCP client call to fail
34
+ or return a differently-shaped response. Concretely:
35
+
36
+ - **Tool surface**
37
+ - Removing a tool.
38
+ - Renaming a tool.
39
+ - Adding a required input argument.
40
+ - Changing an argument's type, enum values, or shape.
41
+ - Tightening validation in a way that rejects previously-accepted inputs.
42
+ - Moving a tool to a lower tier (e.g., standard → advanced or removed from default catalog).
43
+
44
+ - **Response shape**
45
+ - Removing a field from `structuredContent`.
46
+ - Renaming a field.
47
+ - Changing a field's type (string → object, array → scalar).
48
+ - Changing the meaning of an existing enum value.
49
+
50
+ - **Behaviour**
51
+ - Changing a tool's error model (new exit codes, new error shapes callers might pattern-match on).
52
+ - Changing default values in a way that flips a downstream decision (e.g., `openLoop: true` becoming the default when it was `false`).
53
+ - Removing or renaming env vars that affect tool behaviour (`BRAINCLAW_*`).
54
+
55
+ **Non-breaking additions** (safe at any time):
56
+
57
+ - Adding a new tool in any tier.
58
+ - Adding a new **optional** argument.
59
+ - Adding a new field to `structuredContent`.
60
+ - Loosening validation (accepting a superset of previous inputs).
61
+ - Moving a tool to a higher tier.
62
+
63
+ ## Schema versioning rules
64
+
65
+ `SCHEMA_VERSION` in `src/commands/mcp.ts` tracks the MCP *protocol*
66
+ version — distinct from the `package.json` app version which follows
67
+ app evolution. A call to `initialize` returns this in `serverInfo.version`
68
+ and every tool response includes it in `schema_version`.
69
+
70
+ Semver interpretation:
71
+
72
+ | Bump | Allowed changes | Required artefacts |
73
+ |-----------|-------------------------------------------------------------|------------------------------------------------------|
74
+ | **patch** (`x.y.Z`) | Bug fixes, doc updates, internal refactors with no contract change | Changelog entry under "Fixed" |
75
+ | **minor** (`x.Y.0`) | Non-breaking additions (new tools, optional args, new response fields). `advanced`-tier breaking changes *with* a deprecation window. | Changelog entry under "Added" / "Changed". Deprecation warnings for `advanced` changes. |
76
+ | **major** (`X.0.0`) | Breaking changes on `facade`/`standard` tiers. Removal of any deprecated tool. Schema rename/rework. | Changelog entry under "Removed" / "Breaking". Migration guide. Clients expect to update. |
77
+
78
+ Public stability guarantees apply from `1.0.0` onward (the Phase 3
79
+ canonical grammar refactor, `pln_c6472192`). Subsequent v1.x releases
80
+ follow the rules above strictly.
81
+
82
+ ## Deprecation policy
83
+
84
+ A tool slated for removal goes through a deprecation window, not a
85
+ silent drop. Pattern:
86
+
87
+ 1. **Mark deprecated.** Add an entry in `LEGACY_MCP_TOOL_WARNINGS`
88
+ (`src/commands/mcp.ts`) with a short message pointing at the
89
+ replacement. Tool keeps working. Changelog entry under "Deprecated".
90
+ 2. **Surface the warning.** Every call to the tool during this window
91
+ returns a `warning` in `structuredContent` and stderr. Warnings are
92
+ not errors — callers continue to work.
93
+ 3. **Minimum compatibility window.**
94
+ - `facade`/`standard` tier tools: at least **two minor releases**
95
+ with warnings before removal.
96
+ - `advanced` tier tools: at least **one minor release**.
97
+ - `internal` tools: no window required.
98
+ 4. **Removal.** Allowed only on a major bump. Changelog entry under
99
+ "Removed" with the replacement path.
100
+
101
+ Deprecation warnings must name the replacement. "Deprecated, use X
102
+ instead" — no orphan deprecations.
103
+
104
+ ## Changelog discipline
105
+
106
+ `docs/mcp-schema-changelog.md` is the single source of truth for MCP
107
+ protocol changes. Conventions:
108
+
109
+ - One section per released version (`## x.y.z`). The current in-flight
110
+ version is marked `(current)` until it ships; the marker moves on
111
+ release.
112
+ - Subsections in this order:
113
+ - `**Added**` — new surface.
114
+ - `**Changed**` — modifications to existing surface (non-breaking
115
+ unless flagged).
116
+ - `**Deprecated**` — tools entering the deprecation window.
117
+ - `**Removed**` — tools or fields gone.
118
+ - `**Fixed**` — bug fixes that may affect behaviour.
119
+ - `**Breaking**` — any breaking change, called out explicitly. Must
120
+ map to a major bump.
121
+ - Every changelog entry must name the tool and/or field it touches,
122
+ so a client maintainer can grep for references.
123
+ - `SCHEMA_VERSION` constant in `src/commands/mcp.ts` must match the
124
+ latest released version in this changelog. A mismatch is a bug —
125
+ bump the constant or amend the changelog, but do not ship drift.
126
+
127
+ ## Enforcement guard
128
+
129
+ `tests/unit/mcp-governance.test.ts` computes a stable fingerprint of
130
+ the published MCP surface from `src/commands/mcp.ts`:
131
+
132
+ - tool name
133
+ - tier
134
+ - category
135
+ - input schema with descriptions stripped
136
+
137
+ The test requires the current section of
138
+ `docs/mcp-schema-changelog.md` to include that fingerprint. If a
139
+ public tool is added, removed, moved between tiers, or has its input
140
+ contract changed, the test fails until the changelog is updated.
141
+
142
+ This guard is intentionally advisory-by-test rather than a runtime
143
+ block. It catches contract drift in CI and local validation without
144
+ preventing operators from using `brainclaw doctor` during active
145
+ development.
146
+
147
+ ## Schema source-of-truth — zod-derived inputSchemas
148
+
149
+ MCP tool `inputSchema` blocks in `src/commands/mcp.ts` are JSON Schema.
150
+ The runtime validation that actually rejects bad calls lives in zod
151
+ schemas elsewhere (e.g. `src/core/loops/types.ts`,
152
+ `src/core/loops/facade-schema.ts`). When the same shape is expressed
153
+ twice — once as zod, once as hand-written JSON Schema — the two drift,
154
+ silently. The class is the same one flagged by
155
+ `feedback_cross_agent_patterns` rule 2 ("catalog source-of-truth >
156
+ hardcoded constants"); it produced `trp#180` in May 2026 (Copilot
157
+ rejected `bclaw_loop` because `phases`/`slots` arrays had no `items`,
158
+ which Claude Code's permissive validator had silently accepted).
159
+
160
+ The fix is to derive the JSON Schema from the zod source at build time
161
+ and commit the generated artifact. Hand-written schemas remain for tools
162
+ without a zod backing (intent-polymorphic dispatchers, etc.) and stay
163
+ protected by the strict CI test in
164
+ `tests/unit/mcp-input-schema-strict.test.ts`.
165
+
166
+ ### How it works
167
+
168
+ 1. Zod schemas are exported from their owning module (e.g.
169
+ `LoopPhaseSchema`, `LoopSlotInputSchema`).
170
+ 2. `scripts/build-mcp-schemas.mjs` reads the compiled zod from `dist/`
171
+ and emits `src/commands/mcp-schemas.generated.ts` via zod v4's
172
+ native `z.toJSONSchema()`.
173
+ 3. `src/commands/mcp.ts` imports `generatedSchemas` and uses the
174
+ generated objects inline as `items:` / sub-schemas inside the tool's
175
+ `inputSchema`.
176
+ 4. The migrated tool descriptor carries
177
+ `annotations.schemaSource: 'zod-derived'` as a grep-target marker.
178
+ 5. `tests/unit/mcp-zod-parity.test.ts` re-runs `z.toJSONSchema()` at
179
+ test time and deep-compares against the committed generated file.
180
+ Drift fails CI with a one-line fix instruction.
181
+
182
+ The generated file is committed (protobuf pattern). Developers run
183
+ `npm run build:mcp-schemas` after editing a zod schema and commit the
184
+ regen alongside their source change. CI then verifies parity.
185
+
186
+ ### How to migrate a tool to zod-derived schemas
187
+
188
+ Use this checklist when you touch a tool's source for any reason. Do
189
+ **not** mass-migrate in a dedicated PR — the regression risk on the
190
+ combined diff outweighs the cleanup benefit.
191
+
192
+ 1. **Identify the zod schema.** Locate the existing zod that the
193
+ handler validates against (or extract a partial form for input-only
194
+ shapes — see `LoopSlotInputSchema` for the precedent).
195
+ 2. **Export it** as a named symbol so the build script can import it
196
+ from `dist/`.
197
+ 3. **Add the generation entry** in `scripts/build-mcp-schemas.mjs`
198
+ under the `SCHEMAS` map.
199
+ 4. **Run** `npm run build:mcp-schemas`. Inspect the diff in
200
+ `src/commands/mcp-schemas.generated.ts` — it must be small,
201
+ readable, and free of unwanted `$schema` / `$id` / `$defs` headers
202
+ for sub-schemas you intend to inline.
203
+ 5. **Replace the hand-written sub-schema** in `mcp.ts` with the
204
+ generated reference (e.g. `items: generatedSchemas.LoopPhase`).
205
+ 6. **Tag** the tool descriptor with
206
+ `annotations.schemaSource: 'zod-derived'`. The annotation is
207
+ informational today (see comment in `mcp.ts`); the parity test
208
+ currently hardcodes its (tool, schema) pairs explicitly.
209
+ 7. **Add an entry** to `tests/unit/mcp-zod-parity.test.ts` mirroring
210
+ the pattern of `LoopPhase` / `LoopSlotInput`. The test exists to
211
+ catch silent regen drift; it must include every newly migrated
212
+ shape.
213
+ 8. **Run the strict + parity tests** locally
214
+ (`node --test dist-test/tests/unit/mcp-input-schema-strict.test.js
215
+ dist-test/tests/unit/mcp-zod-parity.test.js`). Both must pass.
216
+
217
+ ### When to skip the migration
218
+
219
+ Some inputSchemas should stay hand-written:
220
+
221
+ - **Intent-polymorphic surfaces.** Tools whose `inputSchema` is a flat
222
+ union of intents (`bclaw_work`, `bclaw_coordinate`) where each
223
+ intent permits a different field set. zod can express this via
224
+ `discriminatedUnion`, but `z.toJSONSchema()` produces verbose
225
+ `oneOf` blocks that are harder to read than the hand-written
226
+ flat-properties form. The strict CI test (Phase 1) still protects
227
+ these.
228
+ - **Tools without a zod handler at all.** Some adapters and admin
229
+ utilities validate manually. Migrating them just to satisfy the
230
+ pattern would add zod definitions for shapes that have no other
231
+ consumer.
232
+ - **Build-time-only or developer-only tools.** No external client
233
+ reads their schema; drift cost is bounded.
234
+
235
+ ### Adding a new tool
236
+
237
+ For tools added _after_ Phase 2 of `pln#494`, the default is
238
+ zod-derived. Skip the hand-written sub-schemas entirely:
239
+
240
+ 1. Define the zod input schema in the owning module.
241
+ 2. Export it.
242
+ 3. Add it to the `SCHEMAS` map in `scripts/build-mcp-schemas.mjs`.
243
+ 4. Run `npm run build:mcp-schemas` and reference the generated entry
244
+ in your tool descriptor.
245
+ 5. Add the parity test entry.
246
+
247
+ The strict CI test still runs and validates the generated output —
248
+ defense in depth.
249
+
250
+ ## Changelog → code cross-check
251
+
252
+ Quick command to verify `SCHEMA_VERSION` matches the changelog:
253
+
254
+ ```bash
255
+ node -e "import('./dist/commands/mcp.js').then(m => console.log(m.SCHEMA_VERSION))"
256
+ head -5 docs/mcp-schema-changelog.md
257
+ ```
258
+
259
+ Both should report the same version. Drift = bug.
260
+
261
+ Quick command to inspect the current public-surface fingerprint:
262
+
263
+ ```bash
264
+ node --test dist-test/tests/unit/mcp-governance.test.js
265
+ ```
266
+
267
+ If the test fails, copy the reported fingerprint into the current
268
+ `docs/mcp-schema-changelog.md` section and describe the surface change.
@@ -0,0 +1,122 @@
1
+ # Memory staleness + session resume
2
+
3
+ How brainclaw keeps long-lived memory usable without forcing cleanup.
4
+ Phase 4 Sprint 1 Lane A (`pln#390`).
5
+
6
+ ## The two concerns
7
+
8
+ 1. **Session resume.** When an agent reconnects to a workspace it already
9
+ worked in, the conversation starts fresh — but the store has
10
+ accumulated activity since the last session. Resume should hand
11
+ back a *delta* (what changed since last time) rather than the full
12
+ world.
13
+
14
+ 2. **Memory staleness.** Plans marked `in_progress` that have not been
15
+ touched in a week, traps whose expiry has passed, observation runtime
16
+ notes a month old with no expiry — these accumulate and eventually
17
+ drown signal. They should be flagged, not auto-archived.
18
+
19
+ Neither case requires destructive cleanup. Signals surface; the
20
+ operator (human or agent) decides.
21
+
22
+ ## Session resume
23
+
24
+ `bclaw_work(intent: "resume")` automatically includes the memory delta
25
+ since your previous session for the same agent:
26
+
27
+ ```jsonc
28
+ bclaw_work({ intent: "resume" })
29
+ // → context result contains:
30
+ // context_diff: {
31
+ // since_session: "sess_abc123",
32
+ // summary: "5 decisions, 2 handoffs",
33
+ // counts: { constraints: 0, decisions: 5, ... }
34
+ // }
35
+ ```
36
+
37
+ Under the hood this maps to `buildContext(... sinceSession: <last session>)`,
38
+ identical to `bclaw_context({ kind: "delta", since: "<session_id>" })`
39
+ but without the operator needing to know the session id.
40
+
41
+ The legacy flow still works for CLI:
42
+
43
+ ```bash
44
+ brainclaw session-start --include-context
45
+ ```
46
+
47
+ ## Staleness signals
48
+
49
+ `detectStaleness()` flags items across five entity kinds using
50
+ age-based heuristics. Thresholds live in
51
+ [`src/core/staleness.ts`](../../src/core/staleness.ts) `STALENESS_THRESHOLDS`:
52
+
53
+ | Entity | Flag when… | Default threshold |
54
+ |---|---|---|
55
+ | plan (in_progress) | no update for N days | 7 days |
56
+ | plan (todo / blocked) | never progressed in N days | 30 days |
57
+ | trap (active) | `expires_at` is in the past | — |
58
+ | handoff (open) | created more than N days ago | 14 days |
59
+ | candidate (pending) | age exceeds source-specific threshold | 21 days (user) / 30 days (auto) |
60
+ | runtime_note (observation) | no `expires_at` and older than N days | 30 days |
61
+
62
+ Session start/end runtime notes are transient markers and never
63
+ flagged regardless of age.
64
+
65
+ ## Where the signal surfaces
66
+
67
+ The same `StalenessReport` is emitted by three surfaces — no separate
68
+ probe required.
69
+
70
+ - **`bclaw_context(kind: "memory")`** — top 5 warnings included in the
71
+ context payload as `stale_warnings`.
72
+ - **`brainclaw agent-board`** — warnings appended after the core
73
+ board output. Shows the first 5 with their suggested action.
74
+ - **`brainclaw doctor`** — `stale_memory` check in the health report,
75
+ including full details in JSON mode.
76
+
77
+ ## The resolve flow
78
+
79
+ `brainclaw stale` is the minimal operator wrapper over the canonical
80
+ CRUD verbs:
81
+
82
+ ```bash
83
+ # List what's currently flagged
84
+ brainclaw stale list
85
+
86
+ # Apply the canonical action for the entity type
87
+ brainclaw stale resolve <id>
88
+ ```
89
+
90
+ Dispatch table:
91
+
92
+ | Entity kind | `stale resolve` effect |
93
+ |---|---|
94
+ | plan | `bclaw_transition(entity: "plan", to: "dropped")` |
95
+ | handoff | `bclaw_transition(entity: "handoff", to: "closed")` |
96
+ | candidate | `bclaw_transition(entity: "candidate", to: "rejected")` |
97
+ | trap | `bclaw_transition(entity: "trap", to: "resolved")` |
98
+ | runtime_note | `bclaw_remove(entity: "runtime_note", …)` |
99
+
100
+ For finer control, use the canonical verbs directly — the warning's
101
+ `suggested_action` field names the exact invocation.
102
+
103
+ ## Not done by design
104
+
105
+ - **No auto-archive.** Staleness is a soft signal. An item stays
106
+ visible until the operator resolves it. Exception: runtime notes
107
+ with an explicit `expires_at` that passed — those were operator-
108
+ declared TTLs, so we flag them *as* expired.
109
+ - **No reference-recency weighting (yet).** A stale plan that's still
110
+ referenced by a fresh handoff is treated the same as a truly orphaned
111
+ one. Cross-entity reference graph is a follow-up if the noise signal
112
+ shows it matters.
113
+ - **No per-agent thresholds.** All thresholds are global. Individual
114
+ agents cannot raise or lower their own. Config-driven overrides are
115
+ a follow-up.
116
+
117
+ ## Tuning
118
+
119
+ Thresholds live in `src/core/staleness.ts` as a module-level const.
120
+ Config-file override would land under `staleness: { plan_in_progress_days: … }`
121
+ in `config.yaml`. Not wired yet; open as follow-up when the defaults
122
+ start causing noise complaints.
@@ -0,0 +1,166 @@
1
+ # Multi-Agent Workflows
2
+
3
+ brainclaw is built around a small set of memory primitives — **plans**, **claims**, **handoffs**, **decisions**, **traps**, and **runtime notes** — that work the same way whether you're orchestrating multiple agents in parallel right now or letting the next agent (or the next you) pick up the work next week.
4
+
5
+ This doc walks through four concrete scenarios. Pick the one that matches what you're doing.
6
+
7
+ ---
8
+
9
+ ## 1. Active orchestration — parallel work across agent instances
10
+
11
+ **Scenario** — you have a sequence of independent lanes and want several agents (same agent, different instances, or several different agents) to work on them in parallel.
12
+
13
+ **Walkthrough**:
14
+
15
+ 1. Capture the work as plans, then group them into a sequence with explicit lane labels and dependencies:
16
+
17
+ ```text
18
+ bclaw_create(entity="plan", data={ text: "Refactor auth module", … })
19
+ bclaw_create(entity="plan", data={ text: "Add e2e tests", … })
20
+
21
+ # Then, via CLI or a follow-up call:
22
+ brainclaw sequence create "auth-refactor-cycle" --items '[
23
+ {"planId":"pln_aaa","rank":1,"lane":"refactor"},
24
+ {"planId":"pln_bbb","rank":2,"lane":"tests","hard_after":["pln_aaa"]}
25
+ ]' --status active
26
+ ```
27
+
28
+ 2. Dispatch the sequence — the dispatcher picks up the ready lanes (no `hard_after` blocking), creates one claim + worktree per lane, and routes inbox messages by `claim_id`:
29
+
30
+ ```text
31
+ bclaw_dispatch(intent="execute", agents=[<your agents>])
32
+ ```
33
+
34
+ 3. Each spawned worker runs in its own worktree (so concurrent edits don't collide), reads its inbox, and progresses the plan. Coordinator polls `bclaw_context(kind="board")` to follow progress.
35
+
36
+ 4. As each lane lands a commit, merge it into master and release the claim. Lanes with `hard_after` unblock automatically once their predecessors are `done`.
37
+
38
+ **What the primitives do here**: claims isolate scope per lane, the sequence's `hard_after` graph orders the work, and worktrees give Git-level isolation so parallel commits don't conflict.
39
+
40
+ ---
41
+
42
+ ## 2. Agent switching — when an agent runs out of credits mid-task
43
+
44
+ **Scenario** — your active agent hits a credit/quota limit while a task is half-done. You want the next agent (a different model, a fresh instance, anything you have available) to resume cleanly without re-explaining the whole project.
45
+
46
+ **Walkthrough**:
47
+
48
+ 1. Before the active agent shuts down, close out properly:
49
+
50
+ ```text
51
+ bclaw_session_end(narrative="Implemented X. Need to finish Y. Tests for Z still pending.")
52
+ ```
53
+
54
+ This snapshots the session, releases the active claims, and writes a handoff with the narrative + commit list.
55
+
56
+ 2. Bring up the next agent (any compatible one). Its first call is `bclaw_work(intent="resume")`:
57
+
58
+ ```text
59
+ bclaw_work(intent="resume")
60
+ ```
61
+
62
+ This returns the session context: open plans, recent decisions, active constraints, known traps, the latest handoff narrative, and any unfinished claims it can adopt.
63
+
64
+ 3. The new agent reads the handoff, picks up the right plan, and either creates a fresh claim on the same scope or adopts the existing one:
65
+
66
+ ```text
67
+ bclaw_work(intent="execute", planId="pln_…", scope="src/...")
68
+ ```
69
+
70
+ 4. From here on it's a normal session — the new agent has all the context the previous one had.
71
+
72
+ **What the primitives do here**: the handoff carries the narrative and the file delta, the session record carries the runtime context, and shared memory (decisions, constraints, traps) means the new agent doesn't relearn what the previous one already knows.
73
+
74
+ ---
75
+
76
+ ## 3. Project recovery — returning to a project after weeks
77
+
78
+ **Scenario** — you (or an agent on your behalf) come back to a project after a couple of weeks. You don't remember exactly where things stood. You want to ramp back up in a few minutes, not an afternoon.
79
+
80
+ **Walkthrough**:
81
+
82
+ 1. From the project root, ask any compatible agent to load context with the canonical facade:
83
+
84
+ ```text
85
+ bclaw_work(intent="resume")
86
+ ```
87
+
88
+ You get back: in-progress plans, blocked plans, decisions taken since you left, active constraints, known traps, recent handoffs, and a session continuity hint (where the last session left off).
89
+
90
+ 2. If you want a narrower view focused on one area:
91
+
92
+ ```text
93
+ bclaw_context(kind="memory", path="src/auth", profile="briefing")
94
+ ```
95
+
96
+ 3. Capture the things you remember in the moment — even rough — as runtime notes. They live in memory and can be promoted later to durable decisions or traps:
97
+
98
+ ```text
99
+ bclaw_create(entity="runtime_note", data={ text: "Token rotation logic was the next thing to ship" })
100
+ ```
101
+
102
+ 4. Pick the next plan, claim its scope, and start working. The agent has everything it needs.
103
+
104
+ **What the primitives do here**: durable memory means decisions and constraints survive long absences, the session continuity record bridges the gap between runs, and runtime notes give a low-friction way to capture half-formed ideas as they come back to you.
105
+
106
+ ---
107
+
108
+ ## 4. Team async — multiple humans and agents on the same project
109
+
110
+ **Scenario** — two or more people work on the same project, possibly with their own agents. Everyone needs to see the same plans, the same constraints, the same decisions, without constant Slack pings.
111
+
112
+ **Walkthrough**:
113
+
114
+ 1. Whenever someone takes a non-trivial decision (architecture, library choice, naming convention), capture it once:
115
+
116
+ ```text
117
+ bclaw_create(entity="decision", data={ text: "Use OAuth 2.0 with PKCE", outcome: "approved" })
118
+ bclaw_create(entity="constraint", data={ text: "All auth endpoints must rate-limit", category: "security" })
119
+ bclaw_create(entity="trap", data={ text: "Don't import from src/legacy/", severity: "high" })
120
+ ```
121
+
122
+ These become visible to every agent (and every teammate's agent) on the next `bclaw_context` call.
123
+
124
+ 2. When someone starts a non-trivial chunk of work, claim its scope so others can see it:
125
+
126
+ ```text
127
+ bclaw_work(intent="execute", scope="src/auth", task="Token rotation rework")
128
+ ```
129
+
130
+ The agent board (`bclaw_context(kind="board")` or `brainclaw agent-board`) now shows that scope as taken — anyone considering the same area sees the claim and either coordinates or picks something else.
131
+
132
+ 3. When work is ready for review, hand it off explicitly. The handoff includes the file delta, the narrative, and any open questions:
133
+
134
+ ```text
135
+ bclaw_coordinate(intent="review", task="Auth refactor ready for review", scope="src/auth")
136
+ ```
137
+
138
+ 4. Reviewers pick up the handoff via inbox (`bclaw_read_inbox`) and respond either by accepting + closing it, or by sending back fixes through the same coordination loop.
139
+
140
+ **What the primitives do here**: shared memory means every teammate's agent operates with the same constraints and traps, claims prevent double-work even without coordination meetings, and handoffs replace ad-hoc "hey, can you look at this?" pings with auditable artifacts.
141
+
142
+ ---
143
+
144
+ ## How the four scenarios share the same model
145
+
146
+ Notice that the four walkthroughs above use the **same primitives**, just composed differently:
147
+
148
+ | Primitive | Active orchestration | Agent switching | Project recovery | Team async |
149
+ |---|---|---|---|---|
150
+ | **plan** | unit of work in a lane | what the next agent picks up | what you ramp back into | what teammates see in the board |
151
+ | **claim** | scope lock per lane | snapshotted on session_end, adoptable later | shows what was in flight | prevents teammates from double-editing |
152
+ | **handoff** | between sequential lanes | carries the narrative + delta | bridges across the gap | replaces "ping me when ready" |
153
+ | **decision / constraint / trap** | guides every spawned worker | survives the credit-limit cutover | reminds you of past choices | propagates team knowledge |
154
+ | **runtime_note** | per-lane observations | quick captures before shutdown | half-formed thoughts on return | informal observations to share |
155
+
156
+ You don't pick a "mode" up front. You compose the primitives in whatever way fits the moment, and brainclaw keeps them durable across all of it.
157
+
158
+ ---
159
+
160
+ ## Next reads
161
+
162
+ - [memory.md](memory.md) — what counts as memory and how it's organized
163
+ - [plans-and-claims.md](plans-and-claims.md) — coordination layer in depth
164
+ - [loop-engine.md](loop-engine.md) — structured multi-turn protocols (review loops, ideation, etc.)
165
+ - [memory-staleness.md](memory-staleness.md) — how brainclaw signals when stored items may be outdated
166
+ - [../integrations/overview.md](../integrations/overview.md) — connecting your specific agent
@@ -50,10 +50,11 @@ Plans can have sub-steps for multi-phase work:
50
50
  ```bash
51
51
  brainclaw add-step <plan-id> "write unit tests"
52
52
  brainclaw add-step <plan-id> "update docs"
53
- brainclaw complete-step <plan-id> <step-index>
53
+ brainclaw complete-step <plan-id> <step-id>
54
54
  ```
55
55
 
56
56
  Steps show up in `brainclaw context` and `brainclaw board` so other agents and humans can see granular progress.
57
+ `brainclaw plan update` changes the parent plan item only; step completion is handled through `complete-step`.
57
58
 
58
59
  ### Estimation and calibration
59
60
 
@@ -108,7 +109,7 @@ brainclaw claim release <id>
108
109
 
109
110
  ### Automatic claim release
110
111
 
111
- Claims are automatically released after a `git merge` if the post-merge hook is installed (default since `brainclaw init` v0.25.3+). The hook matches merged file paths against active claim scopes and releases overlapping claims.
112
+ Claims are automatically released after a `git merge` if the post-merge hook is installed (installed by default by `brainclaw init`). The hook matches merged file paths against active claim scopes and releases overlapping claims.
112
113
 
113
114
  You can also install or reinstall the hook manually:
114
115
 
@@ -122,13 +123,37 @@ Without claims, multiple agents can easily touch the same area at once and gener
122
123
  Claims are not necessarily hard file locks.
123
124
  They are a shared coordination signal.
124
125
 
126
+ ## Policy checks
127
+
128
+ Before editing a scope, agents can verify governance compliance using `check-policy`:
129
+
130
+ ```bash
131
+ brainclaw check-policy --scope src/core/auth.ts --agent claude-code
132
+ ```
133
+
134
+ Or via MCP:
135
+
136
+ ```
137
+ bclaw_check_policy(scope: "src/core/auth.ts", agent: "claude-code")
138
+ ```
139
+
140
+ The check is fully **deterministic** (no AI involved) and verifies:
141
+
142
+ - **Claim active** — Does the agent have a claim on this scope? (BLOCK if not)
143
+ - **Claim conflict** — Is another agent claiming this scope? (BLOCK)
144
+ - **Constraints** — Do any active constraints with matching `related_paths` apply? (WARN)
145
+ - **Traps** — Are there known pitfalls for this scope? (WARN)
146
+ - **Governance context** — Active global instructions are surfaced for reference.
147
+
148
+ Policy warnings are also **automatically included** in the `bclaw_claim` response — agents get constraint and trap alerts at claim time without an extra call.
149
+
125
150
  ## Recommended workflow
126
151
 
127
152
  1. create a plan item
128
- 2. claim the target scope
129
- 3. work on the implementation
130
- 4. update the plan status
131
- 5. release the claim when done or blocked
153
+ 2. claim the target scope — `bclaw_claim` (or `bclaw_work(intent="execute", scope=…, planId=…)`) creates an isolated git worktree under `~/.brainclaw/worktrees/<project-hash>/` automatically; policy warnings are surfaced as part of the response
154
+ 3. work on the implementation inside the worktree
155
+ 4. update the plan status (`bclaw_transition(entity="plan", id, to="in_progress" | "done")`)
156
+ 5. commit and merge back; release the claim when done or blocked
132
157
  6. create a handoff if another actor should continue
133
158
 
134
159
  ## Session hygiene
@@ -0,0 +1,35 @@
1
+ # The PROJECT.md Convention (Instruction Layering)
2
+
3
+ When working with AI agents, balancing **context freshness** against **context bloat** is an ongoing challenge. If you feed an agent too many rules, it consumes tokens and increases the risk of "lazy" behavior or hallucinated context loss.
4
+
5
+ Brainclaw enforces a strict separation of concerns via "Instruction Layering":
6
+
7
+ 1. **Coordination Rules (The `brainclaw` context):** Managed completely by Brainclaw. This covers memory synchronization, plans, handoffs, and team coordination.
8
+ 2. **Domain Rules (The Project context):** Managed entirely by you. This covers tech stack features, architecture standards, UI guidelines, and test instructions.
9
+
10
+ To link these two seamlessly, Brainclaw introduces the canonical **`PROJECT.md` Convention**.
11
+
12
+ ## The Mechanism
13
+
14
+ Brainclaw treats the `PROJECT.md` file at the root of a workspace as the definitive source of truth for your domain rules.
15
+
16
+ When Brainclaw updates the surface instruction files for agents (`CLAUDE.md`, `copilot-instructions.md`, `.cursor/rules`, etc.), it automatically extracts and routes your project vision using a **hybrid injection technique**.
17
+
18
+ ### 1. The "Inject Content" Mode (Short Files, <=20 lines)
19
+ If your `PROJECT.md` is concise and serves as a simple "pitch" for the project (under 20 lines), Brainclaw will literally copy its content into the agent surface files under the `## brainclaw — this project` header.
20
+ - **Benefit:** Zero tool calls required by the agent. It gets the pitch instantly on session start.
21
+
22
+ ### 2. The "Inject Pointer" Mode (Detailed Files, >20 lines)
23
+ For larger, production-grade projects, your domain rules will easily exceed 20 lines. If Brainclaw injected 300 lines of coding guidelines into every agent prompt file, it would destroy your context window.
24
+ Instead, when your `PROJECT.md` exceeds 20 lines, Brainclaw injects a rigid pointer:
25
+
26
+ > **Project Domain Rules**
27
+ > This project maintains detailed domain rules and architecture externally to avoid context bloat.
28
+ > You MUST read `PROJECT.md` in the workspace root to understand the project constraints, tech stack, and conventions before coding.
29
+
30
+ - **Benefit:** Prevents context bloat. The agent uses a targeted file read (`read_file`) only when necessary to acquire deep codebase context.
31
+
32
+ ## Best Practices
33
+
34
+ - Always keep architecture guidelines, testing boundaries, and specific rules in `PROJECT.md` (or link out to other docs from it).
35
+ - Never edit the `<!-- brainclaw:start -->` wrapped contents in surface files manually. They will be overwritten during the next `brainclaw export` cycle.