mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-07-12 21:02:17 +02:00
fix(x): cancellation no longer requires live dependency materialization
advance() resolved the context chain, agent snapshot, live model, and every snapshotted tool before applying ANY input — including cancel, which uses none of them. A permanently broken environment (provider removed from models.json, builtin renamed by an update, context predecessor unreadable) therefore rejected every advance forever: the turn could not be cancelled, stopTurn's fallback failed, and the session rejected sendMessage with TurnNotSettledError permanently — a bricked session with valid bytes on disk. Materialization is now a thunk the invocation awaits only for work that continues the turn: run() short-circuits a cancel input straight to the cancel path (same commit ritual, same synthetic results, byte-identical events for healthy turns), while every other input still materializes first, preserving §15.3's reject-before-touching-the-file ordering. applyInput narrows to non-cancel inputs. Tests: cancel succeeds against a broken tool registry (with the non-cancel input asserted to reject file-unchanged), a broken model registry, and an unreadable context chain; plus a healthy-cancel regression pinning the exact event sequence and outcome. All three broken-environment tests fail against the old code. Design doc §15.3, §18, §22, and §26.5 updated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
30def374af
commit
49cb64d8ba
3 changed files with 265 additions and 64 deletions
|
|
@ -1325,6 +1325,10 @@ Missing or mismatched runtime dependencies:
|
|||
- Do not append `turn_failed`.
|
||||
- Leave the turn unchanged so the caller can fix its environment and retry.
|
||||
|
||||
Cancel inputs are exempt from this validation: they are applied before
|
||||
dependency materialization (section 22), because cancellation is the
|
||||
terminal exit for environments that never come back.
|
||||
|
||||
Provider failures after actual execution begins are modeled turn failures.
|
||||
|
||||
## 16. Hot TurnExecution stream
|
||||
|
|
@ -1478,10 +1482,13 @@ At a high level, `advanceTurn` performs:
|
|||
3. Publish turn-processing-start.
|
||||
4. Read and validate JSONL.
|
||||
5. Reduce events to TurnState.
|
||||
6. Materialize context through the injected context resolver.
|
||||
7. Validate terminal state, input, and runtime dependencies.
|
||||
8. Apply the optional single external input.
|
||||
9. Repeatedly advance deterministic work:
|
||||
6. Validate terminal state and the optional input.
|
||||
7. If the input is a cancel, cancel immediately — live dependencies are
|
||||
never materialized for cancellation (section 22).
|
||||
8. Materialize context through the injected context resolver and validate
|
||||
runtime dependencies.
|
||||
9. Apply the optional single external input.
|
||||
10. Repeatedly advance deterministic work:
|
||||
a. Recover from the current durable boundary.
|
||||
b. Resolve permissions.
|
||||
c. Execute eligible sync tools.
|
||||
|
|
@ -1494,9 +1501,9 @@ At a high level, `advanceTurn` performs:
|
|||
j. Persist normalized non-delta events and stream deltas.
|
||||
k. Append model_call_completed or model_call_failed.
|
||||
l. Complete when the response has no tool calls.
|
||||
10. Publish turn-processing-end in finalization.
|
||||
11. Release the lock.
|
||||
12. Resolve/reject outcome and close/error event stream.
|
||||
11. Publish turn-processing-end in finalization.
|
||||
12. Release the lock.
|
||||
13. Resolve/reject outcome and close/error event stream.
|
||||
```
|
||||
|
||||
The loop does not read session queues, accept new user messages, switch agents,
|
||||
|
|
@ -1592,6 +1599,11 @@ Rules:
|
|||
- Append `turn_cancelled`.
|
||||
- Never initiate another model call.
|
||||
- Reject late permission decisions, progress, and results after cancellation.
|
||||
- A cancel input is applied before live-dependency materialization:
|
||||
cancellation never requires the context, agent snapshot, model, or tools
|
||||
to resolve, so a turn whose environment is no longer resolvable (provider
|
||||
removed from config, builtin renamed, context chain unreadable) can
|
||||
always be cancelled — the terminal exit that keeps its session usable.
|
||||
|
||||
Sync tools are cooperatively cancellable. A tool that ignores the signal may not
|
||||
settle immediately. The runtime cannot guarantee rollback of external side
|
||||
|
|
@ -1791,6 +1803,9 @@ Assertions:
|
|||
- Turn becomes terminal cancelled.
|
||||
- No subsequent model request occurs.
|
||||
- Late external inputs are rejected.
|
||||
- Cancellation succeeds when live dependencies can no longer be resolved,
|
||||
while non-cancel inputs against the same broken environment reject with
|
||||
the turn file unchanged.
|
||||
|
||||
### 26.6 Failures
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue