Skip to content

fix(extensions): exclude regenerable bundles from auto-resolve truncation check#1199

Merged
stack72 merged 1 commit intomainfrom
worktree-vectorized-singing-summit
Apr 20, 2026
Merged

fix(extensions): exclude regenerable bundles from auto-resolve truncation check#1199
stack72 merged 1 commit intomainfrom
worktree-vectorized-singing-summit

Conversation

@stack72
Copy link
Copy Markdown
Contributor

@stack72 stack72 commented Apr 20, 2026

Summary

The tri-state inspectInstallation introduced in #1197 stats every path in the lockfile's file list to detect a truncated install. That list includes compiled bundles under .swamp/bundles/**, .swamp/vault-bundles/**, .swamp/driver-bundles/**, .swamp/datastore-bundles/**, and .swamp/report-bundles/** — regenerable build artifacts, not source.

When a user clears any of those caches (normal hygiene, stale rebuild, fresh worktree), auto-resolve flipped from intacttruncated and emitted:

incomplete — missing 1 file(s): ".swamp/bundles/91139983/system_usage.js"

…instead of the alreadyInstalledButFailed ("already installed at … run --force to recover") path that protects user WIP per #121. The motivating swamp-club#133 symptoms are all source-tree artifacts (manifest, kind subdirs, declared source), so the fix is to scope the truncation predicate to source files only.

This filters bundle prefixes out of the stat loop in inspectInstallation. Prefixes are derived from SWAMP_SUBDIRS.{bundles, vaultBundles, driverBundles, datastoreBundles, reportBundles} so a future bundle-dir addition stays in sync. No filesystem mutation, no API/event/wire-format changes.

Test Plan

  • deno fmt --check, deno lint, deno check clean
  • src/cli/auto_resolver_adapters_test.ts — 18/18 pass, including 2 new regression cases:
    • inspectInstallation ignores absent bundle artifacts and stays intact (covers all 5 bundle subdirs)
    • inspectInstallation reports truncated only for missing source, not missing bundles
  • integration/auto_resolver_truncated_test.ts — passes (fix(extensions): detect truncated pulled-extension trees in auto-resolve (swamp-club#133) #1197/feat: add Definition entity with CEL expression support (#117) #133 source-truncation behaviour preserved)
  • integration/auto_resolver_no_clobber_test.ts — passes (Issue 6: Migrate echo model to new architecture #121 no-clobber invariant preserved)
  • deno run compile succeeded
  • End-to-end repro against the rebuilt binary: swamp extension pull @stack72/[email protected] → edit pulled .ts with WIP marker + syntax error → rm -rf .swamp/bundlesswamp model create @stack72/system-usage instance1 now produces:
    Extension "@stack72/system-extensions" is already installed at … but failed to load.
    Local edits may be preventing it from registering — inspect the source and fix errors.
    To reset to the registry version and discard local changes, run: swamp extension pull "@stack72/system-extensions" --force
    
    …instead of the buggy incomplete — missing 1 file(s): ".swamp/bundles/91139983/system_usage.js".
  • UAT tests/cli/extension/pull_wip_preservation_test.ts:156 in swamp-uat (CI gate — local run blocked by membership auto-trust collision unrelated to this fix)

Cross-references

…tion check

The tri-state inspectInstallation introduced in #1197 stat'd every path
in the lockfile's file list, which includes .swamp/bundles/** and the
sibling vault/driver/datastore/report bundle caches. Clearing those
caches (a normal hygiene operation) flipped the resolver to the
truncated branch and emitted "incomplete — missing N file(s)" instead
of the alreadyInstalledButFailed path that protects user WIP (#121).

Filter bundle prefixes out of the stat loop so only source-tree files
under .swamp/pulled-extensions/<name>/ drive truncation. Bundle prefixes
are derived from SWAMP_SUBDIRS so a future bundle-dir addition stays in
sync.

Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

Blocking Issues

None.

Suggestions

None — this is a well-executed fix.

Summary: The change correctly scopes the inspectInstallation truncation predicate to source files only, excluding regenerable bundle artifacts under .swamp/{bundles,vault-bundles,driver-bundles,datastore-bundles,report-bundles}/. This prevents clearing the bundle cache from incorrectly flipping an intact extension into the truncated branch, which would steal the user-WIP error path from #121.

What I checked:

  • Correctness: BUNDLE_ARTIFACT_PREFIXES is derived from SWAMP_SUBDIRS constants, so it stays in sync automatically. The string prefix check is valid because lockfile paths are POSIX-normalized (forward slashes). The single-line continue in the stat loop is the minimal change needed.
  • Import boundary: SWAMP_SUBDIRS is imported from infrastructure/persistence/paths.ts (not a libswamp internal path) — matches the existing import already in the file, no boundary violation.
  • DDD: The bundle-vs-source distinction is an adapter-level concern correctly placed in the CLI adapter, not leaked into the domain's InstallationInspection type.
  • Test coverage: Two new regression tests cover both key scenarios — all 5 bundle subdirs excluded (stays intact) and mixed missing source + missing bundles (only source drives truncation). Good use of the existing seedLockfile/seedPulledTree helpers.
  • License headers: Present on both .ts files. No any types. All promises awaited. Named exports used.
  • Design doc: Updated to explain the rationale — accurately matches the implementation.
  • Security: No new attack surface. Bundle prefixes are derived from constants, not user input.

Clean fix with good test coverage and documentation.

@stack72 stack72 merged commit cdb958c into main Apr 20, 2026
10 checks passed
@stack72 stack72 deleted the worktree-vectorized-singing-summit branch April 20, 2026 23:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant