Skip to content

refactor(http): prepare installs transactionally#10964

Draft
risu729 wants to merge 2 commits into
jdx:mainfrom
risu729:codex-20260713-044458-dc40d0
Draft

refactor(http): prepare installs transactionally#10964
risu729 wants to merge 2 commits into
jdx:mainfrom
risu729:codex-20260713-044458-dc40d0

Conversation

@risu729

@risu729 risu729 commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Summary

  • add an in-memory PreparedInstall / SuccessfulInstall seam to backend installation, with an explicit Legacy path for every unmigrated backend
  • migrate HTTP installs so URL, checksum, size, format, stripping, binary naming, and layout inputs are frozen before destructive install work begins
  • replay the locked HTTP artifact contract instead of re-rendering a changed config URL, and validate checksum/size before populating the shared cache or exposing install symlinks
  • keep lock enrichment attached to successful results and preserve the existing on-disk lockfile schema

This is the first HTTP vertical slice from Migrate lock installs to prepared transactions one backend at a time. It intentionally does not introduce the final global planner, request identity, receipts, plugin bootstrap, or a new lockfile schema.

Tests

  • mise x cargo -- cargo test backend::http::tests::prepared_http_install_prefers_locked_artifact_contract
  • mise run test:e2e e2e/backend/test_http_lock_install_verify
  • mise run lint-fix

The HTTP E2E coverage verifies locked URL replay after config changes, checksum and size failure atomicity, unchanged lockfile contents, unchanged shared cache contents, and no residual install path, including a request for latest.

Summary by CodeRabbit

  • Bug Fixes
    • Strengthened locked HTTP installations to always install the artifact recorded in the lockfile, even if the configured URL or content changes.
    • Locked installs now verify checksum/size up front and avoid creating install directories or writing persistent cache data on failure.
    • Integrity failures now leave lockfiles unchanged to prevent partial or corrupted installs.
  • Refactor
    • Introduced a two-phase “prepared” install flow to improve validation consistency across backends.
  • Tests
    • Expanded end-to-end coverage for checksum/size tampering and “latest” scenarios to ensure fail-before-side-effects behavior.

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 73b1b931-b593-428c-a088-7e3a07a36387

📥 Commits

Reviewing files that changed from the base of the PR and between 77a1c9d and c0fe9cd.

📒 Files selected for processing (2)
  • src/backend/http.rs
  • src/backend/prepared_install.rs
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/backend/prepared_install.rs
  • src/backend/http.rs

📝 Walkthrough

Walkthrough

The backend adds a prepared-install contract, refactors HTTP installation into preparation and execution phases, verifies lockfile contracts before persistent cache or install changes, and expands end-to-end coverage for checksum, size, URL, and cache integrity.

Changes

HTTP prepared installation

Layer / File(s) Summary
Prepared install contract and lifecycle
src/backend/prepared_install.rs, src/backend/mod.rs
Adds prepared HTTP and legacy install variants, successful-install results, backend preparation hooks, and execution through prepared inputs.
HTTP preparation and option normalization
src/backend/http.rs
Resolves target-specific locked or configured values and updates cache, extraction, metadata, and symlink helpers to consume PreparedHttpInstall.
HTTP execution and lock verification
src/backend/http.rs, e2e/backend/test_http_lock_install_verify
Separates artifact and lock-contract verification from download, cache locking, extraction, and installation persistence; tests locked URL, checksum, size, cache, and install-directory behavior.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Backend
  participant HTTPPreparation
  participant HTTPInstall
  participant Lockfile
  participant HTTPCache
  Backend->>HTTPPreparation: prepare target and install contract
  HTTPPreparation-->>Backend: PreparedHttpInstall
  Backend->>HTTPInstall: install prepared artifact
  HTTPInstall->>Lockfile: verify checksum and size contract
  Lockfile-->>HTTPInstall: validation result
  HTTPInstall->>HTTPCache: lock and populate cache after validation
  HTTPInstall-->>Backend: successful installation
Loading

Possibly related PRs

  • jdx/mise#10552: Covers related HTTP checksum expression and lockfile verification behavior.

Poem

A bunny hops through locks so tight,
Checksums guard the code just right.
No cache crumbs when errors call,
No install paths appear at all.
Prepared plans now lead the way—
Safe little hops for every day!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: making HTTP installs transactional through a preparation step.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/backend/http.rs (1)

994-1001: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Redundant pre-population duplicates verify_lock_contract and records checksum/size before verification.

Lines 994-1001 set platform_info.url/checksum/size from the lock spec, but verify_lock_contract (Line 1021) unconditionally sets url, and sets checksum/size whenever lock_checksum/lock_size are present — so this block is a no-op in every case. It's currently safe (verification always runs afterward and tv is dropped on any error), but recording the checksum/size ahead of verification here obscures the "verified-before-recorded" invariant this PR is built around, and would silently persist unverified values if the verification step were ever reordered. Consider dropping the block and letting verify_lock_contract own enrichment.

♻️ Proposed simplification
-        // Carry only the prepared contract into the successful result. The
-        // writer sees this state only when every operation below succeeds.
-        let platform_info = tv.lock_platforms.entry(spec.target.clone()).or_default();
-        platform_info.url = Some(url.clone());
-        if let Some(checksum) = &spec.lock_checksum {
-            platform_info.checksum = Some(checksum.clone());
-        }
-        if let Some(size) = spec.lock_size {
-            platform_info.size = Some(size);
-        }
-
         let lockfile_enabled = Settings::get().lockfile_enabled();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/backend/http.rs` around lines 994 - 1001, Remove the pre-population block
that updates platform_info in the flow before verification. Let
verify_lock_contract exclusively assign url, checksum, and size after successful
validation, preserving the verified-before-recorded invariant and avoiding
duplicate enrichment.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/backend/http.rs`:
- Around line 994-1001: Remove the pre-population block that updates
platform_info in the flow before verification. Let verify_lock_contract
exclusively assign url, checksum, and size after successful validation,
preserving the verified-before-recorded invariant and avoiding duplicate
enrichment.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 3c06423e-1a3e-47f2-879c-8abf601fe901

📥 Commits

Reviewing files that changed from the base of the PR and between 6f78506 and 77a1c9d.

📒 Files selected for processing (4)
  • e2e/backend/test_http_lock_install_verify
  • src/backend/http.rs
  • src/backend/mod.rs
  • src/backend/prepared_install.rs

@greptile-apps

greptile-apps Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR introduces a PreparedInstall / SuccessfulInstall abstraction that freezes all HTTP installation inputs (URL, checksum, size, format, strip, binary naming) before any destructive work begins. The key correctness gains are: locked installs replay the lockfile-recorded URL instead of re-rendering a changed config template, and checksum/size are validated against the downloaded artifact before the shared extraction cache or install symlink is written.

  • Transactional HTTP installs: prepare_http_install resolves the full artifact contract up-front; install_prepared_http verifies the configured artifact, then verifies the lock contract, then populates the cache — so a mismatch leaves no residual state.
  • Legacy backend shim: unmigrated backends get a Legacy prepared install that delegates straight to the existing install_version_ path, leaving their behavior unchanged.
  • Expanded E2E tests: locked URL replay after config change, checksum/size failure atomicity (lockfile and cache unchanged, no install dir created), and a latest-version content-derived-path atomicity case are all covered.

Confidence Score: 4/5

Safe to merge for the common HTTP-backend install flow; one edge case (tool stubs in locked mode) was exempted by the old guard in mod.rs but is no longer exempted by the new prepare_http_install check.

The new transactional prepare path works correctly for the primary use cases and the E2E tests are comprehensive. However, prepare_http_install adds a locked-URL guard that does not carry over the existing tool-stub exemption from mod.rs, meaning mise x http:… under locked = true would fail for any tool that hasn't been through mise lock, changing behavior that the original code explicitly preserved.

src/backend/http.rs — specifically prepare_http_install (missing stub exemption) and install_version_ (dead code that may mislead future maintainers).

Important Files Changed

Filename Overview
src/backend/http.rs Core HTTP install rewrite: URL/checksum/size locked before destructive work; lockfile replay honors locked URL over config; checksum+size verified before cache population. One regression: prepare_http_install lacks the tool-stub exemption present in the mod.rs locked check.
src/backend/mod.rs Adds prepare_install / install_prepared_version_ seam; updates install_version to call install_prepared_version_ with a pre-resolved PreparedInstall; preparation is eagerly resolved for locked and forced-reinstall paths before destructive operations.
src/backend/prepared_install.rs New module: PreparedInstall / PreparedHttpInstall / SuccessfulInstall types. Legacy variant preserves existing behavior for unmigrated backends; Http variant freezes all installation inputs before side effects begin.
e2e/backend/test_http_lock_install_verify Expanded E2E coverage: locked URL replay after config change, checksum/size failure atomicity (lockfile unchanged, no install dir, no cache change), and latest content-derived path atomicity.

Reviews (2): Last reviewed commit: "fix(http): tighten prepared install hand..." | Re-trigger Greptile

Comment thread src/backend/http.rs Outdated
Comment thread src/backend/http.rs
@github-actions

Copy link
Copy Markdown

This PR currently has failing checks. If this continues for 7 days, it will be closed automatically.

This is warning day 1 of 7.

Please update the PR when you have a chance. Feel free to reopen or create a new PR if it is closed and you'd like to continue working on it.

This comment was generated by an automated workflow.

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