Records the durable per-session run-registry implementation (bridge branch
fix/gateway-durable-run-registry): T7 gateway-unconfirmed fallback, T8 terminal
result cache, T9 DeadlineAt interrupt — with the trade-offs (no gatewayruntime
pending-map rewrite; per-session in-memory store not yet cross-restart durable;
T9 only force-terminates when the gateway is unconfirmed) and the test names that
cover each.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Symptom: a gateway turn shows "任务运行中..." forever and 停止 has no effect,
even though the OpenClaw gateway has already finished (ACP_HTTP_CONNECTION_CLOSED).
- T3: add a hard deadline to the running-handle poll branch so the client no
longer polls forever when tasks.get keeps returning "running". Budget is
derived from taskLoadClass (10/30/60min, aligned with the bridge) + grace;
on timeout the turn lands in a recoverable `interrupted` state
(OPENCLAW_RUN_POLL_TIMEOUT) prompting the user to resend.
- T4: make 停止 locally authoritative — capture the association, mark the turn
aborted immediately (clears pending, exits the poll loop), then fire
tasks.cancel best-effort so a hung/failed cancel RPC can't block termination.
- T6: applyGatewayChatFailureInternal now authoritatively clears the pending
flag (both raw + normalized key). Previously runOpenClawGatewayQueuedTurnInternal's
finally never cleared it, leaving "error shown but still running".
Full cross-repo analysis + remaining TODO in docs/cases/06.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Reposition the remote provider contract check as a skippable test-stage
quality gate (needs: build, continue-on-error) so it can never block
build or release. release uses always() to wait without being gated.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>