@enderfga/claw-orchestrator 6.0.2 → 6.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/dist/bin/cli.js +5 -3
  2. package/dist/bin/cli.js.map +1 -1
  3. package/dist/src/acp-server.d.ts +18 -1
  4. package/dist/src/acp-server.js +52 -29
  5. package/dist/src/acp-server.js.map +1 -1
  6. package/dist/src/consensus.js +22 -12
  7. package/dist/src/consensus.js.map +1 -1
  8. package/dist/src/council.d.ts +20 -0
  9. package/dist/src/council.js +73 -36
  10. package/dist/src/council.js.map +1 -1
  11. package/dist/src/embedded-server.d.ts +15 -0
  12. package/dist/src/embedded-server.js +84 -49
  13. package/dist/src/embedded-server.js.map +1 -1
  14. package/dist/src/fanout.js +11 -0
  15. package/dist/src/fanout.js.map +1 -1
  16. package/dist/src/inbox-manager.d.ts +24 -0
  17. package/dist/src/inbox-manager.js +44 -9
  18. package/dist/src/inbox-manager.js.map +1 -1
  19. package/dist/src/kernel/conditions.d.ts +1 -1
  20. package/dist/src/kernel/conditions.js +13 -1
  21. package/dist/src/kernel/conditions.js.map +1 -1
  22. package/dist/src/kernel/engine.d.ts +14 -0
  23. package/dist/src/kernel/engine.js +51 -9
  24. package/dist/src/kernel/engine.js.map +1 -1
  25. package/dist/src/kernel/nodes/subflow.js +19 -1
  26. package/dist/src/kernel/nodes/subflow.js.map +1 -1
  27. package/dist/src/kernel/nodes/verifier.js +7 -2
  28. package/dist/src/kernel/nodes/verifier.js.map +1 -1
  29. package/dist/src/kernel/store.js +7 -1
  30. package/dist/src/kernel/store.js.map +1 -1
  31. package/dist/src/kernel/templates/index.js +16 -8
  32. package/dist/src/kernel/templates/index.js.map +1 -1
  33. package/dist/src/kernel/types.d.ts +13 -0
  34. package/dist/src/kernel/types.js.map +1 -1
  35. package/dist/src/openai-compat.d.ts +27 -2
  36. package/dist/src/openai-compat.js +408 -38
  37. package/dist/src/openai-compat.js.map +1 -1
  38. package/dist/src/proxy/anthropic-adapter.js +30 -11
  39. package/dist/src/proxy/anthropic-adapter.js.map +1 -1
  40. package/dist/src/proxy/handler.js +21 -8
  41. package/dist/src/proxy/handler.js.map +1 -1
  42. package/dist/src/session-manager.d.ts +3 -0
  43. package/dist/src/session-manager.js +49 -14
  44. package/dist/src/session-manager.js.map +1 -1
  45. package/dist/src/types.d.ts +28 -0
  46. package/dist/src/types.js +11 -0
  47. package/dist/src/types.js.map +1 -1
  48. package/dist/src/verify/evidence.d.ts +12 -2
  49. package/dist/src/verify/evidence.js +14 -3
  50. package/dist/src/verify/evidence.js.map +1 -1
  51. package/dist/src/verify/runner.js +32 -3
  52. package/dist/src/verify/runner.js.map +1 -1
  53. package/package.json +1 -1
  54. package/skills/references/acp.md +6 -0
  55. package/skills/references/cli.md +1 -1
  56. package/skills/references/council.md +3 -1
  57. package/skills/references/openai-compat.md +263 -1
  58. package/skills/references/tools.md +14 -6
  59. package/skills/references/verification.md +4 -1
  60. package/skills/references/workflow.md +20 -7
@@ -18,6 +18,8 @@ import { exec as realExec, lastLines } from '../kernel/exec.js';
18
18
  import { changedFilesSince, isUnder, resolveIn } from './baseline.js';
19
19
  import { contractPassed, DEFAULT_CHECK_TIMEOUT_MS, DEFAULT_HTTP_TIMEOUT_MS, DEFAULT_SCREENSHOT_TIMEOUT_MS, } from './contract.js';
20
20
  const TAIL_LINES = 200;
21
+ /** How often an in-flight HTTP check re-checks the run's cancellation flag. */
22
+ const CANCEL_POLL_MS = 100;
21
23
  // ─── Individual check kinds ─────────────────────────────────────────────────
22
24
  async function runCommandCheck(spec, ctx) {
23
25
  const run = ctx.exec ?? realExec;
@@ -51,8 +53,24 @@ async function runHttpCheck(spec, ctx) {
51
53
  while (Date.now() - startedAt < timeoutMs) {
52
54
  if (ctx.signal?.aborted)
53
55
  break;
56
+ // The while-guard is only re-read between iterations, so it cannot bound a
57
+ // fetch that never returns. Without a signal on the request, a server that
58
+ // accepts the connection and never sends headers parked this loop until
59
+ // undici's default 300s headersTimeout — a declared `timeoutMs: 30000`
60
+ // became an effective ten minutes, and `ctx.signal` going true in the
61
+ // meantime had no observer either. Each request now carries the same
62
+ // deadline the loop does, and the run's cancellation preempts it.
63
+ const controller = new AbortController();
64
+ const remaining = Math.max(0, timeoutMs - (Date.now() - startedAt));
65
+ const deadline = setTimeout(() => controller.abort(new Error(`deadline after ${timeoutMs}ms`)), remaining);
66
+ const cancelPoll = ctx.signal
67
+ ? setInterval(() => {
68
+ if (ctx.signal?.aborted)
69
+ controller.abort(new Error('cancelled'));
70
+ }, CANCEL_POLL_MS)
71
+ : undefined;
54
72
  try {
55
- const res = await doFetch(spec.url);
73
+ const res = await doFetch(spec.url, { signal: controller.signal });
56
74
  if (res.status === expect) {
57
75
  return { passed: true, durationMs: Date.now() - startedAt, detail: `GET ${spec.url} → ${res.status}` };
58
76
  }
@@ -61,12 +79,23 @@ async function runHttpCheck(spec, ctx) {
61
79
  catch (e) {
62
80
  lastDetail = `GET ${spec.url} → ${e.message}`;
63
81
  }
82
+ finally {
83
+ clearTimeout(deadline);
84
+ if (cancelPoll)
85
+ clearInterval(cancelPoll);
86
+ }
87
+ if (ctx.signal?.aborted)
88
+ break;
64
89
  await new Promise((r) => setTimeout(r, intervalMs));
65
90
  }
91
+ // Report the time actually spent, not the budget. These two disagreed
92
+ // whenever the budget was not honoured, which was exactly when a reader
93
+ // needed to know.
94
+ const durationMs = Date.now() - startedAt;
66
95
  return {
67
96
  passed: false,
68
- durationMs: Date.now() - startedAt,
69
- detail: `${lastDetail} (gave up after ${timeoutMs}ms)`,
97
+ durationMs,
98
+ detail: `${lastDetail} (gave up after ${durationMs}ms, budget ${timeoutMs}ms)`,
70
99
  timedOut: true,
71
100
  };
72
101
  }
@@ -1 +1 @@
1
- {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/verify/runner.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/verify/runner.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@enderfga/claw-orchestrator",
3
- "version": "6.0.2",
3
+ "version": "6.0.4",
4
4
  "description": "Claw Orchestrator \u2014 run Claude Code, Codex, Gemini, Cursor Agent, OpenCode and custom coding CLIs as one unified runtime. Drop into Hermes Agent, Claude Desktop, Cursor, Cline, Continue, Zed, Windsurf, Goose or any Model Context Protocol (MCP) host, install as an OpenClaw plugin, or run standalone. Persistent sessions, multi-agent council, ultraplan, ultrareview, autoloop, tool orchestration.",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -120,6 +120,12 @@ saying so, so the choice is a session config option instead — which also suits
120
120
  `session/cancel` settles the in-flight prompt as `cancelled` immediately, then tears
121
121
  the underlying session down and recreates it.
122
122
 
123
+ A cancel with **nothing in flight does nothing**. The teardown drops the engine's
124
+ native conversation id — codex, codex-app, agy, cursor and opencode all capture
125
+ theirs mid-turn — so running it on an idle session would fork the history
126
+ silently: the client keeps the same ACP session id while the next prompt opens a
127
+ fresh engine thread.
128
+
123
129
  The session layer has **no mid-turn cancel** — `stopSession()` is the only lever and
124
130
  it destroys the session rather than pausing the turn. So the ACP turn returns
125
131
  promptly while the engine subprocess may take a moment longer to die, and any
@@ -82,7 +82,7 @@ clawo session-start [name] [options]
82
82
  | `--json-schema <schema>` | JSON Schema for structured output |
83
83
  | `--mcp-config <paths>` | MCP config files (comma-separated) |
84
84
  | `--settings <path>` | Settings.json path |
85
- | `--skip-persistence` | Disable session persistence |
85
+ | `--skip-persistence` | Do not save the session — neither the engine's transcript nor the resume registry |
86
86
  | `--betas <headers>` | Beta headers (comma-separated) |
87
87
  | `--enable-agent-teams` | Enable agent teams |
88
88
  | `--include-hook-events` | Stream hook lifecycle events (PreToolUse/PostToolUse) |
@@ -152,7 +152,9 @@ Returns a structured report:
152
152
 
153
153
  Cleans up all council scaffolding:
154
154
 
155
- - Removes all `council/*` worktrees and `.worktrees/` directory
155
+ - Removes the worktrees under `{projectDir}/.worktrees/`, and that directory —
156
+ selection is by containment, so a worktree of yours that merely has `council`
157
+ somewhere in its path is never touched
156
158
  - Deletes all `council/*` branches
157
159
  - Removes `plan.md` and `reviews/` directory
158
160
  - Sets council status to `accepted`
@@ -32,7 +32,19 @@ The hash fallback exists because the previous behavior collapsed every unkeyed c
32
32
 
33
33
  The model is mixed into the hash so that two callers with the same system prompt but different requested models (e.g. one wants `claude-opus-4-6`, another wants `claude-sonnet-4-6`) don't collide and silently get responses from the wrong model.
34
34
 
35
- The full plugin-side session name is `openai-<key>`.
35
+ The full plugin-side session name is `openai-<key>`. The key becomes a directory
36
+ name — the bridge starts each session in `os.tmpdir()/openclaw-compat-<name>` —
37
+ so a key that is not already `[A-Za-z0-9._-]` is replaced by a hash of itself.
38
+ A caller using an ordinary id keeps the session name it has always had; one
39
+ sending path separators no longer chooses where the session runs.
40
+
41
+ The tool list is fingerprinted into the hash fallback by name, a description
42
+ prefix, and the **parameter schema** (with object keys normalised, so a
43
+ re-serialised identical schema still resolves to the same session). On the
44
+ Claude engine the schemas are baked into the session's system prompt at create
45
+ time and deliberately not re-injected per turn, so the key is the only thing
46
+ that can notice a schema change — without it, a caller that edited a tool's
47
+ parameters kept getting `tool_calls` shaped like the schema it had replaced.
36
48
 
37
49
  ## Operator modes
38
50
 
@@ -123,6 +135,234 @@ session (in that mode the tool list is deliberately left out of the session hash
123
135
  It costs the per-turn growth described above — only use it if the tool set really
124
136
  does change mid-conversation.
125
137
 
138
+ ## Conversation history on the way in
139
+
140
+ The caller's `messages[]` can carry the whole conversation: earlier `user` turns and the engine's
141
+ own earlier `assistant` replies. Whether those turns need to be sent is the same question the
142
+ section below asks about tool results — does the engine's own conversation already hold them? — and
143
+ it gets the same answer, from the same predicate. The turns that are in scope are serialized into
144
+ one `<conversation_history>` block of `<user>` / `<assistant>` turns and put in front of the
145
+ caller's latest `user` text. The wrapper tag is the one `renderHistory()` in the autoloop dispatcher
146
+ already uses for the same job; the per-turn tags are not — that one labels its two speakers `<user>`
147
+ / `<agent>`, because its roles are autoloop roles rather than OpenAI wire roles.
148
+
149
+ | On this turn the engine | What is sent |
150
+ | ----------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
151
+ | is **not** resuming a conversation — no session yet, a session that never announced a conversation id, or one being stopped and recreated | every `user`/`assistant` turn except the caller's latest `user` message |
152
+ | **is** resuming a live conversation, but one this bridge never sent these turns to | the same — a live thread is not automatically _this_ thread |
153
+ | **is** resuming the live conversation these turns belong to | nothing — the turns are already in the transcript, and the text goes out alone |
154
+
155
+ The last row is what keeps Anthropic prompt caching warm on `claude` and keeps a resumed `codex`
156
+ thread from being re-fed its own history: on a live thread the message is byte-identical to what it
157
+ was before this block existed. The first row is the one that was losing data. A client that opens a
158
+ new conversation per turn — one whose session key hashes the last message, say — lands in it on
159
+ every turn, and `skipPersistence: true` means an OpenAI-compat session is never auto-resumed from
160
+ disk either, so a follow-up like "yes, go ahead" used to reach the engine with nothing in front of
161
+ it.
162
+
163
+ The middle row is the one that is easy to get wrong. "Is there a live thread under this session
164
+ name?" is not "is that thread holding this conversation?", and the two come apart constantly. A
165
+ caller whose session key hashes its latest message resolves every repeat of a short confirmation —
166
+ "yes, go ahead", typed all day by someone approving invoices — to the session some _earlier_
167
+ invoice opened. A client that sends no session key at all falls back to a hash of
168
+ model+system+tools, which is stable for every turn AND identical between two concurrent chats of
169
+ the same user, so both chats share one session. And on `claude`, the default engine,
170
+ `nativeThreadIsLive()` has no id to check and returns true for anything in the session map, so
171
+ there the question collapses to "does the name exist" with no gate at all.
172
+
173
+ So the bridge records, per session, a fingerprint of the `user` turns it has actually pushed there,
174
+ and replays unless this request continues exactly that. It is the only writer to these sessions, so
175
+ what it sent is what the engine holds. Unknown session, forked conversation, evicted entry: all
176
+ replay. Being wrong in that direction costs a duplicated turn under a framing that says not to act
177
+ on it twice; being wrong in the other direction drops context silently, which is the class of bug
178
+ this exists to fix.
179
+
180
+ What the request is compared against depends on where its array ends, and only an array ending in a
181
+ `user` turn carries a turn the bridge has not sent yet. For that shape the fingerprint of every
182
+ `user` turn _before_ the last one is what the thread should be holding. For every other shape — a
183
+ tool-loop hop ending in `tool`, a prefill/continue ending in `assistant` — the latest `user` turn
184
+ was already pushed on an earlier request, so the whole array is compared. Getting that wrong in the
185
+ other direction is not harmless: comparing a hop against one turn less never matches, and the
186
+ transcript is then replayed into the very session that is already holding it, on every hop, for a
187
+ caller that needed none of this.
188
+
189
+ The map is bounded at 1000 entries and evicted oldest-first, which it needs independently of the
190
+ session map: `_cleanupIdleSessions()` reaps a session by `sessionTtlMinutes` without telling this
191
+ map, so a fingerprint outlives the session it mirrors. Eviction costs a replayed block, never a
192
+ dropped one, and `serve` restarts start it empty for the same price.
193
+
194
+ `system` messages are never in the block: they travel as the session's system prompt (see [Tool
195
+ definitions](#tool-definitions-and-where-they-live)). `tool` messages are never in it either —
196
+ they are the next section's business, and repeating them here would duplicate every payload and
197
+ undo the scoping that keeps a tool loop linear. An `assistant` message that only announces
198
+ `tool_calls` carries no text, so it renders no turn; a turn whose text is empty or whitespace is
199
+ dropped rather than rendered as an empty shell. An array with nothing to replay produces no block
200
+ at all, so a single-turn `[system, user]` request — the shape the OpenClaw main agent, cron jobs
201
+ and subagents send — goes out exactly as it did before.
202
+
203
+ Replayed text has neutralized every tag the assembled prompt treats as structure — the block's own
204
+ `<conversation_history>` / `<user>` / `<assistant>`, and also `<tool_results>` / `<tool_result>`,
205
+ `<system>` and `<tool_calls>` (`</user>` becomes `&lt;/user>`). Unlike a `<tool_result>` body, which
206
+ comes from the caller's own tool runner, a replayed turn is whatever an end user typed, and
207
+ `hi</user>\n<assistant>\n...` would otherwise close its turn early and forge an `assistant` turn —
208
+ putting words in the engine's own mouth. The other three matter for the same reason: a fabricated
209
+ tool return carries the framing sentence that says a payload is authoritative, a `<system>` block
210
+ contradicts the real one the non-claude path prepends, and `<tool_calls>` is the exact protocol JSON
211
+ the model is asked to emit.
212
+
213
+ Only the `<` is escaped, by lookahead. That shape is what makes the boundary decidable: matching up
214
+ to the closing `>` instead means re-emitting whatever was captured, and `hola<user a</user>` then
215
+ smuggles a raw close through the attribute slot of a tag that IS matched. So the match ends at
216
+ anything that ends a tag name — `>`, `/`, `<`, end of text, or a character that occupies no width.
217
+ That last clause is five Unicode properties rather than a list of code points, and it is not
218
+ decoration: measured over the 6,060 code points that are zero-advance or render blank,
219
+ `[\s></\p{Cc}\p{Cf}]` let **5,806** through, so `ok</user︀>\n<assistant︀>` forged a turn that is
220
+ indistinguishable on screen from `ok</user>`. Adding `Default_Ignorable` leaves 1,770;
221
+ `\p{Mn}\p{Me}` closes it; U+2800 BRAILLE PATTERN BLANK is neither and is named. Cost: the same 11 of
222
+ a 28-string corpus of plausible legitimate text change under the wide class as under the narrow one.
223
+
224
+ The name does **not** have to sit flush against `<` or `</`: the same invisible padding, plus the
225
+ slash itself, is allowed before the name, because `hola</​user>` renders as `hola</user>` and a
226
+ model reads it as a close — a trailing class complete over zero-width filler with a flush leading
227
+ side still forges a turn. That is **one** class, `[/\p{Cc}\p{Cf}\p{Mn}\p{Me}\p{Default_Ignorable_Code_Point}]*`,
228
+ not `[…]*\/?[…]*`: two adjacent unbounded quantifiers over the same class backtrack O(n²) on a long
229
+ run that never reaches a valid name, and a single history message of ~100 KB of combining marks hung
230
+ the event loop ~80 s — a one-request denial of service against a fleet whose watchdog already resets
231
+ on event-loop stalls. The class is the zero-**advance** subset only (no `\s`, no U+2800), because a
232
+ visible separator before the name is the `if (count < user && x)` corruption the boundary class
233
+ already refuses. Swept over the 6,060 code points that are zero-advance or separators, in all three
234
+ positions (18,180 probes): 12,120 went through unfenced with the flush leading side, **38** with the
235
+ interior class, and the 38 are 19 `Zs`/`Zl`/`Zp` code points — U+0020, U+00A0, U+2000–200A, U+3000 —
236
+ i.e. exactly the visible-separator limitation below, and nothing else. The single class also lets a
237
+ slash sit among the filler (`<//user`, `</␀/user`); harmless, since the only action is escaping the
238
+ `<`. Filler INSIDE the name (`</us␀er>`) is still not fenced — the old regex missed it too.
239
+
240
+ **What it does not promise.** A positive class cannot be complete over a _visible_ separator, so
241
+ `</ user>` and `< assistant>` go through raw — a model reads them as a boundary. They are excluded on
242
+ cost: reaching them means corrupting `if (count < user && x)` and `the < user > column`. What already
243
+ gets corrupted for the same reason, since the class contains whitespace: `Promise<User | null>` and
244
+ `count<user && total>limit` come out with `&lt;`. Readable to a model, not byte-identical. And the
245
+ body of a `<tool_result>` is never fenced — its content comes from the caller's own tool runner — so a
246
+ tool return that embeds a whole `<conversation_history>` block is not stopped here.
247
+
248
+ The caller's **latest** `user` turn is fenced too, but only on turns that actually carry a block.
249
+ That turn is the one input an attacker controls end to end, and the block teaches the model in the
250
+ same prompt that `<conversation_history>` holds its own earlier turns — unfenced, it could close the
251
+ real block and open a second one indistinguishable from it. With no block in front of it there is
252
+ nothing to forge, so those turns stay byte-for-byte what they were.
253
+
254
+ A `user` turn carrying only non-text content (an image) renders as `[non-text content]` rather than
255
+ vanishing. Dropping it would leave the `assistant` reply to it standing alone under a framing that
256
+ calls the assistant turns the model's own — a reply to a request the model cannot see, which reads
257
+ as license to act on the reply by itself. "Photo of the invoice", then "yes, go ahead", is an
258
+ everyday shape. A leading `assistant` turn with no `user` turn in front of it at all (content
259
+ `null`, or empty) is dropped instead, since no marker could honestly stand in for it.
260
+
261
+ ### What this does not cover
262
+
263
+ - **A turn can be replayed that the engine already had.** The mirror image of the duplicate-once
264
+ trade below, and it comes from the same place: the engine's state is read from the session, not
265
+ from the array. A client whose session looks new to the bridge but whose engine did hold context
266
+ gets those turns a second time. The framing sentences tell the model these are earlier turns and
267
+ not to act on them again, which is what keeps a duplicated turn from becoming a duplicated
268
+ action; nothing enforces it.
269
+ - **The block is not in strict chronological order when the array does not end in the caller's
270
+ latest `user` turn.** Every `user`/`assistant` turn except that one is replayed, including turns
271
+ that come after it — an array ending in `assistant` (prefill, an explicit "continue", a framework
272
+ appending its own reply) keeps that turn, because a transcript presented as complete while
273
+ missing the last thing the model said invites it to redo the work. The cost is that such a turn
274
+ is rendered inside the block, i.e. before the caller's latest text rather than after it.
275
+ - **`X-Session-Reset` is not honored on an array ending in a `tool` result**, so on that one shape a
276
+ reset turn on a live thread gets no history block either. Same pre-existing asymmetry the tool
277
+ results have there, from the same cause — the header is parsed after that branch returns. See the
278
+ note under [Tool definitions](#tool-definitions-and-where-they-live).
279
+ - **`grok` inherits the hole described in the next section**: it resumes by id, but its id is absent
280
+ from `SessionStats`, so `nativeThreadIsLive()` reaches `default: return true` and a `grok` session
281
+ whose first turn died before emitting its id reports a live thread — and so gets no history. Same
282
+ cause, same fix (adding the field), not addressed here.
283
+ - **The two blocks are not interleaved.** When a request carries both, the message is the history
284
+ block, then the tool results, then the caller's new text — chronological between the blocks, but
285
+ a `tool` result that chronologically preceded a replayed `assistant` turn still appears after it.
286
+ - **The block is capped at 24,000 characters — the whole block, not the sum of the turn text.**
287
+ Wrapper tags, per-turn tags, elision markers and the 268 characters of framing are all charged to
288
+ the budget before any turn is. That is the fix for a cap that did not cap: charging only the turn
289
+ text left the retained turn count bounded by nothing but `24,000 / mean-turn-length`, and 8,000
290
+ alternating one-word turns (`ok`, `sí`, `dale`) rendered a **165,008-byte** block — 33 KiB past the
291
+ argv ceiling below, from a request no bigger than a chat backlog. The elision markers were worse:
292
+ 32 characters each, added AFTER the arithmetic, once per truncated turn, which is how a "24,000
293
+ cap" emitted more than it said.
294
+
295
+ Oldest turns are dropped first, and the turn the budget runs out inside is truncated (head kept)
296
+ and marked `[… turn truncated for length …]` rather than dropped whole — dropping it whole would
297
+ take the request with it on the pasted-document shape. The marker comes out of that turn's own
298
+ allowance, so a truncated turn cannot push the block over. Below 200 rendered characters of
299
+ remaining room a turn is not started at all: it and the turns behind it are dropped, and the
300
+ remainder goes unspent, because a fragment that short is a sentence with its qualifier cut off
301
+ rather than context.
302
+
303
+ The newest `user` turn in the block — the ask the turns after it answer — is the one exception to
304
+ spending newest-first: the turns after it (all `assistant`, by definition of "newest `user` turn")
305
+ spend against the budget minus its frame plus `min(its length, 200)`. That reserve is the fix for
306
+ a drop, not a refinement. Without it, replies that add past the cap (one 30k pasted listing, or
307
+ two ordinary 12k ones) take the whole budget, the window starts past every `user` turn, the
308
+ leading-`assistant` rule clears what is left, and NO block goes out at all: the caller's latest
309
+ turn reaches the engine alone, which is this block's own failure mode at its worst.
310
+
311
+ The 200-character floor applies **above** the anchor too, and that is the second half of the cap
312
+ fix. Once the post-anchor turns have truncated the budget down near the reserve, an older turn is
313
+ started with a `room` smaller than the 32-character elision marker, and `slice(0, room - 32)` with
314
+ a negative argument slices from the END of the string — emitting nearly the whole turn while
315
+ charging the budget only `room`, which blows the cap. Measured on a narrating tool loop, where each
316
+ hop's `assistant` narration becomes a consecutive post-anchor turn because `tool` messages are
317
+ filtered out: with the floor removed, 30 hops render 27,627 characters and the three-`user` /
318
+ with-reply sweep shapes reach 28,003 / 30,003. With the floor, that run of older turns is dropped
319
+ instead, which the anchor's reserve makes safe: ending the window there would drop the anchor and
320
+ hand the leading-`assistant` rule an all-`assistant` list to clear, i.e. the empty block again.
321
+
322
+ Verification. 44,000 random shapes across three message-count ranges (≤7, ≤60 and ≤400 messages,
323
+ roles `user`/`assistant`/`system`/`tool`, content string/whitespace/null/array/empty-array/no-text,
324
+ lengths straddling 0/1/199/200/201/11,999/12,000/12,001/23,799/23,800/24,000/24,001/30,000/60,000):
325
+ **max block 23,999 characters, zero shapes over 24,000, zero content-free turns, zero blocks with
326
+ no `user` turn in them, and zero shapes that went from a non-empty block to an empty one.** 7,488
327
+ of them went the other way — empty before, non-empty now — which is the anchor reserve doing its
328
+ job. 11,954 non-empty blocks changed, which is the point: the old arithmetic charged less than it
329
+ emitted, so every block near the ceiling gets shorter. Directed shapes: 30/100/2,000 narrating
330
+ hops and 1,200/8,000/24,000 one-word turns are all ≤ 24,000 with no content-free turns.
331
+
332
+ The ceiling is on characters and argv counts bytes, which is the conservative direction only up to
333
+ a point: 24,000 characters of astral-plane text is 48,000 bytes and the worst case (3-byte BMP) is
334
+ 72,000, both still inside 128 KiB, but the
335
+ block is not the whole prompt — the tool block, the `<system>` prepend and the caller's own turn
336
+ are added after it. What the cap bounds is the part that scales with the transcript.
337
+
338
+ `MAX_BODY_SIZE` (5 MiB) is **not** a usable bound here: six of the nine `ENGINE_TYPES` pass the
339
+ prompt to the CLI as a single argv element (`codex`, `gemini`, `agy`, `cursor`, `grok`,
340
+ `opencode`), and so does a one-shot `custom` engine; Linux caps one argument at `MAX_ARG_STRLEN` =
341
+ 128 KiB whatever `getconf ARG_MAX` reports (measured: 131071 bytes spawns, 131072 throws `E2BIG`).
342
+ Only `claude`, `codex-app` and a persistent `custom` engine write over stdin. Uncapped, ordinary
343
+ traffic reaches that ceiling — 400-character turns with 900-character replies put the message at
344
+ 131,063 characters at turn 96 and 132,425 at turn 97 — and the failure is a 500 with the turn
345
+ lost, which is worse than the missing context the block exists to restore. This is the same trade
346
+ `renderHistory()` makes, with the same `REPLAY_CHAR_BUDGET`, feeding the same engines.
347
+ - **A send that threw records nothing.** The fingerprint is written after the send and only when the
348
+ send landed, because the two ways to be wrong are not symmetric: forgetting a turn that landed
349
+ replays it once more, while assuming one landed that did not drops context silently. "Landed" is
350
+ `sendMessage` returning — a returned error is answered with 502 and still records, since the CLI
351
+ received the prompt — so only a throw withholds the record. An earlier revision of this file
352
+ described the opposite placement as deliberate and named its residue: a caller that answered a 5xx
353
+ by appending an `assistant` turn and sending again got the next turn bare. That was the bug, not
354
+ the design.
355
+ - **A second request that arrives while the first is still in flight replays.** It sees no
356
+ fingerprint yet, so the transcript goes out again into the session that already holds it. The safe
357
+ direction — a duplicate rather than a drop — plus a lost cache prefix.
358
+ - **Cost is O(n) per turn for engines that never resume.** `engineHasNativeConversation()` is false
359
+ for `gemini` and one-shot custom engines, so for them the block is re-serialized on every turn,
360
+ capped but never free. Same for any caller that mints a new session per turn.
361
+ - **`X-Session-Reset` now replays the transcript.** A reset turn means the engine holds nothing, so
362
+ the history goes out in full. Under the reading "the caller asked to start clean" that is the
363
+ opposite of what was asked, and a client that sends the header on every request AND re-sends
364
+ `messages[]` pays for the transcript every time.
365
+
126
366
  ## Tool results on the way back
127
367
 
128
368
  A `tool` role message in the caller's array is the result of a call the model asked for on an
@@ -187,6 +427,28 @@ relying on it:
187
427
  Neither applies to a caller that keeps its own transcript and forwards only the latest turn — it
188
428
  sends one round at a time.
189
429
 
430
+ ### A live session is not the same thing as this conversation
431
+
432
+ Suppressing the replay needs a stronger fact than "a session under this name is live". That is what
433
+ `nativeThreadIsLive()` reports, and a session name can be live while its transcript belongs to a
434
+ different exchange. Three shapes where the two come apart, all reachable with default settings:
435
+
436
+ | shape | what happens |
437
+ | ---------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
438
+ | a caller whose session key hashes its latest message | every repeat of the same short confirmation resolves to whichever session that phrase opened first — often a different subject entirely |
439
+ | a caller that sends no `X-Session-Id` at all | the key falls back to a hash of model + system prompt + tools, so all of that caller's concurrent chats share one name |
440
+ | `engine: 'claude'` — the default | `nativeThreadIsLive()` has no id to check and returns `true` for anything in the session map, so the name is the only evidence there is |
441
+
442
+ So the bridge tracks what it actually pushed into each session and replays whenever the incoming
443
+ conversation is not the one it remembers seeding. The fingerprint covers the `user` turns only: those
444
+ are the caller's own text echoed back verbatim, while assistant text is what the engine produced and
445
+ a client may normalize it. A mismatch replays, which is the safe direction — the cost is a repeated
446
+ block, never a lost one.
447
+
448
+ The map is bounded and evicted oldest-first, and it has to be independent of the session map:
449
+ `_cleanupIdleSessions()` reaps a session by TTL without telling it, so a fingerprint outlives the
450
+ session it mirrors. Losing an entry costs a replayed block, never a dropped one.
451
+
190
452
  ## Environment variables
191
453
 
192
454
  | Variable | Default | Purpose |
@@ -33,7 +33,7 @@ Start a persistent coding session with full CLI flag support.
33
33
  | `mcpConfig` | string \| string[] | MCP server config file(s) |
34
34
  | `settings` | string | Settings.json path or inline JSON |
35
35
  | `ultracode` | boolean | Claude only. Enable "ultracode" / dynamic workflows — Claude plans a JS orchestration script per substantive task and fans out to subagents. Injected as the `ultracode:true` settings key (merged into `settings`), **not** a `--effort` value (the CLI rejects `--effort ultracode`). |
36
- | `noSessionPersistence` | boolean | Do not save session to disk |
36
+ | `noSessionPersistence` | boolean | Do not save session to disk — both the engine's own transcript and this orchestrator's resume registry, so a later start under the same name does not reattach |
37
37
  | `betas` | string \| string[] | Custom beta headers |
38
38
  | `enableAgentTeams` | boolean | Enable experimental agent teams |
39
39
  | `enableAutoMode` | boolean | Enable auto permission mode |
@@ -559,11 +559,19 @@ Start a chat-mode autoloop. Planner starts immediately; Coder + Reviewer start o
559
559
 
560
560
  > **Custom engines are local-only.** A `CustomEngineConfig` names an executable to
561
561
  > spawn plus its argv and env, so it may only be supplied by a caller that already
562
- > runs on the host (this MCP tool, or the `SessionManager` API). The HTTP API
563
- > (`POST /autoloop/new`, `POST /autoloop/<id>/resume`) rejects a `*_custom_engine`
564
- > body field with a 400 — the embedded server is often reverse-tunnelled and its
565
- > token is a monitoring credential, not permission to choose what binary runs.
566
- > Built-in engines are fully selectable over HTTP.
562
+ > runs on the host (this MCP tool, or the `SessionManager` API). **Every** HTTP
563
+ > request body is checked, on every route, and one carrying a custom-engine
564
+ > object at any depth — `customEngine`, `*_custom_engine`, `agentCustomEngines` —
565
+ > is rejected with a 400 naming the offending key path. The embedded server is
566
+ > often reverse-tunnelled and its token is a monitoring credential, not
567
+ > permission to choose what binary runs. Built-in engines stay fully selectable
568
+ > over HTTP.
569
+ >
570
+ > The check used to be wired into two autoloop routes and to match three
571
+ > snake_case names; `POST /session/start` had no guard and `session_start` spells
572
+ > the field `customEngine`, so it went straight through. Matching by shape at the
573
+ > one place every body passes is what stops the next route from inheriting the
574
+ > same gap.
567
575
  >
568
576
  > **Resuming one is done by reference.** Refusing the config over HTTP left a real
569
577
  > gap: a custom-engine run that crashed could not be brought back by any remote
@@ -92,7 +92,10 @@ used to miss every new file while `git add -A` committed them anyway.
92
92
 
93
93
  ## Evidence bundles
94
94
 
95
- Every verifier attempt writes a directory under the run:
95
+ Every verifier attempt writes a directory under the run, named
96
+ `<node>-v<visit>-<attempt>`. Both counters are in the id because the attempt
97
+ counter is per-visit and restarts at 1 each time a loop comes back round — so a
98
+ repair loop keeps every pass rather than overwriting the last one:
96
99
 
97
100
  ```
98
101
  ~/.claw-orchestrator/wf/<runId>/evidence/<evidenceId>/
@@ -210,7 +210,7 @@ add failure modes (partial joins, orphaned branches) that nothing here exercises
210
210
 
211
211
  A spec can arrive from a tool call, which means it can arrive from an agent. If
212
212
  routing accepted a JS expression, the kernel would be an arbitrary code execution
213
- surface. Five closed forms are evaluated and nothing else:
213
+ surface. These closed forms are evaluated and nothing else:
214
214
 
215
215
  ```jsonc
216
216
  { "type": "always" }
@@ -218,8 +218,15 @@ surface. Five closed forms are evaluated and nothing else:
218
218
  { "type": "node_succeeded", "node": "verify" }
219
219
  { "type": "verified", "node": "verify" }
220
220
  { "type": "visits_lt", "node": "implement", "n": 4 }
221
+ { "type": "and", "all": [ /* … */ ] }
221
222
  ```
222
223
 
224
+ `and` is the only recursive one, and nesting is capped at six deep. Use it rather
225
+ than chaining two routers: **a router whose routes all miss falls through to the
226
+ next node**, so a gate that failed to match simply hands control to the router
227
+ after it, which then matches on its own. Chaining reads as AND and behaves as
228
+ "whatever the last router says".
229
+
223
230
  `maxNodeVisits` (default 50) bounds every loop as a backstop. Use `visits_lt` for
224
231
  the actual budget — the backstop failing a run is a bug report, not a feature.
225
232
 
@@ -247,12 +254,18 @@ the actual budget — the backstop failing a run is a bug report, not a feature.
247
254
  {
248
255
  "id": "repair-gate",
249
256
  "kind": "router",
250
- "routes": [{ "when": { "type": "node_failed", "node": "verify" }, "to": "repair-budget" }],
251
- },
252
- {
253
- "id": "repair-budget",
254
- "kind": "router",
255
- "routes": [{ "when": { "type": "visits_lt", "node": "implement", "n": 4 }, "to": "implement" }],
257
+ "routes": [
258
+ {
259
+ "when": {
260
+ "type": "and",
261
+ "all": [
262
+ { "type": "node_failed", "node": "verify" },
263
+ { "type": "visits_lt", "node": "implement", "n": 4 },
264
+ ],
265
+ },
266
+ "to": "implement",
267
+ },
268
+ ],
256
269
  },
257
270
  ],
258
271
  }