Relationships
#2708 Split installExtension into an unlocked prepare and a repo-changing apply
Opened by hammz · 9/29/2026· Shipped 9/29/2026
Summary
installExtension (src/libswamp/extensions/pull.ts:826, ~650 lines) interleaves network I/O with changes to the working tree and the lockfile. It resolves the version, downloads, verifies checksums, extracts and safety-checks, then copies into the pulled root, prunes orphans, writes the lockfile entry and recurses into dependencies — all in one function. No lock can cover the local changes without also being held across the downloads.
Split it into a prepare step, which touches only a private temp dir, and an apply step, which changes the repo. This is a refactor with no behavior change.
Groundwork for swamp-club#2612 (see its planning ripples). The per-checkout lock (swamp-club#2709) is taken around apply only. swamp-club#2495 needs the same split: its write path stages the download, verification and extraction outside any lock, then hydrates, writes and publishes under the lock.
Scope
prepareInstall(ref, ctx) → PreparedInstall: version resolution, registry info, download, the server checksum andexpectedChecksumchecks, listing, the unsafe-path check, extraction into a temp dir, source completeness, and safety analysis. No writes outside its temp dir.PreparedInstallowns the temp dir and has adispose()that is always awaited.applyInstall(prepared, ctx) → InstallResult: conflict detection against the live tree (still throwingConflictError, so the CLI's two-phase prompt keeps working), the copy into the pulled root and skills dirs, orphan pruning,writeEntry, and dependency recursion.installExtensionbecomes prepare, then apply, then dispose, with an unchanged signature and the same order of side effects.InstallExtensionService, the auto-resolver's direct call (src/cli/auto_resolver_adapters.ts:309), update, and upgrade keep working without changes.- Dependencies: keep recursion in apply for now. Record in the code which dependency steps do network I/O, so swamp-club#2709 can decide whether to prepare dependencies before taking the lock.
Tests
- The existing
pull,install_extension_service,updateand auto-resolver tests pass unchanged. They are the behavior-preservation check. - New unit tests: prepare writes nothing outside its temp dir (checked with a snapshot of the repo tree);
dispose()removes the temp dir after both success and failure; apply given a prepared install writes the same tree and lockfile entry as today's single call.
Shipped
Click a lifecycle step above to view its details.
Sign in to post a ripple.