Skip to content

feat(install): support per-dependency agent subsets - #2657

Open
wind127 wants to merge 2 commits into
microsoft:mainfrom
wind127:codex/add-agent-dependency-subsets-2491
Open

feat(install): support per-dependency agent subsets#2657
wind127 wants to merge 2 commits into
microsoft:mainfrom
wind127:codex/add-agent-dependency-subsets-2491

Conversation

@wind127

@wind127 wind127 commented Aug 22, 2026

Copy link
Copy Markdown

TL;DR

This adds per-dependency agent selection alongside the existing skill subset flow. Consumers can declare agents: or repeat apm install --agent NAME; the normalized selection is persisted in the manifest and lockfile, enforced before cross-target deployment, and replayed by bare installs and audit.

Note

Closes #2491, an accepted high-priority issue with no competing branch or PR when implementation started.

Problem (WHY)

  • A package can mix consumer-facing agents with repository-development agents, but APM currently deploys every agent to every active target.
  • Hand-deleting unwanted agents is not stable: a subsequent install deploys them again and makes deployment tracking disagree with the working tree.
  • [!] The existing skills: subset has no parallel agent primitive boundary, so selecting package content is inconsistent across primitive types.

The concrete reproduction and requested semantics are documented in #2491: persist the subset in apm.yml and apm.lock.yaml, make bare installs deterministic, reject an empty list, and treat absence as “all agents.”

Approach (WHAT)

# Change
1 Add a validated, sorted agents: inclusion list to git, path, and registry dependency objects.
2 Add repeatable, additive --agent NAME; use --agent '*' to reset a dependency to all agents.
3 Carry one agent_subset value through request, resolution, lockfile, deployment, and audit replay boundaries.
4 Filter source agents once in AgentIntegrator, before target-specific dialect expansion.
5 Add manifest/lock schemas, OpenAPM requirement req-mf-025, CI consistency checks, docs, and scenario tests.

Implementation (HOW)

Area Files and intent
Dependency model models/dependency/{subsets,object_fields,reference,registry_entry}.py validates non-empty flat names and round-trips the new field across every dependency form.
CLI and manifest commands/{install,_apm_yml_writer}.py exposes --agent, preserves additive pins, implements wildcard reset, and retains the historical command patch seam through install/entrypoint.py.
Install pipeline install/{request,service,pipeline,context,package_resolution,template,services}.py carries and validates intent before handing the effective subset to primitive integration.
Lock and replay deps/lockfile.py, install/phases/lockfile.py, and install/drift.py persist sorted agent_subset values and reconstruct them during audit replay.
Deployment integration/agent_integrator.py derives canonical flat names and filters source agents before translating them for each target.
Governance policy/ci_checks.py adds agent-subset-consistency, preventing manifest/lock drift in CI.
Contract OpenAPM spec, requirement manifest, public schemas, generated conformance reports, CLI/reference/enterprise docs, shipped guide resources, and CHANGELOG.md describe the same behavior.
Tests Model, property, consumer-contract, drift, policy, architecture, spec, and end-to-end tests cover invalid input, additive persistence, bare replay, wildcard reset, and rollback.

Legend: dashed nodes are the new intent and enforcement boundaries; existing target adapters remain unchanged.

flowchart LR
    subgraph Input[Dependency intent]
        C[--agent NAME]
        M[agents list]
    end
    subgraph Persist[Deterministic state]
        R[DependencyReference agent_subset]
        Y[apm.yml]
        L[apm.lock.yaml]
    end
    subgraph Deploy[Primitive deployment]
        V[Validate requested names]
        F[Filter source agents]
        T[Target adapters]
    end
    C --> R
    M --> R
    R --> Y
    R --> L
    Y --> V
    L --> V
    V --> F
    F --> T
    classDef new stroke-dasharray: 5 5;
    class C,M,R,L,V,F new;
Loading

Trade-offs

  • Flat agent names, not paths. Agent selection is an inclusion list over canonical filenames; nested values are rejected through the sanctioned path validator instead of becoming another path-resolution surface.
  • Additive CLI semantics. Repeated targeted installs union with persisted pins, matching --skill; an explicit wildcard is required to return to all agents.
  • Filter before target expansion. One source-level decision prevents unwanted agents from multiplying across Copilot, Claude, Codex, Cursor, and other adapters without changing each adapter.
  • Backward-compatible absence. Missing agents/agent_subset means all agents; older manifests and lockfiles retain their behavior.

Benefits

  1. A dependency containing three agents can deterministically deploy one selected agent instead of all three to every target.
  2. The same subset survives manifest reload, lockfile-only state, bare install, and audit replay.
  3. Unknown CLI agent names fail with available-name diagnostics and do not persist a manifest pin.
  4. CI reports agent subset drift independently from skill subset drift.

Validation

uv run pytest ... (focused model, install, lockfile, policy, and spec suites):

253 passed, 1 skipped in 35.37s

uv run --extra dev ruff check src/ tests/ and ruff format --check:

All checks passed!
1617 files already formatted

uv run --frozen --extra dev python -m pylint --disable=all --enable=R0801 --min-similarity-lines=10 --fail-on=R0801 src/apm_cli/:

Your code has been rated at 10.00/10

Architecture, auth, and OpenAPM conformance guards:

[+] architecture boundary lint clean
[+] auth-signal lint clean
[+] orphan_check OK: 113 requirements aligned across anchors / manifest / Appendix C / pytest markers

Docs build: 123 pages generated; all 969 internal links valid.

Important

The full Windows unit run also contains pre-existing tests that require symlink privileges and a newer Git supporting git init --initial-branch; those environment-limited cases could not run on this host. The focused scenarios and repository lint/architecture contracts above are green.

Scenario Evidence

# Scenario (user promise) Principle(s) Test(s) proving it Type
1 Select one agent, add another later, and get the same two agents on a bare reinstall Portability by manifest, Multi-harness support, DevX tests/unit/install/test_agent_subset.py::TestAgentSubsetInstall::test_cli_subset_is_additive_persisted_and_replayed e2e
2 Reset a dependency to all agents with --agent '*' DevX tests/unit/install/test_agent_subset.py::TestAgentSubsetInstall::test_cli_subset_is_additive_persisted_and_replayed e2e
3 Reject an unknown agent without changing apm.yml Secure by default, DevX tests/unit/install/test_agent_subset.py::TestAgentSubsetInstall::test_unknown_cli_agent_fails_without_persisting_pin e2e
4 Reject empty or nested manifest agent names Secure by default tests/unit/install/test_agent_subset.py::TestAgentSubsetModel::test_invalid_agent_subset_is_rejected unit
5 Preserve the selected agents through lockfile round-trip and audit replay Governed by policy tests/unit/install/test_agent_subset.py::TestAgentSubsetModel::test_lockfile_round_trip_preserves_agent_subset
tests/unit/install/test_drift.py::test_run_replay_threads_locked_primitive_subsets
unit
6 Detect manifest/lock agent subset drift in CI Governed by policy tests/unit/install/test_agent_subset.py::TestAgentSubsetModel::test_ci_baseline_detects_agent_subset_drift unit

How to test

  • Create a local package containing planner.agent.md, reviewer.agent.md, and writer.agent.md.
  • Run apm install <package> --agent planner --target copilot; observe only planner.agent.md under .github/agents/.
  • Re-run with --agent reviewer; observe both planner and reviewer, with sorted agents and agent_subset entries.
  • Run bare apm install --target copilot; observe the same two agents.
  • Run with --agent '*'; observe all three agents and no persisted subset.

PR checklist

Type of change

  • Bug fix
  • New feature
  • Documentation
  • Maintenance / refactor

Testing

  • Tested locally
  • All existing tests pass (host Git/symlink limitations documented above)
  • Added tests for new functionality

Spec conformance (OpenAPM v0.1)

  • Spec edit: docs/src/content/docs/specs/openapm-v0.1.md updated with req-mf-025 and Appendix C.
  • Manifest edit: docs/public/specs/manifests/openapm-v0.1.requirements.yml updated.
  • Test edit: a @pytest.mark.req("req-mf-025") test added under tests/spec_conformance/.
  • CONFORMANCE.{md,json} regenerated and committed.
  • N/A — this PR does change OpenAPM-observable behaviour.

Closes #2491

Copilot AI lite review requested due to automatic review settings August 22, 2026 12:40
@microsoft-github-policy-service

Copy link
Copy Markdown

wind127 please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.

@microsoft-github-policy-service agree [company="{your company}"]

Options:

  • (default - no company specified) I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.
@microsoft-github-policy-service agree
  • (when company given) I am making Submissions in the course of work for my employer (or my employer has intellectual property rights in my Submissions by contract or applicable law). I have permission from my employer to make Submissions and enter into this Agreement on behalf of my employer. By signing below, the defined term “You” includes me and my employer.
@microsoft-github-policy-service agree company="Microsoft"
Contributor License Agreement

Contribution License Agreement

This Contribution License Agreement (“Agreement”) is agreed to by the party signing below (“You”),
and conveys certain license rights to Microsoft Corporation and its affiliates (“Microsoft”) for Your
contributions to Microsoft open source projects. This Agreement is effective as of the latest signature
date below.

  1. Definitions.
    “Code” means the computer software code, whether in human-readable or machine-executable form,
    that is delivered by You to Microsoft under this Agreement.
    “Project” means any of the projects owned or managed by Microsoft and offered under a license
    approved by the Open Source Initiative (www.opensource.org).
    “Submit” is the act of uploading, submitting, transmitting, or distributing code or other content to any
    Project, including but not limited to communication on electronic mailing lists, source code control
    systems, and issue tracking systems that are managed by, or on behalf of, the Project for the purpose of
    discussing and improving that Project, but excluding communication that is conspicuously marked or
    otherwise designated in writing by You as “Not a Submission.”
    “Submission” means the Code and any other copyrightable material Submitted by You, including any
    associated comments and documentation.
  2. Your Submission. You must agree to the terms of this Agreement before making a Submission to any
    Project. This Agreement covers any and all Submissions that You, now or in the future (except as
    described in Section 4 below), Submit to any Project.
  3. Originality of Work. You represent that each of Your Submissions is entirely Your original work.
    Should You wish to Submit materials that are not Your original work, You may Submit them separately
    to the Project if You (a) retain all copyright and license information that was in the materials as You
    received them, (b) in the description accompanying Your Submission, include the phrase “Submission
    containing materials of a third party:” followed by the names of the third party and any licenses or other
    restrictions of which You are aware, and (c) follow any other instructions in the Project’s written
    guidelines concerning Submissions.
  4. Your Employer. References to “employer” in this Agreement include Your employer or anyone else
    for whom You are acting in making Your Submission, e.g. as a contractor, vendor, or agent. If Your
    Submission is made in the course of Your work for an employer or Your employer has intellectual
    property rights in Your Submission by contract or applicable law, You must secure permission from Your
    employer to make the Submission before signing this Agreement. In that case, the term “You” in this
    Agreement will refer to You and the employer collectively. If You change employers in the future and
    desire to Submit additional Submissions for the new employer, then You agree to sign a new Agreement
    and secure permission from the new employer before Submitting those Submissions.
  5. Licenses.
  • Copyright License. You grant Microsoft, and those who receive the Submission directly or
    indirectly from Microsoft, a perpetual, worldwide, non-exclusive, royalty-free, irrevocable license in the
    Submission to reproduce, prepare derivative works of, publicly display, publicly perform, and distribute
    the Submission and such derivative works, and to sublicense any or all of the foregoing rights to third
    parties.
  • Patent License. You grant Microsoft, and those who receive the Submission directly or
    indirectly from Microsoft, a perpetual, worldwide, non-exclusive, royalty-free, irrevocable license under
    Your patent claims that are necessarily infringed by the Submission or the combination of the
    Submission with the Project to which it was Submitted to make, have made, use, offer to sell, sell and
    import or otherwise dispose of the Submission alone or with the Project.
  • Other Rights Reserved. Each party reserves all rights not expressly granted in this Agreement.
    No additional licenses or rights whatsoever (including, without limitation, any implied licenses) are
    granted by implication, exhaustion, estoppel or otherwise.
  1. Representations and Warranties. You represent that You are legally entitled to grant the above
    licenses. You represent that each of Your Submissions is entirely Your original work (except as You may
    have disclosed under Section 3). You represent that You have secured permission from Your employer to
    make the Submission in cases where Your Submission is made in the course of Your work for Your
    employer or Your employer has intellectual property rights in Your Submission by contract or applicable
    law. If You are signing this Agreement on behalf of Your employer, You represent and warrant that You
    have the necessary authority to bind the listed employer to the obligations contained in this Agreement.
    You are not expected to provide support for Your Submission, unless You choose to do so. UNLESS
    REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, AND EXCEPT FOR THE WARRANTIES
    EXPRESSLY STATED IN SECTIONS 3, 4, AND 6, THE SUBMISSION PROVIDED UNDER THIS AGREEMENT IS
    PROVIDED WITHOUT WARRANTY OF ANY KIND, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTY OF
    NONINFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
  2. Notice to Microsoft. You agree to notify Microsoft in writing of any facts or circumstances of which
    You later become aware that would make Your representations in this Agreement inaccurate in any
    respect.
  3. Information about Submissions. You agree that contributions to Projects and information about
    contributions may be maintained indefinitely and disclosed publicly, including Your name and other
    information that You submit with Your Submission.
  4. Governing Law/Jurisdiction. This Agreement is governed by the laws of the State of Washington, and
    the parties consent to exclusive jurisdiction and venue in the federal courts sitting in King County,
    Washington, unless no federal subject matter jurisdiction exists, in which case the parties consent to
    exclusive jurisdiction and venue in the Superior Court of King County, Washington. The parties waive all
    defenses of lack of personal jurisdiction and forum non-conveniens.
  5. Entire Agreement/Assignment. This Agreement is the entire agreement between the parties, and
    supersedes any and all prior agreements, understandings or communications, written or oral, between
    the parties relating to the subject matter hereof. This Agreement may be assigned by Microsoft.

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

Adds per-dependency agent selection via manifest fields and repeatable --agent CLI options, with persistence through lockfiles, deployment, and audit replay.

Changes:

  • Adds validated agent subsets and wildcard reset semantics.
  • Threads selections through installation, locking, deployment, and policy checks.
  • Updates schemas, specifications, documentation, conformance artifacts, and tests.

Reviewed changes

Copilot reviewed 47 out of 47 changed files in this pull request and generated 7 comments.

Show a summary per file
File Review summary
tests/unit/test_audit_policy_command.py Critical (3 votes): Update the expected baseline count from 9 to 10.
tests/unit/policy/test_ci_checks.py Reviewed; no final comment.
tests/unit/install/test_drift.py Reviewed; no final comment.
tests/unit/install/test_agent_subset.py Reviewed; no final comment.
tests/unit/deps/test_lockfile_field_properties.py Reviewed; no final comment.
tests/unit/deps/test_lockfile_consumer_contract.py Reviewed; no final comment.
tests/spec_conformance/test_manifest_reqs.py Reviewed; no final comment.
tests/integration/test_architecture_intent_guards.py Reviewed; no final comment.
src/apm_cli/policy/ci_checks.py Reviewed; no final comment.
src/apm_cli/models/dependency/subsets.py Reviewed; no final comment.
src/apm_cli/models/dependency/registry_entry.py Reviewed; no final comment.
src/apm_cli/models/dependency/reference.py Reviewed; no final comment.
src/apm_cli/models/dependency/object_fields.py Reviewed; no final comment.
src/apm_cli/integration/agent_integrator.py Reviewed; no final comment.
src/apm_cli/install/template.py Moderate (2 votes each): Scope CLI subsets by dependency, and use exact flat-name validation rather than leaf matching.
src/apm_cli/install/services.py Reviewed; no final comment.
src/apm_cli/install/service.py Reviewed; no final comment.
src/apm_cli/install/request.py Reviewed; no final comment.
src/apm_cli/install/pipeline.py Reviewed; no final comment.
src/apm_cli/install/phases/lockfile.py Moderate (2 votes): Apply CLI subsets only to the selected dependency using dependency-keyed selection.
src/apm_cli/install/package_resolution.py Reviewed; no final comment.
src/apm_cli/install/entrypoint.py Reviewed; no final comment.
src/apm_cli/install/drift.py Reviewed; no final comment.
src/apm_cli/install/context.py Reviewed; no final comment.
src/apm_cli/deps/lockfile.py Reviewed; no final comment.
src/apm_cli/commands/install.py Reviewed; no final comment.
src/apm_cli/commands/_apm_yml_writer.py Moderate (2 votes): Normalize and validate entries through parse_agent_subset, preserving None for clearing.
packages/apm-guide/.apm/skills/apm-usage/governance.md Reviewed; no final comment.
packages/apm-guide/.apm/skills/apm-usage/dependencies.md Reviewed; no final comment.
packages/apm-guide/.apm/skills/apm-usage/commands.md Reviewed; no final comment.
docs/src/content/docs/specs/openapm-v0.1.md Reviewed; no final comment.
docs/src/content/docs/reference/manifest-schema.md Reviewed; no final comment.
docs/src/content/docs/reference/lockfile-spec.md Reviewed; no final comment.
docs/src/content/docs/reference/cli/install.md Reviewed; no final comment.
docs/src/content/docs/reference/baseline-checks.md Reviewed; no final comment.
docs/src/content/docs/integrations/ci-cd.md Reviewed; no final comment.
docs/src/content/docs/enterprise/policy-reference.md Reviewed; no final comment.
docs/src/content/docs/enterprise/enforce-in-ci.md Reviewed; no final comment.
docs/src/content/docs/enterprise/drift-detection.md Reviewed; no final comment.
docs/src/content/docs/concepts/the-three-promises.md Nit (3 votes): Correct the documented baseline check count and list to reflect ten checks.
docs/src/content/docs/concepts/lifecycle.md Reviewed; no final comment.
docs/public/specs/schemas/manifest-v0.1.schema.json Moderate (2 votes): Align the schema with parser constraints by rejecting whitespace-only and traversal-segment names.
docs/public/specs/schemas/lockfile-v0.1.schema.json Reviewed; no final comment.
docs/public/specs/manifests/openapm-v0.1.requirements.yml Reviewed; no final comment.
CONFORMANCE.md Reviewed; no final comment.
CONFORMANCE.json Reviewed; no final comment.
CHANGELOG.md Reviewed; no final comment.
Suppressed comments (10)

CHANGELOG.md:15

  • The repository's changelog entries use a trailing PR reference such as (#2435) and (closes #2482) in CHANGELOG.md:23-28, but this new entry ends only with (closes #2491). Append the current PR number while retaining the issue attribution so the entry follows the repository's per-PR format.
  replay. `--agent '*'` resets the dependency to all agents. (closes #2491)

docs/public/specs/schemas/lockfile-v0.1.schema.json:57

  • The lockfile contract describes agent_subset as flat agent names, but this schema accepts path-like values such as team/planner. A schema-valid lockfile can therefore contain a selection that manifest parsing rejects and replay silently deploys nothing. Apply the same no-separator item pattern used by the manifest agents field.
        "agent_subset": { "type": "array", "items": { "type": "string" } },

docs/src/content/docs/enterprise/policy-reference.md:411

  • The new agent-subset-consistency row is added here, but this baseline-check table still omits the existing deployment-ledger-owners check. The table is therefore incomplete and conflicts with the ten-check sequence documented elsewhere; add the ledger-owner row after ref-consistency.
| `agent-subset-consistency` | `agents:` selections in `apm.yml` match `agent_subset` in the lockfile |

src/apm_cli/commands/install.py:1038

  • The help text points users to apm.lock, the legacy filename, but this command persists the new selection in apm.lock.yaml (the filename used by the implementation and documentation). Use the current filename so users can find the persisted state.
    help="Install only named agent(s) from a package. Repeatable and persisted in apm.yml and apm.lock. Additive across installs; use --agent '*' to reset to all agents.",

src/apm_cli/commands/install.py:407

  • After this pin is set, the marketplace/direct-virtual branch serializes with dependency_reference_to_yaml_entry, whose output only includes the Git/path/ref/alias fields. A named --agent pin is therefore omitted from apm.yml for those dependencies, even though it reaches deployment and the lockfile; the next bare install deploys all agents and audit reports manifest/lock drift. Preserve dep_ref.agent_subset in that serializer.
            apply_cli_agent_pin(
                dep_ref,
                agent_subset,
                agent_subset_from_cli,
                current_deps,

src/apm_cli/commands/install.py:1575

  • When apm install --agent NAME is invoked without a positional package, the command skips _validate_and_add_packages_to_apm_yml, so no manifest entry is updated, but these context values still cause the lockfile builder to attach the CLI subset to dependency entries. This leaves apm.yml and apm.lock.yaml inconsistent; the wildcard form is worse because it deploys all agents while leaving the old pin persisted. Reject --agent without package arguments or persist the selection for the affected manifest entries instead of applying an ephemeral override.
                agent_subset=_agent_subset,
                agent_subset_from_cli=bool(agent_names),

src/apm_cli/deps/lockfile.py:500

  • Unlike manifest parsing, this new lockfile field is reconstructed with list(...) and no type or flat-name validation. A malformed lockfile value such as agent_subset: planner becomes character names, while team/planner is accepted and replay then silently deploys no matching agent. Validate the non-empty value with the same agent-subset parser (preserving an empty value as the lockfile's "all" sentinel) before constructing LockedDependency.
            agent_subset=list(data.get("agent_subset") or []),

src/apm_cli/install/package_resolution.py:398

  • normalize_and_merge_agent_subset only strips and deduplicates CLI values, so a value such as team/planner is not rejected. The later component check compares leaf names, so this can pass when planner exists, then persist an invalid agents path while AgentIntegrator's exact flat-name match deploys nothing. Validate CLI values with the canonical flat-name parser before assigning them.
        dep_ref.agent_subset = normalize_and_merge_agent_subset(
            cli_subset,
            current_deps,
            identity,
            dependency_reference_cls=dependency_reference_cls,

src/apm_cli/install/template.py:126

  • Materialization deliberately sets package_info=None when no targets exist (install/sources.py:471-477), but this new validation runs first and calls available_agent_names(m.package_info), which dereferences .install_path. A named --agent on a no-target install raises AttributeError instead of following the no-op path; move the existing m.package_info is None or not ctx.targets guard before this validation.
    src/apm_cli/models/dependency/reference.py:1919
  • When a selected agent is applied to a virtual shorthand such as owner/repo/path, this structured-entry branch omits self.virtual_path. Ordinary GitHub virtual shorthands do not take the GitLab/Artifactory direct_virtual_resolved path, so apm.yml is rewritten as the repository root and the next install loses the virtual-package boundary. Include the virtual path in this entry (or route it through the shared structured serializer).

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

"prerelease": { "type": "boolean" },
"path": { "type": "string" },
"alias": { "type": "string" },
"agents": { "type": "array", "minItems": 1, "items": { "type": "string", "pattern": "^[^/\\\\]+$" } },

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 9893528. The manifest and lockfile schemas now reject blank-only names, ./.., and path separators, with conformance coverage for each case.

Comment on lines 116 to 119
the CI surface used by `apm audit --ci`. It runs 8 baseline
checks: lockfile-exists, ref-consistency, deployed-files-present,
no-orphans, skill-subset-consistency, config-consistency,
no-orphans, agent-subset-consistency, skill-subset-consistency, config-consistency,
content-integrity, and includes-consent.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 9893528. The page now lists all ten checks, including deployment-ledger-owners, and the FAQ count is updated to ten.

Comment thread src/apm_cli/commands/_apm_yml_writer.py Outdated
Comment on lines +124 to +125
if field == "agents":
ref.agent_subset = sorted(set(subset)) if subset else None

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 9893528. Agent write-back now delegates to parse_agent_subset, so helper callers cannot persist invalid flat-name values.

Comment thread src/apm_cli/install/phases/lockfile.py Outdated
Comment on lines +374 to +378
for locked_dep in lockfile.dependencies.values():
merged = effective_deploy_agent_subset(
agent_subset_from_cli=self.ctx.agent_subset_from_cli,
cli_subset=self.ctx.agent_subset,
persisted_subset=locked_dep.agent_subset,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 9893528. CLI agent overrides are keyed to explicitly selected direct dependencies; lockfile reconciliation touches only those keys. Added a regression test proving transitive and unselected entries retain their own subsets.

Comment thread src/apm_cli/install/template.py Outdated
Comment on lines +122 to +126
if ctx.agent_subset_from_cli and ctx.agent_subset:
from apm_cli.install.outcome import require_requested_components
from apm_cli.integration.agent_integrator import AgentIntegrator

available_agents = AgentIntegrator.available_agent_names(m.package_info)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 9893528. InstallContext now resolves --agent targets to direct dependency keys. Integration applies and validates the CLI subset only for the matching dep_key; transitive dependencies use their own persisted subset. Added an end-to-end direct-planner/transitive-writer regression test.

Comment on lines +126 to +134
available_agents = AgentIntegrator.available_agent_names(m.package_info)
if not require_requested_components(
diagnostics,
option="--agent",
component="agent",
requested=ctx.agent_subset,
available=available_agents,
package=dep_key,
):

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 9893528. CLI values are normalized through parse_agent_subset, and agent availability uses exact matching (match_leaf=False), so team/planner is rejected instead of matching planner. Invalid CLI input leaves the manifest unchanged.

Comment thread tests/unit/test_audit_policy_command.py Outdated
Comment on lines 289 to 290
# Only the ten baseline checks, including deployment ownership.
assert data["summary"]["total"] == 9

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in 9893528. The assertion now expects all ten baseline checks, and the audit policy test suite passes.

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.

[FEATURE] Extend per-dependency subsetting to agents (parallel to skills:)

2 participants