Skip to content

[BUG] OpenAPM local-path containment contradicts supported trusted-local sibling paths #2818

Open

Agent suggestions

Public preview

Description

Describe the bug
OpenAPM req-mf-016 and the established CLI/shipped-guide contract disagree about trusted local dependencies outside the consuming project root.

At source revision 69f41ab7f88ac20d43728bc6d8e1e18b6a7112e3:

  • OpenAPM req-mf-016 says: "The resolver MUST refuse any local-path entry whose normalised form contains .. segments that would escape the project root, with a diagnostic naming the offending path."
  • The shipped dependency guide explicitly supports local sibling layouts outside the consuming project root, anchored to the declaring local package. Remote-declared paths instead remain contained in the authenticated remote repository.
  • The local materialization owner deliberately does not enforce consumer-project-root containment for trusted local packages, and explains that remote-parent expansion/rejection is the untrusted-source boundary. Locked local replay in deps/path_anchoring.py follows the same local-anchor contract.

The specification describes project scope as rooted at the consumer project, but user scope as independent of a project root. req-mf-016 does not explain a user-scope boundary or an exemption for trusted local declaring parents. Silently treating its MUST as nonnormative, or redefining the project root as an arbitrary common ancestor, would conceal the discrepancy.

To Reproduce

  1. Compare the three pinned sources above.
  2. Consider a consumer at /R/consumer that explicitly depends on local /R/packages/parent, whose manifest declares path: ../child.
  3. The shipped guide and existing project-scope behavior admit /R/packages/child, despite it being outside the consumer root. The executed project-relative control is documented in [BUG] Global install exits successfully after silently omitting a relative local transitive dependency #2815.
  4. Apply req-mf-016 literally: the escaping relative entry appears forbidden. For user scope, the requirement does not supply a replacement for the consumer project root.

Expected behavior
A reviewed specification decision should clearly distinguish source anchoring, trusted-local admission, remote-repository containment, local-copy symlink containment, and installation scope. Normative wording, shipped guidance, implementation claims, and appropriate conformance examples should agree.

Clarify the trust boundary and user-scope interpretation explicitly. Do not weaken remote-source, symlink, materialization, or deployment containment merely to resolve this prose conflict. If the specification artifact or conformance fixtures change, they should receive the normal specification review.

Environment (please complete the following information):

  • OS: N/A for the normative discrepancy; the linked behavioral controls ran on macOS
  • Python Version: 3.12.10 for the linked behavioral controls
  • APM Version: source revision 69f41ab7f88ac20d43728bc6d8e1e18b6a7112e3
  • VSCode Version (if relevant): N/A

Logs
N/A. This report concerns a verified contradiction between the published requirement, shipped guide, and documented implementation boundary; the concrete CLI reproduction and controls are in #2815.

Additional context
Discovered by the independent #2815 fix owner during APMLifecycle Phase 2 (#2813) contract review. The maintainer explicitly chose to preserve established trusted-local sibling support for the bounded user-scope fix and track this pre-existing specification conflict separately. That ruling does not reconcile the specification or authorize an unreviewed spec change.

The #2815 fix must continue to reject direct/unanchored user-relative input and preserve remote/symlink safety. This issue is the separate specification follow-up, not permission to broaden that fix or begin Phase 3 transaction work.

Activity

  1. danielmeppiel commented on Sep 6, 2026

    @danielmeppiel
    CollaboratorAuthor

    Maintainer decision (2026-09-06): reconcile the stale local-path specification with the explicitly approved trusted-local sibling behavior, with executable conformance coverage alongside the #2815 fix in #2820. The maintainer expressly approved omitting the public comment period for this amendment. This is a one-amendment process exception, not an apm-spec-waiver, a permanent change to Section 9, or permission to bypass review/conformance. Preserve remote-repository, local-copy symlink, and destination containment; preserve rejection of direct/unanchored user-relative inputs. Source anchoring does not introduce cross-scope package lookup or an OS sandbox guarantee. Independent specification review and Phase 2 integration evidence remain required; no merge is being performed by this action.

  2. github-actions commented on Sep 11, 2026

    @github-actions

    Triage decision

    needs-design

    Proposed labels

    theme/security
    area/package-authoring
    area/content-security
    type/bug
    status/needs-design
    

    Milestone

    null

    Suggested next action

    Write a short spec-clarification note distinguishing project-root containment, trusted-local sibling admission, and remote-source containment, then align req-mf-016's wording (or add an explicit user-scope carve-out) with the shipped dependency guide and the local materialization code.

    Suggested issue comment

    Thanks for the careful pinning of the three sources here -- this is exactly the kind of spec/implementation drift we want caught before it becomes a silent inconsistency.
    
    You're right that req-mf-016's literal wording ("MUST refuse any local-path entry whose normalised form contains `..` segments that would escape the project root") doesn't account for the trusted-local-sibling pattern the dependency guide documents, or for how user scope has no project root to escape in the first place.
    
    We're not going to weaken remote-source, symlink, or deployment containment to resolve this -- those stay hard boundaries. What needs to happen is a focused spec clarification: define the trust boundary explicitly (trusted local declaring-parent vs. untrusted remote), and give user scope its own containment story instead of leaving it silently unaddressed. That's a real (if narrow) design call, so we're marking this `status/needs-design` rather than a drop-in doc fix.
    
    If you want to take a first pass at the spec wording, a PR against `docs/src/content/docs/specs/openapm-v0.1.md` alongside the conformance fixtures would be very welcome -- happy to review.

    Per-lens notes (collapsed)

    DevX UX Expert -- User-Need Reviewer

    This is not a UX-facing bug in the traditional sense -- no command output changes -- but it directly affects whether users can trust the documented "local sibling package" workflow. If the spec's literal wording were enforced, a documented and currently-working pattern would start failing installs with no warning. The mental model at stake is "the docs say what happens"; right now three sources disagree, which is worse for users than any single wrong answer.

    Supply Chain Security Expert -- Risk-Surface Reviewer

    This is squarely a containment-boundary question: local-path dependency resolution. The current code deliberately does not enforce project-root containment for trusted local packages, treating the remote-parent boundary as the actual trust edge -- that's a defensible design, but req-mf-016 as written contradicts it without acknowledging the trusted-local exemption. theme/security is warranted because this is a specification-level integrity guarantee, not a decoration issue. No live exploit here (behavior already matches the guide, not the literal spec text), but leaving the spec wrong invites future implementations or forks to enforce the wrong invariant.

    OSS Growth Hacker -- Contributor-Tone Reviewer

    Not activated -- author is danielmeppiel (maintainer), not a first-time or low-interaction contributor.

    Python Architect -- Architecture Reviewer

    This is a spec-wording and scope-definition problem, not a code refactor -- but it requires a genuine design decision (how to define "project root" for user scope, how to phrase the trusted-local exemption) before the spec or conformance fixtures can be edited safely. Cross-cutting because req-mf-016, the shipped guide, local_content.py, and deps/path_anchoring.py must all stay mutually consistent after the fix. Recommend status/needs-design so the spec-guardian panel (or equivalent) reviews the proposed wording before it merges.

    Doc Writer -- Documentation Reviewer

    The spec text itself (docs/src/content/docs/specs/openapm-v0.1.md) is the artifact that needs to change here, plus possibly a clarifying note in the dependencies guide if the trust-boundary language needs sharpening. This is the rare case where the "code" fix is actually a docs/spec fix -- flagging area/content-security rather than area/docs-site since the audience is spec conformance, not the general docs site.

    APM CEO -- Triage Arbiter

    Real internal inconsistency between three artifacts that must agree by construction (spec, guide, implementation). Not urgent (no active break, current behavior matches the more permissive guide) but must be resolved deliberately rather than patched reactively -- hence needs-design, no milestone yet. This is exactly the kind of spec-conformance debt that erodes trust in the OpenAPM spec as a durable contract if left open too long; worth prioritizing once a milestone opens.

    {
      "decision": "needs-design",
      "decision_detail": "",
      "theme": "theme/security",
      "areas": ["area/package-authoring", "area/content-security"],
      "type": "type/bug",
      "status": "status/needs-design",
      "priority": null,
      "preserved_labels": [],
      "milestone": null,
      "next_action": "Write a short spec-clarification note distinguishing project-root containment, trusted-local sibling admission, and remote-source containment, then align req-mf-016's wording with the shipped guide and implementation.",
      "comment_markdown": "Thanks for the careful pinning of the three sources here -- this is exactly the kind of spec/implementation drift we want caught before it becomes a silent inconsistency.\n\nYou're right that req-mf-016's literal wording (\"MUST refuse any local-path entry whose normalised form contains `..` segments that would escape the project root\") doesn't account for the trusted-local-sibling pattern the dependency guide documents, or for how user scope has no project root to escape in the first place.\n\nWe're not going to weaken remote-source, symlink, or deployment containment to resolve this -- those stay hard boundaries. What needs to happen is a focused spec clarification: define the trust boundary explicitly (trusted local declaring-parent vs. untrusted remote), and give user scope its own containment story instead of leaving it silently unaddressed. That's a real (if narrow) design call, so we're marking this `status/needs-design` rather than a drop-in doc fix.\n\nIf you want to take a first pass at the spec wording, a PR against `docs/src/content/docs/specs/openapm-v0.1.md` alongside the conformance fixtures would be very welcome -- happy to review."
    }

    Triage status: agentic proposal pending human ratification.
    Silence is approval. Maintainers can:

    • Override any label or milestone above by editing it directly -- human edits are authoritative and will not be reverted on subsequent runs.
    • Re-trigger triage by applying the status/needs-triage label, or by removing status/triaged to enroll the issue in the next daily sweep.

    Posted by the Triage Panel workflow. See packages/apm-triage-panel for the panel skill.

    Generated by Triage Panel · copilot · auto · 120.9 AIC · ⌖ 26.4 AIC · ⊞ 14.1K · ◷

  3. added
    status/needs-designDesign discussion required before implementation; not scope approval by itself.
    status/triagedAutomated advice completed; deduplication only. Not human approval; silence is not approval.
    on Sep 11, 2026
  4. added
    triage/recommendedAutomated advice completed; not human scope approval.
    and removed
    status/triagedAutomated advice completed; deduplication only. Not human approval; silence is not approval.
    on Sep 12, 2026
  5. added
    status/acceptedHuman scope approval; verify the issue's approval record and review contact before work.
    status/deferredNot invited for implementation now; no release commitment.
    and removed
    status/acceptedHuman scope approval; verify the issue's approval record and review contact before work.
    on Sep 18, 2026
  6. danielmeppiel commented on Oct 19, 2026

    @danielmeppiel
    CollaboratorAuthor

    Decision: approve
    Area: project
    Scope: Reconcile the OpenAPM local-path specification with established trusted-local sibling development. Distinguish the declaring-package source anchor, installation scope, trusted-local admission, authenticated remote-repository containment, local-copy symlink containment and materialization/deployment destination safety. Preserve supported local development rather than changing the CLI to reject it merely to satisfy stale normative wording.
    Done when: Exact normative wording, scope definitions, directly related practical guidance, executable positive/negative conformance examples and the conformance statement agree on this bounded trust model. Preserve rejection of direct/unanchored user-relative input and all remote, symlink and destination boundaries. Do not certify unsupported runtime behavior or a skipped check as passing. Apply normal specification versioning and amendment requirements, including two qualified non-author reviewers covering implementation and consumer/integrator experience, the public-comment period, requirement-level revision history and any applicable migration obligations. Explicitly assess version treatment; a changed MUST is not automatically an editorial erratum.
    Out of scope: Weakening remote-repository, local-copy symlink or destination containment; new direct/unanchored user-relative admission; cross-scope package lookup or OS-sandbox guarantees; renewed public-comment-period exception or review waiver; approval, activation or resumption of the broader #2820 v0.2 foundation; automatic #2815 or #2919 runtime delivery; assignment, PR actions, release promises, automated implementation dispatch or restarting blocked delivery.
    Review contact: Daniel Meppiel (@danielmeppiel)

  7. danielmeppiel commented on Oct 19, 2026

    @danielmeppiel
    CollaboratorAuthor

    Accepted: narrow local-path specification alignment

    Following fresh explicit maintainer confirmation after the acceptance reset, the narrow specification-alignment scope is accepted, with Daniel Meppiel (@danielmeppiel) as review contact. This is a new bounded record, not reliance on the September 6 approval.

    The contradiction remains on main cb06ec21bafd58bc8eb8961d7f4cf6843c604809: req-mf-016 says the resolver must refuse local paths escaping the project root, while the shipped dependency guide and local materialization owner deliberately support trusted local sibling layouts. For example, a developer may keep /work/app and /work/shared-skills beside each other and explicitly select the latter. Do not break that supported workflow merely to satisfy stale normative wording.

    Clarify which directory anchors a dependency reference and which boundary constrains an operation. These are different questions. Remote-declared local paths remain inside the authenticated repository; copied local symlinks remain within their source package; materialization and deployment retain their destination protections. Direct, unanchored user-relative input remains rejected.

    This is not an automatic editorial erratum. Review the exact normative/version change and executable conformance evidence together under the normal specification process. The current req-mf-016 conformance row is skipped; it must not be treated as proof that the specification and implementation agree.

    The former comment-period exception is not renewed. This does not approve or activate the broader inactive #2820 foundation, resolve its outstanding findings, or restart #2815/#2919 runtime work. Those scopes and their evidence remain separate.

    The issue remains open. No assignment, relationship, PR action, implementation dispatch or release commitment is being made. Current text and source were inspected; no new local-sibling runtime reproduction or specification panel was run for this decision.


    Generated by apm-strategy. This comment is AI-generated and may contain errors.

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

    status/deferredNot invited for implementation now; no release commitment.status/needs-designDesign discussion required before implementation; not scope approval by itself.triage/recommendedAutomated advice completed; not human scope approval.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