Add APM manifest as alternate install path (additive to plugin)#37
Open
AlexDeMichieli wants to merge 5 commits into
Open
Add APM manifest as alternate install path (additive to plugin)#37AlexDeMichieli wants to merge 5 commits into
AlexDeMichieli wants to merge 5 commits into
Conversation
- Add apm.yml declaring actions-migrator v1.2.0 as an APM package (targets: copilot). Schema mirrors github/expert-services-agent-skill PR #3. - Add README 'Option C — Install via APM' section with a 'Why APM complements the plugin' comparison table explaining that plugin and APM install solve different problems and are additive (control plane vs lockfile provenance / content scan / SBOM). - Ignore APM-generated output (apm_modules/, build/, .agents/); the committed source of truth remains plugin/ and agents/. apm.lock.yaml is intentionally omitted from this PR — it should be generated by running 'apm install' in a follow-up commit once a maintainer has the APM CLI available. No behavior change to the plugin runtime. Additive only.
Contributor
There was a problem hiding this comment.
Pull request overview
Adds an experimental APM installation path alongside existing Copilot plugin options.
Changes:
- Adds an APM package manifest.
- Documents APM installation and governance benefits.
- Ignores APM-generated output.
Show a summary per file
| File | Description |
|---|---|
apm.yml |
Defines APM package metadata and target. |
README.md |
Documents APM installation and comparison. |
.gitignore |
Excludes generated APM artifacts. |
Review details
Tip
Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Files reviewed: 2/3 changed files
- Comments generated: 4
- Review effort level: Medium
| - reusable-workflows | ||
| targets: | ||
| - copilot | ||
| includes: auto |
| ```yaml | ||
| dependencies: | ||
| apm: | ||
| - github/actions-migrations-via-copilot#v1.2.0 |
| | --- | --- | --- | | ||
| | Control plane | GitHub Copilot admin UI + `.github-private` settings | `apm-policy.yml` in a policy repo (tighten-only inheritance) | | ||
| | Version resolution | Whatever `main` (or the marketplace pointer) resolves to at runtime | Semver tag pinned in `apm.yml`, hash pinned in `apm.lock.yaml` | | ||
| | Content integrity | — | Hidden-Unicode / prompt-injection scan on every install | |
| | Tampering detection | — | `apm audit --ci` diffs on-disk primitives against lockfile hashes | | ||
| | Audit trail | Enterprise audit log | Lockfile diff on every PR; `apm lock export --format cyclonedx\|spdx` (SBOM) | | ||
| | Air-gapped / restricted network | Depends on marketplace reachability | Files land in the consumer repo — no runtime fetch | | ||
| | Non-Copilot harnesses (Claude, Cursor, Codex, ...) | — | Same manifest deploys to every supported harness | |
Rationale lives in the PR description; README stays focused on install instructions.
APM's default includes: auto looks for primitives at .apm/ or root conventional paths (agents/, skills/). Our primitives live under plugin/agents/ and plugin/skills/ — an explicit includes list points APM there without moving files or introducing duplication. Per microsoft/apm docs (apm pack reference), an explicit includes list is exhaustive and overrides implicit discovery. Confirmed with @danielmeppiel that plugin-native paths are supported.
Contributor
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (1)
README.md:116
- This pinned example resolves the existing
v1.2.0tag, whose commit predates and does not contain the newapm.yml. As a result, consumers copying this command cannot use the manifest or itsincludesdeclaration, so the documented APM install path is not reproducible from that release. Point this at the first release tag that actually contains the manifest (the repository already also hasv1.3.0, which likewise predates it), or clearly use a temporary ref until that release is cut.
- github/actions-migrations-via-copilot#v1.2.0
- Files reviewed: 2/3 changed files
- Comments generated: 0 new
- Review effort level: Medium
This reverts commit a90b9eb.
APM's install-time validator requires the target path to be a valid package shape (.apm/, top-level skills/, curated aggregator, plugin.json, or SKILL.md). Our root has apm.yml only, so pointing consumers at the whole repo fails validation. Pointing at /plugin (the subdirectory containing plugin.json) resolves as APM's 'Plugin collection' package type — APM dissects plugin.json and maps the declared agents/ and skills/ directories into the consumer's runtime paths. No producer refactor needed. Verified end-to-end: apm install materialized 9 agents + 11 skills, wrote apm.lock.yaml with resolved commit + per-file hashes.
Contributor
There was a problem hiding this comment.
Review details
Comments suppressed due to low confidence (1)
apm.yml:25
- This manifest is not installable as the repository-root package described in the PR test. APM only classifies an
apm.ymlpackage when it has a.apm/source tree or non-empty dependencies; this repo has neither, and the actualplugin.jsonis underplugin/. As a result,github/actions-migrations-via-copilot#<ref>is classified as invalid, while the documented/plugininstall bypasses this new manifest entirely. Move/expose the plugin primitives in an APM-recognized root layout (or otherwise make the root package resolve toplugin/) and verify the root-reference test.
includes: auto
- Files reviewed: 2/3 changed files
- Comments generated: 1
- Review effort level: Medium
|
|
||
| ```bash | ||
| curl -sSL https://aka.ms/apm-unix | sh # macOS / Linux | ||
| # irm https://aka.ms/apm-windows | iex # Windows |
AlexDeMichieli
marked this pull request as ready for review
July 21, 2026 01:33
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What is APM?
APM (Agent Package Manager) is an open-source dependency manager for AI agent primitives — skills, prompts, instructions, hooks, agents, MCP servers. Think
npm installbut for agent configuration. Oneapm.ymldescribes everything an agent needs;apm installreproduces it deterministically on any machine, with content hashes pinned inapm.lock.yaml.How it complements the plugin
Plugin install and APM install are additive, not competing — they operate at different layers:
.github-private/.github/copilot/settings.json. Frictionless, GitHub-native, zero developer action.The 4-layer defense-in-depth model
APM + hooks (from #33) together give you distinct checks at four moments in the agent lifecycle:
apm audit --cipreToolUse/postToolUsepolicyPlugin marketplace install gives you layer 4 only (once #33 lands). APM adds layers 1–3. That's the "regulated customers" pitch: defense in depth across the whole lifecycle, not just runtime.
Runtime hooks (PR #33) remain the enforcement point — APM never gates tool calls at execution. It stops bad code from reaching the agent; hooks stop the agent from doing bad things with the code it has.
When APM adds value
apm lock export --format cyclonedxgives auditors a standard inventory of every prompt/skill an agent can see.apm-policy.ymlrestricts what other teams in their org can install on top of it.apm.ymlalso configures Claude, Cursor, Codex, and others. Nothing else on the market does this today.mainmoves; a pinned tag + content hash doesn't. Consumers don't get silently upgraded when we push tomain.Additional capabilities worth noting
apm outdated— surfaces which pinned deps have newer versions available. Explicit updates, not automatic drift.apm install .../plugin --skill jenkins-migration --skill actionlintcherry-picks; reduces attack surface.apm-policy.yml) — org-level rules (require_pinned_version,allowed_sources,require_explicit_includes) with tighten-only inheritance from enterprise → org → repo. Wired intoapm audit --ci, so PRs that violate policy fail before merge.How to test
The APM CLI is client-side, so testing is a one-liner in any scratch repo. Verified end-to-end against
feat/apm-manifestat commit33d7d80:Note the
/pluginsuffix on the dependency spec — that's a virtual path pointing at the subdirectory whereplugin.jsonlives. APM recognizes this as a Plugin collection package type (APM docs) and dissectsplugin.jsonto install the agents and skills. Zero producer refactor required.Once merged and a tag (e.g.
v1.3.0) is cut, the dependency line becomesgithub/actions-migrations-via-copilot/plugin#v1.3.0.Enforcement demos (verified locally)
Drift detection catches tampering. Modified a materialized skill file,
apm audit --cifailed with:Wire this into a
.github/workflows/apm-audit.ymland tampered PRs never merge.SBOM export works out of the box:
Produces an industry-standard bill of materials with the resolved commit SHA baked into the purl. Zero effort for procurement/compliance.
Scope
apm.yml(new, minimal) — declaresactions-migrator@1.2.0,targets: copilot. APM ignores this at install time (usesplugin/plugin.jsonvia virtual path) but kept for futuremarketplace:block authoring.README.md— new Option C — Install via APM subsection alongside existing Options A/B, documents the/pluginvirtual-path syntax..gitignore— append APM-generated paths (apm_modules/,build/,.agents/).No behavior change to the plugin runtime. Additive only. Zero file overlap with #33.
Deferred to follow-ups
apm.lock.yaml(needsapm installfrom a maintainer).github/workflows/apm-audit.ymlforapm audit --cion every PRdocs/enterprise/apm-policy-example.ymlRefs