test(release): truncated-download resilience check (§6b) - #276
Merged
Conversation
§6 serves the update archive from localhost, which never truncates — it proves extraction works but cannot catch a download cut short on a real network (the v0.5.0 'Could not find EOCD' field failure, fixed in #275). Close that validation gap: - dist/truncating_server.py: serves a file but advertises the full Content-Length while cutting the body short on the first N requests, then serves it in full — a stand-in for a TLS-inspecting proxy clipping a large HTTPS download. - RELEASE-VALIDATION §6b: two runs — truncate-first 2 (the install self-heals on attempt 3) and truncate-first 999 (ends on the honest 'Download incomplete', not EOCD), with the server's attempt count as the proof the verify+retry path ran. Verified end-to-end against the real updater with the driver build: 2 truncated + 1 full -> 'Update installed'; always-truncate -> exactly 3 attempts then give up. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds an end-to-end manual release validation step that simulates real-world truncated HTTP downloads (middlebox/proxy clipping) to ensure the updater’s verify+retry logic (from PR #275) both self-heals when truncation is transient and fails with an honest “Download incomplete …” error when it’s persistent.
Changes:
- Adds
dist/truncating_server.py, an HTTP server that advertises fullContent-Lengthbut intentionally cuts response bodies short for the first N requests. - Extends
docs/RELEASE-VALIDATION.mdwith mandatory §6b guidance to validate retry/self-heal and honest failure messaging under truncation.
Reviewed changes
Copilot reviewed 1 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| docs/RELEASE-VALIDATION.md | Adds mandatory §6b manual validation procedure for truncated-download resilience and expected outcomes. |
| dist/truncating_server.py | Introduces a localhost HTTP server utility to simulate truncated downloads while keeping Content-Length unchanged. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…_server.py Address Copilot review: §6b no longer inherits §6's reference to the missing dist/slow_server.py. §6b spells out the build + Compress-Archive staging, and §6 now serves via the in-repo truncating_server.py (--truncate-first 0 = serve full) instead of the retired script. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Address Copilot round 2: drop the now-stale 'do not use §6's slow_server.py' warning (§6 no longer has that step), and fix the sign-off range to '1-6b' since 6b sits outside 1-6. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Address Copilot round 3: §6 now recommends a plain localhost server, so the checklist item no longer hard-requires a 'visibly advancing' byte count (that only happens with a throttled server) — it accepts an instant jump to total. The extraction check remains the load-bearing assertion. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
maui1911
added a commit
that referenced
this pull request
Jun 12, 2026
Patch release: in-app updater now verifies download completeness and retries truncated downloads (#275), so a TLS-inspecting proxy / AV middlebox clipping the archive no longer surfaces as a baffling 'Could not find EOCD' extract failure. Adds the truncated-download resilience check to RELEASE-VALIDATION §6b (#276). Tag v0.5.1 after this merges to trigger the release pipeline. Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
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.
Follow-up to #275. Closes the validation gap that let the truncated-download bug ship: RELEASE-VALIDATION §6 serves the archive from localhost, which never truncates, so it proves extraction works but structurally can't catch a truncating network.
What's added
dist/truncating_server.py— serves a file but advertises the realContent-Lengthwhile cutting the body short on the first N requests, then serves it in full. A faithful stand-in for a TLS-inspecting proxy / AV middlebox clipping a large HTTPS download (the exact thing that produced the user'sCould not find EOCD).--truncate-first 2: the install self-heals on attempt 3 → "Update installed".--truncate-first 999: ends on the honest "Download incomplete: received N of M bytes" — not EOCD — with the server's attempt count (exactly 3) as proof the verify+retry path ran.Verified end-to-end
Driver-instrumented build against the real updater (#275 code):
TRUNCATED, TRUNCATED, full→ toast reached "Update installed" (self-heal).TRUNCATEDper click, then give up (old code would issue a single GET then fail at extract — 3 attempts can only be the new verify+retry loop).The exact failure wording is already pinned by the
verify_completeunit tests in #275; this is the end-to-end socket-level wiring check.🤖 Generated with Claude Code