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.
- package/README.md +193 -170
- package/dist/brainclaw-vscode.vsix +0 -0
- package/dist/cli.js +673 -24
- package/dist/commands/accept.js +3 -0
- package/dist/commands/add-step.js +11 -26
- package/dist/commands/agent-board.js +70 -3
- package/dist/commands/audit.js +19 -0
- package/dist/commands/check-policy.js +54 -0
- package/dist/commands/check-security-mcp.js +145 -0
- package/dist/commands/check-security.js +106 -0
- package/dist/commands/claim-resource.js +1 -0
- package/dist/commands/codev.js +672 -0
- package/dist/commands/compact.js +74 -0
- package/dist/commands/complete-step.js +16 -26
- package/dist/commands/constraint.js +8 -20
- package/dist/commands/decision.js +9 -20
- package/dist/commands/delete-plan.js +10 -12
- package/dist/commands/delete-step.js +16 -0
- package/dist/commands/dispatch.js +163 -0
- package/dist/commands/doctor.js +1122 -49
- package/dist/commands/enable-agent.js +1 -0
- package/dist/commands/export.js +280 -22
- package/dist/commands/handoff.js +33 -0
- package/dist/commands/harvest.js +189 -0
- package/dist/commands/hooks.js +82 -25
- package/dist/commands/inbox.js +169 -0
- package/dist/commands/init.js +38 -31
- package/dist/commands/install-hooks.js +71 -44
- package/dist/commands/link.js +89 -0
- package/dist/commands/list-claims.js +48 -3
- package/dist/commands/list-plans.js +129 -25
- package/dist/commands/loops-handlers.js +409 -0
- package/dist/commands/mcp-read-handlers.js +1628 -0
- package/dist/commands/mcp-schemas.generated.js +74 -0
- package/dist/commands/mcp.js +4221 -1501
- package/dist/commands/plan-resource.js +64 -0
- package/dist/commands/plan.js +12 -26
- package/dist/commands/prune.js +37 -2
- package/dist/commands/reflect.js +20 -7
- package/dist/commands/release-claim.js +11 -6
- package/dist/commands/release-notes.js +170 -0
- package/dist/commands/repair.js +210 -0
- package/dist/commands/run-profile.js +57 -0
- package/dist/commands/sequence.js +113 -0
- package/dist/commands/session-end.js +423 -14
- package/dist/commands/session-start.js +214 -41
- package/dist/commands/setup-security.js +103 -0
- package/dist/commands/setup.js +42 -4
- package/dist/commands/stale.js +109 -0
- package/dist/commands/switch.js +100 -2
- package/dist/commands/trap.js +14 -31
- package/dist/commands/update-handoff.js +63 -4
- package/dist/commands/update-plan.js +21 -28
- package/dist/commands/update-step.js +37 -0
- package/dist/commands/upgrade.js +313 -6
- package/dist/commands/usage.js +102 -0
- package/dist/commands/version.js +20 -0
- package/dist/commands/who.js +33 -5
- package/dist/commands/worktree.js +105 -0
- package/dist/core/actions.js +315 -0
- package/dist/core/agent-capability.js +610 -17
- package/dist/core/agent-context.js +7 -1
- package/dist/core/agent-files.js +1169 -85
- package/dist/core/agent-integrations.js +160 -5
- package/dist/core/agent-inventory.js +2 -0
- package/dist/core/agent-profiles.js +93 -0
- package/dist/core/agent-registry.js +162 -30
- package/dist/core/agentrun-reconciler.js +345 -0
- package/dist/core/agentruns.js +424 -0
- package/dist/core/ai-agent-detection.js +31 -10
- package/dist/core/archival.js +77 -0
- package/dist/core/assignment-sweeper.js +82 -0
- package/dist/core/assignments.js +367 -0
- package/dist/core/audit.js +30 -0
- package/dist/core/brainclaw-version.js +94 -2
- package/dist/core/candidates.js +93 -2
- package/dist/core/claims.js +419 -0
- package/dist/core/codev-metrics.js +77 -0
- package/dist/core/codev-personas.js +31 -0
- package/dist/core/codev-plan-gen.js +35 -0
- package/dist/core/codev-prompts.js +74 -0
- package/dist/core/codev-responses.js +62 -0
- package/dist/core/codev-rounds.js +218 -0
- package/dist/core/config.js +4 -0
- package/dist/core/context.js +381 -34
- package/dist/core/coordination.js +201 -6
- package/dist/core/cross-project.js +230 -16
- package/dist/core/default-profiles/doctor.yaml +11 -0
- package/dist/core/default-profiles/janitor.yaml +11 -0
- package/dist/core/default-profiles/onboarder.yaml +11 -0
- package/dist/core/default-profiles/reviewer.yaml +13 -0
- package/dist/core/dispatcher.js +1189 -0
- package/dist/core/duplicates.js +2 -2
- package/dist/core/entity-operations.js +450 -0
- package/dist/core/entity-registry.js +344 -0
- package/dist/core/events.js +106 -2
- package/dist/core/execution-adapters.js +154 -0
- package/dist/core/execution-context.js +63 -0
- package/dist/core/execution-profile.js +270 -0
- package/dist/core/execution.js +255 -0
- package/dist/core/facade-schema.js +81 -0
- package/dist/core/federation-cloud.js +99 -0
- package/dist/core/federation-message.js +52 -0
- package/dist/core/federation-transport.js +65 -0
- package/dist/core/gc-semantic.js +482 -0
- package/dist/core/governance.js +247 -0
- package/dist/core/guards.js +19 -0
- package/dist/core/ideation.js +72 -0
- package/dist/core/identity.js +110 -25
- package/dist/core/ids.js +6 -0
- package/dist/core/input-validation.js +2 -2
- package/dist/core/instruction-templates.js +344 -136
- package/dist/core/io.js +90 -11
- package/dist/core/lock.js +6 -2
- package/dist/core/loops/brief-assembly.js +213 -0
- package/dist/core/loops/facade-schema.js +148 -0
- package/dist/core/loops/index.js +7 -0
- package/dist/core/loops/iteration-engine.js +139 -0
- package/dist/core/loops/lock.js +385 -0
- package/dist/core/loops/store.js +201 -0
- package/dist/core/loops/types.js +403 -0
- package/dist/core/loops/verbs.js +534 -0
- package/dist/core/markdown.js +15 -3
- package/dist/core/memory-compactor.js +432 -0
- package/dist/core/memory-git.js +152 -8
- package/dist/core/messaging.js +278 -0
- package/dist/core/migration.js +32 -1
- package/dist/core/mutation-pipeline.js +4 -2
- package/dist/core/operations/memory-mutation.js +129 -0
- package/dist/core/operations/memory-write.js +78 -0
- package/dist/core/operations/plan.js +190 -0
- package/dist/core/policy.js +169 -0
- package/dist/core/reputation.js +9 -3
- package/dist/core/schema.js +491 -6
- package/dist/core/search.js +21 -2
- package/dist/core/security-cache.js +71 -0
- package/dist/core/security-guard.js +152 -0
- package/dist/core/security-scoring.js +86 -0
- package/dist/core/sequence.js +130 -0
- package/dist/core/socket-client.js +113 -0
- package/dist/core/staleness.js +246 -0
- package/dist/core/state.js +98 -22
- package/dist/core/store-resolution.js +43 -11
- package/dist/core/toml-writer.js +76 -0
- package/dist/core/upgrades/backup.js +232 -0
- package/dist/core/upgrades/health-check.js +169 -0
- package/dist/core/upgrades/patches/candidate-archive.js +145 -0
- package/dist/core/upgrades/patches/handoff-review-strip.js +128 -0
- package/dist/core/upgrades/patches/provenance-rollout.js +136 -0
- package/dist/core/upgrades/schema-version.js +97 -0
- package/dist/core/worktree.js +606 -0
- package/dist/facts.js +114 -0
- package/dist/facts.json +111 -0
- package/docs/architecture/project-refs.md +5 -1
- package/docs/cli.md +690 -43
- package/docs/concepts/ideation-loop.md +317 -0
- package/docs/concepts/loop-engine.md +456 -0
- package/docs/concepts/mcp-governance.md +268 -0
- package/docs/concepts/memory-staleness.md +122 -0
- package/docs/concepts/multi-agent-workflows.md +166 -0
- package/docs/concepts/plans-and-claims.md +31 -6
- package/docs/concepts/project-md-convention.md +35 -0
- package/docs/concepts/troubleshooting.md +220 -0
- package/docs/concepts/upgrade-cli.md +202 -0
- package/docs/concepts/upgrade-dogfood-procedure.md +114 -0
- package/docs/context-format-changelog.md +2 -2
- package/docs/context-format.md +2 -2
- package/docs/index.md +68 -0
- package/docs/integrations/agents.md +15 -16
- package/docs/integrations/cline.md +88 -0
- package/docs/integrations/codex.md +75 -23
- package/docs/integrations/continue.md +60 -0
- package/docs/integrations/copilot.md +67 -9
- package/docs/integrations/kilocode.md +72 -0
- package/docs/integrations/mcp.md +304 -21
- package/docs/integrations/mistral-vibe.md +122 -0
- package/docs/integrations/opencode.md +84 -0
- package/docs/integrations/overview.md +23 -8
- package/docs/integrations/roo.md +74 -0
- package/docs/integrations/windsurf.md +83 -0
- package/docs/mcp-schema-changelog.md +191 -1
- package/docs/playbooks/integration/index.md +121 -0
- package/docs/playbooks/productivity/index.md +102 -0
- package/docs/playbooks/team/index.md +122 -0
- package/docs/product/agent-first-model.md +184 -0
- package/docs/product/entity-model-audit.md +462 -0
- package/docs/quickstart-existing-project.md +135 -0
- package/docs/quickstart.md +124 -37
- package/docs/release-maintenance.md +79 -0
- package/docs/review.md +2 -0
- package/docs/server-operations.md +118 -0
- package/package.json +20 -12
- package/dist/commands/claude-desktop-extension.js +0 -18
- package/dist/commands/diff.js +0 -99
- 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-
|
|
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
|
|
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.
|