You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
APM today treats the contents of a skill bundle (.apm/skills/<name>/) as opaque local content: bulk-copied during install, hashed at the directory level in apm.lock.yaml, with no notion of one skill referencing another primitive (skill, agent, instructions). This leaks across several surfaces:
Implicit cross-primitive references. A skill's SKILL.md or assets can reference any agent/skill in the repo via prose. There is no declared dependency edge, so the relationship cannot be validated, audited, or migrated.
No policy enforcement of dependency closure.apm-policy.yml cannot express "a skill's primitives must come from its declared dep closure" because skills don't have a dependency closure today.
Plugin export semantics undefined for sub-bundle deps.apm pack --format plugin flattens the dep graph at the project level. Per-bundle dep graphs (e.g. this skill needs that agent) are not modeled.
Goal (direction of travel)
Skills and agents become first-class APM packages addressable via local-path deps within their parent repo. A primitive that consumes another primitive declares it in its own apm.yml. The resolver walks intra-repo manifests. The lockfile enriches with per-bundle deps + per-asset hashes. An apm-policy.yml check makes the dependency closure load-bearing. apm pack --format plugin continues to flatten the resolved graph for runtime distribution.
This dissolves the per-asset-hash gap (each bundle's apm.yml is the natural unit to enrich the lockfile against) and makes cross-primitive references explicit, validatable, and migratable.
Conceptual modelling question to settle first
Before designing implementation, decide which mental model apm-review-panel (and similar multi-persona skills) should adopt:
Option A: skill-with-transitive-skill-dep
apm-review-panel/apm.yml declares local-path deps to the agent persona files it orchestrates. Each agent becomes a tiny package (folder with apm.yml + agent.md).
Pros: Granular, composable; each persona is independently versionable; matches the mental model of "this skill orchestrates these specific personas."
Cons: Requires promoting every loose .agent.md to a folder; many tiny apm.yml files; agents lose their "loose file under agents/" affordance.
Option B: plugin-bundle
The whole orchestration unit (review-panel skill + its 7 personas + verdict template) becomes a plugin packed via apm pack --format plugin. Cross-references inside the bundle are intra-bundle, no dep declaration needed.
Pros: Matches industry convention (one shippable artifact); fewer manifests; apm pack --format plugin already exists as the export path.
Cons: Personas can't be reused independently across skills; encourages duplication when two skills want the same persona; runs counter to PROSE "Favor small, chainable primitives over monolithic frameworks".
Option C: hybrid
Personas live as standalone primitives (Option A's leaf packages). Skills declare them as deps. apm pack --format plugin is the export path that flattens the resolved graph for runtime distribution. Same outcome at runtime as Option B, but source layout preserves composability.
Pros: Composable source, monolithic ship artifact; aligns with how npm + bundlers work.
Cons: Most engineering work; requires both the manifest plumbing AND the plugin flattener to understand sub-bundle deps.
Recommendation: Option C. It's the only model that both (i) makes cross-references declarable and enforceable at source, and (ii) preserves the proven plugin distribution channel. It also generalizes — third-party APM packages publishing reusable personas would slot in naturally.
A decision-record-style brainstorm via superpowers:brainstorming is warranted before committing.
Concrete required changes (assuming Option C)
1. Bundle authoring convention
Add apm.yml to .apm/skills/<name>/ for any skill that depends on other primitives.
Promote .apm/agents/<name>.agent.md to .apm/agents/<name>/{agent.md, apm.yml} (or extend the package marker set to allow a bare .agent.md; decide in Option A vs B/C debate).
2. Resolver enhancement
During the local-content phase (src/apm_cli/install/phases/local_content.py), scan .apm/skills/*/apm.yml and .apm/agents/*/apm.yml; resolve their deps as transitive locals before the bulk copy.
Validate no cycles; respect existing local-path dep semantics (source: local, no resolved_commit).
3. Lockfile enrichment
Replace the single local_deployed_files: [.github/skills/apm-review-panel] line with per-bundle entries that enumerate constituent files + hashes.
Update apm.lock.yaml schema (versioned bump if needed).
Update integrity checks in src/apm_cli/policy/ci_checks.py (_check_content_integrity) to walk the per-bundle file list.
4. Policy check
Add apm-policy.yml rule (audit-only initially, install-blocking later): "a skill's prose may not reference a primitive outside its declared dependency closure." Implement as a content scan against the resolved dep graph.
Define a stable "primitive reference" syntax (e.g. apm:agent/python-architect) so the check has something concrete to scan for, rather than fuzzy path-matching.
5. Plugin export verification
Confirm apm pack --format plugin (src/apm_cli/bundle/plugin_exporter.py) flattens sub-bundle deps into the platform output. If lockfile enrichment (src/apm_cli/bundle/lockfile_enrichment.py) drives plugin output correctly, this should fall out for free; verify with a fixture covering nested local deps.
6. Migration of microsoft/apm itself
This repo is the canonical dogfooding site. After (1)-(5) land:
Add apm.yml to .apm/skills/apm-review-panel/ declaring local deps on its 7 personas.
Decide skill vs plugin packaging for review-panel (likely skill with transitive deps, since personas are reused across apm-strategy, apm-review-panel, etc.).
Restore the explicit cross-reference in .apm/skills/apm-review-panel/assets/verdict-template.md once the dep is declared and scannable.
Update apm-policy.yml to enforce the new closure rule on this repo.
7. Documentation
Update docs/src/content/docs/guides/dependencies.md with the intra-repo local-dep pattern.
Update docs/src/content/docs/introduction/anatomy-of-an-apm-package.md with the skill-as-package and agent-as-package conventions.
Update packages/apm-guide/.apm/skills/apm-usage/package-authoring.md per doc-sync rule.
Sequencing
Brainstorm + decision record for Option A vs B vs C (superpowers:brainstorming).
Schema spike: design lockfile v2 enrichment + manifest format for nested bundles.
Resolver implementation: phases 1-3 above.
Audit/policy integration: phase 4.
Self-host migration: phase 6 (this repo).
Docs: phase 7.
Each lane is review-panel-worthy on its own. Phase 1 (brainstorm/decision) gates the rest.
Acceptance criteria
A skill's SKILL.md or any asset can reference another primitive only if the primitive appears in its apm.yml declared dep closure (audit check passes).
Edits to any file inside a skill bundle change the corresponding lockfile hash; CI integrity check (apm audit --ci) catches bundle drift at file granularity.
microsoft/apm itself is migrated: apm-review-panel declares its persona deps; apm-policy.yml enforces the closure check; CI is green.
apm pack --format plugin of a project containing nested-dep skills produces a runtime layout identical to today's flattened output (no behavioral regression for existing consumers).
Conceptual anchors: PROSE "Favor small, chainable primitives over monolithic frameworks"; Agent Skills "store [resources] in assets/ and reference them from SKILL.md so they only load when needed".
Problem
APM today treats the contents of a skill bundle (
.apm/skills/<name>/) as opaque local content: bulk-copied during install, hashed at the directory level inapm.lock.yaml, with no notion of one skill referencing another primitive (skill, agent, instructions). This leaks across several surfaces:SKILL.mdor assets can reference any agent/skill in the repo via prose. There is no declared dependency edge, so the relationship cannot be validated, audited, or migrated..apm/skills/<name>/assets/do not changeapm.lock.yamlbecause only the bundle root path is recorded underlocal_deployed_files. Surfaced concretely on harden(apm-review-panel): one-comment discipline + Hybrid E auth routing + apm-primitives-architect persona #882 bycopilot-pull-request-reviewer(comment) — the verdict-template asset edit was invisible to the lockfile.apm-policy.ymlcannot express "a skill's primitives must come from its declared dep closure" because skills don't have a dependency closure today.apm pack --format pluginflattens the dep graph at the project level. Per-bundle dep graphs (e.g. this skill needs that agent) are not modeled.Goal (direction of travel)
This dissolves the per-asset-hash gap (each bundle's
apm.ymlis the natural unit to enrich the lockfile against) and makes cross-primitive references explicit, validatable, and migratable.Conceptual modelling question to settle first
Before designing implementation, decide which mental model
apm-review-panel(and similar multi-persona skills) should adopt:Option A: skill-with-transitive-skill-dep
apm-review-panel/apm.ymldeclares local-path deps to the agent persona files it orchestrates. Each agent becomes a tiny package (folder withapm.yml+agent.md)..agent.mdto a folder; many tinyapm.ymlfiles; agents lose their "loose file underagents/" affordance.Option B: plugin-bundle
The whole orchestration unit (review-panel skill + its 7 personas + verdict template) becomes a plugin packed via
apm pack --format plugin. Cross-references inside the bundle are intra-bundle, no dep declaration needed.apm pack --format pluginalready exists as the export path.Option C: hybrid
Personas live as standalone primitives (Option A's leaf packages). Skills declare them as deps.
apm pack --format pluginis the export path that flattens the resolved graph for runtime distribution. Same outcome at runtime as Option B, but source layout preserves composability.Recommendation: Option C. It's the only model that both (i) makes cross-references declarable and enforceable at source, and (ii) preserves the proven plugin distribution channel. It also generalizes — third-party APM packages publishing reusable personas would slot in naturally.
A decision-record-style brainstorm via
superpowers:brainstormingis warranted before committing.Concrete required changes (assuming Option C)
1. Bundle authoring convention
apm.ymlto.apm/skills/<name>/for any skill that depends on other primitives..apm/agents/<name>.agent.mdto.apm/agents/<name>/{agent.md, apm.yml}(or extend the package marker set to allow a bare.agent.md; decide in Option A vs B/C debate).2. Resolver enhancement
src/apm_cli/install/phases/local_content.py), scan.apm/skills/*/apm.ymland.apm/agents/*/apm.yml; resolve their deps as transitive locals before the bulk copy.source: local, noresolved_commit).3. Lockfile enrichment
local_deployed_files: [.github/skills/apm-review-panel]line with per-bundle entries that enumerate constituent files + hashes.apm.lock.yamlschema (versioned bump if needed).src/apm_cli/policy/ci_checks.py(_check_content_integrity) to walk the per-bundle file list.4. Policy check
apm-policy.ymlrule (audit-only initially, install-blocking later): "a skill's prose may not reference a primitive outside its declared dependency closure." Implement as a content scan against the resolved dep graph.apm:agent/python-architect) so the check has something concrete to scan for, rather than fuzzy path-matching.5. Plugin export verification
apm pack --format plugin(src/apm_cli/bundle/plugin_exporter.py) flattens sub-bundle deps into the platform output. If lockfile enrichment (src/apm_cli/bundle/lockfile_enrichment.py) drives plugin output correctly, this should fall out for free; verify with a fixture covering nested local deps.6. Migration of
microsoft/apmitselfapm.ymlto.apm/skills/apm-review-panel/declaring local deps on its 7 personas.apm-strategy,apm-review-panel, etc.)..apm/skills/apm-review-panel/assets/verdict-template.mdonce the dep is declared and scannable.apm-policy.ymlto enforce the new closure rule on this repo.7. Documentation
docs/src/content/docs/guides/dependencies.mdwith the intra-repo local-dep pattern.docs/src/content/docs/introduction/anatomy-of-an-apm-package.mdwith the skill-as-package and agent-as-package conventions.packages/apm-guide/.apm/skills/apm-usage/package-authoring.mdperdoc-syncrule.Sequencing
superpowers:brainstorming).Each lane is review-panel-worthy on its own. Phase 1 (brainstorm/decision) gates the rest.
Acceptance criteria
SKILL.mdor any asset can reference another primitive only if the primitive appears in itsapm.ymldeclared dep closure (audit check passes).apm audit --ci) catches bundle drift at file granularity.microsoft/apmitself is migrated:apm-review-paneldeclares its persona deps;apm-policy.ymlenforces the closure check; CI is green.apm pack --format pluginof a project containing nested-dep skills produces a runtime layout identical to today's flattened output (no behavioral regression for existing consumers).Related
assets/and reference them fromSKILL.mdso they only load when needed".