fix(fleet): bounded-poll send --verify to eliminate false unverifiable on slow TUIs
Replace the single fixed 300ms capture-pane delay in `agent send --verify` with a bounded polling loop. After sending, the loop polls `capture-pane` every 400ms (VERIFY_POLL_INTERVAL_MS) up to a configurable total timeout (default 6000ms, VERIFY_DEFAULT_TIMEOUT_MS). classifySendResult is called on each poll: accepted/draft return immediately; unverifiable keeps polling until timeout, then fails closed with the existing "no pane change after send" message. New `--verify-timeout <ms>` option on `agent send` (default 6000ms documented). Injectable SleepFn added to FleetCommandDeps for test isolation — no real sleeps in tests. Exports VERIFY_POLL_INTERVAL_MS and VERIFY_DEFAULT_TIMEOUT_MS as constants. classifySendResult and all other pure functions remain unchanged. Tests: multi-poll acceptance on 2nd/3rd poll => exit 0; pane unchanged until timeout => exit 1; draft detected on first poll => exit 1. All 386 tests pass. docs/fleet/PRD.md Known-limitations updated: verify now polls up to bounded timeout (default ~6s, --verify-timeout); definitive acceptance still deferred to Phase-3 heartbeat-ack. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RMoEx7hfdFGjUiCHuN1RRi
This commit is contained in:
@@ -80,14 +80,17 @@ observability and no safe way to watch a session.
|
||||
- **Verify heuristic is best-effort:** `agent send --verify` uses a `>` -prefix draft
|
||||
heuristic that is specific to pi/claude TUIs. Draft detection for codex and opencode
|
||||
TUIs is best-effort only; those runtimes may not use the same input-line indicator.
|
||||
- **Pane-change check is the best Phase-2 signal:** `agent send --verify` compares a
|
||||
BEFORE snapshot (captured immediately before the send) to an AFTER snapshot (captured
|
||||
after the send delay). A pane that changed and does not end in a draft line is reported
|
||||
as 'accepted'. A pane that did not change — including a wedged pane showing stale
|
||||
non-empty content — is reported 'unverifiable' (exit 1, "no pane change after send").
|
||||
Definitive acceptance ultimately requires a runtime acknowledgement (Phase-3
|
||||
heartbeat-ack); the pane-change check is the best signal available against an opaque
|
||||
TUI for Phase-2.
|
||||
- **Pane-change check is the best Phase-2 signal; verify now polls up to a bounded
|
||||
timeout:** `agent send --verify` captures a BEFORE snapshot, sends the message, then
|
||||
polls `capture-pane` every ~400 ms up to a configurable total timeout (default ~6 s,
|
||||
controlled by `--verify-timeout <ms>`). On each poll it runs classifySendResult: if
|
||||
the pane shows 'accepted' or 'draft' the loop exits immediately; while the result is
|
||||
'unverifiable' (no pane change yet) it keeps polling. After the timeout with no
|
||||
definitive result, it fails closed: exit 1 with "no pane change after send". This
|
||||
eliminates false 'unverifiable' failures for slow/loaded TUIs that were previously
|
||||
caused by the old fixed 300 ms single-capture. Definitive acceptance ultimately
|
||||
requires a runtime acknowledgement (Phase-3 heartbeat-ack); the bounded pane-change
|
||||
poll is the best signal available against an opaque TUI for Phase-2.
|
||||
- **Blank AFTER capture fails closed:** Full-screen TUIs (claude, codex, opencode, pi)
|
||||
render blank for `tmux capture-pane`. When the AFTER snapshot is empty, `send --verify`
|
||||
returns non-zero with an "unverifiable" message rather than silently succeeding. This
|
||||
|
||||
Reference in New Issue
Block a user