Skip to content

[BUG] Global install exits successfully after silently omitting a relative local transitive dependency #2815

Description

Describe the bug
A user-scope install of an absolute local parent package silently drops that parent's existing relative local child dependency. The CLI exits 0 and reports a successful one-package install, while the child is absent from both the lockfile and native deployments.

This is an outcome/graph-completeness defect, not a request to silently relax the existing rejection of direct relative paths at user scope.

To Reproduce
Use a disposable fixture root and isolated HOME. All paths below labeled /ABS/R must be replaced with the actual absolute fixture root.

  1. Create /ABS/R/packages/parent/apm.yml:
name: parent
version: 0.1.0
targets: [cursor]
dependencies:
  apm:
    - path: ../child
  1. Create /ABS/R/packages/child/apm.yml:
name: child
version: 0.1.0
targets: [cursor]
  1. Give each package a distinct command source: parent/.apm/prompts/parent.prompt.md and child/.apm/prompts/child.prompt.md, each with a valid description frontmatter and distinct body. For example:
---
description: Local dependency reproduction
---
# Parent command
  1. Create the isolated user's ~/.apm/apm.yml:
name: consumer
version: 0.1.0
targets: [cursor]
dependencies:
  apm:
    - path: /ABS/R/packages/parent
  1. From a separate consumer directory, run the installed CLI:
apm install --global --target cursor --no-policy --parallel-downloads 0
  1. Inspect ~/.apm/apm.lock.yaml and ~/.cursor/commands/: only the parent is installed/locked/deployed.

Matched controls, each in a fresh isolated fixture:

Scope Parent's child reference Exit Locked/deployed packages
Project ../child 0 2
User absolute /ABS/R/packages/child 0 2
User ../child 0 1

The fixture verifies that the relative reference resolves against the parent's source directory to an existing child manifest before running APM.

Expected behavior
A successful install must not silently omit a declared dependency. Either resolve the transitive child against its declaring local parent if that behavior is supported, or reject it with a nonzero exit and an actionable diagnostic. Whether to support anchored transitive references while retaining rejection of direct user-relative paths is an explicit contract decision.

Environment (please complete the following information):

  • OS: macOS
  • Python Version: 3.12.10, locked development dependencies
  • APM Version: 0.29.1, source commit 23e921750e5bdb25d02c7b0c71a6b97bd7b851ac, editable installed CLI
  • VSCode Version (if relevant): N/A

Logs
Representative observed output:

[i] Installing to user scope (~/.apm/)
[>] Resolving /ABS/R/packages/parent...
[>] Resolving ../child...
[+] /ABS/R/packages/parent (local)
|-- 1 commands integrated -> .cursor/commands/
[*] Installed 1 APM dependency in 0.1s.

Exit status is 0. The child lock entry and command file are missing.

Additional context
Discovered while independently hardening the APMLifecycle interaction campaign after #2809 / during rework of #2813. Reproduced by both the implementation engineer and coordinating engineer. A focused unskipped regression with the three controls exists in the current, not-yet-published test-only worktree: tests/integration/test_primitive_target_covering_array.py::test_local_transitive_command_scope_parity.

Source evidence at the tested commit: src/apm_cli/install/phases/resolve.py:557-570 rejects every relative local ref at USER scope before the declaring-parent source anchor at lines 580-583. This path records a callback failure but the observed overall command still succeeds. The locally available origin/main at 7f36da6e61fd5cebe29c16ced77fb4351823ec06 had an identical src tree; this is not a claim about subsequently fetched main.

Generalized properties: outcome.status_matches_state, dependency-graph completeness. This report does not authorize production changes or Phase 3 transaction redesign.

Activity

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

Metadata

Metadata

Labels

area/lockfileLockfile schema, per-file provenance, integrity hashes, drift detection.status/shepherdingActively being driven by an APM shepherd runstatus/triagedAutomated advice completed; deduplication only. Not human approval; silence is not approval.theme/portabilityOne manifest, every target. Multi-target deploy, marketplace, packaging, install.type/bugSomething does not work as documented.

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions