Skip to content

fix(install): preview positional packages in dry runs - #2664

Open
Daniel Meppiel (danielmeppiel) wants to merge 5 commits into
mainfrom
danielmeppiel-fix-positional-dry-run
Open

fix(install): preview positional packages in dry runs#2664
Daniel Meppiel (danielmeppiel) wants to merge 5 commits into
mainfrom
danielmeppiel-fix-positional-dry-run

Conversation

@danielmeppiel

@danielmeppiel Daniel Meppiel (danielmeppiel) commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

fix(install): preview positional packages in dry runs

TL;DR

apm install PACKAGE --dry-run now validates and previews the requested positional package, including an in-memory ref change, without changing an existing apm.yml. Rendering, policy checks, insecure-source validation, and final counts consume one prospective plan.

Note

Fixes #2612.

Community overlap

This PR no longer claims or implements #2550 or #2549. Those issues remain with Aryan Singh K. (@aryansk)'s community PRs #2580 and #2592. Their work was not cherry-picked here, so their authorship and review ownership remain intact.

Problem

Validation kept positional additions in memory during dry-run, but the renderer reparsed the unchanged manifest. The package could therefore be absent from the preview and final count. Existing dependency ref changes could also be written during a preview.

Approach

  • Build an interpreted prospective package from validation's in-memory manifest.
  • Preserve structured dependency identity and configured registry routing.
  • Select only the requested positional APM dependency for rendering and checks.
  • Route rendering, checks, orphan intent, and counts through ProspectiveInstallPlan.
  • Preserve source-aware local paths and ref-update terminology in the preview.
  • Keep bootstrap behavior unchanged; this PR only guarantees that an existing manifest is not changed.

Implementation

flowchart LR
    V[Validated positional request] --> M[Prospective manifest in memory]
    M --> P[ProspectiveInstallPlan]
    P --> S[Selected dependency checks]
    P --> R[Dry-run renderer]
    P --> C[Final count]
Loading

The architecture owner registry now records the prospective dry-run plan. A registered static rule and mutation case prevent the command or renderer from rebuilding preview state outside that owner.

Trade-offs

Validation

  • Focused dry-run, rendering, logging, and owner-registry tests pass.
  • Architecture owner mutation tests pass.
  • The full lint contract, auth boundary lint, and architecture boundary lint pass locally.

Scenario evidence

Scenario Principle Test
A validated local package is listed and counted without changing the project DevX, Portability by manifest tests/unit/test_install_command.py::TestInstallCommandAutoBootstrap::test_positional_local_package_dry_run_previews_validated_addition
Unrequested manifest dependencies are excluded from a positional preview DevX tests/unit/test_install_command.py::TestInstallCommandAutoBootstrap::test_positional_dry_run_excludes_unrequested_manifest_dependencies
Unrequested denied dependencies do not produce policy diagnostics Governed by policy, DevX tests/integration/test_policy_install_e2e.py::TestI10DryRunDenied::test_positional_dry_run_excludes_unrequested_denied_manifest_dependency
A changed ref is previewed without changing apm.yml Secure by default, Portability by manifest tests/unit/test_install_command.py::TestInstallCommandAutoBootstrap::test_positional_dry_run_previews_ref_update_without_persisting
The prospective plan remains the registered architecture owner DevX tests/integration/test_architecture_owner_rule_mutations.py

How to test

  1. Initialize a project and create a local package.
  2. Run apm install ./local-package --dry-run.
  3. Confirm the package appears once in the plan and final count.
  4. Confirm the existing apm.yml, lockfile, modules, and deployment files are unchanged.
  5. Request a new ref for an existing dependency and confirm the ref appears in output while apm.yml remains byte-identical.

apm-spec-waiver: This fixes internal install preview planning without extending the OpenAPM manifest contract.

Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR fixes apm install PACKAGE --dry-run so that validated positional package additions are reflected in the printed dry-run plan even when the existing apm.yml is not modified. It introduces an immutable ProspectiveInstallPlan as the single source of truth for dry-run rendering, orphan intent preview, and selected dependency counts, and adds tests + an architecture-boundary lint guard to prevent re-parsing in the renderer.

Changes:

  • Add ProspectiveInstallPlan (frozen dataclass) to represent dry-run preview state derived from manifest deps + validated positional additions.
  • Update the install command to carry validated additions into dry-run and route rendering/preflight/counts through the frozen plan.
  • Add regression tests, an architecture boundary lint check + mutation test, and update CLI docs/usage guide to document non-persistence of positional additions.
Show a summary per file
File Description
tests/unit/test_install_command.py Adds regression test covering positional local package dry-run preview without mutating the project.
tests/unit/install/test_dry_run_render.py Adapts legacy render fixtures to the new plan and adds plan count semantics test.
tests/unit/commands/test_install_context.py Extends InstallContext field coverage to include validated_additions.
tests/integration/test_architecture_authorities.py Adds authority/guard assertions and a mutation test to reject renderer-side reparsing.
src/apm_cli/install/presentation/dry_run.py Updates dry-run renderer to accept a ProspectiveInstallPlan and consume plan-derived state.
src/apm_cli/install/dry_run_plan.py Introduces the frozen ProspectiveInstallPlan and plan-derived counts/intended keys.
src/apm_cli/commands/install.py Threads validated additions into dry-run plan construction and returns plan-selected counts.
scripts/lint-architecture-boundaries.sh Adds a boundary check enforcing ProspectiveInstallPlan as the sole owner for dry-run preview state.
packages/apm-guide/.apm/skills/apm-usage/commands.md Documents dry-run preview behavior for positional packages without persisting to existing manifests.
docs/src/content/docs/reference/cli/install.md Updates --dry-run reference to clarify positional packages appear in preview but aren’t persisted to existing apm.yml.
.github/instructions/architecture.instructions.md Adds canonical-owner table entry for the prospective dry-run plan.
.apm/instructions/architecture.instructions.md Adds canonical-owner table entry for the prospective dry-run plan (APM-internal copy).

Review details

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

  • Files reviewed: 12/12 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment on lines 53 to 57
if plan.should_install_apm and plan.apm_dependencies:
logger.progress(f"APM dependencies ({plan.apm_dependency_count}):")
for dep in plan.apm_dependencies:
action = "update" if update else "install"
logger.progress(f" - {dep.repo_url}#{dep.reference or 'main'} -> {action}")
@danielmeppiel

Copy link
Copy Markdown
Collaborator Author

APM Review Panel: needs_rework

Narrow #2664 to a truthful, identity-preserving #2612 preview while preserving Aryan Singh K. (@aryansk)'s ownership of #2580 and #2592.

cc Sergio Sisternes (@sergio-sisternes-epam) -- a fresh advisory pass is ready for your review.

The panel agrees that #2612 is a useful, bounded improvement: validated positional packages should appear in apm install PACKAGE --dry-run without changing an existing manifest. The passing regression in tests/unit/test_install_command.py proves the local-package path, but does not cover changed references, exact source identity, selected-package filtering, or the final summary.

The concrete #2612 issues should be folded into this change. A changed reference can still persist apm.yml; disabling the effective default registry and reparsing canonical strings can alter dependency identity and security metadata; and only_packages is not consistently honored by rendering, counts, and preflight. Use one required structured preview plan carrying resolved dependency references, the live install's read-only registry context, prospective replacements, and the selected dependency view. Do not broaden the promise to total filesystem immutability while update-check or policy caches may still write.

The overlap strategy is explicit: #2664 should stop claiming or implementing #2550 and #2549, remove the overlapping LSP/global-no-write work and evidence, and say Fixes #2612 only. Prefer landing community PRs #2580 and #2592 first, then rebase #2664 as their clearly sequenced follow-up. Acknowledge both PRs and Aryan Singh K. (@aryansk) in the advisory and PR body; preserve their ownership rather than cherry-picking their work unless integration is genuinely unavoidable, in which case obtain consent and retain authorship credit.

Dissent. DevX classified selected-package overcounting as recommended while CLI logging and supply-chain security classified it as blocking-severity. The higher weight is appropriate because displaying and validating dependencies the user did not select makes the preview materially untruthful.

Aligned with: Portable by manifest: changed-reference previews must preserve existing apm.yml bytes while carrying prospective replacements in memory; Secure by default: preview validation must retain the live install's effective registry and structured dependency identity; Governed by policy: checks must evaluate only selected dependencies; OSS community driven: retain #2580 and #2592 under Aryan Singh K. (@aryansk)'s ownership; Pragmatic as npm: report exactly the requested package, count, and summary without persisting it.

Growth signal. Frame #2664 as a focused follow-up built on Aryan Singh K. (@aryansk)'s community contributions: one issue, one clear promise, and explicit credit.

Reservations carried from strategic alignment

Panel summary

Persona B R N Takeaway
Python Architect 2 1 0 Keep #2664 on #2612, enforce one typed preview authority, and avoid claiming read-only behavior while cache writes remain.
CLI Logging Expert 2 2 1 Dry-run selection is not truthful: positional previews overcount, and --only lsp can diagnose unselected APM dependencies.
DevX UX Expert 2 3 0 Fix remaining dry-run mutations and validation drift, then narrow attribution to positional preview work.
Supply Chain Security Expert 3 1 0 Narrow to #2612, but fix dry-run writes and preserve exact dependency identity and selection.
OSS Growth Hacker 0 2 0 Preserve community credit by making #2664 a clearly sequenced #2612 follow-up to #2580 and #2592.
Doc Writer 0 3 0 Narrow the documentation and PR body to #2612; reserve #2550 and #2549 for community PRs #2580 and #2592.
Test Coverage Expert 0 2 0 The focused #2612 test passes; add the final-summary assertion and remove evidence overlapping #2580/#2592.
Performance Expert 0 2 0 Core #2612 adds no network work and only linear parsing; narrow the overlaps and avoid whole-suite guard runs.

B = blocking-severity findings, R = recommended, N = nits.
Counts are signal strength, not gates. The maintainer ships.

Top 5 follow-ups

  1. [Python Architect] (blocking-severity) Remove [BUG] apm install --dry-run reports "No dependencies found in apm.yml" when only dependencies.lsp is declared #2550/[BUG] apm install --dry-run creates ~/.apm/apm.yml, config.json, and apm_modules/ while reporting "no changes made" #2549 implementation and claims; rebase as a [BUG] apm install PACKAGE --dry-run omits the new package from its plan on 0.28.0 #2612-only follow-up to fix: include LSP dependencies in install dry-run #2580 and fix: keep global install dry-run out of user state #2592. -- This avoids duplicate work, preserves contributor ownership, and keeps the change reviewable.
  2. [Supply Chain Security Expert] (blocking-severity) Prevent changed-reference dry runs from persisting apm.yml and add an automated regression case. -- The mutation was reproduced and directly contradicts the scoped [BUG] apm install PACKAGE --dry-run omits the new package from its plan on 0.28.0 #2612 promise.
  3. [Python Architect] (blocking-severity) Make one structured preview plan authoritative, preserving resolved dependency identity, prospective replacements, and effective registry context. -- Canonical-string reparsing and alternate construction can change source semantics and let install paths drift.
  4. [CLI Logging Expert] (blocking-severity) Apply only_packages consistently to preview rendering, counts, and preflight diagnostics. -- A positional preview currently reports or diagnoses manifest dependencies the user did not select.
  5. [Test Coverage Expert] Assert the final Dry run completed: would install 1 APM dependency summary in the focused [BUG] apm install PACKAGE --dry-run omits the new package from its plan on 0.28.0 #2612 scenario. -- The current passing test protects listing and manifest immutability but leaves the completion count without a durable regression trap.

Architecture

classDiagram
    direction LR
    class InstallCommand {
      <<Module>>
      +validate_packages()
      +build_preview_plan()
    }
    class InstallContext {
      <<ParameterObject>>
      +dry_run bool
      +validated_additions tuple
    }
    class ProspectiveInstallPlan {
      <<ValueObject>>
      +selected_apm_dependencies tuple
      +all_apm_dependencies tuple
      +intended_dependency_keys frozenset
    }
    class DependencyReference {
      <<ValueObject>>
      +get_unique_key() str
    }
    class DryRunRenderer {
      <<Renderer>>
      +render_and_exit(plan)
    }
    InstallCommand *-- InstallContext : builds
    InstallCommand *-- ProspectiveInstallPlan : builds once
    ProspectiveInstallPlan o-- DependencyReference : preserves
    DryRunRenderer --> ProspectiveInstallPlan : consumes
    class InstallCommand:::touched
    class ProspectiveInstallPlan:::touched
    class DryRunRenderer:::touched
    classDef touched fill:#fff3b0,stroke:#d47600
Loading
flowchart TD
    U["apm install PACKAGE --dry-run"]
    V["Validate into structured dependency references"]
    P["Build one prospective plan"]
    S["Select requested APM dependency view"]
    C["Run policy and security checks on selected view"]
    R["Render plan and final count"]
    N["Leave existing apm.yml unchanged"]
    U --> V --> P --> S --> C --> R --> N
Loading

Recommendation

Rebase and fold #2664 into a #2612-only change, preferably after #2580 and #2592 land. Preserve Aryan Singh K. (@aryansk)'s ownership, then address manifest mutation, identity-preserving resolution, selected-package truthfulness, and the missing summary assertion before requesting another advisory pass.


Full per-persona findings

Python Architect

CLI Logging Expert

DevX UX Expert

  • [blocking] Existing dependency updates can still write apm.yml during dry-run at src/apm_cli/commands/install.py.
    Skip persistence in dry-run and carry prospective replacements into the plan.
  • [blocking] Dry-run no longer follows configured default-registry routing at src/apm_cli/commands/install.py.
    Use the same effective registry through a read-only path.
  • [recommended] Limit positional previews to packages the command would install.
    Rendering, counts, and preflight currently include unrelated manifest dependencies.
  • [recommended] Rebase onto or sequence after the community LSP and global dry-run fixes.
    Preserve Aryan Singh K. (@aryansk)'s authorship and keep fix(install): preview positional packages in dry runs #2664 scoped to [BUG] apm install PACKAGE --dry-run omits the new package from its plan on 0.28.0 #2612.
  • [recommended] Remove contradictory dry-run documentation.
    Align docs and the packaged guide with the narrowed contract.

Supply Chain Security Expert

OSS Growth Hacker

Auth Expert -- inactive

The changes touch install dry-run planning/presentation and related docs, tests, and architecture guards, not auth paths.

Doc Writer

Test Coverage Expert

Performance Expert

This panel is advisory. It does not block merge. Re-apply the
panel-review label after addressing feedback to re-run.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Preserve validated dependency identity, filter previews to the requested package, and keep changed refs in memory so dry-run output matches the corresponding install without mutating an existing manifest. This addresses the review-panel follow-ups while narrowing the PR to #2612.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danielmeppiel
Daniel Meppiel (danielmeppiel) force-pushed the danielmeppiel-fix-positional-dry-run branch from 7645f3b to aeaa358 Compare September 1, 2026 09:16
Give direct dry-run validation fixtures the required manifest version and add the new architecture rule to the frozen inventory. This addresses the first CI recovery findings after the rebase.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danielmeppiel

Copy link
Copy Markdown
Collaborator Author

APM Review Panel: needs_rework

PR #2664 now focuses on #2612, preserves contributor ownership, and needs three bounded follow-ups before shipping.

cc Sergio Sisternes (@sergio-sisternes-epam) -- a fresh advisory pass is ready for your review.

The scope reservation is resolved: all #2550/#2549 implementation and claims were removed, Aryan Singh K. (@aryansk) is explicitly credited, and independent ownership of #2580/#2592 is preserved without cherry-picking. CI run 33492159456 is fully green, while DevX, security, docs, performance, and growth report no concerns. Performance remains O(n+k), adds no network round trips, and has negligible planning cost.

Three in-scope items should fold now. Highest signal is the split policy authority: MCP policy input must use prospective_plan.mcp_dependencies rather than raw mcp_deps if should_install_mcp, with the guard extended accordingly. Add the missing positional dry-run integration fixture on the governed-policy path, then normalize the two related output inconsistencies by preserving the requested ./name path and using ref-update terminology instead of new-package/install wording.

Aligned with: Governed by policy: policy evaluation should consistently consume the prospective plan; OSS community driven: the narrowed scope credits Aryan Singh K. (@aryansk) and preserves #2580/#2592; Pragmatic as npm: output should echo the requested path and distinguish ref updates from installs.

Growth signal. Preserve the explicit Aryan Singh K. (@aryansk) credit and independent issue ownership in the final PR narrative; that scope discipline strengthens contributor trust.

Reservations carried from strategic alignment

Panel summary

Persona B R N Takeaway
Python Architect 1 0 0 Route the remaining MCP policy consumer through the prospective plan.
CLI Logging Expert 0 2 0 Local additions and ref updates still use misleading plan text.
DevX UX Expert 0 0 0 Positional dry-run behavior is truthful, non-mutating, documented, and covered.
Supply Chain Security Expert 0 0 0 Manifest mutation, registry identity drift, and unselected preflights are fixed.
OSS Growth Hacker 0 0 0 Scope and contributor ownership are now explicit.
Doc Writer 0 0 0 Docs and PR body match the narrowed behavior and credit.
Test Coverage Expert 0 1 0 Add fixture-level policy coverage for unrequested dependencies.
Performance Expert 0 0 0 The plan remains linear, local, and inexpensive.

B = blocking-severity findings, R = recommended, N = nits.
Counts are signal strength, not gates. The maintainer ships.

Top 3 follow-ups

  1. [Python Architect] (blocking-severity) Fold now: make prospective_plan.mcp_dependencies the MCP policy input and extend the guard. -- One prospective-plan authority prevents policy behavior from diverging.
  2. [Test Coverage Expert] Fold now: add a positional dry-run integration fixture for an unrequested denied manifest dependency. -- The governed-policy promise needs a fixture-level regression trap.
  3. [CLI Logging Expert] Fold now: preserve ./name in local-path output and describe ref changes as updates rather than new installs. -- Accurate paths and terminology keep feedback aligned with the request.

Architecture

flowchart TD
    A["apm install PACKAGE --dry-run"]
    V["Validate request into prospective package"]
    P["ProspectiveInstallPlan"]
    S["Selected APM security and plugin checks"]
    M["Plan-owned MCP policy input"]
    R["Render plan and counts"]
    A --> V --> P
    P --> S
    P --> M
    P --> R
Loading

Recommendation

Fold these three bounded items into the current PR, led by the prospective-plan authority correction, then return it for maintainer consideration with the narrowed scope and community credit unchanged.


Full per-persona findings

Python Architect

  • [blocking] Route the MCP policy input through the canonical preview plan at src/apm_cli/commands/install.py:1813.
    _dr_preflight recombines raw mcp_deps and should_install_mcp even though the plan owns both. Pass the plan's MCP dependencies and extend the registered guard.

CLI Logging Expert

  • [recommended] Render the requested local path in the dependency plan at src/apm_cli/install/presentation/dry_run.py:40.
    Use the dependency's source-aware display reference rather than constructing output from repo_url.
  • [recommended] Do not describe a ref update as a new package.
    Carry preview action into the plan so validation, resolution, rendering, and the final summary use consistent update terminology.

DevX UX Expert

No findings.

Supply Chain Security Expert

No findings.

OSS Growth Hacker

No findings.

Auth Expert -- inactive

The final diff changes install dry-run planning, output, tests, documentation, and architecture files, with no authentication changes.

Doc Writer

No findings.

Test Coverage Expert

  • [recommended] Selected-package policy checks lack fixture-level regression coverage at src/apm_cli/commands/install.py:1812.
    Proof (missing at integration-with-fixtures): tests/integration/test_policy_install_e2e.py::TestI10DryRunDenied::test_positional_dry_run_excludes_unrequested_denied_manifest_dependency.

Performance Expert

No findings.

This panel is advisory. It does not block merge. Re-apply the
panel-review label after addressing feedback to re-run.

Route MCP policy checks through the prospective plan, preserve local display paths, and distinguish ref updates throughout the dry-run lifecycle. Fixture-level policy coverage proves unrequested denied dependencies stay outside the preview. This addresses the second panel pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danielmeppiel

Copy link
Copy Markdown
Collaborator Author

APM Review Panel: ship_with_followups

PR #2664 cleanly resolves #2612 with green CI; only two bounded documentation cleanups remain.

cc Sergio Sisternes (@sergio-sisternes-epam) -- a fresh advisory pass is ready for your review.

At dd8e5e0, the code-focused reviewers found no substantive concerns, and CI run 33494456057 is fully green. The panel signals converge on a complete implementation with no further code or test work indicated.

Fold the two doc-writer recommendations now: consolidate the positional dry-run note under the guide's existing install-flags section, and name insecure-source validation precisely in the PR body. Scope and contributor credit are also clear: #2664 addresses only #2612, while Aryan Singh K. (@aryansk) retains #2580 and #2592 without cherry-pick.

Aligned with: Secure by default: precise terminology avoids overstating security scope; OSS community driven: Aryan Singh K. (@aryansk) retains ownership and credit for #2580/#2592; Pragmatic as npm: one authoritative guide location reduces drift.

Reservations carried from strategic alignment

Panel summary

Persona B R N Takeaway
Python Architect 0 0 1 The prospective plan has one owner with behavioral and static guardrails.
CLI Logging Expert 0 0 0 Local paths and ref-update output are now consistent.
DevX UX Expert 0 0 0 UX, docs, and tests align with #2612.
Supply Chain Security Expert 0 0 0 Identity, registry routing, immutability, and selected checks hold.
OSS Growth Hacker 0 0 0 Scope and community credit are explicit.
Doc Writer 0 1 1 Consolidate one duplicate guide note and sharpen one PR-body phrase.
Test Coverage Expert 0 0 0 All scenario claims and owner mutations pass.
Performance Expert 0 0 0 Planning remains O(n+k), local, and negligible.

B = blocking-severity findings, R = recommended, N = nits.
Counts are signal strength, not gates. The maintainer ships.

Top 2 follow-ups

  1. [Doc Writer] Fold the positional dry-run note into the install-flags text and remove the duplicate. -- One authoritative location prevents wording drift.
  2. [Doc Writer] Replace generic security checks in the PR body with insecure-source validation. -- The specific term accurately describes this PR.

Architecture

flowchart TD
    V["Validated positional request"] --> P["ProspectiveInstallPlan"]
    P --> A["Selected APM checks"]
    P --> M["Selected MCP policy input"]
    P --> R["Dry-run renderer"]
    P --> C["Final summary counts"]
Loading

Recommendation

The maintainer can ship after folding these two bounded documentation edits; the implementation and tests are otherwise converged.


Full per-persona findings

Python Architect

  • [nit] Pattern assessment only; no action requested.
    The immutable value-object plan and CommandLogger subclassing fit the current scope.

CLI Logging Expert

No findings.

DevX UX Expert

No findings.

Supply Chain Security Expert

No findings.

OSS Growth Hacker

No findings.

Auth Expert -- inactive

The final diff contains no auth, token, or host-resolution changes.

Doc Writer

  • [recommended] Fold the duplicate positional dry-run note into the existing install command entry in packages/apm-guide/.apm/skills/apm-usage/commands.md.
  • [nit] Use insecure-source validation instead of generic security checks in the PR body.

Test Coverage Expert

No findings.

Performance Expert

No findings.

This panel is advisory. It does not block merge. Re-apply the
panel-review label after addressing feedback to re-run.

Keep the dry-run contract with the canonical install command entry instead of repeating it after unrelated policy guidance. This addresses the terminal panel documentation follow-up.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danielmeppiel

Copy link
Copy Markdown
Collaborator Author

APM Review Panel: ship_now

PR #2664 makes positional install dry runs accurate and non-mutating while preserving contributor ownership.

cc Sergio Sisternes (@sergio-sisternes-epam) -- a fresh advisory pass is ready for your review.

At exact head 45c68576c3c445efb7f82f05bd75da84aeb370eb, all active specialists report no actionable findings; the Python architect's pattern-assessment nit explicitly requests no action. CI run 33495665073 is fully green, guide consolidation is complete, and the scope cleanly fixes only #2612 while crediting Aryan Singh K. (@aryansk) and preserving independent work in #2580 and #2592.

Aligned with: Portable by manifest: the prospective plan previews positional changes while leaving the existing apm.yml unchanged; Secure by default: validation and insecure-source checks consume the prospective plan; Governed by policy: checks exclude unrelated manifest entries; OSS community driven: Aryan Singh K. (@aryansk) retains #2580/#2592; Pragmatic as npm: output shows the requested package, ref change, and count.

Reservations carried from strategic alignment

Panel summary

Persona B R N Takeaway
Python Architect 0 0 1 One frozen plan owner feeds selected checks, rendering, and counts with dual guardrails.
CLI Logging Expert 0 0 0 Guide consolidation preserves the dry-run output contract.
DevX UX Expert 0 0 0 Dry-run UX, documentation, scope, and contributor credit are consistent.
Supply Chain Security Expert 0 0 0 Identity, registry routing, policy checks, and manifest immutability hold.
OSS Growth Hacker 0 0 0 #2612-only scope and independent community ownership are confirmed.
Doc Writer 0 0 0 Duplicate guidance, security terminology, scope, and credit are resolved.
Test Coverage Expert 0 0 0 All five scenario claims and the owner mutation matrix are covered.
Performance Expert 0 0 0 Planning remains O(n+k), adds no network round trips, and is negligible.

B = blocking-severity findings, R = recommended, N = nits.
Counts are signal strength, not gates. The maintainer ships.

Architecture

flowchart TD
    V["Validated positional request"] --> P["ProspectiveInstallPlan"]
    P --> A["Selected APM checks"]
    P --> M["Selected MCP policy input"]
    P --> R["Dry-run renderer"]
    P --> C["Final summary counts"]
    G["Registered static rule and mutation case"] --> P
Loading

Recommendation

The maintainer may ship this exact head now; the panel identified no follow-up work requiring tracking.

Folded in this run

  • (panel) Narrowed the PR to [BUG] apm install PACKAGE --dry-run omits the new package from its plan on 0.28.0 #2612 and preserved Aryan Singh K. (@aryansk)'s independent fix: include LSP dependencies in install dry-run #2580 and fix: keep global install dry-run out of user state #2592 ownership without cherry-picking -- resolved in aacc9ea037f360bfe48ca996de9194231f290cad.
  • (panel) Kept ref updates prospective and preserved structured dependency identity and registry routing -- resolved in aeaa358f85c6d97339b1a9f206c08fade315f1aa.
  • (panel) Routed rendering, checks, and counts through the requested dependency view -- resolved in aeaa358f85c6d97339b1a9f206c08fade315f1aa.
  • (panel) Added final count coverage and a registered prospective-plan owner guard -- resolved in aeaa358f85c6d97339b1a9f206c08fade315f1aa.
  • (panel) Routed MCP policy input through the plan and extended mutation coverage -- resolved in dd8e5e04acff467fbd10c024bb3600617e2a816f.
  • (panel) Preserved local display paths and consistent ref-update terminology -- resolved in dd8e5e04acff467fbd10c024bb3600617e2a816f.
  • (panel) Added fixture-level policy-selection proof -- resolved in dd8e5e04acff467fbd10c024bb3600617e2a816f.
  • (panel) Consolidated positional dry-run guidance at the canonical install command entry -- resolved in 45c68576c3c445efb7f82f05bd75da84aeb370eb.

Regression-trap evidence (mutation-break gate)

  • test_positional_dry_run_previews_ref_update_without_persisting -- removed the dry-run persistence guard and updated-package tracking; the test failed as expected; guards restored.
  • test_positional_dry_run_excludes_unrequested_manifest_dependencies -- removed selected APM filtering; the test failed as expected; guard restored.
  • test_positional_local_package_dry_run_previews_validated_addition -- removed source-aware display; the test failed as expected; guard restored.
  • test_positional_dry_run_excludes_unrequested_denied_manifest_dependency -- removed plan-selected policy input; the test failed as expected; guard restored.
  • test_owner_rule_catches_its_guard_mutation -- replaced plan-owned MCP policy input; the architecture mutation test caught it; guard restored.

Lint contract

The full CI-mirror ruff, format, pylint R0801, auth-signal, architecture-boundary, and file-length checks exited 0. CI Lint passed.

CI

All required checks passed on https://github.com/microsoft/apm/actions/runs/33495665073 after 1 CI fix iteration.

Mergeability status

PR head SHA CEO stance iters folds defers Copilot rounds CI mergeable mergeStateStatus notes
#2664 45c6857 ship_now 4 8 0 2 green MERGEABLE BLOCKED awaiting required review

Convergence

4 outer iterations; 2 Copilot rounds with no inline findings. Final panel stance: ship_now.

Ready for maintainer review.


Full per-persona findings

Python Architect

  • [nit] Pattern assessment only; no action requested.
    The immutable value-object plan and CommandLogger subclassing are the simplest correct design at this scope.

CLI Logging Expert

No findings.

DevX UX Expert

No findings.

Supply Chain Security Expert

No findings.

OSS Growth Hacker

No findings.

Auth Expert -- inactive

The final diff contains no authentication, token, credential-resolution, or host changes.

Doc Writer

No findings.

Test Coverage Expert

No findings.

Performance Expert

No findings.

This panel is advisory. It does not block merge. Re-apply the
panel-review label after addressing feedback to re-run.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[BUG] apm install PACKAGE --dry-run omits the new package from its plan on 0.28.0

2 participants