Skip to content

chore: dogfood APM by migrating primitives from .github/ to .apm/#823

Merged
danielmeppiel merged 3 commits intomainfrom
chore/dogfood-apm-primitives
Apr 21, 2026
Merged

chore: dogfood APM by migrating primitives from .github/ to .apm/#823
danielmeppiel merged 3 commits intomainfrom
chore/dogfood-apm-primitives

Conversation

@danielmeppiel
Copy link
Copy Markdown
Collaborator

Motivation

Eat our own dogfood: microsoft/apm now uses APM to manage its own AI primitives. This PR:

  1. Validates fix: deploy root project .apm/ primitives without a sub-package stub #715 by exercising apm install --target copilot end-to-end on the real repo with 26 primitives.
  2. Unblocks a future gh-aw automation PR that will declare microsoft/apm as a dependency in CI workflows so apm-action can pack/restore the primitives bundle (see dogfood-layout-spec.md sections 3-4 for the consumer-side install path).
  3. Establishes the source-of-truth model: .apm/<type>/ is authored; .github/<type>/ is the deployed/regenerated artifact that stays committed for raw Copilot CLI users without APM and for PR review visibility.

Migration matrix

Type Count Source (authored) Target (deployed)
Skills 8 .apm/skills/<name>/SKILL.md .github/skills/<name>/SKILL.md
Agents 10 .apm/agents/<name>.agent.md .github/agents/<name>.agent.md
Instructions 8 .apm/instructions/<name>.instructions.md .github/instructions/<name>.instructions.md

Note on the 8th instruction: .apm/instructions/python.md was previously dead content (the integrator globs *.instructions.md only — instruction_integrator.py:34-42). It is renamed to python.instructions.md so it now deploys properly.

Deleted as legacy (pre-dated the skill/agent primitive model, no source/test/workflow references):

  • .github/prompts/*.prompt.md (7 files)
  • .github/chatmodes/oss-architect.chatmode.md (1 file)

Pack verification approach

apm pack from microsoft/apm's own root is a no-op today (pack_bundle only walks dependency deployed_files, not lockfile.local_deployed_files). That is fine for the gh-aw flow: gh-aw declares microsoft/apm as a dependency in a fresh CI workspace, runs apm install (which routes microsoft/apm through FreshDependencySource -> integrators -> .github/<type>/), then runs apm pack — at which point the deployed files ARE in the dependency's deployed_files and ARE bundled. See bundle/packer.py:122-135 and dogfood-layout-spec.md section 3.

Byte-equality regression evidence

After apm install --target copilot --verbose against the migrated .apm/:

$ diff -ruN .dogfood-baseline/skills        .github/skills        && echo "[+] skills OK"
[+] skills OK

$ diff -ruN .dogfood-baseline/agents        .github/agents        && echo "[+] agents OK"
[+] agents OK

$ diff -ruN .dogfood-baseline/instructions  .github/instructions
diff -ruN .dogfood-baseline/instructions/python.instructions.md .github/instructions/python.instructions.md
--- .dogfood-baseline/instructions/python.instructions.md   1970-01-01 01:00:00
+++ .github/instructions/python.instructions.md             2026-04-21 23:45:24
@@ -0,0 +1,8 @@
+---
+description: Python development guidelines
+applyTo: '**/*.py'
+---
+
+Use type hints for all function parameters and return values.
+Follow PEP 8 style guidelines.
+Write comprehensive docstrings.

All 7 pre-existing .github/instructions/*.instructions.md files round-trip byte-identical. The single delta is the newly-resurrected python.instructions.md (renamed from the dead python.md), which is the documented spec outcome (section 7).

Lockfile shape

$ grep -E "^local_deployed_files:|^dependencies:" apm.lock.yaml
dependencies: []
local_deployed_files:

26 entries under local_deployed_files (8 agents are wrong, sorry: 10 agents + 8 instructions + 8 skills = 26). No synthetic dependency. SHA-256 hashes recorded under local_deployed_file_hashes for collision/staleness detection.

Test evidence

uv run pytest tests/unit tests/test_console.py: 4770 passed, 1 deselected. The single deselection (test_user_scope_skips_workspace_runtimes) is a pre-existing failure on main (verified by re-running with my branch stashed) that is unrelated to this migration — it asserts MCP scope filtering behavior. Out of scope for this PR.

Out of scope (NOT in this PR)

  • .github/copilot-instructions.md migration — tracked separately by apm compile should emit .github/copilot-instructions.md (dogfood gap) #792.
  • .apm/AGENTS.md, .github/AGENTS.md, .github/CODEOWNERS, .github/ISSUE_TEMPLATE/, .github/aw/, .github/pull_request_template.md, .github/release.yml, .github/workflows/ — repo infrastructure, not APM-managed primitives.
  • Extending pack_bundle to walk lockfile.local_deployed_files for self-publishable repos. The gh-aw consumer flow does not need it (see "Pack verification" above). File a follow-up if a future use case requires apm pack from microsoft/apm's own root.
  • Fixing pre-existing non-ASCII characters in some migrated .instructions.md files (em dashes, en dashes, curly quotes). Pre-existing per spec section 7; out of scope per repo code-change rules.

Note on #792's "gitignore" suggestion

#792 floats the idea of gitignoring the deployed .github/<type>/ artifacts. This PR explicitly does not adopt that fork. The .github/<type>/ deployed/compiled output should always remain committed because:

  1. Raw Copilot CLI users without APM installed still need primitive discovery — Copilot reads from .github/skills/, .github/agents/, .github/instructions/ directly. Gitignoring breaks the contributor-onboarding zero-tools path.
  2. PR reviewers need to see deployed output in the diff to catch link-resolver rewrites, target-format drift, and integrator-introduced bugs. Hiding the artifact hides regressions.
  3. CI staleness guard is the correct enforcement mechanism, not gitignore. A simple workflow that runs apm install --target copilot and asserts no diff catches drift without compromising reviewability.

I'll restate this on #792 as a comment.

Related issues

Reviewer checklist

  • Confirm apm install --target copilot runs cleanly from a fresh checkout
  • Confirm .github/<type>/ is byte-identical to pre-migration content (modulo the documented python.instructions.md resurrection)
  • Confirm apm.lock.yaml local_deployed_files shape
  • Spot-check one skill, one agent, one instruction file content survived intact

Move skills (8), agents (10), and instructions (7) from .github/ to .apm/
as the source of truth, and regenerate identical .github/<type>/ artifacts
via 'apm install --target copilot'. The deployed .github/<type>/ tree
remains committed so raw Copilot CLI users without APM continue to
discover primitives natively, and so PR reviewers see the deployed
output.

Also rename the previously-dead .apm/instructions/python.md to
python.instructions.md so the integrator (which globs *.instructions.md)
deploys it. Add a minimal root apm.yml so 'apm install' integrates root
primitives and apm-action can consume microsoft/apm as a dependency.

Delete legacy .github/prompts/ (7 files) and .github/chatmodes/ (1 file)
that pre-dated the skill/agent primitive model. No source code,
workflow, test, or doc page references the specific files.

Validates #715 self-install flow. Stepping stone toward #792 (which
this PR explicitly does NOT close: copilot-instructions.md is out of
scope and the always-committed deployment artifact stance is preserved).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

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 dogfoods APM in microsoft/apm by migrating the repo's own AI primitives into .apm/ as the authored source of truth, while keeping .github/{skills,agents,instructions}/ as committed deployed artifacts regenerated by apm install --target copilot.

Changes:

  • Add root apm.yml and apm.lock.yaml to track locally deployed primitives via local_deployed_files (+ hashes).
  • Introduce authored primitives under .apm/ (agents, skills, instructions) and add the newly-deployed .github/instructions/python.instructions.md.
  • Remove legacy .github/prompts/*.prompt.md and .github/chatmodes/oss-architect.chatmode.md, and document the migration in CHANGELOG.md.
Show a summary per file
File Description
apm.yml Adds a root manifest to make the repo an APM project with no external deps.
apm.lock.yaml Records locally deployed .github/{agents,instructions,skills} artifacts + hashes for drift detection.
CHANGELOG.md Adds an Unreleased entry describing the dogfood migration and legacy deletions.
.github/instructions/python.instructions.md Adds the resurrected Python Copilot instructions file in deployed form.
.github/prompts/*.prompt.md Removes legacy prompt files no longer used by the repo's primitive model.
.github/chatmodes/oss-architect.chatmode.md Removes a legacy chatmode artifact.
.apm/agents/*.agent.md Adds authored agent primitives that deploy into .github/agents/.
.apm/skills/**/SKILL.md Adds authored skills that deploy into .github/skills/.
.apm/instructions/*.instructions.md Adds authored instructions that deploy into .github/instructions/.

Copilot's findings

  • Files reviewed: 37/38 changed files
  • Comments generated: 1

Comment thread CHANGELOG.md Outdated
Comment on lines +11 to +17
### Changed

- Dogfood APM: moved repository's own AI primitives to `.apm/` as the source of truth (8 skills, 10 agents, 8 instructions). The deployed `.github/{skills,agents,instructions}/` artifacts are now regenerated by `apm install --target copilot` and remain committed for raw Copilot CLI users without APM.

### Removed

- Legacy `.github/prompts/` (7 files) and `.github/chatmodes/` (1 file) that pre-dated the skill/agent primitive model. Not referenced by any source code, workflow, or test.
Copy link

Copilot AI Apr 21, 2026

Choose a reason for hiding this comment

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

CHANGELOG entry does not follow the repo's Keep a Changelog rules: entries should be one line per PR and end with a PR reference like "(#NNN)". These bullets are multi-sentence and missing the required PR number suffix; please reformat accordingly (and keep code references in backticks).

Copilot generated this review using guidance from repository custom instructions.
…tion

Address Copilot review feedback on PR #823: each entry must be one line
per PR ending with (#NNN) and use backticks for code references, per
.github/instructions/changelog.instructions.md.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@danielmeppiel
Copy link
Copy Markdown
Collaborator Author

Addressed in 5ad9d89 — reformatted both entries to one line per PR with the (#823) suffix and backticked code refs, per .github/instructions/changelog.instructions.md. Thanks @copilot-pull-request-reviewer for catching this.

@danielmeppiel danielmeppiel merged commit 4f345ea into main Apr 21, 2026
9 checks passed
@danielmeppiel danielmeppiel deleted the chore/dogfood-apm-primitives branch April 21, 2026 22:09
danielmeppiel added a commit that referenced this pull request Apr 21, 2026
Automates the apm-review-panel skill against PRs labelled
`panel-review`. Pulls panel skill + 7 persona agents from
4f345ea (PR #823 dogfood) via gh-aw dependencies:.
Posts one synthesized verdict comment via safe-outputs.add-comment.

Trigger uses pull_request (not pull_request_target -- gh-aw blocks
the latter on public repos). Default fork policy restricts to
same-repo PRs; cost-gated by the `panel-review` label.

Compiled with gh aw v0.68 in strict mode.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
danielmeppiel added a commit that referenced this pull request Apr 21, 2026
* feat(workflows): add pr-review-panel gh-aw workflow

Automates the apm-review-panel skill against PRs labelled
`panel-review`. Pulls panel skill + 7 persona agents from
4f345ea (PR #823 dogfood) via gh-aw dependencies:.
Posts one synthesized verdict comment via safe-outputs.add-comment.

Trigger uses pull_request (not pull_request_target -- gh-aw blocks
the latter on public repos). Default fork policy restricts to
same-repo PRs; cost-gated by the `panel-review` label.

Compiled with gh aw v0.68 in strict mode.

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

* docs(changelog): add pr-review-panel workflow entry

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

* feat(workflows): pin pr-review-panel to ${{ github.sha }}

Self-referential dogfooding: the workflow lives in the same repo as
the APM package it depends on, so pin to the PR's own head SHA
instead of a frozen merge SHA. Net effects:

- Zero maintenance: no manual SHA bump after PRs that touch .apm/.
- Self-consistent review: a PR that modifies the panel skill or
  persona agents is reviewed BY those modified primitives.

Mirrors the standard actions/checkout@${{ github.sha }} self-reference
pattern. gh-aw v0.68 preserves the expression through to the lock
file's AW_APM_PACKAGES env var.

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

* fix(workflows): pin pr-review-panel to microsoft/apm@main

Reverts the ${{ github.sha }} self-reference. A PR that modifies the
panel skill or persona agents could otherwise trick its own review
into APPROVE by weakening the very prompts that judge it.

Pinning to main means the review always runs against the trusted,
already-merged panel -- changes to .apm/ only take effect AFTER they
have themselves been reviewed and merged. Same rationale as GitHub's
own guidance to pin workflow `uses:` to a ref, never to the PR head.

Auto-updates on every merge to main, zero maintenance, no
trust-on-first-use hole.

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

* fix(workflows): use #main spec form (APM does not accept @main)

APM 0.9.0 dependency parser accepts `owner/repo#ref` (hash) but
rejects `owner/repo@ref` (at-sign) with 'Invalid repository path
component'. Switching the spec from `@main` to `#main`.

Same trust property: review runs against the merged-and-trusted panel
on main, never against PR-modified primitives.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
danielmeppiel added a commit that referenced this pull request Apr 22, 2026
- Bump version to 0.9.1 in pyproject.toml and uv.lock
- Move CHANGELOG [Unreleased] entries into [0.9.1] - 2026-04-22
- Audit pass: 1 PR = 1 entry, no bloat
  - Consolidate the seven scattered entries from #832 into a single
    Added line that names the closed issues (#827/#829/#831/#834)
    and keeps the migration warning inline
  - Combine the three fork-PR fixes (#826, #836, #837) into one
    Fixed entry per the multi-PR convention
  - Drop the doc-only consolidation commits from the log

Highlights of 0.9.1:
- Install-time enforcement of org apm-policy.yml (#832)
- pr-review-panel automation now usable from fork PRs (#824, #826,
  #836, #837)
- Docs site publish gated on stable releases only (#822)
- Repository dogfooding via .apm/ as primitive source of truth (#823)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
danielmeppiel added a commit that referenced this pull request Apr 22, 2026
- Bump version to 0.9.1 in pyproject.toml and uv.lock
- Move CHANGELOG [Unreleased] entries into [0.9.1] - 2026-04-22
- Audit pass: 1 PR = 1 entry, no bloat
  - Consolidate the seven scattered entries from #832 into a single
    Added line that names the closed issues (#827/#829/#831/#834)
    and keeps the migration warning inline
  - Combine the three fork-PR fixes (#826, #836, #837) into one
    Fixed entry per the multi-PR convention
  - Drop the doc-only consolidation commits from the log

Highlights of 0.9.1:
- Install-time enforcement of org apm-policy.yml (#832)
- pr-review-panel automation now usable from fork PRs (#824, #826,
  #836, #837)
- Docs site publish gated on stable releases only (#822)
- Repository dogfooding via .apm/ as primitive source of truth (#823)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
danielmeppiel added a commit that referenced this pull request Apr 23, 2026
Address PR #878 review:

1. Sync .apm/instructions/cicd.instructions.md (canonical source per
   #823) with .github/instructions/cicd.instructions.md so future
   apm install --target copilot regenerations don't revert the
   build-release smoke-gating doc note (and to bring along the
   stub-removal changes from #875 + branch-protection refinement
   from #874 that had also drifted).

2. Append (#878) suffix to the new CHANGELOG entry, matching the
   established Keep-a-Changelog convention used by neighbouring
   entries.

No workflow behavior change.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
danielmeppiel added a commit that referenced this pull request Apr 23, 2026
* ci(build-release): gate smoke to tag/schedule/dispatch only

Push-time smoke in build-release.yml's build-and-test job (Linux x86_64,
Linux arm64, Windows) duplicated the merge-time smoke gate already enforced
by ci-integration.yml on the same SHA content, while burning ~15 redundant
codex-binary downloads per active day and amplifying network-flake exposure.

Smoke now runs only at promotion boundaries:

  - tags (pre-ship release gate; only validation tag-cut releases receive)
  - schedule (nightly drift catch for upstream openai/codex URL changes)
  - workflow_dispatch (manual safety net)

Push-to-main retains unit tests on all build-and-test platforms for
platform-regression signal; smoke coverage on Linux at merge_group time
(ci-integration.yml) and on Linux x86_64 nightly (ci-runtime.yml) is
unchanged. Multi-platform smoke (arm64 + Windows) shifts from per-push
to per-tag, narrowing the time-to-detection window for platform-specific
regressions in scripts/runtime/setup-codex.sh by hours-to-days but
trading that for a meaningful reduction in network noise.

The gating expression matches the existing canonical pattern used by the
macOS Intel/ARM jobs and integration-tests/release-validation jobs in
this same workflow.

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

* ci(build-release): sync .apm canonical + add PR ref to changelog

Address PR #878 review:

1. Sync .apm/instructions/cicd.instructions.md (canonical source per
   #823) with .github/instructions/cicd.instructions.md so future
   apm install --target copilot regenerations don't revert the
   build-release smoke-gating doc note (and to bring along the
   stub-removal changes from #875 + branch-protection refinement
   from #874 that had also drifted).

2. Append (#878) suffix to the new CHANGELOG entry, matching the
   established Keep-a-Changelog convention used by neighbouring
   entries.

No workflow behavior change.

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

---------

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.

2 participants