Skip to content

fix(install): honor --skill subset on non-package skill-collection install (closes #1707)#1709

Merged
danielmeppiel merged 2 commits into
mainfrom
fix/1707-skill-subset-standalone-promotion
Jun 9, 2026
Merged

fix(install): honor --skill subset on non-package skill-collection install (closes #1707)#1709
danielmeppiel merged 2 commits into
mainfrom
fix/1707-skill-subset-standalone-promotion

Conversation

@danielmeppiel

Copy link
Copy Markdown
Collaborator

Plugin-manifest skill collections currently copy every manifest skill into .apm/skills and then promote the entire standalone set, so --skill selections are lost outside the SKILL_BUNDLE path. This threads the normalized skill subset into standalone promotion, accepts both leaf names and nested manifest paths, adds a regression test for plugin-manifest collections, and updates the CLI docs for plugin subset selection.

How-to-test:

  • uv run --extra dev pytest tests/unit/integration/test_skill_integrator_phase3w4.py::TestPromoteSubSkillsStandaloneDedup::test_plugin_manifest_subset_promotes_only_selected_nested_skill -q
  • uv run --extra dev pytest tests/ -x -q -k "skill or subset or promote or plugin or integrat"
  • uv run --extra dev ruff check src/ tests/ --quiet
  • uv run --extra dev ruff format --check src/ tests/ --quiet

Closes #1707

Thread the install skill subset through standalone sub-skill promotion so plugin-manifest skill collections install only the requested skills. Normalize subset path values to their leaf skill names for promotion filtering.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings June 9, 2026 13:50

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

Fixes apm install --skill ... subset installs for plugin-manifest skill collections that are not APM packages, ensuring the selected subset is honored during standalone sub-skill promotion (closing #1707).

Changes:

  • Thread skill_subset into the standalone sub-skill promotion path and normalize subset entries to support both leaf names and manifest paths.
  • Add a regression unit test covering plugin-manifest nested-skill selection.
  • Update CLI/reference docs to document subset selection for plugin manifests.
Show a summary per file
File Description
src/apm_cli/integration/skill_integrator.py Adds subset normalization and passes the resulting filter into standalone sub-skill promotion so plugin-manifest installs honor --skill.
tests/unit/integration/test_skill_integrator_phase3w4.py Adds a regression test validating only the selected plugin-manifest nested skill is promoted.
packages/apm-guide/.apm/skills/apm-usage/commands.md Updates the apm install flag reference to describe plugin-manifest subset selection via --skill.
docs/src/content/docs/reference/package-types.md Documents plugin collections’ ability to cherry-pick skills via --skill (leaf or manifest path).
docs/src/content/docs/reference/cli/install.md Updates --skill flag docs to include plugin-manifest collections and manifest-path examples.
docs/src/content/docs/getting-started/migration.md Notes that plugin-manifest collections accept either skill name or manifest path for --skill.

Copilot's findings

  • Files reviewed: 6/6 changed files
  • Comments generated: 1

return links_resolved

@staticmethod
def _skill_subset_name_filter(skill_subset) -> set[str] | None:
Add the missing type annotation for the helper introduced by the subset filtering fix. This folds the python-architect panel follow-up without changing runtime behavior.

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

Copy link
Copy Markdown
Collaborator Author

APM Review Panel: ship_now

--skill subset filtering for plugin-manifest skill collections ships with a type-annotated helper and a mutation-break regression test, closing a selective-install gap.

cc @danielmeppiel @sergio-sisternes-epam -- a fresh advisory pass is ready for your review.

Panel signals converge cleanly. The feature restores targeted skill installation from manifest-declared collections, the shepherd folded the only code follow-up, and the regression test plus mutation-break gate confirm the contract is load-bearing. Ruff is silent, Copilot raised no inline comments, and CI is green on the latest head.

Aligned with: portable_by_manifest: subset filtering operates on manifest-declared skills; pragmatic_as_npm: --skill gives users selective-install ergonomics for large plugin collections.

Panel summary

Persona B R N Takeaway
Python Architect 0 0 0 Type annotation follow-up folded; no architecture issues remain.
CLI Logging Expert 0 0 0 No CLI output or logging changes.
DevX UX Expert 0 0 0 --skill plugin manifest subset behavior and docs are coherent.
Supply Chain Security Expert 0 0 0 Filter tokens are only compared against discovered names, not used as paths.
OSS Growth Hacker 0 0 0 Selective install story is stronger for large plugin repos.
Doc Writer 0 0 0 Docs accurately describe SKILL_BUNDLE and plugin manifest subset selection.
Test Coverage Expert 0 0 0 Regression test covers the bug path; mutation-break gate passed.

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

Folded in this run

  • (panel) Add type annotation to _skill_subset_name_filter parameter -- resolved in 8f70f59.

Regression-trap evidence (mutation-break gate)

  • tests/unit/integration/test_skill_integrator_phase3w4.py::TestPromoteSubSkillsStandaloneDedup::test_plugin_manifest_subset_promotes_only_selected_nested_skill -- deleted name_filter=name_filter guard in standalone promotion; test FAILED as expected; guard restored.

Lint contract

uv run --extra dev ruff check src/ tests/ and uv run --extra dev ruff format --check src/ tests/ both silent.

CI

gh pr checks 1709 --repo microsoft/apm --watch reports 14 successful, 1 skipped, 0 pending, 0 failing (after 0 CI fix iteration(s)).

Mergeability status

Captured from gh pr view 1709 --json mergeable,mergeStateStatus,statusCheckRollup immediately after the last push of this run.

PR head SHA CEO stance iters folds defers Copilot rounds CI mergeable mergeStateStatus notes
#1709 8f70f59 ship_now 1 1 0 2 green MERGEABLE BLOCKED pending required review

Convergence

1 outer iteration(s); 2 Copilot round(s). Final panel verdict: ship_now.

Ready for maintainer review.


Full per-persona findings

No remaining findings after shepherd fold.

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

@danielmeppiel danielmeppiel merged commit efdfc1a into main Jun 9, 2026
15 checks passed
@danielmeppiel danielmeppiel deleted the fix/1707-skill-subset-standalone-promotion branch June 9, 2026 14:15
sergio-sisternes-epam pushed a commit that referenced this pull request Jun 9, 2026
Resolve conflict in skill_integrator.py from #1709 (honor --skill subset
on non-package skill-collection install). My refactor extracted skill
promotion into skill_deploy.py; main's #1709 edited the inline original.

Resolution: keep HEAD's thin-delegator structure; port #1709 semantics
into the relocated impl:
- Add _skill_subset_name_filter() normalization helper to skill_deploy.py
  (matches --skill by raw name, normalized path, or leaf name).
- Thread skill_subset -> name_filter through _promote_sub_skills_standalone
  (the #1707 fix: standalone/non-package-skill path now honors --skill).
- skill_orchestrate.py: pass skill_subset on both standalone promotion
  routes (MARKETPLACE_PLUGIN / no-root-SKILL.md packages).
- _integrate_skill_bundle uses the normalized helper.

Shadow gate green: ruff, ruff format, pylint R0801 10.00/10, auth-signals,
import smoke, 378 targeted tests pass. Files within 800-line guard
(skill_integrator.py 458, skill_deploy.py 789).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
sergio-sisternes-epam pushed a commit that referenced this pull request Jun 9, 2026
The #1709 port left two copies of the subset-normalization helper: a
module function in skill_deploy.py and an identical SkillIntegrator
staticmethod. CI's pylint R0801 guard (evaluated on the merge commit)
flagged the 15-line duplication. Make the staticmethod delegate to the
skill_deploy module function, matching the file's delegator pattern.

R0801 now exits 0; ruff/format clean; 378 targeted tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
sergio-sisternes-epam pushed a commit that referenced this pull request Jun 9, 2026
…e integrity)

Sync with main through v0.19.0 (#1715, #1714, #1718, #1719, #1717).

Conflicts resolved:
- CHANGELOG.md: main cut the v0.19.0 release, moving prior Unreleased
  entries into a dated section. Took main's restructure; relocated the
  #1681 "Tightened Stage 2 code-complexity thresholds" entry to the new
  ## [Unreleased] section (released sections stay immutable per Keep a
  Changelog). Took main's #1702/#1710 close-ref for the lockfile entry.
- src/apm_cli/install/services.py: #1718 added per-file skill-bundle
  integrity recording inline at a site my refactor had extracted into
  _log_skill_result. Kept the new _skill_bundle_file_entries helper in
  services.py (sibling of _deployed_path_entry); dropped main's duplicate
  inline _log_hook_display_payloads (already relocated to
  services_integrate.py and re-exported in my #1700 port); accepted the
  _log_skill_result delegator at the call site.
- src/apm_cli/install/services_integrate.py: ported #1718's
  deployed.extend(_skill_bundle_file_entries(tp, ...)) into
  _log_skill_result's deployed-path loop (deployed aliases
  result["deployed_files"]), with a lazy import of the helper.

Shadow gate: no markers, all src <=800 lines, ruff check + format clean,
pylint R0801 EXIT=0, auth-signals clean; 11144 tests pass across the
install/integration suites plus the #1718, #1700, and #1709 targeted sets.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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] --skill subset selection is ignored for a non-package skill collection repo (all skills get installed)

2 participants