Skip to content

Agent-mode apply can't apply Maven patch records keyed by jar member paths, although vendor accepts the same record #264

Description

[agent] Filed by Claude Code on behalf of Mikola Lysenko (@mikolalysenko) while adding Maven patch SBOM annotations to depscan. Repro artifacts were produced with real Maven and a stub patch API.

Summary

Maven patch records are keyed differently depending on the consumer:

  • Vendored mode (vendor, scan/get --mode vendored) treats record file keys as jar member paths (META-INF/NOTICE.txt, org/…/Foo.class). It extracts the cached jar, applies the patch to the members, and re-zips.
  • Agent mode (apply) resolves the keys relative to the version directory (~/.m2/repository/<g>/<a>/<v>/<key>) and never opens the jar.

So one API record cannot serve both modes. The Socket patch backend builds Maven patches as jar-member overlays: depscan's maven repacker applies the record's files as jar entries at the archive root. Every such patch therefore fails in agent mode.

Impact

Agent mode (scan --sync, get + apply) is unusable for real Socket Maven patches. It fails with apply_failed: … File not found, and the jar in ~/.m2 stays unpatched. The docker e2e only passes because its record uses a version-directory key (package/commons-lang3-3.12.0.pom).

Repro

Stage one record in .socket/manifest.json with a blob, keyed META-INF/NOTICE.txt (git-sha256 before/after of the member, exactly like e2e_vendor_maven_build::stage_manifest). MAVEN_REPO_LOCAL holds Central's commons-lang3 3.12.0 jar and pom.

socket-patch apply --json --offline
  -> exit 1 {"status":"partialFailure","events":[{"action":"failed","errorCode":"apply_failed",
             "error":"Cannot apply patch: META-INF/NOTICE.txt - File not found"}]}
  ~/.m2 jar: PRISTINE
socket-patch vendor --json --offline   (same manifest)
  -> exit 0 {"events":[{"action":"applied","files":[{"path":"META-INF/NOTICE.txt","verified":true,"appliedVia":"blob"}]}]}

Expected vs actual

  • Expected: agent-mode apply handles Maven records whose keys are not version-directory files by patching the jar's members in place. It could reuse the vendored stage_local_jar / member-apply path, rewriting the jar and its .sha1, and keeping the rollback before-blob as the original jar. Alternatively it refuses Maven member-keyed records up front with a clear code that recommends --mode hosted/vendored.
  • Actual: a generic "File not found" failure.

CLI revision

3efdc31d

Suggested fix

  • Share the vendored jar-member application with apply, keyed off "the record key is not a file in the version directory, but is an entry in <a>-<v>[-<classifier>].jar".
  • Add a docker/e2e case with a member-keyed record.
  • Rollback and VEX (vex_consumed maven copies) need to agree on the after-hash semantics: member hash vs. whole-jar hash.

File refs (at 3efdc31)

  • crates/socket-patch-core/src/patch/apply.rs (no jar/zip handling; see the classifier comment near l.350)
  • crates/socket-patch-core/src/vendor/maven_repo.rs:153-420 (vendor_maven: member-level apply + deterministic re-zip)
  • crates/socket-patch-cli/tests/docker_e2e_maven.rs:109-116 (version-dir keys only)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions