When an agent run pauses on a tool approval and I answer it from the playground, the runner evicts the parked warm session and replays the whole turn cold, but only when the gated turn is NOT the session's first user turn. The first turn resumes warm as expected.
Observable in the runner logs when it happens:
[keepalive] approval-mismatch (history) ...; evict + cold
[HITL] cold replay: ... resumeFrame=approval
Steps to reproduce (dev stack, Pi harness, permission mode allow_reads):
- Start an agent session, send any first message, let it finish.
- Send a second message that triggers a gated bash call and wait for the approval card.
- Approve it and watch the runner logs: the parked session is evicted with
approval-mismatch (history) and the turn replays cold.
- Same experiment on a fresh session's very first message resumes warm, no eviction.
The answer still reaches the model correctly, so this is a performance and latency bug, not a correctness one: every non-first-turn approval pays a full cold replay, which is most expensive exactly when the turn carries attachments. Subsequent approvals in the same turn resume warm again, which is why it looks intermittent.
Seen on the v0.107.0 base plus the multi-modality train, 2026-08-01; the comparison logic on main is stricter and hits related cases (see #5593).
When an agent run pauses on a tool approval and I answer it from the playground, the runner evicts the parked warm session and replays the whole turn cold, but only when the gated turn is NOT the session's first user turn. The first turn resumes warm as expected.
Observable in the runner logs when it happens:
Steps to reproduce (dev stack, Pi harness, permission mode allow_reads):
approval-mismatch (history)and the turn replays cold.The answer still reaches the model correctly, so this is a performance and latency bug, not a correctness one: every non-first-turn approval pays a full cold replay, which is most expensive exactly when the turn carries attachments. Subsequent approvals in the same turn resume warm again, which is why it looks intermittent.
Seen on the v0.107.0 base plus the multi-modality train, 2026-08-01; the comparison logic on main is stricter and hits related cases (see #5593).