Repository navigation
Decide: keep the --update binary swap, or replace it with the installer and keep only the update notifier #983
Description
Activity
- addedarch-auditFiled by a scheduled architecture audit routine (see the architecture review discussion)Filed by a scheduled architecture audit routine (see the architecture review discussion)refactorStructural change: duplicated code or logic, missing abstraction, layering, dead codeStructural change: duplicated code or logic, missing abstraction, layering, dead code
on Oct 7, 2026 mikolalysenko commented
on Oct 7, 2026 CollaboratorAuthorMore actions[agent] Triaged as
priority:p3. This is a product decision (keep the self-update swap, replace it, or go hybrid), so it staysagent:needs-humanand isn't eligible for an agent claim until a maintainer chooses an option. Related follow-ups: #676 and #615.
Generated by Claude Code
mikolalysenko commented
on Oct 7, 2026 CollaboratorAuthorMore actionsSelf update is a great feature and arguably more essential than the install.socket.dev pathway for users who already running socket-patch. We must keep this working and continue to improve it.
mikolalysenko commented
on Oct 7, 2026 CollaboratorAuthorMore actions[agent] Decision recorded: keep the
--updatebinary swap and the update notifier (option 1). Options 2 and 3 are rejected. Self-update is a supported, first-class update path. It is the only updater Windows standalone users have, and per the maintainer it matters more than install.socket.dev for people who already run socket-patch.What this means
- No behavior or contract change. The CLI_CONTRACT.md "Self-update contract" section, its error codes and the
--update --dry-runprobe stay as they are. The repo docs (README,docs/installer-hosting.md,docs/releasing.md) already present--updateas the standalone update path and have no "may be removed" wording, so no docs PR is needed. - The architecture audit's suggestion to "replace the swap with re-run install.sh" is withdrawn. The living document (§3 recommendation 15, §5 support tiers, §7.5 and §7.6 Use patches-api.socket.dev for public patch data #10) will be updated to say the swap stays and is being improved, and register row C36 is closed as decided.
Improvements to file as follow-ups (main @
db83f01)- Retry transient failures. The two private clients (
download_client,crates/socket-patch-core/src/update/download.rs:59;metadata_client,release.rs:262) make one attempt each. A single 502 or connection reset from GitHub or the CDN fails the update. Add retry withRetry-Afterand jitter to the redirect probe, the API fallback,SHA256SUMSand the archive download, reusing theapi::retryprimitive from Tracking: one retry primitive for the patch API client (JSON, vendor service, blob and diff) #676. Tracking: one retry primitive for the patch API client (JSON, vendor service, blob and diff) #676 currently lists self-update as out of scope; this will be a sibling child, or Tracking: one retry primitive for the patch API client (JSON, vendor service, blob and diff) #676's scope will be widened. - Stall timeout instead of a whole-download budget. The archive download has a 300 s whole-request budget (
release.rs:114), so an update over a slow link fails while bytes are still arriving. This is the same class of bug as Registry downloads give up after 60 s even while the body is still arriving #872. Switch to a connect timeout plus an idle (no bytes received) timeout, keepingSOCKET_UPDATE_TIMEOUT_MS. - Stream the archive to disk.
fetch_archivebuffers up to 256 MiB in memory (download.rs:98,read_capped) before verifying it. Instead, stream it to the stage directory, hashing as it goes, the way blob downloads already do (C37). Verify-before-extract ordering is unchanged. - Live post-release test. The only test against real GitHub releases is an ignored
--dry-runsmoke (crates/socket-patch-cli/tests/self_update_e2e.rs:339). PR coverage uses a wiremock fixture. Add a post-release job: install the previous release on Linux, macOS and Windows, run a real--updateto the new tag, and check--version. That catches asset-naming, redirect andSHA256SUMSdrift in the real published pipeline. SOCKET_FORCEsplit: still Decide: give SOCKET_FORCE per-command names so forcing a self-update doesn't also force apply and vendor #615, so forcing a self-update stops also forcingapplyandvendor.- Shared spawn deadline: the hand-rolled 10 s timeout in
sanity_exec(download.rs:253) moves onto the shared child-process deadline when C48 lands. No behavior change.
Closing this decision issue. No PR is needed for the decision itself, since nothing in the repo changes. The improvements above will be filed as their own issues.
Generated by Claude Code
- No behavior or contract change. The CLI_CONTRACT.md "Self-update contract" section, its error codes and the
- added a commit that references this issue
on Oct 7, 2026
[agent] Filed by the scheduled architecture audit routine (CLI and core). Register: discussion #560 register.
Kind: decision. Source: review §5 ("Self-update binary swap"), §6 Q2, 7.5 and recommendation 15; register C36 (the self-update half; the agent-mode half is a separate row).
Question
Should
socket-patch --updatekeep replacing its own binary, or should it hand the upgrade to the installer and keep only the passive notifier?Options:
SOCKET_FORCEsharing stays Decide: give SOCKET_FORCE per-command names so forcing a self-update doesn't also force apply and vendor #615.--updatewould print (or, with--yes, run)curl -fsSL https://install.socket.dev/patch | sh, honoring theSOCKET_PATCH_VERSIONpin. That deletesupdate/download.rs,update/swap.rs, the update lock and most ofcommands/update.rs: about −1.1K production lines and −1.5K test lines. It's a contract MAJOR (the self-update section, its error codes, the--update --dry-runprobe). Windows standalone users lose their only updater, because there is no PowerShell installer: the README tells them to extract the zip by hand.install.shon Unix and keep the swap only for Windows. This keeps every piece of the swap machinery for one platform and adds a second path, so it saves the least.Whatever is chosen, the notifier stays: the review and this issue agree it's cheap and channel-aware.
Problem (main @
9c43dfc)Self-update is 2,350 production lines (unchanged since the review's 2,351), plus 2,369 inline and 2,634 external test lines:
update/: channel 245, download 378, mod 161, release 452, state 135, swap 208;commands/update.rs416,update_notifier.rs355.What it does, against the installer:
InstallChannel::Standalonemay swap; npm, Cargo and Homebrew get their own upgrade command, and the pre-v5 PyPI and gem locations get a migration hint.releases/latestredirect probe, then a GitHub API JSON fallback (fetch_latest_version).install.shneeds neither, because it downloads fromlatest/download/.SHA256SUMScheck, stage, sanity-exec and atomic rename run under a separate lock (perform_update).install.shdoes the same download and checksum steps, theninstall -m 755. The trust model is the same (HTTPS + GitHub, unsigned checksums), as docs/installer-hosting.md says.asset_name_for_target), so a musl binary updates to musl.install.shre-detects libc withldd(L55-L70), and its platform table has no Windows rows.socket-patch --update.swap.rshas its own#[cfg(windows)]path.download_client,metadata_client) with whole-request budgets (30 s metadata, 300 s download) and no retry.Symptoms
No open bugs. #128, #140 and #171 were the swap's own flake and hardening fixes.
Impact
This is a product and maintenance trade-off, not a defect. Option 2 removes the code that's the most expensive to test (exec sanity checks, ETXTBSY retries, Windows rename), but it costs Windows users and changes a documented contract.
Proposed change (after the decision)
perform_update's call site with the hint, deletesupdate/download.rs,update/swap.rsand the update lock, keepschannel.rs,release.rs(the notifier's version check) andstate.rs, and rewrites the contract's "Self-update contract" section with a MAJOR note.perform_updateoncfg(windows)and add the Unix hint.Size and scope
Option 2: about −1.1K production and −1.5K test lines in
update/,commands/update.rs, theself_update_*andtests/update/suites,CLI_CONTRACT.mdand the README. The notifier and channel detection are out of scope.Acceptance criteria
CLI_CONTRACT.mddocuments the new--updatebehavior with a MAJOR note, the README's install section matches, andupdate_notifier_e2estays green.Dependencies
SOCKET_FORCEis shared with--update --force) and Tracking: one retry primitive for the patch API client (JSON, vendor service, blob and diff) #676 (one retry primitive).