Skip to content

v5 WS4/WS6: one hosted engine for disk + memory; unified Ledgers view - #282

Merged
Mikola Lysenko (mikolalysenko) merged 13 commits into
release/v5-prereleasefrom
v5/one-hosted-engine
Sep 28, 2026
Merged

Mikola Lysenko (mikolalysenko) merged 13 commits into
release/v5-prereleasefrom
v5/one-hosted-engine

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Sep 27, 2026 •

Copy link
Copy Markdown
Collaborator

Implements WS4 and a first cut of WS6 from docs/design/v5-plan.md, on top of #280 (ledger-free hosted, 686e5fb).

WS4: one hosted engine (disk + memory)

  • The plan → rewrite stages of run_redirect_selected now live in socket_patch_core::hosted::engine, as pure functions over ProjectView: build_candidates, bun_lockb_symlinked, withhold_everywhere, read_candidate_files, wheel_targets, rewrite and guard.
  • The disk flow (scan / get --mode hosted) keeps only the host side:
    • the apply lock
    • the probes: pipenv version, and stale installs for gem, python and vlt
    • the vendored takeover (vendored_takeover)
    • the symlink refusal
    • the commit of the rewritten files
  • The in-memory engine moves to socket_patch_core::hosted::memory and runs the same stages over ProjectView::Memory. Its duplicated redirect orchestration is deleted.
  • Other code that moved:
    • the pnpm trustLockfile / npm allow-remote planners → hosted::guidance
    • the vlt preflight → hosted::vlt
    • the JSON shaping of skipped patches, warnings and the redirect block → hosted::render; the engine emits typed RewriteWarnings, not serde_json::Value.
  • No hosted ledger. Following v5 WS1+WS2: ledger-free hosted mode, upstream-restore rollback, vendor ejects hosted projects #280, neither engine reads or writes .socket/vendor/redirect-state.json. This branch's old hosted::ledger module (the redirect-ledger merge, in-memory load and serializer) is deleted, not moved.
  • socket-patch-node now depends on socket-patch-core only. The CLI re-exports hosted_memory for hosted-bundle and the tests.
  • hosted_memory_parity, redirect_golden and v5 WS1+WS2: ledger-free hosted mode, upstream-restore rollback, vendor ejects hosted projects #280's upstream_restore_golden pass on the merged tree.

WS6: one Ledgers view + ProjectContext

socket_patch_core::ledgers holds the one owner-precedence rule:

  • manifest > vendor ledger > hosted records, by ledger key;
  • a manifest key claims every vendor entry filed under it or naming it as base purl.

The hosted records are what v5 has instead of a ledger: the lockfiles' hosted pins, or a run's fetched records, plus a pre-v5 ledger that is read, never written, for migration.

The rule exposes these views:

  • owned: one group per owner key, with the losing copies as alternates;
  • listed: every copy worth showing;
  • matching: store entries a remove/rollback identifier matches;
  • hosted_vendored_overlap.

These views replace:

LoadedLedgers::load loads the manifest, the vendor ledger and any pre-v5 redirect ledger once, and each store keeps its own load outcome.

commands::context::ProjectContext loads the stores, the lockfile inventory and the wiring discovery lazily, at most once per run:

  • locks() and discovery() read --cwd through one read-through DiskSnapshot (ProjectView::Snapshot), so each lock or config file is read at most once and both see the same bytes.
  • Scan's discovery phase and hosted-pin reads, list and get go through it.

Behavior differences, listed in the CHANGELOG:

  • scan's updates[] no longer folds a vendor entry the manifest claims by base purl.
  • vex treats every vendor entry a manifest key claims as a fallback copy of that key's record.
  • setup --check no longer folds a detached vendor entry whose base purl is in the manifest.
  • get falls back to the committed artifacts on a corrupt vendor ledger, as scan does.

Follow-ups (not in this PR)

Listed in a PR comment: the rest of review item 3 (share the parsed models; thread the context into vendor / vex) and item 4 (a typed HostedOutcome with JSON, human and memory adapters), plus F17.

Validation (on 4cabaf1, the merge)

  • cargo clippy --workspace --all-targets --all-features -- -D warnings is clean.
  • cargo test --workspace --all-features --no-fail-fast -j4:
    • this branch: 10216 passed, 18 failed;
    • release/v5-prerelease @ 686e5fb, same sandbox: 10211 passed, 18 failed.
    • The 18 failures are the same tests on both, all root-user write-failure tests.

🤖 Generated with Claude Code

https://claude.ai/code/session_01KHZ8uzdXfkG2zH8ZYDG8ju


Note

Medium Risk
Broad refactor of how patch stores are merged and how hosted rewrites run, with intentional behavior changes across scan, vex, get, and setup rather than cosmetic CLI moves.

Overview
This PR centralizes hosted-mode lockfile rewriting in socket_patch_core::hosted so the CLI disk path and the in-memory engine (Node addon / hosted-bundle) share the same plan → rewrite stages over ProjectView. The CLI keeps host-only concerns (apply lock, vendored takeover, symlink guards, commits); pnpm/npm install-policy text, vlt preflight, and JSON rendering move into core. socket-patch-node no longer depends on the CLI—it uses core only, with hosted_memory re-exported for compatibility.

It also introduces socket_patch_core::ledgers with a single precedence rule (manifest → vendor ledger → hosted records, including manifest claims by ledger key or base purl) and ProjectContext to load stores, lock inventory, and wiring discovery once per run (shared DiskSnapshot for lock/config reads).

Commands list, scan, vex, get, setup --check, rollback, and remove now read patch stores through that view instead of ad hoc merging. User-visible fixes include: scan updates[] no longer double-counts vendor entries the manifest owns by base purl; vex treats claimed vendor rows as fallback copies of the manifest record; setup --check stops folding detached vendor entries when the manifest already records the base purl; get matches scan when the vendor ledger is corrupt (fallback to committed artifacts). Manifest record building from API patches moves from get into core for reuse.

Reviewed by Cursor Bugbot for commit 4cabaf1. Configure here.

Extract the plan -> rewrite -> edits stages of `run_redirect_selected`
into `socket_patch_core::hosted::engine`, a set of pure functions over a
`ProjectView` (build_candidates, bun_lockb_symlinked, withhold_everywhere,
read_candidate_files, wheel_targets, rewrite, guard). The disk flow
(`scan`/`get --mode hosted`) keeps only the apply lock, the host probes
(pipenv version, gem/python/vlt stale installs), the vendored takeover,
the symlink refusal and the commit of the rewritten files.

The in-memory engine moves to `socket_patch_core::hosted::memory` and
runs the same stages over `ProjectView::Memory`; its duplicated
redirect.rs / ledger.rs orchestration is deleted. The pnpm trust / npm
allow-remote planners move to `hosted::guidance`, the vlt preflight to
`hosted::vlt`, and the redirect-ledger delta to `hosted::ledger`, which
the engine never calls, so removing the hosted ledger only touches the
two callers. `socket-patch-node` now depends on socket-patch-core only;
the CLI re-exports `hosted_memory` for `hosted-bundle` and the tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KHZ8uzdXfkG2zH8ZYDG8ju
The previous commit ran `cargo fmt --all` over a tree that is not
rustfmt-clean, reformatting ~30 files it does not otherwise touch.
Restore those files; no code changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KHZ8uzdXfkG2zH8ZYDG8ju
`socket_patch_core::ledgers` holds the one owner-precedence rule for the
manifest, the vendor ledger and the hosted redirect ledger (manifest >
vendored > hosted by ledger key; a manifest key claims every vendor entry
filed under it or naming it as base purl) and the views every reader
derives from it: `owned` (one group per owner key, losers as alternates),
`listed` (every copy worth showing), `matching` (remove/rollback
identifiers) and `hosted_vendored_overlap`. It replaces list's
combined_entries, fold_vendor_records / vendor_record_is_unowned, scan's
merge_ledger_records_for_updates, vex_sources' build_candidates and
overlap_from_states, and rollback/remove's per-store matching loops.
`LoadedLedgers::load` loads the three stores once, each with its own
outcome so every caller keeps its error posture.

`commands::context::ProjectContext` lazily loads the stores, the
lockfile inventory and the wiring discovery at most once per run; scan's
discovery phase, list and get read through it. `get`'s installed-version
narrowing now reuses scan's lockfile and vendored-ledger supplements
instead of its own inventory and ledger reads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KHZ8uzdXfkG2zH8ZYDG8ju
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

vlt patch compatibility / install-proof (ubuntu-latest, *) fails on vlt_pinned_matrix_agent_get_and_remove with left: Absent, right: Patched at tests/e2e_vlt.rs:156.

This is not caused by this PR. The same test fails the same way on release/v5-prerelease @ 8ae7dc3 (for example run 36352437746, job install-proof (ubuntu-latest, 0.0.0-18)).

Root cause: v5 get defaults to hosted mode (commands/get.rs: args.mode.unwrap_or(... ScanMode::Hosted)). This agent-mode test still calls get <uuid> without a mode, so it now runs the hosted rewrite plus the vlt warm-tree heal, which removes the stale installed copy. That is why the package reads Absent instead of Patched.

No fix exists yet. Proposed patch, a test-only change I'm not adding here to keep this PR's scope:

--- a/crates/socket-patch-cli/tests/e2e_vlt.rs
+++ b/crates/socket-patch-cli/tests/e2e_vlt.rs
@@ async fn vlt_pinned_matrix_agent_get_and_remove() {
-    let out = socket_api(&fx.proj, &fx.svc, &["get", UUID], &[]);
+    let out = socket_api(&fx.proj, &fx.svc, &["get", UUID, "--mode", "agent"], &[]);

Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

CI / coverage (and test (*) / test-release) fail on e2e_redirect_cargo_build::cargo_get_uuid_hosted_fresh_checkout_fetch and cargo_hosted_fresh_checkout_fetch_pulls_patched_crate_and_vex_verifies. The failing assertion is (3) offline: left Some(0), right Some(1): an offline vex still attests the patch (redirected).

This isn't from this PR. release/v5-prerelease @ 8ae7dc3 fails the same two tests with the same assertion (CI run 36352437716, job coverage), and they fail locally on the base branch as well.

Likely cause, not yet verified: step (2) runs the "read-only" embedded scan --vex with no --mode. In v5 that defaults to hosted, so it writes the redirect ledger and its records. Step (3) ("offline with no ledger") then finds the record locally. A fix is probably to run that step as scan --mode agent --vex … or --dry-run, or to delete .socket/vendor/redirect-state.json before (3). No fix exists on the base branch yet, so I'm not changing it in this PR.


Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

CI / test (windows-latest) fails two targets: covgap_commands_scan_mod and e2e_redirect_cargo_build. The cargo one is covered in my earlier comment. release/v5-prerelease @ 8ae7dc3 fails exactly the same two targets on Windows (CI run 36352437716, job test (windows-latest)), so neither failure comes from this PR. The Linux and macOS test jobs fail only the cargo target. No fix exists on the base branch yet.


Generated by Claude Code

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

v5 review at 5dcf9882 — moving the hosted engine into core and removing the Node addon's CLI dependency is the right boundary. Keep it. I did not confirm a new functional regression, but there is avoidable work and unfinished integration.

  1. Index ledger ownership once. Ledgers::owned() sorts and scans all vendor keys inside each manifest-record iteration (ledgers.rs:173–192). For M manifest and V vendor entries this adds O(M·V log V) work, even for direct key matches. Build a deterministic owner-to-entry index once and derive the different views from it. This is a source-level complexity finding, not a measured wall-clock regression.
  2. Finish the ledger-free integration before calling this complete. Disk and memory still serialize the hosted ledger, and the new abstraction models three persistent stores. With #280, retain only legacy read/migration support for hosted records; remove the hosted writer/merge path from both engines. The #280/#282 heads conflict across these paths, so parity must be checked again on the combined tree.
  3. Cache one project snapshot, not two interpretations of the files. ProjectContext::locks() and discovery() independently read/parse the project, and the context has no shared crawl snapshot. Back both with the shared format models and a consistent project root; rebuild/invalidate the snapshot after writes before embedded VEX. Thread it through vendor/VEX as well as scan/get/list.
  4. Keep rendering out of orchestration. Return a typed plan/result from the shared engine, then let disk, memory, JSON and human adapters consume it. This makes the reduction durable rather than relocating the old CLI state machine into core.

Validation: source/diff review; existing parity/golden coverage inspected, not rerun here.

`Ledgers::owned` re-sorted and scanned every vendor key for each
manifest key. Group the vendor entries under their claiming manifest key
in one pass over the sorted ledger (`claims`), so each view is
O(V log V + M) instead of O(M * V log V). Same ordering and alternates.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KHZ8uzdXfkG2zH8ZYDG8ju
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Thanks, replies by item:

  1. Ledger ownership index: fixed in 04b3d96, not pushed yet; it's waiting on the full test run. Ledgers::claims() groups the vendor entries under the manifest key that claims them, in one pass over the sorted ledger. owned()/listed() read from that group, which removes the per-manifest-key re-sort and scan. Each view is now O(V log V + M). Ordering and alternates are unchanged: the ledgers unit tests and the 844 CLI lib tests pass unchanged, and clippy is clean.

  2. Ledger-free integration. Agreed that this isn't complete until the hosted writer and merge path are gone. v5 WS1+WS2: ledger-free hosted mode, upstream-restore rollback, vendor ejects hosted projects #280 is still a draft with WS1 items open, and our heads overlap on hosted/engine.rs, scan/hosted.rs and the rollback/remove hosted legs. So my proposal is:

    If you'd rather land v5 WS4/WS6: one hosted engine for disk + memory; unified Ledgers view #282 first and have v5 WS1+WS2: ledger-free hosted mode, upstream-restore rollback, vendor ejects hosted projects #280 rebase onto it, say so. I kept the ledger delta isolated in hosted::ledger (the engine never calls it) so that either order is a deletion, not a rewrite.

  3. One project snapshot. Planned next on this branch:

    • ProjectContext gets one ProjectSnapshot: the root plus the parsed lock/config files through the shared format models. locks() and discovery() both derive from it instead of reading files twice.
    • A write through the engine commit returns the touched paths, and the context invalidates them. Embedded scan --vex then re-derives from the refreshed snapshot rather than re-crawling.
    • Thread the context through vendor and vex too.
  4. Rendering out of orchestration. Also planned here. The engine will return a typed HostedOutcome: confirmed, skipped, the warnings as typed variants, files, and the stale-install results. It will no longer build serde_json::Value warnings. The JSON envelope and the human output become adapters over it, as will the memory engine's JS result. redirect_json_block / format_* move into a render module that only consumes the outcome.

I'll push 1 once the suite is clean, then do 3 and 4 as separate commits on this PR. Item 2 waits on the #280 ordering decision.


Generated by Claude Code

The engine's own warnings (rush repo-state, pnpm trustLockfile, npm
allow-remote, vlt artifact-unverifiable, record_fetch_failed, the
in-memory takeover refusal) were built as serde_json values inside
orchestration. They are now RewriteWarning values; the new
hosted::render module holds the only JSON spelling (warnings, skipped
entries, the nested redirect block), consumed by the disk adapter and
the in-memory engine. No output change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KHZ8uzdXfkG2zH8ZYDG8ju
ProjectView gains a Snapshot variant: the disk under a read-through
cache (DiskSnapshot), so each lock or config file is read at most once
per run and every reader sees the same bytes; probes that are not
content reads still go to the disk. Lockfile discovery's guarded reads
now go through a ProjectView (discover_patched_refs_in), and
ProjectContext backs both locks() and discovery() with one snapshot of
--cwd.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KHZ8uzdXfkG2zH8ZYDG8ju
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Status on the review as of f39ed1c:

  1. Ownership index: done (04b3d96). Ledgers::claims() builds the owner → entries index in one pass. owned() and listed() both derive from it.
  2. Ledger-free integration: still waiting on the v5 WS1+WS2: ledger-free hosted mode, upstream-restore rollback, vendor ejects hosted projects #280 ordering decision. The plan is in my earlier reply.
  3. One project snapshot: partly done (f39ed1c).
    • Done:
      • ProjectView::Snapshot wraps a read-through DiskSnapshot, so each lock or config file is read at most once per run and every reader sees the same bytes.
      • ProjectContext::locks() and discovery() both read --cwd through that one snapshot.
      • Lockfile discovery's guarded reads now go through a ProjectView (discover_patched_refs_in).
    • Remaining:
      • Share the parsed format models, not only the bytes.
      • Invalidate the snapshot after the engine's writes so embedded --vex reuses it.
      • Thread the context into vendor and vex.
  4. Rendering out of orchestration: partly done (f4e8d54).
    • Done:
      • The engine emits typed RewriteWarnings instead of serde_json::Value. This covers rush/pnpm/npm guidance, the vlt preflight, fetch failures and the memory engine's pre-warnings.
      • The JSON shaping lives in hosted::render: skipped_json, rewrite_warnings_json, redirect_json_block.
    • Remaining: a single typed HostedOutcome returned by the engine, with the disk JSON, human output and the memory JS result as adapters over it.

CI on f39ed1c: every red check is one of the base-branch failures I commented on above (vlt agent_get_and_remove, cargo fresh_checkout_fetch, Windows covgap_commands_scan_mod). The earlier Bun production and Poetry failures went green on this head. Locally the full suite gives 10320 passed; its only failures are the ones the base branch also has in this sandbox. Clippy -D warnings is clean.


Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Restack request from the v5 coordinator (please act now).

#280 (ledger-free hosted) is now merged into release/v5-prerelease as 686e5fb4. Please merge origin/release/v5-prerelease into this branch, resolve the conflicts, get CI to "base-inherited reds only", and mark the PR ready for review (not draft) when done.

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Owner decision (via coordinator): on ordering, #280 has landed first (686e5fb4). Merge the base, drop the hosted-ledger writer/merge from both engines (legacy read only), and keep parity green. Items 3 (shared parsed snapshot) and 4 (typed HostedOutcome) become follow-up PRs. Priority is landing after #279.

…sted-engine

Resolved toward #280's model: v5 hosted mode keeps no ledger.

- hosted::ledger (the redirect-ledger merge, in-memory load and
  serializer) is deleted; neither the disk flow nor the in-memory engine
  reads or writes .socket/vendor/redirect-state.json.
- Ledgers' hosted store is now the hosted records: the lockfiles' hosted
  pins (or a run's fetched records), plus a pre-v5 ledger read only for
  migration. hosted_vendored_overlap drops the edits-only fallback.
- list, scan's updates[] and rollback run the shared owner rule over the
  manifest and the vendor ledger and take the hosted pins from the
  lockfiles; updates[] keeps #280's precedence (manifest > pins > vendor
  ledger). scan reads the pins through ProjectContext's one discovery.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KHZ8uzdXfkG2zH8ZYDG8ju
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

I merged release/v5-prerelease @ 686e5fb (#280) into this branch at 4cabaf1.

Resolved toward #280's ledger-free model:

Local validation on the merge:

  • clippy with -D warnings is clean.
  • The full suite has the same 18 failures as the base in this sandbox, all root-user write-failure tests: 10216 passed here, 10211 on the base.
  • The parity and golden suites pass: hosted_memory_parity, redirect_golden, upstream_restore_golden.

I'll mark the PR ready once CI on 4cabaf1 shows only base-inherited reds, and I'll re-merge the base after #283, #281 and #279 land.

Follow-up list (non-blocking, not in this PR):

  1. Review item 3, rest: share the parsed format models across ProjectContext::locks() and discovery() (today they share bytes, not parses). Invalidate the snapshot after the engine's writes so embedded --vex reuses it. Thread the context into vendor and vex.
  2. Review item 4, rest: a single typed HostedOutcome from the engine, with disk JSON, human output and the memory JS result as adapters over it.
  3. Move the remaining single-store load sites (vendor, repair, apply, bun preflight) onto ProjectContext.
  4. F17: the napi addon (socket-patch-node) and hosted-bundle have no consumers. Listed only, no action here.

Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

This PR is ready for review at head 4cabaf1d3193bcf7ab6d2ae2c5255bb08b58c7e0, which merges release/v5-prerelease @ 686e5fb (#280).

CI on 4cabaf1:

  • CI: 38 jobs passed and 5 were skipped. The only red is test (windows-latest), and the only failing target in it is covgap_commands_scan_mod, which also fails on the base branch.
    • The first attempt was cancelled at the 50-minute job budget with no failures. The re-run finished in time.
  • vlt patch compatibility: every install-proof leg fails only vlt_pinned_matrix_agent_get_and_remove. That failure also comes from the base branch, and v5: remove setup (WS7) + patch UI streamlining (WS8) #279 fixes it.
  • Bun patch compatibility: green on re-run.
    • The first attempt failed only three macOS 1.3.10 workspace-hosted legs, where bun install --frozen-lockfile timed out after 180s.
    • Their vendored twins, and every other leg, passed.
  • Other compatibility workflows: pnpm, npm, Poetry, Pipenv, PDM and Go are green.

Local run on the merge:

  • clippy with -D warnings is clean.
  • The full suite has the same 18 failures as the base in this sandbox, all root-user write-failure tests.

I'll merge the base again after each of #283, #281 and #279 lands.


Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

#283 landed on release/v5-prerelease as 06437d2; please merge origin/release/v5-prerelease again, resolve conflicts, get green, and keep it ready.


Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

This PR is at head 907de9c, which merges release/v5-prerelease @ 06437d2 (#283). The merge was clean, with no conflicts, and the PR is still ready for review.

CI on 907de9c:

  • CI: 38 jobs passed and 5 were skipped. The only red is Windows covgap_commands_scan_mod, which also fails on the base branch.
  • vlt: the install-proof legs fail only agent_get_and_remove, which also fails on the base branch and is fixed on v5: remove setup (WS7) + patch UI streamlining (WS8) #279.
  • Bun: green on re-run.
    • The first attempt hit a DNS failure on a macOS 0.8.1 runner (nodename nor servname provided).
    • It also hit a timed-out rollback in one macOS 1.3.0 leg.
  • Other workflows: pnpm, npm, Poetry, Pipenv, PDM and Go are green.

Local checks on the merge:

  • clippy with -D warnings is clean.
  • The full suite has the same 18 failures as 06437d2 in this sandbox, all root-user write-failure tests: 10168 passed here, 10163 on the base.

Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

#281 landed on release/v5-prerelease as 73c0c4f; please merge origin/release/v5-prerelease again, resolve conflicts, get green, and keep it ready.


Generated by Claude Code

…into v5/one-hosted-engine

#281's format-registry changes to the hosted flow land where this branch
moved that code: core hosted::engine derives REDIRECT_CANDIDATE_FILES
and file_ecosystem from formats::registry, hosted::guidance re-exports
the pnpm lock-version sniffs from formats::pnpm, and the in-memory
root detection reads registry::root_marker. The CLI hosted_memory
redirect.rs #281 edited is already gone on this branch.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KHZ8uzdXfkG2zH8ZYDG8ju
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

CI on 94dc5d2 (the merge of #281 base 73c0c4f). Two reds so far:

  1. Pipenv compatibility / matrix (ubuntu-latest, 2018.11.26 … 2026.8.0): the hosted legs failed at random across versions (dryRunParity, appliedExactlyOne, and so on). macOS passed on the same versions. The single re-run passed with no change, so it is transient.

  2. vlt install-proof ubuntu 0.0.0-11 and ubuntu 0.0.0-1: e2e_redirect_vlt_build fails vlt_pinned_matrix_hosted_{rollback_byte_exact,crlf_lock,idempotence}. Hosted rollback doesn't restore the node tuple's 4th element, the original https://registry.npmjs.org/…tgz URL. It either drops it or rewrites it to the options.registry host. This is not this PR's failure. With vlt 0.0.0-11 locally, the same 3 tests fail identically (35 pass / 3 fail) on:

    It comes from the ledger-free upstream restore for vlt pins (v5 WS1+WS2: ledger-free hosted mode, upstream-restore rollback, vendor ejects hosted projects #280 model, patch/redirect/upstream/vlt.rs). That restore rebuilds the tarball URL from the lock's registry, so a pre-alpha vlt lock that carried an explicit npmjs URL under a different options.registry can't round-trip. No fix exists on the base or in an open PR, so nothing is ported. Suggested fix, as a follow-up on the base: when the pin was written, keep the replaced tuple URL in the pin itself (as the uv/pypi pins keep their source), and have upstream::vlt restore that instead of re-deriving it. The alternative is to scope these three legs' byte-exact assertion to vlt ≥ 1.0 locks.

The rest of CI is still running. I'll post the head SHA and CI summary when it finishes.


Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

#279 landed on release/v5-prerelease as f6bdad5; please merge origin/release/v5-prerelease again, resolve conflicts, get green, and keep it ready.


Generated by Claude Code

…to v5/one-hosted-engine

setup.rs goes, with the setup-only fold_vendor_records helper this
branch had moved onto the Ledgers view; vendor_record_is_unowned has no
callers left here (list, vex and scan read Ledgers), so it goes too.
#279's hosted wording lands where this branch moved the code: the pnpm
trust guidance in core hosted::guidance, the record_fetch_failed and
rush repo-state texts in core hosted::engine (shared by the memory
engine), and the human warning/summary text in the CLI scan/hosted.rs,
which also gets the one-line npm allow-remote note and its test. The
CHANGELOG owner-rule entry drops its `setup --check` clauses.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01KHZ8uzdXfkG2zH8ZYDG8ju
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

v5 coordinator: #282 is next to land and is up to date with the base (f6bdad5, #279). It has no unresolved threads and is ready for review. Only one thing blocks landing: CI run 36474481876 on head 24a8241 is still in progress.

vlt patch compatibility failed on this head. Three install-proof legs are red: ubuntu 0.0.0-1, ubuntu 0.0.0-1 on Node 22.0.0, and ubuntu 0.0.0-11. The windows 0.0.0-11 leg is red too. When CI finishes, please post the head SHA and CI summary. For each red, show that it is base-inherited: it fails on the base's latest CI run under the same job name, or it is Windows covgap_commands_scan_mod. The coordinator will land this PR on its next run once that holds.


Generated by Claude Code

@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

Head 24a82415f506327072d04c793c10c788ae40268b: the merge of release/v5-prerelease at f6bdad5 (#279). The PR is up to date with the base and ready.

Local validation before the push:

  • clippy -D warnings is clean.
  • The full workspace suite has the same failure set as the base f6bdad5: 12 failures on each (root-sandbox write-failure tests), with 9435 passing on the merge vs 9430 on the base.

CI on this head

CI run 36474481876: 228 of 233 jobs pass. The Windows test job finished inside its timeout. The 5 reds:

Job Base evidence Why it is not this PR's
yarn-classic 1.0.2, 1.6.0, 1.7.0, 1.9.4 The same four job names are the only reds on page 1 of #279's final CI run, 36466224860 (head 88c444c, squash-landed as f6bdad5). They are base-inherited: mode_migration_npm in the e2e tier enabled by #288.
e2e-docker (deno) Passes on 36466224860. Infrastructure: curl https://deno.land/install.sh exited 35 (TLS connect) while building the Docker image, before any test ran. I re-ran the failed jobs once just now.

vlt patch compatibility run 36474482017 has 4 reds:

  • install-proof (ubuntu-latest, 0.0.0-11)
  • install-proof (ubuntu-latest, 0.0.0-1)
  • install-proof (windows-latest, 0.0.0-11)
  • install-proof (ubuntu-latest, 0.0.0-1, 22.0.0)

These four are exactly the failed jobs of #279's final vlt run, 36466226104 (head 88c444c). That workflow runs only on pull_request, so the base branch has no vlt run of its own and #279's final head is the closest base run. Each leg fails vlt_pinned_matrix_hosted_{crlf_lock,idempotence,rollback_byte_exact}, and those three tests fail identically locally on 73c0c4f and 28cebf7. Details are in my earlier comment.

Every other workflow on this head is green: pnpm, Poetry, Go, Pipenv, npm, PDM and Bun.


Generated by Claude Code

@mikolalysenko
Mikola Lysenko (mikolalysenko) merged commit 14a9cb0 into release/v5-prerelease Sep 28, 2026
742 of 755 checks passed
@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the v5/one-hosted-engine branch September 28, 2026 21:18
Mikola Lysenko (mikolalysenko) pushed a commit that referenced this pull request Sep 28, 2026
Brings in #282, which moves the in-memory engine into
socket-patch-core (`hosted::memory`). The two-phase policy selection
moves with it. Conflicts:
- `canon`, `FilteredEntry`, `RetainedEntry` and `policy_block` move
  from the CLI into `socket_patch_core::policy`, so the core engine
  and disk scans share one `policy` block.
- `roots` is now public in core, for disk scans' marker lookup.
- scan reads the ledgers and wiring through the base's
  `ProjectContext`, and keeps loading the recorded view before
  filtering.
- CLI_CONTRACT's hosted-bundle row takes the base's path, plus the
  policy fields.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BKsyzefGhAnPkYmXCwq3H3
Mikola Lysenko (mikolalysenko) pushed a commit that referenced this pull request Sep 28, 2026
Brings in #282 through A: the in-memory engine now runs the disk
engine's stages in socket_patch_core::hosted::memory.

The rollout moves with it. The stage, the recorded view and the
classification live in socket_patch_core::rollout::stage, and the
ledger fold for updates lives in socket_patch_core::ledgers, so disk
and memory share them. scan keeps updates[], the hosted gate and the
human lines. On disk the gate plans after the engine's first rewrite
and rewrites again without the deferred rows; in memory each root
keeps its plan for that second pass.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.

2 participants