historic-fleet: retry transient network failures at the harness level - #424
Merged
Conversation
Three consecutive formal fleet runs each failed exactly one case on a momentary runner network blip during a delivery hop. The updater retry shipped in PR #417 lives inside releases, so the installed foundation's pre-fix updater cannot protect these runs. The journey executor now retries only transient network delivery failures (network-unavailable, DNS resolution, connection reset/timeout) up to three bounded attempts with 10s/30s backoff around the foundation bridge and follow-up delivery hops, records the attempt count in the journey transcript and failure diagnostic, and fails exactly as before for non-network failures or exhausted attempts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
What this pull request touches
Gates that will judge this change
Based on 4 changed files. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Three consecutive formal
historic-fleet-darwinruns each failed exactly one of 202 cases on a momentary runner network blip, at different starting tags each time:dist/archive/v1.64.0-aa005a9failed at phasefollow-up-deliverywithfailure_reason: "network-unavailable",elapsed_ms: 134, retainingfollow-up-delivery-failure.diagnostic.jsonA 134 ms failure is a connectivity blip, not a real upgrade regression, yet it costs a full multi-hour fleet rerun.
Why PR #417 cannot cover this
The retry fix merged in #417 lives in the updater code inside releases. The fleet's delivery step runs the installed foundation release's (v1.81.16-era) updater via the fixture lifecycle runtime — code frozen at whatever the foundation shipped, which predates that fix. No in-release retry can ever protect the delivery of pre-fix foundations, so the protection has to live in the harness that drives them.
Retry design (harness level, executor-owned)
scripts/release_fleet_executor.pynow wraps the two per-case delivery hops — the foundation bridge and the follow-updeliver_latest_release— in a bounded transient-network retry:network-unavailabledelivery reason, or an error message matching DNS-resolution / connection-reset / connection-refused / connection-timeout / unreachable-network fragments. Everything else (evidence-invalid, route drift, approval violations, runtime timeouts, …) raises exactly as before on the first attempt.ExecutorError, same 202/202 bar). Public-route drift is checked per attempt and never retried. Bridge approvals are reset per attempt so a retried bridge still enforces the exact approval word and count.bridge-foundationandfoundation-previewevents now carryjourney_transport: {"attempt_count": N}(mirroring the existing Doctor transport evidence), and the failure diagnostic'sdeliverysection gainsattempt_count— so a retried-then-passed case is distinguishable from a first-try pass, and an exhausted-retries failure is distinguishable from a single-shot failure.Because the journey protocol pins the executor's exact bytes,
core/update/journey-protocol-v1.jsonis regenerated viascripts/generate-update-journey-protocol.py.Tests
ExecutorErrorretry, non-network delivery failure never retried, bounded exhaustion still fails withattempt_count: 3in the diagnostic, bridge network blip retried with fresh exact approvals, non-network bridge failure never retried, plus direct classifier coverage.attempt_countfield.core/tests/test_release_fleet_executor.py,test_release_fleet_failure_diagnostics.py,test_update_journey_protocol.py— 60 passed;test_release_fleet.py,test_release_fleet_acceptance.py,test_historic_fleet_darwin_workflow.py— 115 passed, 3 pre-existing macOS-only failures also present on clean main;test_distribution_artifacts.py— 82 passed. Full macOS fleet behavior is exercised by the PR canary.🤖 Generated with Claude Code