From 8d3d4e19a203351e43b60c35c43ddfeab3b97762 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Oct 2026 07:47:21 +0000 Subject: [PATCH 1/2] Retry bun backtest cells on hosted fetch 5xx Bun patch compatibility went red on main in run 37852649519: all four bun.lockb legs (0.8.1, 1.0.0, 1.0.36, 1.1.0) failed the same vendored-then-hosted cell at the same moment with "HTTP Error 503: Service Unavailable" while patch.socket.dev blipped. The cell has a fresh-tree retry for transport failures, but it never fired: - the 503 came from hosted_lockb_digest's own urllib fetch, and urllib's "HTTP Error 5xx" / "" text matched neither the CLI's nor bun's transport patterns; - the cold frozen/ordinary installs that failed in the same window kept bun's own "error: GET - 503" line only in their logs, never on the row has_transport_failure inspects. Classify urllib 5xx/429/no-response errors as transport failures, and record each labelled install's bun transport lines on the row, as the VEX checkout install already does. Functional failures and 4xx responses still fail on the first attempt. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01KTF5Q8WeZfwTw6EyQrGorh --- scripts/backtest-bun.py | 15 +++++++-- scripts/tests/test_backtest_harnesses.py | 39 ++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/scripts/backtest-bun.py b/scripts/backtest-bun.py index d35b524aa..f7af759b1 100644 --- a/scripts/backtest-bun.py +++ b/scripts/backtest-bun.py @@ -167,6 +167,11 @@ def save(path, data): BUN_TRANSPORT_FAILURE = re.compile( r'^error: (?:Connection\w+|FailedToOpenSocket|Timeout|TLSHandshakeTimeout) downloading ' r'|^error: GET \S+ - 5\d\d\b', re.M) +# The harness's own urllib fetch of a hosted service (e.g. the patched +# tarball `hosted_lockb_digest` reads from patch.socket.dev) failing with a +# 5xx / 429 (`HTTP Error 503: Service Unavailable`) or no response at all +# (``). +HARNESS_TRANSPORT_FAILURE = re.compile(r'\bHTTP Error (?:5\d\d|429)\b|= (1, 2, 23)): diff --git a/scripts/tests/test_backtest_harnesses.py b/scripts/tests/test_backtest_harnesses.py index edecfbb0d..114405cde 100644 --- a/scripts/tests/test_backtest_harnesses.py +++ b/scripts/tests/test_backtest_harnesses.py @@ -63,6 +63,45 @@ def test_a_patch_api_5xx_is_a_transport_failure(self): self.assertTrue(bun.has_transport_failure(['API request failed with status 504: error code: 504'])) self.assertFalse(bun.has_transport_failure({'error': 'API request failed with status 404: not found'})) + def test_a_harness_fetch_5xx_is_a_transport_failure(self): + # run 37852649519: hosted_lockb_digest's urlopen of patch.socket.dev + # raised this on all four bun.lockb legs and none of them retried. + self.assertTrue(bun.has_transport_failure({'error': 'HTTP Error 503: Service Unavailable'})) + self.assertTrue(bun.has_transport_failure({'error': 'HTTP Error 429: Too Many Requests'})) + self.assertTrue(bun.has_transport_failure( + {'error': ''})) + self.assertFalse(bun.has_transport_failure({'error': 'HTTP Error 404: Not Found'})) + + def test_a_failed_install_fetch_is_a_transport_failure(self): + output = 'bun install v1.0.0\nerror: GET https://patch.socket.dev/x.tgz - 503\n' + row = dict(passed=False, checks={'frozenPatchedBytes': False}, + frozenInstallTransport=bun.bun_transport_failures(output)) + self.assertTrue(bun.has_transport_failure(row)) + row['frozenInstallTransport'] = bun.bun_transport_failures('bun install v1.0.0\n') + self.assertFalse(bun.has_transport_failure(row)) + + def test_a_harness_fetch_5xx_cell_retries_fresh(self): + with tempfile.TemporaryDirectory() as temp: + root = Path(temp) + job = ('0.8.1', 'vendored-then-hosted', 'vendored') + case = root / 'captures' / '-'.join(job) + calls = [] + + def run_case(_job): + case.mkdir(parents=True) + calls.append(True) + row = dict(passed=len(calls) > 1, checks={'frozenPatchedBytes': len(calls) > 1}) + if len(calls) == 1: + row['error'] = 'HTTP Error 503: Service Unavailable' + bun.save(case / 'result.json', row) + return row + + with patch.object(bun.time, 'sleep'): + row = bun.retry_network_cell(run_case, job, root) + self.assertTrue(row['passed']) + self.assertEqual(len(calls), 2) + self.assertEqual(row['networkRetryAttempts'][0]['failedChecks'], ['frozenPatchedBytes']) + def test_functional_failure_is_never_retried(self): with tempfile.TemporaryDirectory() as temp: row = dict(passed=False, checks={'frozenPatchedBytes': False}, error='installed bytes differ') From 4c33a0cda06cbad718741427c6ef7a97442b49d1 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 9 Oct 2026 13:41:17 +0000 Subject: [PATCH 2/2] Merge main; fold the two harness transport regexes #1009 landed its own HARNESS_TRANSPORT_FAILURE in backtest-bun.py after this branch was queued. The squash merged cleanly, but the later assignment shadowed this PR's HTTP 5xx/429 pattern, so BunTransportRetryTests failed in merge group 87ff737 and every group stacked behind it. Keep one definition: the urllib 5xx/429 match plus #1009's anchored urlopen and Errno connection-reset matches. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_01LVVtQNBuPeYaRmV82s6r6V --- scripts/backtest-bun.py | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/scripts/backtest-bun.py b/scripts/backtest-bun.py index a8b94ce92..71020c4c8 100644 --- a/scripts/backtest-bun.py +++ b/scripts/backtest-bun.py @@ -187,16 +187,12 @@ def save(path, data): BUN_TRANSPORT_FAILURE = re.compile( r'^error: (?:Connection\w+|FailedToOpenSocket|Timeout|TLSHandshakeTimeout) downloading ' r'|^error: GET \S+ - 5\d\d\b', re.M) -# The harness's own urllib fetch of a hosted service (e.g. the patched -# tarball `hosted_lockb_digest` reads from patch.socket.dev) failing with a -# 5xx / 429 (`HTTP Error 503: Service Unavailable`) or no response at all -# (``). -HARNESS_TRANSPORT_FAILURE = re.compile(r'\bHTTP Error (?:5\d\d|429)\b|`. -HARNESS_TRANSPORT_FAILURE = re.compile(r'^`). +HARNESS_TRANSPORT_FAILURE = re.compile( + r'\bHTTP Error (?:5\d\d|429)\b|^