Skip to main content
← Back to list
01Issue
FeatureShippedSwamp CLIPublic
Assigneeshammz

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

  1. prepareInstall(ref, ctx) → PreparedInstall: version resolution, registry info, download, the server checksum and expectedChecksum checks, listing, the unsafe-path check, extraction into a temp dir, source completeness, and safety analysis. No writes outside its temp dir. PreparedInstall owns the temp dir and has a dispose() that is always awaited.
  2. applyInstall(prepared, ctx) → InstallResult: conflict detection against the live tree (still throwing ConflictError, so the CLI's two-phase prompt keeps working), the copy into the pulled root and skills dirs, orphan pruning, writeEntry, and dependency recursion.
  3. installExtension becomes 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.
  4. 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, update and 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.
02Bog Flow
✓OPEN✓TRIAGED✓IN PROGRESS✓SHIPPED+ 1 MOREASSIGNED+ 6 MOREFINDINGS+ 7 MOREPR_MERGED+ 2 MORESESSION_SUMMARIZED

Shipped

9/29/2026, 6:15:37 PM

Click a lifecycle step above to view its details.

03Sludge Pulse
hammz assigned hammz9/29/2026, 5:45:33 PM

Sign in to post a ripple.