fix(acp): retry transient connection failures - #9011
Conversation
Design Review (Fable 5, fork) — ✅ PASSDesign-level review of The design is sound: right layer (the existing raw-error classifier that both the formatter and retry verdict key off), terminal branches keep precedence, the retry budget is already bounded, and ENOTFOUND-vs-EAI_AGAIN shows deliberate transient/permanent discrimination. The only asymmetry I found: Design-Verdict: PASS A real transient-failure gap, closed at the established classifier seam with bounded retries and terminal precedence preserved — proportionate and reversible. Suggestions
[DESIGN-REVIEWED] a9ea9ee |
GPT 5.6 Review (fork) — ✅ no blocking findingsReviewed Review detailsNo findings. |
First Principles Review (Fable 5, fork) — 🟡 CONCERNSPremise-level review of All evidence is gathered: the patch adds a connection-failure classification to an existing retry classifier; base First-Principles-Verdict: CONCERNS Node-style tokens ("socket hang up", "fetch failed", ECONNREFUSED) rest on no captured error frame — no issue, no observed string, only author-invented test inputs. Not justified as shipped
What this change shipsIntent: keep a session alive through a momentary backend/transport outage by letting the existing bounded retry ladder absorb connection failures — a FIX.
Watch
Subtractions
[FIRST-PRINCIPLES-REVIEWED] a9ea9ee |
Opus 4.8 Review (fork) — ✅ no blocking findingsReviewed |
|
@Premshay Thanks for this. A read-only audit of all open PRs found two other open PRs working in the same code, so a short reconciliation now would save a painful rebase later. #9330 ("classify prose-spelled dispatch failure as transient", by @ShortEmperor) widens the same classifier, #9099 (by @iamwhatever) rewrites the entitlement branches of the same This branch is 170 commits behind main and its mergeable state reads unknown, so a rebase is needed regardless. Posted from the 2026-09-08 open-PR relationship audit (read-only, one auditor per PR); reply here if any of this is wrong. |
Classify connection errors and plain 5xx responses as retryable while retaining terminal auth, quota, and DNS precedence.
efcf6f6 to
a9ea9ee
Compare
Problem / Motivation
ACP connection failures such as refused/reset/timeouts and plain service-unavailable responses are currently terminal, though they can clear without user intervention.
Why it matters
A transient backend or transport outage ends a session unnecessarily instead of using the existing bounded retry path.
What changed
Classify common connection failures and plain 5xx service-unavailable responses as retryable. Authentication, quota, and session-expiry classifications retain precedence. The surfaced fallback now tells the user that the backend could not be reached.
Tests
python -m pytest test/test_acp_error_surface.py test/test_acp_client.py -n0 -q— 651 passed.What changed (motivation → approach → change)
N/A — covered by the existing
## What changedsection.Manual verification
N/A — focused automated coverage is sufficient.
Related Issues
N/A.
Checklist
Contribution License Agreement
N/A — template placeholder; no CLA wording is supplied.
Pattern harvest
Not generalizable: this is a bounded adapter-startup retry at a specific process-creation boundary.