brainclaw 1.19.0 → 1.19.1
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/dist/brainclaw-vscode.vsix +0 -0
- package/dist/commands/claim.js +5 -1
- package/dist/commands/mcp-write-claims.js +6 -1
- package/dist/commands/mcp.js +6 -1
- package/dist/core/claims.js +35 -2
- package/dist/facts.js +7 -7
- package/dist/facts.json +6 -6
- package/package.json +1 -1
|
Binary file
|
package/dist/commands/claim.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { buildOperationalIdentity } from '../core/identity.js';
|
|
2
2
|
import { memoryExists } from '../core/io.js';
|
|
3
3
|
import { mutate } from '../core/mutation-pipeline.js';
|
|
4
|
-
import { saveClaim, generateClaimId, listClaims } from '../core/claims.js';
|
|
4
|
+
import { saveClaim, generateClaimId, listClaims, claimBaselineFields } from '../core/claims.js';
|
|
5
5
|
import { rebuildProjectMd } from '../core/markdown.js';
|
|
6
6
|
import { loadState, saveState } from '../core/state.js';
|
|
7
7
|
import { nowISO } from '../core/ids.js';
|
|
@@ -64,6 +64,10 @@ export function runClaim(description, options) {
|
|
|
64
64
|
status: 'active',
|
|
65
65
|
expires_at: options.ttl ? parseTtl(options.ttl) : undefined,
|
|
66
66
|
model: resolveCurrentModel(options.cwd),
|
|
67
|
+
// pln#636 C0-b / trp#1292 — resolved here, OUTSIDE the mutate() below, so the
|
|
68
|
+
// git subprocess never widens the critical section that serializes writes on
|
|
69
|
+
// the claims store.
|
|
70
|
+
...claimBaselineFields(options.cwd),
|
|
67
71
|
};
|
|
68
72
|
try {
|
|
69
73
|
mutate({ cwd: options.cwd }, () => {
|
|
@@ -18,7 +18,7 @@ import { getTriggeredItems, renderTriggeredItems } from '../core/lifecycle.js';
|
|
|
18
18
|
import { buildContext } from '../core/context.js';
|
|
19
19
|
import { checkBrainclawInstallableUpdate, getInstalledBrainclawVersion, renderBrainclawInstallableUpdateNotice } from '../core/brainclaw-version.js';
|
|
20
20
|
import { loadConfig } from '../core/config.js';
|
|
21
|
-
import { generateClaimId, loadClaim, saveClaim, adoptClaimSession, releaseClaimWithCascade } from '../core/claims.js';
|
|
21
|
+
import { generateClaimId, loadClaim, saveClaim, adoptClaimSession, releaseClaimWithCascade, claimBaselineFields } from '../core/claims.js';
|
|
22
22
|
import { releaseClaimNextActions } from '../core/next-actions.js';
|
|
23
23
|
import { reconcileClaimConformity } from '../core/claim-conformity.js';
|
|
24
24
|
import { pushStructuredWarning } from '../core/warnings.js';
|
|
@@ -128,6 +128,11 @@ export async function handleBclawClaim(payload, ctx) {
|
|
|
128
128
|
worktree_path: worktreePath,
|
|
129
129
|
expires_at: claimExpiresAt,
|
|
130
130
|
handoff_mode: handoffMode,
|
|
131
|
+
// pln#636 C0-b / trp#1292 — this handler builds its claim literal instead of
|
|
132
|
+
// going through acquireClaimScope, which is why the baseline was missing on
|
|
133
|
+
// every MCP-created claim and the conformity reconcile never had anything to
|
|
134
|
+
// compare against.
|
|
135
|
+
...claimBaselineFields(claimCwd),
|
|
131
136
|
}, claimCwd);
|
|
132
137
|
appendAuditEntry({ actor: resolvedIdentity.agent_name, actor_id: resolvedIdentity.agent_id, action: 'claim', item_id: claimId, item_type: 'claim', scope: claimScope, session_id: identity.session_id, host_id: identity.host_id }, claimCwd);
|
|
133
138
|
// Post-claim policy check: surface constraints/traps as warnings
|
package/dist/commands/mcp.js
CHANGED
|
@@ -13,7 +13,7 @@ import { collectLoadValidationWarnings, findLoadValidationWarning, loadState } f
|
|
|
13
13
|
import { memoryExists, MEMORY_DIR } from '../core/io.js';
|
|
14
14
|
import { getEntity, listEntities, boundListResult, DEFAULT_FIND_CHAR_BUDGET, GRAMMAR_FILTER_CONTRACT, } from '../core/entity-operations.js';
|
|
15
15
|
import { handoffDiffPreviewNote } from '../core/handoff-snapshot.js';
|
|
16
|
-
import { generateClaimId, listClaims, loadClaim, saveClaim, adoptClaimSession } from '../core/claims.js';
|
|
16
|
+
import { generateClaimId, listClaims, loadClaim, saveClaim, adoptClaimSession, claimBaselineFields } from '../core/claims.js';
|
|
17
17
|
import { assertCrossProjectBoundary, checkPolicy } from '../core/policy.js';
|
|
18
18
|
import { startSession } from './session-start.js';
|
|
19
19
|
import { AgentIdentityResolutionError, AgentTrustError, resolveCurrentModel, } from '../core/agent-registry.js';
|
|
@@ -1302,6 +1302,11 @@ async function _executeMcpToolCallInner(payload) {
|
|
|
1302
1302
|
status: 'active',
|
|
1303
1303
|
plan_id: workReq.planId,
|
|
1304
1304
|
model: currentModel,
|
|
1305
|
+
// pln#636 C0-b / trp#1292 — bclaw_work(execute) is the entry point the
|
|
1306
|
+
// session protocol tells every agent to start with, so a missing
|
|
1307
|
+
// baseline here made the conformity reconcile inert for nearly all
|
|
1308
|
+
// real claims.
|
|
1309
|
+
...claimBaselineFields(targetCwd),
|
|
1305
1310
|
}, targetCwd);
|
|
1306
1311
|
appendAuditEntry({ actor: sessionResult.agent, actor_id: sessionResult.agent_id, action: 'claim', item_id: claimId, item_type: 'claim', scope: workReq.scope, session_id: sessionResult.session_id }, targetCwd);
|
|
1307
1312
|
claimStatus = 'created';
|
package/dist/core/claims.js
CHANGED
|
@@ -150,6 +150,34 @@ export function resolveClaimBaseSha(cwd) {
|
|
|
150
150
|
return undefined;
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
+
/**
|
|
154
|
+
* The baseline fields every NEW claim must carry, ready to spread into a claim
|
|
155
|
+
* literal: `{ ...claimBaselineFields(cwd) }`.
|
|
156
|
+
*
|
|
157
|
+
* WHY A HELPER AND NOT AN INLINE CALL. `base_sha` shipped in 1.19.0 stamped from
|
|
158
|
+
* exactly ONE place — inside `acquireClaimScope` — and it turned out nothing
|
|
159
|
+
* user-facing calls that function. All four real creation paths
|
|
160
|
+
* (`bclaw_work(execute)`, `bclaw_claim`, the CLI `claim create`, and
|
|
161
|
+
* `createCoordinatorClaim`) build their claim literal inline and call `saveClaim`
|
|
162
|
+
* directly, so NO real claim ever got a baseline and the whole conformity
|
|
163
|
+
* reconcile that depends on it was inert (trp#1292). A named, greppable helper is
|
|
164
|
+
* what makes "did this creation path stamp the baseline?" answerable, and it is
|
|
165
|
+
* asserted per surface rather than only on the core function — testing
|
|
166
|
+
* `acquireClaimScope` directly is exactly what hid the gap.
|
|
167
|
+
*
|
|
168
|
+
* Returns an EMPTY object rather than `{ base_sha: undefined }` so a claim created
|
|
169
|
+
* outside a git repo has no such key at all, matching the "optional, never
|
|
170
|
+
* backfilled" contract the schema documents.
|
|
171
|
+
*
|
|
172
|
+
* Deliberately NOT applied inside `saveClaim`: that function also persists
|
|
173
|
+
* UPDATES (release, patch, adoption), and the baseline must be a fixed point —
|
|
174
|
+
* re-stamping it on every save is precisely the moving-ground failure that made
|
|
175
|
+
* `git diff HEAD` unusable in the first place.
|
|
176
|
+
*/
|
|
177
|
+
export function claimBaselineFields(cwd) {
|
|
178
|
+
const base_sha = resolveClaimBaseSha(cwd);
|
|
179
|
+
return base_sha ? { base_sha } : {};
|
|
180
|
+
}
|
|
153
181
|
/**
|
|
154
182
|
* Atomically check for an active claim on `scope` and save a new one if absent.
|
|
155
183
|
*
|
|
@@ -160,7 +188,7 @@ export function acquireClaimScope(input, cwd) {
|
|
|
160
188
|
// Resolved OUTSIDE the mutate callback: one git call per acquisition, and it
|
|
161
189
|
// stays off the critical section (mutate serializes filesystem writes on the
|
|
162
190
|
// claims store, so a subprocess spawn inside it would widen the lock window).
|
|
163
|
-
const
|
|
191
|
+
const baseline = claimBaselineFields(cwd);
|
|
164
192
|
return mutate({ cwd }, () => {
|
|
165
193
|
const conflictingClaim = listClaims(cwd).find((claim) => claim.status === 'active' && claim.scope === input.scope);
|
|
166
194
|
if (conflictingClaim) {
|
|
@@ -180,7 +208,7 @@ export function acquireClaimScope(input, cwd) {
|
|
|
180
208
|
model: input.model,
|
|
181
209
|
// pln#636 C0-b — capture the baseline while we know it. Absent when the
|
|
182
210
|
// project is not a git repo; downstream treats that as unverifiable.
|
|
183
|
-
...
|
|
211
|
+
...baseline,
|
|
184
212
|
...(input.paths?.length ? { paths: input.paths } : {}),
|
|
185
213
|
};
|
|
186
214
|
saveClaimUnlocked(claim, cwd);
|
|
@@ -854,6 +882,10 @@ export function createCoordinatorClaim(options) {
|
|
|
854
882
|
};
|
|
855
883
|
}
|
|
856
884
|
const claimId = generateClaimId();
|
|
885
|
+
// Resolved OUTSIDE the lock below, for the same reason acquireClaimScope does
|
|
886
|
+
// it: a subprocess spawn inside the mutate callback would widen the critical
|
|
887
|
+
// section that serializes writes on the claims store.
|
|
888
|
+
const baseline = claimBaselineFields(options.cwd);
|
|
857
889
|
let worktreePath;
|
|
858
890
|
let worktreeWarning;
|
|
859
891
|
// Create isolated worktree (matching bclaw_claim MCP handler behavior).
|
|
@@ -905,6 +937,7 @@ export function createCoordinatorClaim(options) {
|
|
|
905
937
|
created_at: nowISO(),
|
|
906
938
|
status: 'active',
|
|
907
939
|
worktree_path: worktreePath,
|
|
940
|
+
...baseline, // pln#636 C0-b / trp#1292 — dispatched lanes need it most
|
|
908
941
|
}, options.cwd);
|
|
909
942
|
return { claimId, worktreePath, worktreeWarning, reusedExisting: false };
|
|
910
943
|
});
|
package/dist/facts.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Generated by scripts/emit-site-facts.mjs at build time. Do not edit manually.
|
|
2
|
-
// Source: brainclaw v1.19.
|
|
2
|
+
// Source: brainclaw v1.19.1 on 2026-08-02T07:16:39.143Z
|
|
3
3
|
export const FACTS = {
|
|
4
|
-
"version": "1.19.
|
|
5
|
-
"generated_at": "2026-08-
|
|
4
|
+
"version": "1.19.1",
|
|
5
|
+
"generated_at": "2026-08-02T07:16:39.143Z",
|
|
6
6
|
"tools": {
|
|
7
7
|
"count": 67,
|
|
8
8
|
"published_count": 65,
|
|
@@ -474,7 +474,7 @@ export const FACTS = {
|
|
|
474
474
|
},
|
|
475
475
|
"bench": {
|
|
476
476
|
"schema": "brainclaw.bench.v1",
|
|
477
|
-
"generated_at": "2026-08-
|
|
477
|
+
"generated_at": "2026-08-02T07:16:37.042Z",
|
|
478
478
|
"node_version": "v24.18.0",
|
|
479
479
|
"platform": "linux-x64",
|
|
480
480
|
"repeats": 3,
|
|
@@ -483,7 +483,7 @@ export const FACTS = {
|
|
|
483
483
|
"name": "cold_onboard",
|
|
484
484
|
"volume": "empty",
|
|
485
485
|
"description": "fresh machine → init → first useful context. Baseline for time-to-first-value.",
|
|
486
|
-
"duration_ms_median":
|
|
486
|
+
"duration_ms_median": 81,
|
|
487
487
|
"payload_chars_median": 1640,
|
|
488
488
|
"payload_tokens_est_median": 410
|
|
489
489
|
},
|
|
@@ -491,7 +491,7 @@ export const FACTS = {
|
|
|
491
491
|
"name": "warm_work",
|
|
492
492
|
"volume": "medium",
|
|
493
493
|
"description": "bclaw_work consult over a real-shaped store (~200 plans / 500 handoffs / 450 claims).",
|
|
494
|
-
"duration_ms_median":
|
|
494
|
+
"duration_ms_median": 123,
|
|
495
495
|
"payload_chars_median": 2626,
|
|
496
496
|
"payload_tokens_est_median": 657
|
|
497
497
|
},
|
|
@@ -499,7 +499,7 @@ export const FACTS = {
|
|
|
499
499
|
"name": "first_edit",
|
|
500
500
|
"volume": "medium",
|
|
501
501
|
"description": "code_find + code_brief on the fresh-agent path (missing index, first touch).",
|
|
502
|
-
"duration_ms_median":
|
|
502
|
+
"duration_ms_median": 12,
|
|
503
503
|
"payload_chars_median": 499,
|
|
504
504
|
"payload_tokens_est_median": 125
|
|
505
505
|
}
|
package/dist/facts.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.19.
|
|
3
|
-
"generated_at": "2026-08-
|
|
2
|
+
"version": "1.19.1",
|
|
3
|
+
"generated_at": "2026-08-02T07:16:39.143Z",
|
|
4
4
|
"tools": {
|
|
5
5
|
"count": 67,
|
|
6
6
|
"published_count": 65,
|
|
@@ -472,7 +472,7 @@
|
|
|
472
472
|
},
|
|
473
473
|
"bench": {
|
|
474
474
|
"schema": "brainclaw.bench.v1",
|
|
475
|
-
"generated_at": "2026-08-
|
|
475
|
+
"generated_at": "2026-08-02T07:16:37.042Z",
|
|
476
476
|
"node_version": "v24.18.0",
|
|
477
477
|
"platform": "linux-x64",
|
|
478
478
|
"repeats": 3,
|
|
@@ -481,7 +481,7 @@
|
|
|
481
481
|
"name": "cold_onboard",
|
|
482
482
|
"volume": "empty",
|
|
483
483
|
"description": "fresh machine → init → first useful context. Baseline for time-to-first-value.",
|
|
484
|
-
"duration_ms_median":
|
|
484
|
+
"duration_ms_median": 81,
|
|
485
485
|
"payload_chars_median": 1640,
|
|
486
486
|
"payload_tokens_est_median": 410
|
|
487
487
|
},
|
|
@@ -489,7 +489,7 @@
|
|
|
489
489
|
"name": "warm_work",
|
|
490
490
|
"volume": "medium",
|
|
491
491
|
"description": "bclaw_work consult over a real-shaped store (~200 plans / 500 handoffs / 450 claims).",
|
|
492
|
-
"duration_ms_median":
|
|
492
|
+
"duration_ms_median": 123,
|
|
493
493
|
"payload_chars_median": 2626,
|
|
494
494
|
"payload_tokens_est_median": 657
|
|
495
495
|
},
|
|
@@ -497,7 +497,7 @@
|
|
|
497
497
|
"name": "first_edit",
|
|
498
498
|
"volume": "medium",
|
|
499
499
|
"description": "code_find + code_brief on the fresh-agent path (missing index, first touch).",
|
|
500
|
-
"duration_ms_median":
|
|
500
|
+
"duration_ms_median": 12,
|
|
501
501
|
"payload_chars_median": 499,
|
|
502
502
|
"payload_tokens_est_median": 125
|
|
503
503
|
}
|