brainclaw 0.29.2 → 1.5.3

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 (195) hide show
  1. package/README.md +193 -170
  2. package/dist/brainclaw-vscode.vsix +0 -0
  3. package/dist/cli.js +673 -24
  4. package/dist/commands/accept.js +3 -0
  5. package/dist/commands/add-step.js +11 -26
  6. package/dist/commands/agent-board.js +70 -3
  7. package/dist/commands/audit.js +19 -0
  8. package/dist/commands/check-policy.js +54 -0
  9. package/dist/commands/check-security-mcp.js +145 -0
  10. package/dist/commands/check-security.js +106 -0
  11. package/dist/commands/claim-resource.js +1 -0
  12. package/dist/commands/codev.js +672 -0
  13. package/dist/commands/compact.js +74 -0
  14. package/dist/commands/complete-step.js +16 -26
  15. package/dist/commands/constraint.js +8 -20
  16. package/dist/commands/decision.js +9 -20
  17. package/dist/commands/delete-plan.js +10 -12
  18. package/dist/commands/delete-step.js +16 -0
  19. package/dist/commands/dispatch.js +163 -0
  20. package/dist/commands/doctor.js +1122 -49
  21. package/dist/commands/enable-agent.js +1 -0
  22. package/dist/commands/export.js +280 -22
  23. package/dist/commands/handoff.js +33 -0
  24. package/dist/commands/harvest.js +189 -0
  25. package/dist/commands/hooks.js +82 -25
  26. package/dist/commands/inbox.js +169 -0
  27. package/dist/commands/init.js +38 -31
  28. package/dist/commands/install-hooks.js +71 -44
  29. package/dist/commands/link.js +89 -0
  30. package/dist/commands/list-claims.js +48 -3
  31. package/dist/commands/list-plans.js +129 -25
  32. package/dist/commands/loops-handlers.js +409 -0
  33. package/dist/commands/mcp-read-handlers.js +1628 -0
  34. package/dist/commands/mcp-schemas.generated.js +74 -0
  35. package/dist/commands/mcp.js +4221 -1501
  36. package/dist/commands/plan-resource.js +64 -0
  37. package/dist/commands/plan.js +12 -26
  38. package/dist/commands/prune.js +37 -2
  39. package/dist/commands/reflect.js +20 -7
  40. package/dist/commands/release-claim.js +11 -6
  41. package/dist/commands/release-notes.js +170 -0
  42. package/dist/commands/repair.js +210 -0
  43. package/dist/commands/run-profile.js +57 -0
  44. package/dist/commands/sequence.js +113 -0
  45. package/dist/commands/session-end.js +423 -14
  46. package/dist/commands/session-start.js +214 -41
  47. package/dist/commands/setup-security.js +103 -0
  48. package/dist/commands/setup.js +42 -4
  49. package/dist/commands/stale.js +109 -0
  50. package/dist/commands/switch.js +100 -2
  51. package/dist/commands/trap.js +14 -31
  52. package/dist/commands/update-handoff.js +63 -4
  53. package/dist/commands/update-plan.js +21 -28
  54. package/dist/commands/update-step.js +37 -0
  55. package/dist/commands/upgrade.js +313 -6
  56. package/dist/commands/usage.js +102 -0
  57. package/dist/commands/version.js +20 -0
  58. package/dist/commands/who.js +33 -5
  59. package/dist/commands/worktree.js +105 -0
  60. package/dist/core/actions.js +315 -0
  61. package/dist/core/agent-capability.js +610 -17
  62. package/dist/core/agent-context.js +7 -1
  63. package/dist/core/agent-files.js +1169 -85
  64. package/dist/core/agent-integrations.js +160 -5
  65. package/dist/core/agent-inventory.js +2 -0
  66. package/dist/core/agent-profiles.js +93 -0
  67. package/dist/core/agent-registry.js +162 -30
  68. package/dist/core/agentrun-reconciler.js +345 -0
  69. package/dist/core/agentruns.js +424 -0
  70. package/dist/core/ai-agent-detection.js +31 -10
  71. package/dist/core/archival.js +77 -0
  72. package/dist/core/assignment-sweeper.js +82 -0
  73. package/dist/core/assignments.js +367 -0
  74. package/dist/core/audit.js +30 -0
  75. package/dist/core/brainclaw-version.js +94 -2
  76. package/dist/core/candidates.js +93 -2
  77. package/dist/core/claims.js +419 -0
  78. package/dist/core/codev-metrics.js +77 -0
  79. package/dist/core/codev-personas.js +31 -0
  80. package/dist/core/codev-plan-gen.js +35 -0
  81. package/dist/core/codev-prompts.js +74 -0
  82. package/dist/core/codev-responses.js +62 -0
  83. package/dist/core/codev-rounds.js +218 -0
  84. package/dist/core/config.js +4 -0
  85. package/dist/core/context.js +381 -34
  86. package/dist/core/coordination.js +201 -6
  87. package/dist/core/cross-project.js +230 -16
  88. package/dist/core/default-profiles/doctor.yaml +11 -0
  89. package/dist/core/default-profiles/janitor.yaml +11 -0
  90. package/dist/core/default-profiles/onboarder.yaml +11 -0
  91. package/dist/core/default-profiles/reviewer.yaml +13 -0
  92. package/dist/core/dispatcher.js +1189 -0
  93. package/dist/core/duplicates.js +2 -2
  94. package/dist/core/entity-operations.js +450 -0
  95. package/dist/core/entity-registry.js +344 -0
  96. package/dist/core/events.js +106 -2
  97. package/dist/core/execution-adapters.js +154 -0
  98. package/dist/core/execution-context.js +63 -0
  99. package/dist/core/execution-profile.js +270 -0
  100. package/dist/core/execution.js +255 -0
  101. package/dist/core/facade-schema.js +81 -0
  102. package/dist/core/federation-cloud.js +99 -0
  103. package/dist/core/federation-message.js +52 -0
  104. package/dist/core/federation-transport.js +65 -0
  105. package/dist/core/gc-semantic.js +482 -0
  106. package/dist/core/governance.js +247 -0
  107. package/dist/core/guards.js +19 -0
  108. package/dist/core/ideation.js +72 -0
  109. package/dist/core/identity.js +110 -25
  110. package/dist/core/ids.js +6 -0
  111. package/dist/core/input-validation.js +2 -2
  112. package/dist/core/instruction-templates.js +344 -136
  113. package/dist/core/io.js +90 -11
  114. package/dist/core/lock.js +6 -2
  115. package/dist/core/loops/brief-assembly.js +213 -0
  116. package/dist/core/loops/facade-schema.js +148 -0
  117. package/dist/core/loops/index.js +7 -0
  118. package/dist/core/loops/iteration-engine.js +139 -0
  119. package/dist/core/loops/lock.js +385 -0
  120. package/dist/core/loops/store.js +201 -0
  121. package/dist/core/loops/types.js +403 -0
  122. package/dist/core/loops/verbs.js +534 -0
  123. package/dist/core/markdown.js +15 -3
  124. package/dist/core/memory-compactor.js +432 -0
  125. package/dist/core/memory-git.js +152 -8
  126. package/dist/core/messaging.js +278 -0
  127. package/dist/core/migration.js +32 -1
  128. package/dist/core/mutation-pipeline.js +4 -2
  129. package/dist/core/operations/memory-mutation.js +129 -0
  130. package/dist/core/operations/memory-write.js +78 -0
  131. package/dist/core/operations/plan.js +190 -0
  132. package/dist/core/policy.js +169 -0
  133. package/dist/core/reputation.js +9 -3
  134. package/dist/core/schema.js +491 -6
  135. package/dist/core/search.js +21 -2
  136. package/dist/core/security-cache.js +71 -0
  137. package/dist/core/security-guard.js +152 -0
  138. package/dist/core/security-scoring.js +86 -0
  139. package/dist/core/sequence.js +130 -0
  140. package/dist/core/socket-client.js +113 -0
  141. package/dist/core/staleness.js +246 -0
  142. package/dist/core/state.js +98 -22
  143. package/dist/core/store-resolution.js +43 -11
  144. package/dist/core/toml-writer.js +76 -0
  145. package/dist/core/upgrades/backup.js +232 -0
  146. package/dist/core/upgrades/health-check.js +169 -0
  147. package/dist/core/upgrades/patches/candidate-archive.js +145 -0
  148. package/dist/core/upgrades/patches/handoff-review-strip.js +128 -0
  149. package/dist/core/upgrades/patches/provenance-rollout.js +136 -0
  150. package/dist/core/upgrades/schema-version.js +97 -0
  151. package/dist/core/worktree.js +606 -0
  152. package/dist/facts.js +114 -0
  153. package/dist/facts.json +111 -0
  154. package/docs/architecture/project-refs.md +5 -1
  155. package/docs/cli.md +690 -43
  156. package/docs/concepts/ideation-loop.md +317 -0
  157. package/docs/concepts/loop-engine.md +456 -0
  158. package/docs/concepts/mcp-governance.md +268 -0
  159. package/docs/concepts/memory-staleness.md +122 -0
  160. package/docs/concepts/multi-agent-workflows.md +166 -0
  161. package/docs/concepts/plans-and-claims.md +31 -6
  162. package/docs/concepts/project-md-convention.md +35 -0
  163. package/docs/concepts/troubleshooting.md +220 -0
  164. package/docs/concepts/upgrade-cli.md +202 -0
  165. package/docs/concepts/upgrade-dogfood-procedure.md +114 -0
  166. package/docs/context-format-changelog.md +2 -2
  167. package/docs/context-format.md +2 -2
  168. package/docs/index.md +68 -0
  169. package/docs/integrations/agents.md +15 -16
  170. package/docs/integrations/cline.md +88 -0
  171. package/docs/integrations/codex.md +75 -23
  172. package/docs/integrations/continue.md +60 -0
  173. package/docs/integrations/copilot.md +67 -9
  174. package/docs/integrations/kilocode.md +72 -0
  175. package/docs/integrations/mcp.md +304 -21
  176. package/docs/integrations/mistral-vibe.md +122 -0
  177. package/docs/integrations/opencode.md +84 -0
  178. package/docs/integrations/overview.md +23 -8
  179. package/docs/integrations/roo.md +74 -0
  180. package/docs/integrations/windsurf.md +83 -0
  181. package/docs/mcp-schema-changelog.md +191 -1
  182. package/docs/playbooks/integration/index.md +121 -0
  183. package/docs/playbooks/productivity/index.md +102 -0
  184. package/docs/playbooks/team/index.md +122 -0
  185. package/docs/product/agent-first-model.md +184 -0
  186. package/docs/product/entity-model-audit.md +462 -0
  187. package/docs/quickstart-existing-project.md +135 -0
  188. package/docs/quickstart.md +124 -37
  189. package/docs/release-maintenance.md +79 -0
  190. package/docs/review.md +2 -0
  191. package/docs/server-operations.md +118 -0
  192. package/package.json +20 -12
  193. package/dist/commands/claude-desktop-extension.js +0 -18
  194. package/dist/commands/diff.js +0 -99
  195. package/dist/core/claude-desktop-extension.js +0 -224
@@ -2,220 +2,358 @@
2
2
  * Adaptive instruction file templates — generates brainclaw section content
3
3
  * based on the agent's capability profile (tier A/B/C).
4
4
  *
5
- * Core (static) vs Run (dynamic) separation:
6
- * Core: protocol, "why brainclaw", constraints, instructions, estimation rule
7
- * Run: traps, plans, decisions, claims, handoffs, runtime notes
5
+ * Two surface types:
6
+ * STABLE (versioned, rare refresh) — vision, protocol, durable constraints, instructions
7
+ * LIVE (gitignored, frequent refresh) — plans, claims, traps, decisions, sequences
8
8
  *
9
- * Tier A (MCP + hooks): lightweight — hooks inject run content automatically
10
- * Tier B (MCP, no hooks): directiveincludes top traps, forces MCP calls
11
- * Tier C (no MCP): rich includes plans, traps, decisions (only source)
9
+ * Tier delivery:
10
+ * Tier A (MCP + hooks): stable file only live context via hooks/MCP
11
+ * Tier B (MCP, no hooks): stable file + live companion file
12
+ * Tier C (no MCP): stable file + live companion file (richer, only source)
12
13
  */
13
14
  /**
14
- * Render the brainclaw section content for an instruction file,
15
- * adapted to the agent's capability profile.
15
+ * Render the STABLE brainclaw section content for an instruction file.
16
+ * This is the versioned file that changes rarely (on upgrade, convention change).
17
+ *
18
+ * For backward compatibility, this is also the entry point used by existing
19
+ * export code. Tier B/C stable output no longer includes traps/plans/decisions.
16
20
  */
17
21
  export function renderBrainclawSection(input) {
22
+ return renderStableSection(input);
23
+ }
24
+ /**
25
+ * Render stable content only: vision, protocol, constraints, instructions.
26
+ * No traps, plans, decisions, claims — those go in the live companion.
27
+ */
28
+ export function renderStableSection(input) {
18
29
  const { profile } = input;
19
30
  switch (profile.templateTier) {
20
- case 'A': return renderTierA(input);
21
- case 'B': return renderTierB(input);
22
- case 'C': return renderTierC(input);
31
+ case 'A': return renderStableTierA(input);
32
+ case 'B': return renderStableTierB(input);
33
+ case 'C': return renderStableTierC(input);
23
34
  }
24
35
  }
25
- // ─── Tier A: Full integration (MCP + hooks) ─────────────────────────────────
26
- function renderTierA(input) {
36
+ /**
37
+ * Render LIVE companion content: traps, plans, claims, candidates, handoffs,
38
+ * and (for tier C) recent decisions.
39
+ * This is the gitignored file refreshed on plan/claim/sequence mutations.
40
+ *
41
+ * Returns undefined when the profile does not emit a filesystem live
42
+ * companion.
43
+ */
44
+ export function renderLiveSection(input) {
45
+ const tier = resolveLiveCompanionTier(input.profile);
46
+ if (!tier)
47
+ return undefined;
48
+ return renderLiveCompanion(input, {
49
+ tier,
50
+ maxTraps: tier === 'C' ? input.maxTraps ?? 10 : input.maxTraps ?? 5,
51
+ maxPlans: tier === 'C' ? input.maxPlans ?? 10 : input.maxPlans ?? 5,
52
+ maxHandoffs: tier === 'C' ? 10 : 5,
53
+ includeDecisions: tier === 'C',
54
+ });
55
+ }
56
+ // ─── Tier A: Stable only ────────────────────────────────────────────────────
57
+ // Minimal: vision + protocol. Everything else arrives via hooks/MCP.
58
+ function renderStableTierA(input) {
27
59
  const sections = [];
28
60
  const included = [];
29
61
  sections.push(renderHeader(input));
30
62
  included.push('header');
31
- sections.push(renderWhySection(input.profile));
32
- included.push('why');
33
- sections.push(renderProtocolTierA());
34
- included.push('protocol');
35
- sections.push(renderEstimationRule());
36
- included.push('estimation');
37
- sections.push(renderVersionCheckRule());
38
- included.push('version-check');
39
- const constraints = renderConstraints(input.state);
40
- if (constraints) {
41
- sections.push(constraints);
42
- included.push('constraints');
63
+ const vision = renderVisionSection(input);
64
+ if (vision) {
65
+ sections.push(vision);
66
+ included.push('vision');
43
67
  }
68
+ sections.push(renderSessionProtocol());
69
+ included.push('protocol');
70
+ sections.push(renderUserWorkflow());
71
+ included.push('user-workflow');
72
+ sections.push(renderAutonomyContract());
73
+ included.push('autonomy-contract');
74
+ sections.push(renderAvailableTools());
75
+ included.push('available-tools');
44
76
  const instructions = renderInstructions(input.resolvedInstructions);
45
77
  if (instructions) {
46
78
  sections.push(instructions);
47
79
  included.push('instructions');
48
80
  }
49
- return {
50
- content: sections.join('\n\n'),
51
- tier: 'A',
52
- sectionsIncluded: included,
53
- };
81
+ return { content: sections.join('\n\n'), tier: 'A', sectionsIncluded: included };
54
82
  }
55
- // ─── Tier B: Standard integration (MCP, no hooks) ───────────────────────────
56
- function renderTierB(input) {
83
+ // ─── Tier B: Stable + Live ──────────────────────────────────────────────────
84
+ function renderStableTierB(input) {
57
85
  const sections = [];
58
86
  const included = [];
59
87
  sections.push(renderHeader(input));
60
88
  included.push('header');
61
- sections.push(renderWhySection(input.profile));
62
- included.push('why');
63
- sections.push(renderProtocolTierB());
89
+ const vision = renderVisionSection(input);
90
+ if (vision) {
91
+ sections.push(vision);
92
+ included.push('vision');
93
+ }
94
+ sections.push(renderSessionProtocol());
64
95
  included.push('protocol');
65
- sections.push(renderEstimationRule());
66
- included.push('estimation');
67
- sections.push(renderVersionCheckRule());
68
- included.push('version-check');
69
- const constraints = renderConstraints(input.state);
70
- if (constraints) {
71
- sections.push(constraints);
72
- included.push('constraints');
96
+ sections.push(renderUserWorkflow());
97
+ included.push('user-workflow');
98
+ sections.push(renderAutonomyContract());
99
+ included.push('autonomy-contract');
100
+ const rules = renderWorkingRules(input.state);
101
+ if (rules) {
102
+ sections.push(rules);
103
+ included.push('working-rules');
104
+ }
105
+ const arch = renderArchitecture(input.state);
106
+ if (arch) {
107
+ sections.push(arch);
108
+ included.push('architecture');
73
109
  }
74
110
  const instructions = renderInstructions(input.resolvedInstructions);
75
111
  if (instructions) {
76
112
  sections.push(instructions);
77
113
  included.push('instructions');
78
114
  }
79
- // Tier B includes top traps statically (agent has no hooks to get them)
80
- const traps = renderTopTraps(input.state, input.maxTraps ?? 5);
115
+ return { content: sections.join('\n\n'), tier: 'B', sectionsIncluded: included };
116
+ }
117
+ const LIVE_COMPANION_TIER_B_AGENTS = new Set([
118
+ 'cursor',
119
+ 'cline',
120
+ 'windsurf',
121
+ 'github-copilot',
122
+ ]);
123
+ function resolveLiveCompanionTier(profile) {
124
+ if (profile.templateTier === 'C')
125
+ return 'C';
126
+ if (profile.templateTier === 'B')
127
+ return 'B';
128
+ return LIVE_COMPANION_TIER_B_AGENTS.has(profile.name) ? 'B' : undefined;
129
+ }
130
+ function renderLiveCompanion(input, options) {
131
+ const sections = [];
132
+ const included = [];
133
+ sections.push(renderLiveHeader(input));
134
+ included.push('live-header');
135
+ const traps = renderTopTraps(input.state, options.maxTraps);
81
136
  if (traps) {
82
137
  sections.push(traps);
83
138
  included.push('traps');
84
139
  }
85
- return {
86
- content: sections.join('\n\n'),
87
- tier: 'B',
88
- sectionsIncluded: included,
89
- };
140
+ const plans = renderActivePlans(input.state, options.maxPlans);
141
+ if (plans) {
142
+ sections.push(plans);
143
+ included.push('plans');
144
+ }
145
+ const claims = renderActiveClaimsFromInput(input);
146
+ if (claims) {
147
+ sections.push(claims);
148
+ included.push('claims');
149
+ }
150
+ const candidates = renderPendingCandidates(input);
151
+ if (candidates) {
152
+ sections.push(candidates);
153
+ included.push('candidates');
154
+ }
155
+ const handoffs = renderOpenHandoffs(input.state, options.maxHandoffs);
156
+ if (handoffs) {
157
+ sections.push(handoffs);
158
+ included.push('handoffs');
159
+ }
160
+ if (options.includeDecisions) {
161
+ const decisions = renderRecentDecisions(input.state);
162
+ if (decisions) {
163
+ sections.push(decisions);
164
+ included.push('decisions');
165
+ }
166
+ }
167
+ return { content: sections.join('\n\n'), tier: options.tier, sectionsIncluded: included };
90
168
  }
91
- // ─── Tier C: Limited integration (no MCP) ────────────────────────────────────
92
- function renderTierC(input) {
169
+ // ─── Tier C: Stable + Live (richer) ─────────────────────────────────────────
170
+ function renderStableTierC(input) {
93
171
  const sections = [];
94
172
  const included = [];
95
173
  sections.push(renderHeader(input));
96
174
  included.push('header');
97
- sections.push(renderWhySection(input.profile));
98
- included.push('why');
99
- sections.push(renderProtocolTierC(input.profile));
175
+ const vision = renderVisionSection(input);
176
+ if (vision) {
177
+ sections.push(vision);
178
+ included.push('vision');
179
+ }
180
+ sections.push(renderSessionProtocol());
100
181
  included.push('protocol');
101
- sections.push(renderEstimationRule());
102
- included.push('estimation');
103
- const constraints = renderConstraints(input.state);
104
- if (constraints) {
105
- sections.push(constraints);
106
- included.push('constraints');
182
+ sections.push(renderUserWorkflow());
183
+ included.push('user-workflow');
184
+ sections.push(renderAutonomyContract());
185
+ included.push('autonomy-contract');
186
+ const rules = renderWorkingRules(input.state);
187
+ if (rules) {
188
+ sections.push(rules);
189
+ included.push('working-rules');
190
+ }
191
+ const arch = renderArchitecture(input.state);
192
+ if (arch) {
193
+ sections.push(arch);
194
+ included.push('architecture');
107
195
  }
108
196
  const instructions = renderInstructions(input.resolvedInstructions);
109
197
  if (instructions) {
110
198
  sections.push(instructions);
111
199
  included.push('instructions');
112
200
  }
113
- // Tier C includes everything statically — it's the only source of context
114
- const traps = renderTopTraps(input.state, input.maxTraps ?? 10);
115
- if (traps) {
116
- sections.push(traps);
117
- included.push('traps');
118
- }
119
- const plans = renderActivePlans(input.state, input.maxPlans ?? 10);
120
- if (plans) {
121
- sections.push(plans);
122
- included.push('plans');
123
- }
124
- const decisions = renderRecentDecisions(input.state);
125
- if (decisions) {
126
- sections.push(decisions);
127
- included.push('decisions');
128
- }
129
- return {
130
- content: sections.join('\n\n'),
131
- tier: 'C',
132
- sectionsIncluded: included,
133
- };
201
+ return { content: sections.join('\n\n'), tier: 'C', sectionsIncluded: included };
134
202
  }
135
203
  // ─── Shared section renderers ────────────────────────────────────────────────
204
+ function renderVisionSection(input) {
205
+ if (!input.projectVision?.trim())
206
+ return undefined;
207
+ return [
208
+ `## brainclaw — this project`,
209
+ '',
210
+ input.projectVision.trim(),
211
+ ].join('\n');
212
+ }
136
213
  function renderHeader(input) {
137
214
  return [
138
215
  `> Managed by brainclaw v${input.brainclawVersion} — do not edit manually.`,
139
216
  `> Regenerate: brainclaw export --format ${formatForAgent(input.profile.name)} --write`,
140
217
  ].join('\n');
141
218
  }
142
- function renderWhySection(profile) {
143
- const lines = [
144
- '## brainclawwhy this matters',
145
- '',
146
- 'This project uses brainclaw for shared memory and multi-agent coordination.',
147
- ];
148
- if (profile.hasMcp) {
149
- lines.push('Other agents and developers work in this repo. Without brainclaw context:', '- You may edit files another agent is actively working on', '- You will miss known traps and architectural decisions', '- You will duplicate or contradict planned work');
150
- }
151
- else {
152
- lines.push('Project context is maintained in brainclaw memory. This includes:', '- Active constraints that must be respected', '- Known traps to avoid repeating mistakes', '- Plans and decisions for ongoing work coordination');
153
- }
154
- return lines.join('\n');
219
+ function renderLiveHeader(_input) {
220
+ return [
221
+ `> Brainclaw live state auto-refreshed, do not edit.`,
222
+ `> Last updated: ${new Date().toISOString().slice(0, 19)}`,
223
+ ].join('\n');
155
224
  }
156
- function renderProtocolTierA() {
225
+ function renderSessionProtocol() {
157
226
  return [
158
227
  '## brainclaw — session protocol',
159
228
  '',
160
- 'Brainclaw context is injected automatically via hooks at each prompt.',
229
+ '1. Call `bclaw_work(intent)` to start working — it handles session, context, and claims automatically. Returns a compact payload by default; pass `compact: false` for the full context result, or use `bclaw_context(kind="memory")` after.',
230
+ '2. Use the canonical grammar (`bclaw_find` / `bclaw_get` / `bclaw_create` / `bclaw_update` / `bclaw_remove` / `bclaw_transition`) to work with memory objects (plans, decisions, constraints, traps, handoffs, claims, candidates, runtime_notes, …). Read `## brainclaw — working with memory` below for the full map.',
231
+ '3. Do not assume project state without reading brainclaw context first.',
161
232
  '',
162
- '1. Read the injected board state before acting',
163
- '2. Call `bclaw_get_context(target)` for deeper memory on a specific scope',
164
- '3. Call `bclaw_claim(scope)` before editing if other agents are active',
165
- '4. Call `bclaw_session_end(auto_release: true)` when done',
233
+ '_Escalation path (only when you orchestrate other agents) — by goal:_',
234
+ '- Start a code review / consult an agent / assign a scope → `bclaw_coordinate(intent=review|consult|assign)`',
235
+ '- Parallelize execute across a sequence\'s lanes `bclaw_dispatch(intent=execute)`',
236
+ '- Drive a turn in a loop already assigned to you → `bclaw_loop(intent=turn|complete_turn|advance|close)`',
237
+ '',
238
+ 'Do NOT call `bclaw_loop(intent=open)` directly — it creates a loop structure without dispatch, so the reviewer/participant never gets the work. Use the goal entries above.',
166
239
  ].join('\n');
167
240
  }
168
- function renderProtocolTierB() {
241
+ function renderUserWorkflow() {
169
242
  return [
170
- '## brainclaw — session protocol (REQUIRED)',
243
+ '## brainclaw — user workflow',
171
244
  '',
172
- 'You MUST follow this protocol before any work in this project.',
245
+ 'The intended end-to-end flow, executable by a single agent:',
173
246
  '',
174
- '1. Call `bclaw_session_start` identify yourself and see the active board',
175
- '2. Call `bclaw_get_context(target: "<file or dir>")` — load relevant memory',
176
- '3. Call `bclaw_get_execution_context` — check for brainclaw updates',
177
- '4. Check that no other agent has claimed your target scope',
178
- '5. Call `bclaw_claim(scope)` before editing',
179
- '6. Call `bclaw_write_note(text)` to record observations',
180
- '7. Call `bclaw_session_end(auto_release: true)` when done',
181
- ].join('\n');
182
- }
183
- function renderProtocolTierC(profile) {
184
- const lines = [
185
- '## brainclaw — project coordination',
247
+ ' ideation plan (+ steps) claim implement release claim → review → close step/plan → merge',
186
248
  '',
187
- ];
188
- if (profile.hasSkills) {
189
- lines.push('Use the brainclaw-context skill to refresh project memory.', 'Trigger: "refresh project memory", "load brainclaw context", "inspect active plans"', '');
190
- }
191
- lines.push('Before working:', '- Review the constraints and active plans below', '- Check the known traps section for pitfalls in your scope', '', 'The sections below are regenerated from brainclaw memory.', 'For the freshest state, use the brainclaw skill or ask the developer to run `brainclaw context`.');
192
- return lines.join('\n');
249
+ 'Multi-agent coordination is optional — use the escalation path only when delegating to another agent.',
250
+ '`sequence` is optional: add it between plan and claim when you want parallelized lanes across agents.',
251
+ '',
252
+ '**Entity → role in the flow:**',
253
+ '- `plan` intended outcome. Create with `bclaw_create(plan, …)`, decompose with `bclaw_add_step`.',
254
+ '- `step` — incremental unit inside a plan; mark done with `bclaw_complete_step` as you implement.',
255
+ '- `sequence` — ordered lanes when work can be parallelized across claims/agents (optional).',
256
+ '- `claim` — advisory reservation of a scope before editing; release once implementation is ready for review.',
257
+ '- `handoff` — immutable snapshot of what moved to the next stage (review, merge).',
258
+ '- `candidate` — proposed decision / constraint / trap awaiting review before entering durable memory.',
259
+ '- `decision` / `constraint` / `trap` / `runtime_note` — captured along the way to preserve context for future sessions.',
260
+ '',
261
+ '**Review & Fix Loop (multi-turn delegation):**',
262
+ '- Start: `bclaw_coordinate(intent=review, open_loop=true, review_mode=symmetric|asymmetric, targetAgents=[reviewer])` — opens the loop AND dispatches the first turn to the reviewer.',
263
+ '- Drive: `bclaw_loop(intent=turn|complete_turn|advance|close)` for turns assigned to your slot.',
264
+ '- Anti-pattern: `bclaw_loop(intent=open)` alone — creates the loop structure without any dispatch, so nothing actually runs.',
265
+ '',
266
+ 'Ideation / Debug / Research / Planning loops — *planned*. See `docs/product/agent-first-model.md` §3.',
267
+ ].join('\n');
193
268
  }
194
- function renderEstimationRule() {
269
+ /**
270
+ * Autonomy contract — emitted into every agent surface (pln#496 Phase 1).
271
+ *
272
+ * The contract binds protocol-defined transitions as MUST-execute, so live
273
+ * agents stop pausing on `should I send this reply? / merge? / release?`
274
+ * after every step. Without this, brainclaw collapses into a messaging layer
275
+ * with the human as the synchronization carrier-pigeon.
276
+ *
277
+ * Empirical motivation: in May 2026, multi-agent review threads systematically
278
+ * stalled at protocol-defined transitions (pln#480 worker did not release the
279
+ * claim, copilot pln#490 reviewer asked the human whether to send the reply).
280
+ * See feedback_agent_autonomy_gap + run_77e65e77 for the full diagnostic.
281
+ *
282
+ * Surface-fingerprint test (tests/unit/instruction-templates-autonomy-fingerprint.test.ts)
283
+ * fails CI if any tier drops this block — drift here re-introduces the gap.
284
+ */
285
+ function renderAutonomyContract() {
195
286
  return [
196
- '## brainclaw — plans and estimation',
287
+ '## brainclaw — autonomous workflow contract',
288
+ '',
289
+ 'When a brainclaw protocol prescribes the next action after the one you just',
290
+ 'completed, **execute it. Do not ask for permission.** brainclaw\'s coordination',
291
+ 'promise depends on this — every avoidable pause forces the human back into the',
292
+ 'synchronization loop, which is exactly what brainclaw is built to eliminate.',
293
+ '',
294
+ '**Protocol-defined transitions you MUST execute autonomously:**',
295
+ '',
296
+ '- IF you completed a review (assigned via `bclaw_coordinate(intent=review)` or',
297
+ ' inbox `review_request` message) → produce findings → **send the reply with',
298
+ ' your verdict via `bclaw_send_message(type="reply", thread_id=…)`**. Do not',
299
+ ' ask whether to send.',
300
+ '- IF you receive a reply with an `LGTM` verdict AND you are the requester →',
301
+ ' **close the loop and merge the branch yourself** (when you own the merge).',
302
+ ' Do not pass the merge to the human.',
303
+ '- IF the reviewer reply contains findings → **apply the symmetric fixes you',
304
+ ' can make**, commit on the same branch, then reroute via',
305
+ ' `bclaw_send_message(type="reply", …)` for re-review. Do not stop after the',
306
+ ' fixes.',
307
+ '- IF you have an active claim and your work is complete → call',
308
+ ' `bclaw_release_claim(id=…, planStatus="done")`. Do not leave the claim',
309
+ ' active for someone else to clean up.',
310
+ '- IF you have an `assignment_id` (you were dispatched via `bclaw_coordinate` /',
311
+ ' `bclaw_dispatch`) → at end of work, call',
312
+ ' `bclaw_assignment_update(assignment_id=…, status="completed", artifacts=[…])`.',
313
+ ' The coordinator depends on this lifecycle event; without it, the loop never',
314
+ ' converges and the supervisor cannot tell success from silent failure.',
315
+ '',
316
+ '**Legitimate reasons to pause and ask the human:**',
317
+ '',
318
+ '1. The action would be **destructive AND irreversible AND outside the',
319
+ ' protocol** (e.g. `git push --force` on a public branch, dropping a',
320
+ ' production database, deleting a non-empty memory cluster). Protocol-',
321
+ ' defined merges to a local branch are NOT in this category.',
322
+ '2. The protocol genuinely **does not specify** the next action (e.g. a',
323
+ ' verdict that splits the dispatched work into two new plans — needs',
324
+ ' scoping judgement only the human owns).',
325
+ '3. The user has **explicitly told you to confirm** before specific actions',
326
+ ' in this session.',
197
327
  '',
198
- 'When creating a plan or step, always estimate duration in minutes.',
199
- 'When completing, report actual effort. This calibrates future estimates.',
328
+ 'Asking *"should I send the reply?"* on a protocol-defined send is a UX bug,',
329
+ 'not safety. If the next step appears in the workflow above — do it. The',
330
+ 'empirical cost of skipping the contract: in May 2026, multi-agent review',
331
+ 'threads systematically stalled at "should I send this reply?" / "should I',
332
+ 'merge?", forcing the human supervisor to manually carry context between',
333
+ 'agents. Stop reproducing that pattern.',
200
334
  ].join('\n');
201
335
  }
202
- function renderVersionCheckRule() {
336
+ // ─── Constraint sections (split by category) ────────────────────────────────
337
+ const RULE_CATEGORIES = new Set(['process', 'reliability', 'compatibility', 'security', 'other']);
338
+ const ARCH_CATEGORIES = new Set(['architecture', 'performance']);
339
+ function renderWorkingRules(state) {
340
+ const rules = state.active_constraints.filter((c) => c.status === 'active' && (!c.category || RULE_CATEGORIES.has(c.category)));
341
+ if (rules.length === 0)
342
+ return undefined;
203
343
  return [
204
- '## brainclaw — version check',
344
+ '## brainclaw — working rules',
205
345
  '',
206
- 'Call `bclaw_get_execution_context` at session start to check for brainclaw updates.',
207
- 'If a newer version is available, inform the developer and suggest updating.',
208
- 'Brainclaw updates may include new features, bug fixes, and improved coordination.',
346
+ ...rules.map((c) => `- ${c.text}`),
209
347
  ].join('\n');
210
348
  }
211
- function renderConstraints(state) {
212
- const active = state.active_constraints.filter((c) => c.status === 'active');
213
- if (active.length === 0)
349
+ function renderArchitecture(state) {
350
+ const arch = state.active_constraints.filter((c) => c.status === 'active' && c.category && ARCH_CATEGORIES.has(c.category));
351
+ if (arch.length === 0)
214
352
  return undefined;
215
353
  return [
216
- '## brainclaw — active constraints',
354
+ '## brainclaw — architecture',
217
355
  '',
218
- ...active.map((c) => `- ${c.text}`),
356
+ ...arch.map((c) => `- ${c.text}`),
219
357
  ].join('\n');
220
358
  }
221
359
  function renderInstructions(instructions) {
@@ -227,6 +365,39 @@ function renderInstructions(instructions) {
227
365
  ...instructions.map((text) => `- ${text}`),
228
366
  ].join('\n');
229
367
  }
368
+ function renderAvailableTools() {
369
+ return [
370
+ '## brainclaw — available tools',
371
+ '',
372
+ 'The default MCP catalog is intentionally small. Start with `bclaw_work`, then use the canonical grammar for reads/writes on any entity. Coordination facades below are an **escalation path** for agents that orchestrate other agents — not the default loop.',
373
+ '',
374
+ '**Entry facades:** `bclaw_work(intent, compact?)`, `bclaw_context(kind)` — bclaw_work defaults to compact:true (minimal payload); use compact:false or bclaw_context for full memory',
375
+ '**Canonical grammar (standard tier) — your main tool for working with memory:**',
376
+ '- `bclaw_find(entity, filter?)` — list by type',
377
+ '- `bclaw_get(entity, id)` — read one',
378
+ '- `bclaw_create(entity, data)` — add a new plan / decision / constraint / trap / handoff / candidate / runtime_note',
379
+ '- `bclaw_update(entity, id, patch)` — edit in place',
380
+ '- `bclaw_remove(entity, id, purge?)` — soft-delete (or purge)',
381
+ '- `bclaw_transition(entity, id, to)` — change status (e.g. plan todo→in_progress→done)',
382
+ '',
383
+ 'Entities supported by the grammar: plan, decision, constraint, trap, handoff, runtime_note, candidate, claim, action, assignment, agent_run.',
384
+ '',
385
+ '**Cross-project access (pln#359):** every canonical-grammar call, `bclaw_context`, and `bclaw_coordinate` accept an optional `project: <name>` argument that routes the operation to a linked project (cross_project_links from `brainclaw link list` OR a workspace store-chain child). Identity is sourced from the caller; writes + audit land in the target. Unknown project names throw — no silent fallback. The CLI exposes the same as `--project <name>` (mutually exclusive with `--cwd`). Example: `bclaw_get(entity="trap", id="trp#36", project="brainclaw-site")`. Cross-project `bclaw_coordinate` is inbox-only — auto-spawn is force-disabled because the spawn cwd / worktree are tied to the target repo; the target agent picks the brief up async via its own `bclaw_work`.',
386
+ '',
387
+ '**Session + claims:** `bclaw_session_start`, `bclaw_session_end`, `bclaw_claim`, `bclaw_release_claim`',
388
+ '**Plan steps:** `bclaw_add_step`, `bclaw_complete_step`, `bclaw_update_step`, `bclaw_delete_step`',
389
+ '**Inbox + handoffs:** `bclaw_read_inbox`, `bclaw_ack_message`, `bclaw_send_message`, `bclaw_correct_handoff`',
390
+ '**Notes + search:** `bclaw_write_note`, `bclaw_quick_capture`, `bclaw_search`',
391
+ '**Escalation (orchestrator path):**',
392
+ '- Review / consult / assign another agent → `bclaw_coordinate(intent=review|consult|assign)` (use `open_loop=true` on review to also dispatch the reviewer turn)',
393
+ '- Parallel execute across a sequence\'s lanes → `bclaw_dispatch(intent=execute)`',
394
+ '- Drive your turn in an already-opened loop → `bclaw_loop(intent=turn|complete_turn|advance|close)`',
395
+ '**Setup + navigation:** `bclaw_setup`, `bclaw_bootstrap`, `bclaw_switch`, `bclaw_release_notes`',
396
+ '',
397
+ 'Legacy per-entity tools (`bclaw_list_plans`, `bclaw_accept`, `bclaw_get_context`, `bclaw_dispatch_review`, …) were removed from the catalog at v1.0 — direct calls still succeed as a migration escape hatch but emit a redirect warning. See `docs/integrations/mcp.md` + `docs/concepts/mcp-governance.md` for the full catalog and stability contract; raw MCP clients can request advanced tools with `tools/list` params `{ catalog: "all" }`.',
398
+ ].join('\n');
399
+ }
400
+ // ─── Live section renderers ─────────────────────────────────────────────────
230
401
  function renderTopTraps(state, limit) {
231
402
  const traps = state.known_traps
232
403
  .filter((t) => t.visibility === 'shared' && (!t.status || t.status === 'active') && !t.platform_scope)
@@ -262,6 +433,42 @@ function renderActivePlans(state, limit) {
262
433
  }),
263
434
  ].join('\n');
264
435
  }
436
+ function renderActiveClaimsFromInput(input) {
437
+ const claims = input.activeClaims;
438
+ if (!claims || claims.length === 0)
439
+ return undefined;
440
+ return [
441
+ '## brainclaw — active claims',
442
+ '',
443
+ ...claims.map((c) => `- ${c.scope} (by ${c.agent ?? 'unknown'})`),
444
+ ].join('\n');
445
+ }
446
+ function renderPendingCandidates(input) {
447
+ const candidates = input.pendingCandidates;
448
+ if (!candidates || candidates.length === 0)
449
+ return undefined;
450
+ return [
451
+ '## brainclaw — open candidates',
452
+ '',
453
+ ...candidates.slice(0, 5).map((c) => `- [${c.type}] ${c.text} (by ${c.author ?? 'unknown'})`),
454
+ ].join('\n');
455
+ }
456
+ function renderOpenHandoffs(state, limit) {
457
+ const handoffs = state.open_handoffs
458
+ .filter((h) => !h.status || h.status === 'open')
459
+ .slice(-limit)
460
+ .reverse();
461
+ if (handoffs.length === 0)
462
+ return undefined;
463
+ return [
464
+ '## brainclaw — open handoffs',
465
+ '',
466
+ ...handoffs.map((h) => {
467
+ const plan = h.plan_id ? ` (${h.plan_id})` : '';
468
+ return `- ${h.from ?? 'unknown'} -> ${h.to ?? 'unknown'}${plan}: ${h.text}`;
469
+ }),
470
+ ].join('\n');
471
+ }
265
472
  function renderRecentDecisions(state) {
266
473
  const decisions = state.recent_decisions.slice(-5);
267
474
  if (decisions.length === 0)
@@ -301,6 +508,7 @@ function formatForAgent(agentName) {
301
508
  case 'windsurf': return 'windsurf';
302
509
  case 'cline': return 'cline';
303
510
  case 'roo': return 'roo';
511
+ case 'kilocode': return 'kilocode';
304
512
  case 'continue': return 'continue';
305
513
  default: return 'agents-md';
306
514
  }