microsoft/apm-apm-triage-panel
>- Use this skill to triage a single newly opened, reopened, or `status/needs-triage`-labelled issue in microsoft/apm. Emit one synthesized comment with a triage decision, label set, milestone, and suggested next action.
This is a copy. The original lives at microsoft/apm-triage-panel.
npx skills add https://github.com/microsoft/apm --skill apm-triage-panel
The panel is fixed at **3 mandatory specialist lenses + up to 3
conditional lenses + 1 arbiter lens = up to 6 active persona sections
in one triage comment** (3 mandatory + 3 conditional). You play each
lens in turn from inside a single agent loop (progressive-disclosure
skill model -- no sub-agent dispatch). Routing chooses *which* lenses
execute; it never changes which headings appear in the final comment.
This skill mirrors the apm-review-panel orchestration shape on
purpose. Same single-comment discipline, same completeness gate, same
persona-pass procedure -- only the personas, the rubric, and the
output template differ.
| Agent | Persona | Always active? |
|-------|---------|----------------|
| DevX UX Expert | User-Need Reviewer | Yes |
| Supply Chain Security Expert | Risk-Surface Reviewer | Yes |
| APM CEO | Triage Arbiter | Yes (always arbitrates) |
| OSS Growth Hacker | Contributor-Tone Reviewer | Conditional (see below) |
| Python Architect | Architecture Reviewer | Conditional (see below) |
| Doc Writer | Documentation Reviewer | Conditional (see below) |
Skipped by default: CLI Logging Expert, Auth Expert. Triage operates
on issue intent, not on diffs -- those personas are invoked downstream
by apm-review-panel once a PR exists.
devx-ux-expert supply-chain-security-expert
\_______________________/
|
| <-- python-architect (conditional; design /
| architecture / new primitive / new schema)
|
| <-- doc-writer (conditional; docs work or
| user-facing change that needs new doc pages)
v
apm-ceo <---- oss-growth-hacker
(final call / arbiter) (conditional; tunes tone
when author is new)
reply. CEO has the final call on the decision rubric.
to the CEO when activated. They never block a specialist finding;
they feed the CEO's arbitration:
low-interaction contributors.
pushes the decision toward status/needs-design when warranted.
suggested comment wording is grounded in the user vocabulary used
in the README and guides.
Three personas are conditional: OSS Growth Hacker, Python Architect,
and Doc Writer. Each follows the same shape: an explicit YES/NO
activation rule plus an inactive-reason fallback. Maximum lenses in a
single triage = 6 (3 mandatory + 3 conditional).
Activate oss-growth-hacker if either rule below matches.
immediately when the issue's author meets ANY of:
author_association is FIRST_TIME_CONTRIBUTOR,FIRST_TIMER, or NONE against microsoft/apm.
comments) on microsoft/apm.
similar.
this before activating the lens:
> Would the warmth, framing, or pointer-set in the reply meaningfully
> change if I knew this was someone's first interaction with the
> project? Answer YES or NO with one sentence.
> If unsure, answer YES.
Routing rule:
procedure) and capture its tone-tuning findings.
OSS Growth Hacker inactive reason: <one sentence>in working notes; do not take the lens.
Activate python-architect if either rule below matches.
Reviewer lens immediately when ANY of:
type/architecture (current or proposed) orthe breaking-change preserved label.
change to apm.yml, apm.lock.yaml, or apm-policy.yml.
cross-file work, a new module, a new pattern, a new contract, or
a new primitive design -- e.g. "refactor", "rearchitect", "new
module", "design", "abstraction", "schema change", "pluggable",
"introduce X pattern".
before activating the lens:
> Does this issue, if accepted as written, require a cross-cutting
> design decision (interface, data model, migration boundary, or
> new primitive) before code can land safely? Answer YES or NO
> with one sentence. If unsure, answer YES.
Routing rule:
the design as proposed, callouts of cross-cutting impact, and
whether the issue should land as status/needs-design instead of
status/accepted.
Python Architect inactive reason: <one sentence>in working notes; do not take the lens.
Activate doc-writer if either rule below matches.
Reviewer lens immediately when ANY of:
type/docs or carries area/docs-site (current orproposed).
or migration-note changes.
pages -- e.g. a new CLI flag, a new primitive, a new authoring
concept.
before activating the lens:
> Will an implementing PR for this issue need to add or change
> user-facing documentation in docs/src/content/docs/ or in the
> README? Answer YES or NO with one sentence. If unsure, answer
> YES.
Routing rule:
implied (and whether area/docs-site should be added as a
secondary area/* so the implementing PR is reminded), and whether
the proposed comment wording is clear and grounded in the user
vocabulary used in the README and guides.
Doc Writer inactive reason: <one sentence> inworking notes; do not take the lens.
The CEO arbiter picks exactly ONE outcome from this rubric:
accept -- direction is clear and aligned with the README spine andthe roadmap. Assigns full label set + milestone if a current
candidate exists.
needs-design -- direction is sound but the design must be settledbefore code lands. Apply status/needs-design and name in the
comment exactly what must be designed (interface, data model,
migration, security boundary).
decline-with-reason -- out of scope for APM as positioned by theREADME spine. Suggest an alternative tool, a workaround, or the
upstream project. Always courteous, always concrete.
duplicate-of #N -- propose the canonical issue. The orchestratormust verify the link resolves before posting.
defer-later -- accepted in principle but no current milestone.Sits as status/accepted plus theme/* + area/* only; no
priority/*, no milestone.
auto-handle -- automated noise such as a daily CLI-consistencyreport PR or scheduled bot issue. Propose closing if the report has
zero unaddressed High findings; otherwise propose splitting into
individual issues with the right area/* labels and reference back
to the parent.
Triage produces a single proposed label set. The taxonomy:
theme/portability, theme/security, theme/governance.
area/*, one or more):area/multi-target, area/marketplace, area/package-authoring,
area/distribution, area/mcp-config, area/content-security,
area/lockfile, area/mcp-trust, area/audit-policy,
area/enterprise, area/cli, area/ci-cd, area/testing,
area/docs-site.
type/bug, type/feature, type/docs, type/refactor,
type/architecture, type/automation, type/release,
type/performance.
status/needs-triage, status/accepted, status/needs-design,
status/blocked, status/in-flight.
priority/high, priority/low.
breaking-change, good first issue, help wanted,
experimental, panel-review, dx, agentic-workflows,
dependencies.
Construction rules:
theme/<mega> label is required UNLESS the issue ispure infra (only area/cli, area/ci-cd, area/testing, or
area/docs-site apply, with no product surface implication). State
this explicitly in the per-lens notes when omitting the theme.
first and drives the milestone.
type/* label.status/* label. The default status/needs-triage isalways replaced by the triage outcome (status/accepted,
status/needs-design, status/blocked, etc.). Do not leave
status/needs-triage on a triaged issue.
priority/* only on accept with a current milestone or nextminor. Never on defer-later, needs-design, or decline-*.
0.9.x) for bug fixes and smallDX work that fits a patch release.
0.10.0) for type/feature accepted withpriority/high.
null) for defer-later and needs-design.The orchestrator looks up open milestones with:
gh api repos/microsoft/apm/milestones --jq '.[]|select(.state=="open")|.title'
The lowest-numbered open patch milestone is "current patch"; the
lowest-numbered open minor is "next minor". If neither exists, set
milestone to null and note it.
A triage comment passes when:
(or fails to map) to a concrete README-anchored capability
the issue touches lockfile, marketplace, MCP config, signing,
or auth, theme/security or theme/governance is on the set
ratified
taken, tone tuned for a new or low-interaction contributor and
the reply names a concrete next step they can take
taken, feasibility, cross-cutting impact, and any
status/needs-design recommendation are captured
docs implication is named and any area/docs-site secondary
label is proposed when the implementing PR will need new pages
the only agent. You load each persona's .agent.md reference file
on demand (progressive disclosure), assume that persona's lens to
produce its findings, then move to the next persona. Do NOT spawn
sub-agents (no task tool dispatch) -- the panel is a sequence of
reasoning passes inside one agent loop, not a multi-agent fan-out.
.agent.md files. Read eachone when you switch to that persona; do not pre-load all of them.
When this skill is activated for an issue, work through these steps
in order, in a single agent loop. Do not skip ahead and do not emit
any output before the final step.
author_association, prior comments). The orchestrating workflow
already fetches this with gh issue view --json -- do not
re-fetch from inside the skill.
Python Architect, Doc Writer -- using the rules in "Conditional
panelists" above. For each, record either an activation decision
or <Persona> inactive reason: <one sentence> in working notes.
activated), follow the Persona pass procedure below, one
persona at a time. Do not try to play multiple personas in a
single pass.
(DevX UX Expert, Supply Chain Security Expert).
exactly one of <Persona> findings or `<Persona> inactive
reason` exists (neither = incomplete; both = inconsistent
routing).
If any check fails, redo that persona's pass and repeat the gate.
Do not proceed to step 5 until the gate passes.
../../agents/apm-ceo.agent.md) and arbitrate the collected
findings into a single decision: rubric outcome, primary theme,
area/* set, type/*, status/*, optional priority/*,
milestone, and reply tone. Still in your own context. CEO
arbitration may run only after the completeness gate has passed.
duplicate-of #N, verify the candidateissue exists and is open with gh issue view N --json state,title
before committing the link.
assets/triage-template.md and fill itin with the collected findings, decision, label set, milestone,
and proposed comment body.
safe-outputs.add-comment channel. For direct (non-workflow)
invocation, return the comment text and the structured
triage-decision JSON tail so an orchestrator can apply labels
and post the comment without parsing prose. This is the ONLY
output emission for the entire panel run -- no per-persona
comments, no progress comments.
For each persona, run this exact procedure in your own context:
.agent.md file (linked in the roster) andread its scope, lens, anti-patterns, and required return shape.
author signals, and any prior comments against the scope declared
in the file.
<persona-name>: <findings> (or, for an inactive conditional
persona, <Persona> inactive reason: <one sentence>).
from inside a persona pass; persona findings stay in working
notes until step 7 synthesizes them.
This contract is non-negotiable -- it is the difference between a
triage that lands as one cohesive comment and one that fragments into
per-persona noise.
assets/triage-template.md as the comment body. Keep itssection headings exactly as written. Adapt the body of each
section to the issue. Do not invent new top-level sections or drop
existing ones.
json block named triage-decision` isREQUIRED. It is the machine-readable contract that downstream
automation uses to apply labels, set the milestone, and post the
reply without parsing prose.
Unicode dashes, no box-drawing characters. Use [+] [!] [x] [i] [*] [>]
if status symbols are needed.
comments, or "I will now invoke X" status comments.
assets/triage-template.md at synthesis time only (step7 above) -- not at activation, not while collecting findings.
theme/* + area/* + type/* + status/* + priority/* + preserved/*.
If you find yourself reaching for 7+, prune the weakest area/*.
whose status is not status/accepted or status/in-flight.
needs-design and defer-later are explicitly milestone-free.
decline-with-reasonwithout a courteous reason linked to the README spine, the
manifesto, or the public roadmap. Every decline names where the
user can go instead.
status/needs-design withoutnaming, in the suggested comment, exactly what must be designed
(interface, data model, migration, security boundary). "We need to
think about this" is not a design-needed reason.
status/needs-triage carryover. Triage replaces thedefault status/needs-triage label. Leaving it on a triaged issue
is a routing bug.
*new* or *first* keyword matches alone -- always cross-check
author_association and prior interactions on microsoft/apm.
Same discipline for Python Architect (do not fire on the bare word
"refactor" in unrelated context -- check the issue's actual scope)
and Doc Writer (do not fire purely on the word "docs" appearing in
passing -- the issue must propose or imply a doc-surface change).
table, the conditional-panelist rule, the triage template, and the
quality gates MUST agree on the persona set. If you change one,
change all of them in the same edit.
devx-ux-expert, supply-chain-security-expert, apm-ceo,
oss-growth-hacker, python-architect, and doc-writer. Do not
create a triage-* persona; the README spine plus the label
taxonomy plus the existing CEO arbiter are sufficient grounding.
agentic workflow, the APM bundle is unpacked under
.github/skills/apm-triage-panel/ first, with .apm/skills/...
as a fallback. The asset path is the same relative to the skill
root (assets/triage-template.md) in both layouts -- prefer the
.github/... path when present.
.agent.md for a reason -- read it when you take that lens, write
the findings, then drop the lens before moving on.
you find yourself wanting to "post a quick partial decision and
then update it", don't. Buffer in working notes; emit once.
Take microsoft/apm-apm-triage-panel from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.