Skip to content

Decide vendored-entry liveness through one discovery verdict - #1050

Merged
Mikola Lysenko (mikolalysenko) merged 13 commits into
mainfrom
arch-fix/vendored-liveness
Oct 8, 2026
Merged

Mikola Lysenko (mikolalysenko) merged 13 commits into
mainfrom
arch-fix/vendored-liveness

Conversation

@mikolalysenko

@mikolalysenko Mikola Lysenko (mikolalysenko) commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Architecture audit §3.B asks one question: is this vendored entry still live? Four separate oracles answer it today: vendor_entry_live, dispatch_in_use_one, scan_vendor_references and the JVM entry_wired. They disagree.

  • B19. dispatch_in_use_one serves the prune GC, scan's ledger supplement and the vendor --check remedy. It only had probes for npm, cargo and the pypi requirements flavor. Every gem, golang, composer, nuget, maven/jvm, uv, poetry, pdm, pipenv and pylock entry answered None and was kept forever:
    • scan --prune could never reclaim one;
    • scan's supplement recreated it as a discovered package and never emitted vendor_ledger_entry_unwired;
    • meanwhile vendor --check and vex already called it dead.
  • B62. vendor --check reported orphaned JVM trees (maven2, gradle, coursier and their indexes, plus the generated sbt file) only when the whole ledger was empty.
  • B61. Legacy Maven and NuGet treated a raw substring as "already wired". A commented-out <repository> or <packageSources> source took the in-sync hot path, so the build resolved the unpatched package.

Change

  • Core: one GC / supplement in-use verdict. Discovery::vendor_entry_in_use(root, entry) -> Option<bool> sits next to vendor_entry_live and is derived from the same discovery:

    • Some(true) in any of these cases:
      • the entry is live;
      • another lock contests its wiring;
      • a file that mentions its uuid had wiring dropped as DIAG_REF_UNATTRIBUTABLE;
      • cargo withheld a relock-pending [patch].
    • Some(false): discovery read and parsed an install-deciding lockfile of the entry's ecosystem, and nothing above holds.
    • None: discovery read no such lockfile, or one of its files could not be read or parsed.
    • JVM entries answer from their own layout (entry_references).
  • An attestation drop is not a liveness verdict. Attestation fails closed by dropping a ref it cannot tie to the one copy that installs. Examples:

    • an unpatched copy in the same lock;
    • npm's legacy dependencies mirror;
    • a non-registry nested copy;
    • vlt's other instances or bundled copies;
    • a yarn git block;
    • a version-less Go replace.

    The GC has to fail safe, by keeping the entry. One rule covers every extractor: keep the entry whenever a file that mentions the uuid carries an unattributable diagnostic. This is deliberately file-grained, so it errs toward keeping. Mentions rejected as DIAG_REF_INVALID are shapes the package manager never installs from, and they still read as unused. Examples: stale bun.lockb pool strings, a vlt edge spec, cargo's leftover [patch] after a hosted takeover.

  • New discovery evidence:

    • Discovery::read: every guarded read, tagged with the reading extractor's ecosystem. A manifest alone (Cargo.toml, pyproject.toml, hatch.toml) is not a lock, so it decides nothing.
    • Discovery::withheld: now only cargo's relock-pending [patch], which cargo reports as invalid rather than unattributable. The earlier npm and bun pushes were removed because the diagnostic rule subsumes them.
  • Routing.

    • run_vendor_gc pass (b) takes every verdict from one discovery snapshot taken before it reverts anything. Before, each probe re-read the files after the previous revert. Reverting one entry never rewires another, so the snapshot only removes ordering effects.
    • vendored_ledger_supplement reads the run's ProjectContext discovery (scan and get pass their context).
    • The vendor --check remedy uses the same verdict.
  • B62. The JVM orphan check fires whenever no ledger entry is a JVM entry:

    • empty ledger: refuses, as before;
    • otherwise: records a failed vendor_ledger_missing artifact event, whose path names the orphan.

    The path list is now one jvm::apply::LEDGER_OWNED_PATHS.

  • B61. Each backend now uses the comment-masking reader its forward writer already uses: find_wireable_anchor for the pom, parse_config_source_keys(blank_comments(..)) for nuget.config.

Duplicates deleted

The GC, supplement and vendor --check remedy oracles go from 5 to 1. Deleted:

  • commands::vendor::dispatch_in_use_one
  • vendor::npm_flavor::vendored_entry_in_use
  • vendor::cargo::vendored_entry_in_use
  • vendor::pypi::vendored_entry_in_use
  • vendor::pypi_requirements::requirements_entry_in_use

Kept on purpose (see Deferred):

  • the pnpm, pnpm-legacy and vlt structural probes (pnpm_entry_in_use, pnpm_legacy_entry_in_use, vlt_entry_in_use). Their revert guards still use them. If one disagrees with the GC verdict, the guard refuses and the entry lands in GC failed, so nothing is reverted unsafely.
  • the two JVM checks. entry_wired (vex, vendor --check) is strict attestation: every half is wired and the Gradle script is intact. entry_references (GC, supplement) asks whether anything still references the tree. Wired implies referenced, so the GC never reverts an entry that vex attests.
  • scan_vendor_references, the raw-text check used by orphan sweeps, repair, rollback and vendor --check's unknown-wiring scan.

JVM orphan path lists: the CLI inline list and coursier_tree::ORPHAN_PATHS become LEDGER_OWNED_PATHS, so 2 lists become 1.

Behaviour changes

Testing

Run locally on macOS. Every cargo command went through heavy-job.sh with CARGO_INCREMENTAL=0 and -j4.

  • cargo test -p socket-patch-core --lib -- vex:: vendor::: 2987 passed, plus the new pyproject test.

  • cargo test -p socket-patch-cli:

    target passed
    --lib 871
    vendor_jvm_cli 30
    covgap_commands_scan_mod 53
    covgap_commands_vendor 54
    scan 118
    repair 126
    rollback 38
    vendor 91
    e2e_vex_lockfile 323
    in_process_vendor 121
    scan_vendor_e2e 37
    scan_vendor_requirements_unwired 3
    vendor_eject 8

    All green on head.

  • cargo clippy -p socket-patch-core -p socket-patch-cli --all-targets: no diagnostics in any file this PR touches. Toolchain 1.93.1 still flags pre-existing lints elsewhere (jvm_jar.rs, python_crawler.rs, redirect/mod.rs, test helpers), and those are on main too.

Keep-side coverage for every newly prunable ecosystem. Each successful, non-dry-run vendor through the vendor::test_support wrappers now asserts that the GC verdict on the entry it just wrote is not Some(false). In vendor::, that ran against real backend output for every ecosystem and flavor, with every verdict Some(true) (count per ecosystem/flavor):

ecosystem / flavor runs
cargo 70
composer 45
gem 76
golang 23
maven 43
nuget 42
jvm 1
npm (package-lock, bun, pnpm, pnpm-legacy, vlt, yarn-berry, yarn-classic) 535
pypi requirements 44
pypi uv 13
pypi poetry 14
pypi pdm 23
pypi pipenv 11
pypi hatch 3
pypi python-lock 3

Regression tests, failing first.

  • vendor::npm_flavor::tests::unattributable_wiring_stays_in_use covers the v2 legacy mirror, a v3 nested git copy and a vlt other instance. With the new rule disabled it fails: left: Some(false), right: Some(true).

  • gc_tests::vendor_gc_keeps_an_entry_whose_wiring_is_only_unattributable: run_vendor_gc keeps a legacy-mirror entry, dry and wet. It fails with the rule disabled.

  • vex::discover::tests::lockless_pyproject_entries_stay_undecidable pins None.

  • Run on the merge-base c5be5d1 (test hunks only, in a throwaway worktree), these three failed as expected:

    • vendor_gc_reclaims_unused_composer_entry_and_keeps_a_wired_one (B19): unused_reverted was [].
    • ledger_supplement_reports_a_bumped_composer_entry_unwired (B19): the entry was resurrected into packages.
    • check_reports_jvm_trees_without_a_jvm_entry_beside_other_entries (B62): no JVM orphan event; only the npm entry's own failure.

    The B62 test now also asserts that the event's path is an existing LEDGER_OWNED_PATHS member.

  • commented_out_repository_is_not_wired and commented_out_source_is_not_wired (B61) fail with the old substring checks restored.

Linux and docker suites are left to CI.

Deferred

🤖 Generated with Claude Code


Note

High Risk
Changes prune GC, vendor --check, and scan supplement behavior across all ecosystems; incorrect liveness could revert live patches or leave stale ledger entries.

Overview
Unifies vendored-ledger liveness behind Discovery::vendor_entry_in_use, replacing separate per-ecosystem probes (dispatch_in_use_one, npm/cargo/pypi vendored_entry_in_use) so scan --prune, the vendored ledger supplement, and vendor --check share one verdict.

Discovery now records which lockfiles were read (Discovery::read) and cargo relock-pending wiring (withheld), and treats unattributable attestation drops and contested locks as keep (fail-safe) rather than unused. The prune GC loads one discovery snapshot before reverting entries so half-pruned locks cannot skew later probes.

Behavior fixes: Composer and other previously unprobed ecosystems can be reclaimed when install-deciding locks no longer wire them; JVM orphan detection runs when the ledger has no JVM entry (not only when empty); Maven/NuGet commented-out repository/source blocks no longer count as wired for the in-sync vendor path.

Vendor test helpers assert a freshly vendored entry is never Some(false) for the GC verdict.

Reviewed by Cursor Bugbot for commit e9bd805. Configure here.


Generated by Claude Code

The prune GC and scan's ledger supplement asked a per-backend probe
(npm, cargo, pypi-requirements only) whether a vendored entry is still
consumed, while vex and vendor --check judge liveness by discovery.
Give discovery the evidence for a tri-state in-use answer for every
ecosystem:

- `Discovery::read` logs every guarded read, tagged with the ecosystem
  whose extractor read it, so "nothing wires it" can mean "unused" only
  once a lockfile of that ecosystem was actually read and parsed.
- `Discovery::withheld` records wiring an extractor withholds as a ref
  although a file still routes through the patch: npm's and bun's
  in-lock contests and cargo copies whose lock lags (another tag, or an
  untagged override). Not attested, but still wiring the GC must keep.
- `vendor_entry_in_use` = live, contested or withheld -> Some(true);
  a read lockfile of the ecosystem and nothing wiring it -> Some(false);
  no lockfile, or one that cannot be read or parsed -> None. JVM
  entries answer from their own layout (`entry_references`).

Audit B19 (§3.B "is this vendored entry live").

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…re readers

The vendored Maven backend treated any occurrence of its repository id
in pom.xml as wiring, and the NuGet backend any occurrence of its source
key in nuget.config, so a commented-out (or profile-scoped) repository
or source took the in-sync hot path and the build resolved the
unpatched package. Use the same masking the forward writers already
use: `find_wireable_anchor` (comments and <profiles> masked) for the
pom, and `parse_config_source_keys(blank_comments(..))` for the
nuget.config <packageSources>.

Audit B61.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
`vendor --check` reported committed JVM trees (maven2, gradle, coursier,
their indexes, the generated sbt file) as `vendor_ledger_missing` only
when the whole ledger was empty, so a project that also vendors another
ecosystem never noticed a lost JVM half. Fire whenever no ledger entry
is a JVM entry: an empty ledger still refuses as before, otherwise the
orphan is recorded as a failed artifact event beside the other checks.

The path list moves to one `jvm::apply::LEDGER_OWNED_PATHS` (replacing
the CLI's inline list and `coursier_tree::ORPHAN_PATHS`), and the JVM
path tables spell the tree roots through their named constants.

Audit B62.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…gh one in-use verdict

`dispatch_in_use_one` answered "is this vendored entry still consumed"
for npm, cargo and the pypi requirements flavor only and kept every
other entry (gem, golang, composer, nuget, maven/jvm, uv, poetry, pdm,
pipenv, hatch, pylock) forever: `scan --prune` could never reclaim them
and scan's ledger supplement resurrected them as discovered packages,
never reporting `vendor_ledger_entry_unwired`, while `vendor --check`
and vex already called them dead.

Every caller now asks `Discovery::vendor_entry_in_use`:
- run_vendor_gc (pass b) takes all verdicts from one discovery of the
  project before it reverts anything;
- vendored_ledger_supplement reads the run's ProjectContext discovery
  (scan and get pass their context);
- vendor --check's "dependency removed" remedy.

Deleted: `dispatch_in_use_one` (CLI) and the per-backend dispatchers
`vendor::npm_flavor::vendored_entry_in_use`,
`vendor::cargo::vendored_entry_in_use`,
`vendor::pypi::vendored_entry_in_use` and
`pypi_requirements::requirements_entry_in_use` (4 in-use oracles -> 1;
the pnpm/vlt structural probes stay for their revert guards). Their
tests now assert the discovery verdict, with lock fixtures carrying the
version an install records.

Audit B19.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ibutable

The prune GC's in-use verdict read every vendored ref that attestation
dropped as unused unless an extractor had recorded it as withheld, and
only npm's in-pair contest, bun and cargo did. Every other unattributable
drop (an unpatched copy in the same lock, npm's legacy `dependencies`
mirror, a non-registry nested copy, vlt's other instances and bundled
copies, a yarn git block, a version-less Go replace) made `scan --prune`
unwire a vendored patch the package manager still installs.

`vendor_entry_in_use` now keeps an entry whenever a file that mentions
its uuid also carries a DIAG_REF_UNATTRIBUTABLE diagnostic. That one rule
covers every extractor, so the npm and bun `withheld` pushes are gone;
cargo's relock-pending record stays because cargo reports that case as
DIAG_REF_INVALID. Mentions rejected as invalid (stale bun.lockb pool
strings, vlt edge specs, cargo's leftover [patch] after a hosted
takeover) still read as unused.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…e GC

Each successful, non-dry-run vendor through the test_support wrappers now
asks discovery's in-use verdict about the entry it just wrote and fails
on Some(false). Every backend suite (npm flavors, pnpm, yarn, bun, vlt,
cargo, composer, gem, golang, maven, nuget and every pypi flavor) thus
pins the keep side of the GC against its real output.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The B62 test now checks that the vendor_ledger_missing event names a
LEDGER_OWNED_PATHS member that exists, not just any maven-tagged event.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mikolalysenko
Mikola Lysenko (mikolalysenko) marked this pull request as ready for review October 7, 2026 17:06

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.

Autofix Details

Bugbot Autofix prepared fixes for both issues found in the latest run.

  • ✅ Fixed: Gradle JVM prune may fail open
    • Created gradle::references_checked that returns Result<bool, String> and fails when files cannot be read, ensuring fail-closed behavior consistent with other JVM backends.
  • ✅ Fixed: Empty-wiring JVM entries skip layout check
    • Modified is_jvm_entry to recognize empty-wiring maven-ecosystem entries with valid maven purls, preventing them from incorrectly falling through to generic maven discovery.

Create PR

Or push these changes by commenting:

@cursor push 002ca36d71
Preview (002ca36d71)
diff --git a/crates/socket-patch-core/src/vendor/jvm/apply.rs b/crates/socket-patch-core/src/vendor/jvm/apply.rs
--- a/crates/socket-patch-core/src/vendor/jvm/apply.rs
+++ b/crates/socket-patch-core/src/vendor/jvm/apply.rs
@@ -36,13 +36,20 @@
 };
 
 /// Whether `entry` was written by this backend: it has wiring and every
-/// record is one of this backend's kinds.
+/// record is one of this backend's kinds, OR it's a maven-ecosystem entry
+/// with a valid maven purl (covers empty-wiring reconstructed entries).
 pub fn is_jvm_entry(entry: &VendorEntry) -> bool {
-    !entry.wiring.is_empty()
+    if !entry.wiring.is_empty()
         && entry
             .wiring
             .iter()
             .all(|w| KINDS.contains(&w.kind.as_str()))
+    {
+        return true;
+    }
+    // Empty-wiring entries (e.g., from repair/reconstruction) that are
+    // maven-ecosystem with valid maven purls should still be treated as JVM entries
+    entry.ecosystem == "maven" && parse_maven_purl(&entry.base_purl).is_some()
 }
 
 /// Offline inputs have not been authenticated by independent registry checksums.
@@ -827,7 +834,7 @@
     }
     let (maven, gradle) = sides(&entry.wiring);
     (maven && maven_reactor::wired_checked(&read, &c).unwrap_or(true))
-        || (gradle && gradle::references(&read, &c))
+        || (gradle && gradle::references_checked(&read, &c).unwrap_or(true))
 }
 
 /// The liveness proof `vex` needs: every half of the entry is wired, and

diff --git a/crates/socket-patch-core/src/vendor/jvm/gradle.rs b/crates/socket-patch-core/src/vendor/jvm/gradle.rs
--- a/crates/socket-patch-core/src/vendor/jvm/gradle.rs
+++ b/crates/socket-patch-core/src/vendor/jvm/gradle.rs
@@ -1197,6 +1197,42 @@
     indexed && applied
 }
 
+/// Checked variant of [`references`] that returns an error when files
+/// cannot be read, for fail-closed GC ([`crate::vex::discover::Discovery::vendor_entry_in_use`]).
+pub fn references_checked(read: ReadFn<'_>, c: &Coords<'_>) -> Result<bool, String> {
+    let gav = format!("{}:{}:{}", c.group_id, c.artifact_id, c.version);
+    let index_bytes = read(INDEX_REL).ok_or_else(|| format!("cannot read {}", INDEX_REL))?;
+    let index_text = String::from_utf8(index_bytes)
+        .map_err(|_| format!("{} is not valid UTF-8", INDEX_REL))?;
+    let rows = index_rows(&index_text)
+        .ok_or_else(|| format!("{} could not be parsed", INDEX_REL))?;
+    let indexed = rows.iter().any(|r| {
+        let cols: Vec<&str> = r.split('\t').collect();
+        cols.first() == Some(&gav.as_str()) && cols.get(3) == Some(&c.uuid)
+    });
+    
+    let wiring = WiringTarget::vendored();
+    let mut applied = false;
+    let mut settings_found = false;
+    for rel in ["settings.gradle", "settings.gradle.kts"] {
+        if let Some(bytes) = read(rel) {
+            settings_found = true;
+            let text = String::from_utf8(bytes)
+                .map_err(|_| format!("{} is not valid UTF-8", rel))?;
+            let dsl = dsl::dsl_of(rel).unwrap_or(Dsl::Groovy);
+            if has_apply_line(&text, dsl, &wiring, "") {
+                applied = true;
+                break;
+            }
+        }
+    }
+    if !settings_found {
+        return Err("cannot read settings.gradle or settings.gradle.kts".to_string());
+    }
+    
+    Ok(indexed && applied)
+}
+
 /// The liveness proof `vex` needs for this layout: `c` is
 /// [`references`]d, the script is ours (line endings aside), and a re-plan
 /// over the committed tree is refused nowhere and degraded nowhere.

You can send follow-ups to the cloud agent here.

Comment thread crates/socket-patch-core/src/vendor/jvm/apply.rs
Comment thread crates/socket-patch-core/src/vex/discover/mod.rs
`scan --prune` reverts a JVM ledger entry when `entry_references` answers
false, but the Gradle arm returned `gradle::references` as is: a malformed
gradle-index.tsv, a non-UTF-8 settings file, or a file the reader could
not read (permission error, link out of the checkout) all read as "not
referenced", so the GC could delete a tree that is still wired. The
maven/sbt/scala-cli arms already map undecidable to true.

Add `gradle::references_checked`, which answers None when a file it
decides by exists but cannot be parsed, and have `entry_references` treat
that, and any read error the ProjectReader recorded, as still in use.
`gradle::references` keeps its old answers for revert and attestation.

Also pin with a test that a hand-stripped, empty-wiring `jvm` entry stays
undecidable (None) for the prune GC.

Co-Authored-By: Claude <noreply@anthropic.com>
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

bugbot run


Generated by Claude Code

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit e9bd805. Configure here.

@mikolalysenko Mikola Lysenko (mikolalysenko) added the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 7, 2026
@mikolalysenko

Copy link
Copy Markdown
Collaborator Author

[agent] Ready for review at e9bd80572b5805aa639cc82e19e47447e9dd4d32.

  • CI: required ci-ok green (22:53Z). 529 success / 6 skipped / 0 failing of 563 check runs; 28 non-required macOS/Windows legs still queued on the runner backlog.
  • Bugbot reviewed e9bd80572b; no unresolved review threads.
  • Mergeable, no conflicts. The branch is 8 commits behind main (no overlap reported by GitHub); the merge queue re-tests against main.
  • Reviewer focus: vendored-entry liveness now comes from a single discovery verdict.

Generated by Claude Code

@mikolalysenko
Mikola Lysenko (mikolalysenko) added this pull request to the merge queue Oct 7, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a conflict with the base branch Oct 8, 2026
@mikolalysenko Mikola Lysenko (mikolalysenko) removed the Ready for review Agent-verified: mergeable, CI green, Bugbot clean — awaiting human review label Oct 8, 2026
Conflicts were main's rustfmt-only reflows of code this branch rewrote
(vendored_ledger_supplement test calls now take a ProjectContext,
dispatch_in_use_one moved behind the shared liveness probe, cargo
vendored_from_patches keeps the relock_pending claim); kept this
branch's versions.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mikolalysenko
Mikola Lysenko (mikolalysenko) added this pull request to the merge queue Oct 8, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to a manual request Oct 8, 2026
Pick up #1093 so PR CI runs without the macOS legs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mikolalysenko
Mikola Lysenko (mikolalysenko) added this pull request to the merge queue Oct 8, 2026
Resolve golden.rs Discovery destructure: keep this PR's read/withheld
fields and main's unwired_copies (#1033).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Brings in #1044 (governing lock table), #1035, #1038, #1083, #724.
Drop the BUN_LOCK/BUN_LOCKB/NPM_LOCKS imports #1044 added to
npm_flavor.rs: their only user, vendored_entry_in_use, is removed by
this PR (liveness now comes from Discovery::vendor_entry_in_use).
This unused import failed clippy in the merge group.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@mikolalysenko
Mikola Lysenko (mikolalysenko) added this pull request to the merge queue Oct 8, 2026
@github-merge-queue
github-merge-queue Bot removed this pull request from the merge queue due to failed status checks Oct 8, 2026
@mikolalysenko
Mikola Lysenko (mikolalysenko) added this pull request to the merge queue Oct 8, 2026
Merged via the queue into main with commit 18c5f81 Oct 8, 2026
455 checks passed
@mikolalysenko
Mikola Lysenko (mikolalysenko) deleted the arch-fix/vendored-liveness branch October 8, 2026 11:20
Mikola Lysenko (mikolalysenko) added a commit that referenced this pull request Oct 8, 2026
Resolve conflicts with #1050 (vendored-entry liveness): keep its
fail-closed Gradle references_checked and ledger-owned orphan check, and
route both through vendor::jvm::layout (LEDGER_OWNED_PATHS replaces
ORPHAN_PATHS there, re-exported from jvm::apply; settings files come from
layout::GRADLE_SETTINGS_FILES).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Mikola Lysenko (mikolalysenko) added a commit that referenced this pull request Oct 8, 2026
maven_repo.rs: keep this PR's deletion of the legacy same-GAV
<repository> backend; #1050's B61 change (comment-aware "already
wired" check via find_wireable_anchor) and its test only touched that
deleted backend.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Mikola Lysenko (mikolalysenko) pushed a commit that referenced this pull request Oct 8, 2026
Resolve the conflicts with main's move of vendored in-use detection
into discovery (#1050) and its PurlKey rename (#1045):

- npm_flavor.rs: drop the branch's vendored_entry_in_use, now that
  Discovery::vendor_entry_in_use replaces it. Bun discovery already
  picks the live lock through bun_text_lock_drives, so the #735
  regression test now runs through the shared in_use helper with a
  minimist entry.
- lock_inventory/tests.rs: keep both sides' new tests.
- vendor.rs: key the Bun reinstall dedupe on PurlKey.

Assisted-by: Claude Code:claude-opus-5-5
Mikola Lysenko (mikolalysenko) pushed a commit that referenced this pull request Oct 8, 2026
Mikola Lysenko (mikolalysenko) pushed a commit that referenced this pull request Oct 8, 2026
Resolve the three conflicts by keeping both sides:

- scan/policy.rs: keep the PR's dir_markers/lock_markers split (lock
  markers decide nested roots for #554) and re-apply main's #1032 change
  inside dir_markers: the JVM manifest fallback now reads
  vendor::jvm::layout::JVM_PROJECT_MARKERS, with main's is_file comment.
- vex/discover/mod.rs: Discovery keeps the PR's `shadowed` refs (#828)
  alongside main's `read` and `withheld` evidence (#1050). Shadowed refs
  carry DIAG_REF_UNATTRIBUTABLE, so vendor_entry_in_use already keeps
  their entries through unattributable_mention.
- vex/discover/testing/golden.rs: destructure all three fields.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

arch-refactor PR opened by the scheduled architecture refactor routine

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants