brainclaw 1.26.2 → 1.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +13 -0
- package/dist/brainclaw-vscode.vsix +0 -0
- package/dist/cli/register-coordination.js +65 -1
- package/dist/commands/attempt-authority.js +80 -0
- package/dist/commands/harvest.js +140 -61
- package/dist/commands/loop.js +34 -0
- package/dist/commands/loops-handlers.js +143 -15
- package/dist/commands/mcp-catalog.js +52 -18
- package/dist/commands/mcp-schemas.generated.js +64 -0
- package/dist/commands/mcp-write-claims.js +128 -1
- package/dist/commands/mcp-write-coordination.js +149 -76
- package/dist/core/agent-capability.js +1 -1
- package/dist/core/agentrun-reconciler.js +148 -22
- package/dist/core/agentruns.js +254 -29
- package/dist/core/assignment-request-schema.js +7 -0
- package/dist/core/assignment-sweeper.js +5 -3
- package/dist/core/assignments.js +131 -33
- package/dist/core/claim-request-schema.js +7 -0
- package/dist/core/claims.js +53 -2
- package/dist/core/dispatch-status.js +16 -6
- package/dist/core/dispatcher.js +51 -51
- package/dist/core/entity-operations.js +20 -0
- package/dist/core/events.js +4 -0
- package/dist/core/execution-adapters.js +189 -14
- package/dist/core/execution-contract.js +345 -0
- package/dist/core/execution.js +130 -16
- package/dist/core/facade-schema.js +3 -0
- package/dist/core/harness-adapters/base.js +150 -0
- package/dist/core/harness-adapters/claude.js +39 -0
- package/dist/core/harness-adapters/codex.js +57 -0
- package/dist/core/harness-adapters/harvest.js +109 -0
- package/dist/core/harness-adapters/index.js +8 -0
- package/dist/core/harness-adapters/prompt-only.js +13 -0
- package/dist/core/harness-adapters/registry.js +48 -0
- package/dist/core/harness-adapters/result.js +33 -0
- package/dist/core/harness-adapters/types.js +2 -0
- package/dist/core/ideation-loop-close.js +25 -2
- package/dist/core/instruction-templates.js +3 -2
- package/dist/core/loop-turn-dispatch.js +235 -0
- package/dist/core/loops/artifact-contract.js +11 -0
- package/dist/core/loops/attempt-authority.js +496 -0
- package/dist/core/loops/attempt-generations.js +509 -0
- package/dist/core/loops/attempt-reservation.js +197 -35
- package/dist/core/loops/attempt-rollout.js +404 -0
- package/dist/core/loops/attempt-takeover.js +155 -0
- package/dist/core/loops/bootstrap-acquire.js +7 -3
- package/dist/core/loops/brief-assembly.js +21 -4
- package/dist/core/loops/evidence.js +188 -0
- package/dist/core/loops/facade-schema.js +75 -11
- package/dist/core/loops/gate-policy.js +533 -0
- package/dist/core/loops/impl-bind.js +91 -81
- package/dist/core/loops/index.js +9 -0
- package/dist/core/loops/iteration-engine.js +31 -19
- package/dist/core/loops/kind-policies.js +90 -0
- package/dist/core/loops/lock.js +71 -13
- package/dist/core/loops/reconcile-turn.js +237 -18
- package/dist/core/loops/result-reducers.js +113 -10
- package/dist/core/loops/store.js +34 -3
- package/dist/core/loops/turn-execution.js +480 -0
- package/dist/core/loops/types.js +127 -3
- package/dist/core/loops/verbs.js +335 -99
- package/dist/core/loops/verify-command.js +105 -20
- package/dist/core/loops/workspace-digest.js +54 -0
- package/dist/core/review-loop-close.js +25 -3
- package/dist/core/review-loop-turn-dispatch.js +210 -161
- package/dist/core/runtime-signals.js +62 -25
- package/dist/core/schema.js +40 -0
- package/dist/core/spawn-check.js +3 -2
- package/dist/core/upgrades/backup.js +27 -4
- package/dist/facts.js +9 -8
- package/dist/facts.json +8 -7
- package/docs/cli.md +49 -1
- package/docs/concepts/attempt-authority.md +407 -0
- package/docs/concepts/evidence-attestations.md +135 -0
- package/docs/concepts/execution-contract.md +166 -0
- package/docs/concepts/harness-adapters.md +166 -0
- package/docs/concepts/ideation-loop.md +5 -4
- package/docs/concepts/loop-engine.md +302 -113
- package/docs/index.md +4 -1
- package/docs/integrations/codex.md +3 -3
- package/docs/integrations/mcp.md +59 -5
- package/docs/loops/debug.md +144 -0
- package/docs/loops/ideation.md +158 -0
- package/docs/loops/implementation.md +174 -0
- package/docs/loops/research.md +136 -0
- package/docs/loops/review.md +200 -0
- package/docs/mcp-schema-changelog.md +18 -5
- package/package.json +1 -1
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Execution contract and capability snapshot
|
|
2
|
+
|
|
3
|
+
Every worker-backed Loop turn now carries an immutable `ExecutionContract v1`.
|
|
4
|
+
It answers a narrower question than the Loop protocol: **what exact work may
|
|
5
|
+
this selected worker launch, under which capabilities and evidence rules?** The
|
|
6
|
+
Loop Engine still owns phases, gates, iteration and convergence. The contract
|
|
7
|
+
freezes one physical attempt at the dispatch boundary.
|
|
8
|
+
|
|
9
|
+
This is shared infrastructure for all five `LoopKind` values. It is neither a
|
|
10
|
+
review-loop feature nor a new workflow engine:
|
|
11
|
+
|
|
12
|
+
| Loop kind | Examples of contracted worker phases |
|
|
13
|
+
|---|---|
|
|
14
|
+
| `review` | `findings`, `author_response`, `followup_review` |
|
|
15
|
+
| `ideation` | `critique` |
|
|
16
|
+
| `implementation` | `execute` |
|
|
17
|
+
| `research` | `investigate`, `synthesize` |
|
|
18
|
+
| `debug` | `reproduce`, `hypothesize`, `isolate`, `fix` |
|
|
19
|
+
|
|
20
|
+
Engine and manual phases do not launch workers and therefore do not create an
|
|
21
|
+
execution contract.
|
|
22
|
+
|
|
23
|
+
## What is frozen
|
|
24
|
+
|
|
25
|
+
`ExecutionContract v1` contains:
|
|
26
|
+
|
|
27
|
+
- loop, turn, logical attempt epoch, Assignment and AgentRun identity;
|
|
28
|
+
- LoopKind, phase and iteration;
|
|
29
|
+
- completion mode and explicitly typed expected artifacts;
|
|
30
|
+
- a `CapabilityRequirement`;
|
|
31
|
+
- workspace scope, checkout isolation and write policy;
|
|
32
|
+
- dispatch and launch-grant durations;
|
|
33
|
+
- evidence requirements (`turn_id`, `run_id`, nonce and artifact-hash policy);
|
|
34
|
+
- the minimum contract and AttemptAuthority protocol versions a reader must
|
|
35
|
+
understand.
|
|
36
|
+
|
|
37
|
+
The logical attempt epoch belongs to immutable identity. It is distinct from
|
|
38
|
+
the mutable launch-grant epoch, which may increase when an armed generation is
|
|
39
|
+
revoked and safely re-armed before crossing.
|
|
40
|
+
|
|
41
|
+
Canonical JSON recursively sorts object keys, removes `undefined`, preserves
|
|
42
|
+
array order and normalizes strings to Unicode NFC. Its SHA-256 is the immutable
|
|
43
|
+
contract identity. A policy change therefore changes the hash; equivalent
|
|
44
|
+
Unicode and object-key ordering do not.
|
|
45
|
+
|
|
46
|
+
## Requirement is not observation
|
|
47
|
+
|
|
48
|
+
`CapabilityRequirement` says what the attempt needs. Before reservation,
|
|
49
|
+
Brainclaw resolves the selected agent's declared profile into a separate,
|
|
50
|
+
persisted `CapabilitySnapshot`:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
CapabilityRequirement + selected agent profile
|
|
54
|
+
|
|
|
55
|
+
v
|
|
56
|
+
deterministic resolver
|
|
57
|
+
|
|
|
58
|
+
accepted snapshot or reasons
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
The resolver checks role, integration surfaces, execution surface and model.
|
|
62
|
+
Current profiles do not attest an exact tool catalog, so a named
|
|
63
|
+
`required_tools` list fails closed with `tool_catalog_unattested`; Brainclaw
|
|
64
|
+
does not infer tool availability from generic MCP or skill support.
|
|
65
|
+
|
|
66
|
+
For worker-backed turns, the resolved snapshot also freezes a
|
|
67
|
+
`HarnessCapabilityBinding`: adapter id/version plus requested and selected model
|
|
68
|
+
string. A CLI model selector is marked `unattested` unless the harness can
|
|
69
|
+
actually attest account-specific availability; it is never mislabeled as an
|
|
70
|
+
exact capability merely because `--model` exists. The adapter cannot change on
|
|
71
|
+
replay or after a feature-flag flip. Runtime model and adapter observations are
|
|
72
|
+
stored separately on AgentRun and compared with the contract-bound snapshot.
|
|
73
|
+
See [Harness adapters](./harness-adapters.md).
|
|
74
|
+
|
|
75
|
+
Default roles follow the work performed by each worker phase: review findings
|
|
76
|
+
and follow-up plus ideation critique require `review`; research requires
|
|
77
|
+
`consult`; review author response, implementation and debug require `execute`.
|
|
78
|
+
A caller can provide a stricter explicit requirement when a protocol needs one.
|
|
79
|
+
|
|
80
|
+
## Persistence and authority
|
|
81
|
+
|
|
82
|
+
No new store or event journal was introduced.
|
|
83
|
+
|
|
84
|
+
| Record | Persisted contract data | Role |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `TurnReservation` | full contract, hash/reference, capability snapshot | authoritative immutable attempt record |
|
|
87
|
+
| `Assignment` | hash/reference + snapshot | business projection |
|
|
88
|
+
| `AgentRun` | hash/reference + snapshot + optional monotone anomaly fence | runtime projection |
|
|
89
|
+
|
|
90
|
+
The Assignment and AgentRun are created or validated before the launch fence
|
|
91
|
+
crosses. Recovery enriches a legacy projection only when its new fields are
|
|
92
|
+
absent; a present, divergent hash or snapshot is a projection conflict. A
|
|
93
|
+
pre-v1 reservation remains readable and adoptable without fabricating a
|
|
94
|
+
historical contract (`contract_status: legacy_uncontracted`). New records
|
|
95
|
+
always persist the complete triplet. A partial triplet fails closed because it
|
|
96
|
+
cannot prove which contract and capability observation belong together.
|
|
97
|
+
|
|
98
|
+
Compatibility is symmetric at the projection boundary. A legacy-shaped caller
|
|
99
|
+
may replay a record that already contains P1 fields without erasing or
|
|
100
|
+
conflicting with them; a P1 caller may enrich an older projection whose fields
|
|
101
|
+
are absent; two present but divergent values remain a hard conflict.
|
|
102
|
+
|
|
103
|
+
## Launch acceptance
|
|
104
|
+
|
|
105
|
+
The safe order for every worker-backed protocol is:
|
|
106
|
+
|
|
107
|
+
```text
|
|
108
|
+
validate loop/slot/claim
|
|
109
|
+
-> resolve CapabilitySnapshot
|
|
110
|
+
-> build + hash ExecutionContract
|
|
111
|
+
-> reserve / commit / arm
|
|
112
|
+
-> project Assignment + AgentRun + bindings
|
|
113
|
+
-> cross launch fence exactly once
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
An adapter that can attest an accepted contract before crossing passes both the
|
|
117
|
+
contract and capability-snapshot hashes to `prepareTurnExecution`; a mismatch
|
|
118
|
+
is rejected before reservation and the caller may reselect a worker. The normal
|
|
119
|
+
CLI path crosses the exactly-once launch fence immediately before spawn. The
|
|
120
|
+
contract variables take precedence over any environment supplied by the invoke
|
|
121
|
+
template. A small child bootstrap then reads the environment it actually
|
|
122
|
+
received, compares it with the immutable reference and:
|
|
123
|
+
|
|
124
|
+
1. writes a JSON `ack` containing the effective hashes and an
|
|
125
|
+
`accepted`/`rejected` status before invoking the worker;
|
|
126
|
+
2. exposes the hashes as `BRAINCLAW_EXECUTION_CONTRACT_HASH` and
|
|
127
|
+
`BRAINCLAW_CAPABILITY_SNAPSHOT_HASH`;
|
|
128
|
+
3. echoes them into the mechanical `completed` or `failed` sentinel; and
|
|
129
|
+
4. asks the worker to echo them in `LANE-RESULT.json`.
|
|
130
|
+
|
|
131
|
+
The dispatcher validates the acknowledgement, and harvest/reconciliation
|
|
132
|
+
validate terminal evidence against the authoritative reservation reference. A
|
|
133
|
+
missing or different hash after `launch.status=crossed` is a
|
|
134
|
+
`post_crossing_anomaly`: convergence is withheld and `respawn:false` is
|
|
135
|
+
propagated. The first observation is persisted on AgentRun as a monotone fence;
|
|
136
|
+
the bootstrap ack remains a durable fallback signal. Later correct-looking
|
|
137
|
+
lane or sentinel data cannot erase the anomaly. The process may already be
|
|
138
|
+
running, so Brainclaw never converts this condition into a manual fallback or
|
|
139
|
+
a second launch for the generation.
|
|
140
|
+
|
|
141
|
+
Manual execution uses the same environment, child bootstrap, ack and terminal
|
|
142
|
+
sentinels. The bootstrap creates the generation-keyed ack exclusively, so
|
|
143
|
+
re-running a copied command cannot start the same generation twice. Once an
|
|
144
|
+
automatic spawn has been attempted, a missing handshake or spawn error is
|
|
145
|
+
treated as an uncertain post-crossing anomaly: Brainclaw does not offer a
|
|
146
|
+
manual fallback command for that contracted generation. Contracted manual
|
|
147
|
+
commands are currently emitted only by Brainclaw's native adapter; an opaque
|
|
148
|
+
custom adapter cannot self-declare its command safe.
|
|
149
|
+
|
|
150
|
+
## Version and rollback behavior
|
|
151
|
+
|
|
152
|
+
Contract and protocol readers reject a `minimum_reader_version` above the
|
|
153
|
+
version they implement. Contract fields on TurnReservation, Assignment and
|
|
154
|
+
AgentRun are optional only for dual-reading records written before v1. A fully
|
|
155
|
+
legacy reservation continues under its historical evidence rules; new work is
|
|
156
|
+
contracted; partial or unknown future contracts fail closed instead of being
|
|
157
|
+
silently misinterpreted. The projection compatibility rules above make a
|
|
158
|
+
producer rollback non-destructive for already-enriched records.
|
|
159
|
+
|
|
160
|
+
Reference implementation:
|
|
161
|
+
|
|
162
|
+
- [`src/core/execution-contract.ts`](../../src/core/execution-contract.ts)
|
|
163
|
+
- [`src/core/loops/turn-execution.ts`](../../src/core/loops/turn-execution.ts)
|
|
164
|
+
- [`src/core/loops/attempt-reservation.ts`](../../src/core/loops/attempt-reservation.ts)
|
|
165
|
+
- [`tests/unit/execution-contract.test.ts`](../../tests/unit/execution-contract.test.ts)
|
|
166
|
+
- [`tests/unit/loops-p0c-conformance.test.ts`](../../tests/unit/loops-p0c-conformance.test.ts)
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
# Harness adapters
|
|
2
|
+
|
|
3
|
+
Brainclaw's Loop Engine can launch the same contracted turn through different
|
|
4
|
+
agent harnesses without teaching the engine about Codex, Claude, or their CLI
|
|
5
|
+
output formats. `HarnessAdapter` is the boundary between a logical worker
|
|
6
|
+
attempt and one concrete harness. It is shared by the `review`, `ideation`,
|
|
7
|
+
`implementation`, `research`, and `debug` protocols.
|
|
8
|
+
|
|
9
|
+
This is an execution seam, not another workflow engine. Loop phases, iteration,
|
|
10
|
+
stop conditions, evidence policy, and convergence remain owned by the Loop
|
|
11
|
+
Engine. Process creation, environment, working directory, timeout,
|
|
12
|
+
cancellation, sentinels, and Windows command handling remain owned by
|
|
13
|
+
`ExecutionAdapter`.
|
|
14
|
+
|
|
15
|
+
## The execution path
|
|
16
|
+
|
|
17
|
+
```text
|
|
18
|
+
Loop worker phase
|
|
19
|
+
-> resolve capability + immutable harness binding
|
|
20
|
+
-> freeze both in the ExecutionContract capability snapshot
|
|
21
|
+
-> HarnessAdapter.prepare({ contract, prompt, mode })
|
|
22
|
+
-> structured InvokeCommand
|
|
23
|
+
-> ExecutionAdapter.start(...)
|
|
24
|
+
-> raw transport observation
|
|
25
|
+
-> HarnessAdapter.parseOutcome(...)
|
|
26
|
+
-> normalized lane result
|
|
27
|
+
-> server-owned evidence envelope and protocol gates
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
The adapter receives the prompt separately because `ExecutionContract v1`
|
|
31
|
+
freezes authority and requirements, not the complete prompt body. It returns a
|
|
32
|
+
structured invocation rather than spawning a process itself. On Windows this
|
|
33
|
+
keeps prompts out of argv and out of shell quoting. A direct child receives the
|
|
34
|
+
prompt through stdin. An ack-wrapped child receives the same bytes through a
|
|
35
|
+
private per-run file redirected to stdin; the wrapper removes that file after
|
|
36
|
+
writing the terminal sentinel. This gives native Windows children a reliable
|
|
37
|
+
EOF without embedding the prompt in a second command string.
|
|
38
|
+
|
|
39
|
+
## Built-in adapters
|
|
40
|
+
|
|
41
|
+
| Adapter | Selection | Native output | Compatibility |
|
|
42
|
+
|---|---|---|---|
|
|
43
|
+
| `prompt-only@1` | Default | Existing prompt/sentinel contract | Byte-for-byte invocation compatibility with the previous path |
|
|
44
|
+
| `codex-cli@1` | `BRAINCLAW_NATIVE_HARNESS=1` for a Codex profile | JSONL (`--json`) | Falls closed to a partial result when a successful process emits invalid structured output |
|
|
45
|
+
| `claude-cli@1` | `BRAINCLAW_NATIVE_HARNESS=1` for a Claude profile | JSON (`--output-format json`) | Rejects an unattested requested model before the launch fence |
|
|
46
|
+
|
|
47
|
+
The feature flag is deliberately opt-in. An unknown or unavailable native
|
|
48
|
+
adapter does not silently become another native adapter. Existing generic
|
|
49
|
+
profiles continue through `prompt-only@1`.
|
|
50
|
+
|
|
51
|
+
## Platform and opt-in E2E matrix
|
|
52
|
+
|
|
53
|
+
The adapter contract is cross-platform even though the process boundary is
|
|
54
|
+
different. CI runs the default suite on Linux and Windows; on Windows the
|
|
55
|
+
execution adapter owns shell resolution while the harness still supplies a
|
|
56
|
+
structured argv and a separate prompt body.
|
|
57
|
+
|
|
58
|
+
| Coverage | Linux | Windows |
|
|
59
|
+
|---|---|---|
|
|
60
|
+
| Unit/contract tests for prompt-only, Codex and Claude adapters | Default CI suite on Node 22 and 24 | Default CI suite on Node 24 |
|
|
61
|
+
| Command boundary | Direct executable + argv/stdin | ExecutionAdapter shell resolution; ack-wrapped stdin uses an ephemeral redirected file, never prompt re-quoting |
|
|
62
|
+
| Repository E2E suite | Dedicated Linux job | Covered by the default platform suite; no separate Windows E2E job |
|
|
63
|
+
| Real Codex/Claude account smoke | Explicit local opt-in | Explicit local opt-in |
|
|
64
|
+
|
|
65
|
+
The real-account smoke tests are skipped by default because they require an
|
|
66
|
+
installed, authenticated CLI and spend provider quota. Run either one after
|
|
67
|
+
`npm run build:test`:
|
|
68
|
+
|
|
69
|
+
```powershell
|
|
70
|
+
$env:BRAINCLAW_CODEX_HARNESS_E2E = '1'
|
|
71
|
+
$env:BRAINCLAW_CODEX_E2E_MODEL = 'gpt-5.6-sol' # optional
|
|
72
|
+
node --test dist-test/tests/unit/harness-adapters.test.js
|
|
73
|
+
|
|
74
|
+
$env:BRAINCLAW_CLAUDE_HARNESS_E2E = '1'
|
|
75
|
+
$env:BRAINCLAW_CLAUDE_E2E_MODEL = 'sonnet' # optional
|
|
76
|
+
node --test dist-test/tests/unit/harness-adapters.test.js
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Use the equivalent environment-variable syntax on POSIX shells. These flags
|
|
80
|
+
only enable the two native smoke cases; deterministic adapter, parsing,
|
|
81
|
+
capability, restart and evidence-boundary tests always run.
|
|
82
|
+
|
|
83
|
+
## Requested, resolved, and observed capabilities
|
|
84
|
+
|
|
85
|
+
Model identity has three distinct stages:
|
|
86
|
+
|
|
87
|
+
- **requested** — what the caller asked the harness to run;
|
|
88
|
+
- **resolved** — the exact selector passed to the CLI, frozen with the adapter
|
|
89
|
+
id and version in `CapabilitySnapshot.resolved.harness` before reservation.
|
|
90
|
+
Because neither installed CLI exposes an authoritative account-specific
|
|
91
|
+
model catalogue, an explicit selector is marked `unattested`, not falsely
|
|
92
|
+
labelled `exact`;
|
|
93
|
+
- **observed** — what the harness reports after execution, stored separately on
|
|
94
|
+
`AgentRun.runtime_capability_observation`.
|
|
95
|
+
|
|
96
|
+
Requested and resolved values are immutable attempt inputs. Runtime observation
|
|
97
|
+
never rewrites that snapshot. A different observed model creates a monotone
|
|
98
|
+
execution-contract anomaly: later correct-looking output cannot erase it or
|
|
99
|
+
open a convergence gate. A retry therefore needs a new attempt instead of an
|
|
100
|
+
in-place adapter or model substitution.
|
|
101
|
+
|
|
102
|
+
## Result and evidence boundary
|
|
103
|
+
|
|
104
|
+
`parseOutcome` converts harness-specific terminal output into a result claim.
|
|
105
|
+
Normalization may map transport failure, invalid JSON, blocked work, or a
|
|
106
|
+
successful result into the common lane-result vocabulary. It may not create an
|
|
107
|
+
`EvidenceEnvelope`, decide that a phase gate passed, or advance a Loop.
|
|
108
|
+
|
|
109
|
+
Native adapters append a versioned terminal contract to the worker prompt. The
|
|
110
|
+
final assistant message inside the Codex JSONL or Claude JSON envelope must be
|
|
111
|
+
exactly one strict object (no prose inference):
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{
|
|
115
|
+
"schema_version": 1,
|
|
116
|
+
"status": "completed",
|
|
117
|
+
"summary": "No blocking findings",
|
|
118
|
+
"body": "Optional details",
|
|
119
|
+
"artifact_type": "verdict",
|
|
120
|
+
"review_verdict": "approve"
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
`review_verdict` is mandatory for review-verdict work. A missing, unknown, or
|
|
125
|
+
narratively implied verdict remains partial/failed and cannot close a review
|
|
126
|
+
Loop. Other Loop kinds use the same result-claim envelope with their own
|
|
127
|
+
server-owned expected artifact type.
|
|
128
|
+
|
|
129
|
+
Those decisions remain server-controlled. The normal order is:
|
|
130
|
+
|
|
131
|
+
```text
|
|
132
|
+
transport facts -> harness result claim -> lane-result normalization
|
|
133
|
+
-> reconciliation -> evidence sealing -> gate evaluation
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
This separation prevents a harness from turning its own prose or exit status
|
|
137
|
+
into proof. The same rule applies to all five Loop kinds; their different
|
|
138
|
+
artifact contracts are interpreted only after normalization.
|
|
139
|
+
|
|
140
|
+
## Failure and restart rules
|
|
141
|
+
|
|
142
|
+
- Missing native binaries and models known to be unsupported are rejected
|
|
143
|
+
before the launch fence. Other explicit model names are passed unchanged,
|
|
144
|
+
marked `unattested`, and never get a fallback flag; the CLI must either run
|
|
145
|
+
that selector or fail the attempt.
|
|
146
|
+
- A persisted adapter id/version must match the adapter used to prepare a
|
|
147
|
+
restart. A feature-flag change cannot silently move an existing attempt to a
|
|
148
|
+
different harness.
|
|
149
|
+
- Spawn failures and timeouts are transport diagnostics, not protocol
|
|
150
|
+
verdicts.
|
|
151
|
+
- Native structured-output parse failures are explicit partial/failed results,
|
|
152
|
+
never successful fallback to unstructured prose.
|
|
153
|
+
- Observed capability mismatch fences convergence and is recorded once on the
|
|
154
|
+
AgentRun.
|
|
155
|
+
- When a native worker does not write `LANE-RESULT.json`, targeted harvest can
|
|
156
|
+
normalize its terminal runtime logs into the same untrusted lane-result
|
|
157
|
+
ingress. Attempt identity is sourced from the reservation and completion
|
|
158
|
+
signal; reconciliation still seals evidence and evaluates the protocol gate.
|
|
159
|
+
|
|
160
|
+
## Reference implementation
|
|
161
|
+
|
|
162
|
+
- [`src/core/harness-adapters/`](../../src/core/harness-adapters/)
|
|
163
|
+
- [`src/core/execution-adapters.ts`](../../src/core/execution-adapters.ts)
|
|
164
|
+
- [`src/core/execution-contract.ts`](../../src/core/execution-contract.ts)
|
|
165
|
+
- [`src/core/loops/turn-execution.ts`](../../src/core/loops/turn-execution.ts)
|
|
166
|
+
- [`tests/unit/harness-adapters.test.ts`](../../tests/unit/harness-adapters.test.ts)
|
|
@@ -209,12 +209,13 @@ bclaw_coordinate(intent='ideate', task='Should we extract the dispatcher into a
|
|
|
209
209
|
- Opens a loop with one `champion` slot = caller.
|
|
210
210
|
- Stores `task` as a `proposal` artifact (sliced to fit the 4 KB
|
|
211
211
|
artifact body cap).
|
|
212
|
-
- Stops at the proposal phase. The champion drives
|
|
213
|
-
|
|
212
|
+
- Stops at the manual `proposal` phase. The champion drives lifecycle with
|
|
213
|
+
`bclaw_loop(intent='turn'|'advance')`; `critique`, `revision`, and
|
|
214
|
+
`synthesis` are worker phases, so a trusted caller uses `turn(dispatch=true)`
|
|
215
|
+
when it wants Brainclaw to launch them.
|
|
214
216
|
- Returns `{loop_id, proposal_artifact_id, mode: 'single_agent',
|
|
215
217
|
dispatched_critics: 0, current_phase: 'proposal'}`.
|
|
216
|
-
- Surfaces a single-agent warning so the caller knows dispatch is
|
|
217
|
-
manual.
|
|
218
|
+
- Surfaces a single-agent warning so the caller knows dispatch is not automatic.
|
|
218
219
|
|
|
219
220
|
This is the right mode when you want the loop's structure (memory
|
|
220
221
|
filter, gate, iteration accounting) but want to drive each turn
|