Address review: every answered agent target fences a late Go

Only targets answered with a session were fenced against a delayed
generate event. A request that timed out (or ended in another failure
verdict the CLI already reported) was simply forgotten, so a Go whose
capture outlasted the timeout still opened a session nobody was told
about.

`resolve_agent_target` now records every terminal resolution, with the
answering session when the verdict carried one, and
`agent_target_refusal` refuses a generate event for any answered
target unless it comes from the answering session itself. The
browser_timeout instructions no longer send the agent to live-status
for a session that can no longer start. The overlay's refusal toast
covers both causes.

Tests: a Rust integration case and a Node protocol case (claim, time
out, late Go refused with 409 and nothing journaled), a unit test for
the timeout instruction; contract doc updated.

Written with AI assistance (Claude).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Abdul Wahab
2026-09-15 05:45:49 +05:00
committed by Abdul Wahab
co-authored by Claude Fable 5
parent 7adb81672d
commit 76db418212
7 changed files with 123 additions and 39 deletions
+6 -5
View File
@@ -7736,9 +7736,10 @@
}).then(async res => {
if (res.ok) return res;
const body = await res.json().catch(() => ({}));
// The helper refused to open a second session for an agent target
// another page already served (this page's lease lapsed while it was
// capturing): drop the local session and hand the surface back.
// The helper refused to open a session for an agent target it has
// already answered (another page served it after this page's lease
// lapsed mid-capture, or the request timed out): drop the local
// session and hand the surface back.
if (body.error === 'agent_target_already_served' && msg.type === 'generate'
&& msg.id && msg.id === currentSessionId) {
abandonSupersededGo(msg.id);
@@ -7767,10 +7768,10 @@
function abandonSupersededGo(sessionId) {
if (sessionId !== currentSessionId) return;
console.warn('[impeccable] Another page already served this agent target; clearing session ' + sessionId + '.');
console.warn('[impeccable] The helper already answered this agent target; clearing session ' + sessionId + '.');
markSessionHandled();
cleanup({ instantChrome: true });
showToast('Another tab already served this request, so this session was cleared.', 6000);
showToast('The helper already answered this request, so this session was cleared. Pick an element to start fresh.', 6000);
}
let abandonedForeignSessionId = null;