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.
- Create
/ABS/R/packages/parent/apm.yml:
name: parent
version: 0.1.0
targets: [cursor]
dependencies:
apm:
- path: ../child
- Create
/ABS/R/packages/child/apm.yml:
name: child
version: 0.1.0
targets: [cursor]
- 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
- Create the isolated user's
~/.apm/apm.yml:
name: consumer
version: 0.1.0
targets: [cursor]
dependencies:
apm:
- path: /ABS/R/packages/parent
- From a separate consumer directory, run the installed CLI:
apm install --global --target cursor --no-policy --parallel-downloads 0
- 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.
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/Rmust be replaced with the actual absolute fixture root./ABS/R/packages/parent/apm.yml:/ABS/R/packages/child/apm.yml:parent/.apm/prompts/parent.prompt.mdandchild/.apm/prompts/child.prompt.md, each with a valid description frontmatter and distinct body. For example:~/.apm/apm.yml:~/.apm/apm.lock.yamland~/.cursor/commands/: only the parent is installed/locked/deployed.Matched controls, each in a fresh isolated fixture:
../child/ABS/R/packages/child../childThe 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):
23e921750e5bdb25d02c7b0c71a6b97bd7b851ac, editable installed CLILogs
Representative observed output:
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-570rejects 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 availableorigin/mainat7f36da6e61fd5cebe29c16ced77fb4351823ec06had an identicalsrctree; 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.