Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 33 additions & 11 deletions .agents/skills/autopilot-issue-triage-worker/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,14 +109,35 @@ output template differ.

## Agent roster

| Agent | Persona | Always active? |
|-------|---------|----------------|
| [DevX UX Expert](../../agents/devx-ux-expert.agent.md) | User-Need Reviewer | Yes |
| [Supply Chain Security Expert](../../agents/supply-chain-security-expert.agent.md) | Risk-Surface Reviewer | Yes |
| [APM CEO](../../agents/apm-ceo.agent.md) | Triage Arbiter | Yes (always arbitrates) |
| [OSS Growth Hacker](../../agents/oss-growth-hacker.agent.md) | Contributor-Tone Reviewer | Conditional (see below) |
| [Python Architect](../../agents/python-architect.agent.md) | Architecture Reviewer | Conditional (see below) |
| [Doc Writer](../../agents/doc-writer.agent.md) | Documentation Reviewer | Conditional (see below) |
| Agent slug | 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) |

These agent files are consumer-provided companion assets, not part of this
package. For a Copilot consumer, APM deploys them under
`.github/agents/<agent-slug>.agent.md`. Do not resolve them through a
path relative to the installed skill directory.

Before reading persona files or producing advice, run the bundled
`scripts/check_required_agents.py` with the three always-active slugs and
every conditional slug activated for this issue, using the consumer's
`.github/agents` directory as `--agents-dir`. The script emits JSON and
returns nonzero when any required role is absent; stop and report every
missing role. Never silently omit a mandatory or activated conditional lens.
For example, the always-active roles are checked with:

```bash
python3 .agents/skills/autopilot-issue-triage-worker/scripts/check_required_agents.py \
--agents-dir .github/agents \
devx-ux-expert supply-chain-security-expert apm-ceo
```

Add any conditional role selected for this issue to the role arguments.

Skipped by default: CLI Logging Expert, Auth Expert. Triage operates
on issue intent, not on diffs -- those personas are invoked downstream
Expand Down Expand Up @@ -376,7 +397,7 @@ write/receipt step.
If any check fails, redo that persona's pass and repeat the gate.
Do not proceed to step 5 until the gate passes.
5. Take the **APM CEO** lens (load
`../../agents/apm-ceo.agent.md`) and arbitrate the collected
`.github/agents/apm-ceo.agent.md`) and arbitrate the collected
findings into a single recommendation, useful classification,
proposed brief, and reply tone. Still in your own context. CEO
arbitration may run only after the completeness gate has passed.
Expand Down Expand Up @@ -423,8 +444,9 @@ write/receipt step.

For each persona, run this exact procedure in your own context:

1. Open the persona's `.agent.md` file (linked in the roster) and
read its scope, lens, anti-patterns, and required return shape.
1. Open the persona's `.agent.md` file from the consumer's
`.github/agents/` directory and read its scope, lens,
anti-patterns, and required return shape.
2. From that persona's lens, review the issue title, body, labels,
author signals, and the complete prior comment history against the
scope declared in the file. Reconcile with earlier advice and any
Expand Down
7 changes: 3 additions & 4 deletions .agents/skills/autopilot-issue-triage-worker/apm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ author: Microsoft
license: MIT
type: skill

# Stand-alone primitive: no transitive APM deps. Persona lenses are
# referenced by relative path (../../agents/*.agent.md) and resolved
# against the consumer repo's installed .apm/agents/** or
# .github/agents/** -- identical to the autopilot-pr-review-worker precedent.
# Stand-alone primitive: no transitive APM deps. Required specialist
# roles are consumer-provided companions checked in the deployed
# .github/agents/ directory before the worker gives advice.
dependencies:
apm:
- ../autopilot-comment
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env python3
"""Check that required Copilot agent files exist in a consumer repository."""

from __future__ import annotations

import argparse
import json
import re
import sys
from pathlib import Path

_AGENT_SLUG = re.compile(r"[a-z0-9]+(?:-[a-z0-9]+)*\Z")


def main() -> int:
"""Report available and missing required agent roles as JSON."""
parser = argparse.ArgumentParser(
description="Check required .github/agents/<slug>.agent.md files."
)
parser.add_argument(
"--agents-dir",
type=Path,
default=Path(".github/agents"),
help="consumer agent directory (default: .github/agents)",
)
parser.add_argument("roles", nargs="+", help="required agent role slugs")
args = parser.parse_args()

invalid = [role for role in args.roles if not _AGENT_SLUG.fullmatch(role)]
if invalid:
parser.error(f"invalid role slug(s): {', '.join(invalid)}")

roles = sorted(set(args.roles))
available = [role for role in roles if (args.agents_dir / f"{role}.agent.md").is_file()]
missing = [role for role in roles if role not in available]
print(
json.dumps(
{
"agents_dir": str(args.agents_dir),
"available_roles": available,
"missing_roles": missing,
"ready": not missing,
},
sort_keys=True,
)
)
if missing:
print(
f"Missing required agent roles in {args.agents_dir}: {', '.join(missing)}",
file=sys.stderr,
)
return 1
return 0


if __name__ == "__main__":
raise SystemExit(main())
42 changes: 31 additions & 11 deletions .agents/skills/autopilot-pr-review-worker/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,16 +210,20 @@ are active for this `panel-mode` and surface. Do not spawn

| Agent | Role | When spawned |
|-------|------|----------------|
| [Python Architect](.apm/agents/python-architect.agent.md) | Architectural Reviewer + mermaid in `full` | Core, unless docs/changelog-only. Optional in `lean` on tiny diffs. |
| [CLI Logging Expert](.apm/agents/cli-logging-expert.agent.md) | Output UX Reviewer | Surface-gated |
| [DevX UX Expert](.apm/agents/devx-ux-expert.agent.md) | Package-Manager UX | Surface-gated |
| [Supply Chain Security Expert](.apm/agents/supply-chain-security-expert.agent.md) | Threat-Model Reviewer | Surface-gated |
| [OSS Growth Hacker](.apm/agents/oss-growth-hacker.agent.md) | Adoption Strategist | Surface-gated |
| [Auth Expert](.apm/agents/auth-expert.agent.md) | Auth / Token Reviewer | Surface-gated |
| [Doc Writer](.apm/agents/doc-writer.agent.md) | Documentation Reviewer | Surface-gated |
| [Test Coverage Expert](.apm/agents/test-coverage-expert.agent.md) | Test-Presence Reviewer | Core unless docs-only (`src/` untouched) |
| [Performance Expert](.apm/agents/performance-expert.agent.md) | Package-Manager Performance Reviewer | Surface-gated |
| [APM CEO](.apm/agents/apm-ceo.agent.md) | Strategic Arbiter / Synthesizer | Always |
| `python-architect` | Architectural Reviewer + mermaid in `full` | Core, unless docs/changelog-only. Optional in `lean` on tiny diffs. |
| `cli-logging-expert` | Output UX Reviewer | Surface-gated |
| `devx-ux-expert` | Package-Manager UX | Surface-gated |
| `supply-chain-security-expert` | Threat-Model Reviewer | Surface-gated |
| `oss-growth-hacker` | Adoption Strategist | Surface-gated |
| `auth-expert` | Auth / Token Reviewer | Surface-gated |
| `doc-writer` | Documentation Reviewer | Surface-gated |
| `test-coverage-expert` | Test-Presence Reviewer | Core unless docs-only (`src/` untouched) |
| `performance-expert` | Package-Manager Performance Reviewer | Surface-gated |
| `apm-ceo` | Strategic Arbiter / Synthesizer | Always |

These agent files are consumer-provided companion assets, not part of this
package. For a Copilot consumer, APM deploys them under
`.github/agents/<agent-slug>.agent.md`.

## Topology

Expand All @@ -244,6 +248,22 @@ are active for this `panel-mode` and surface. Do not spawn
Caller (merge-worker, scheduler, or human) SHOULD set
`panel-mode: full | lean | delta`. Omitted or unknown -> `lean`.

After resolving the active roster from the mode and surface, but before
spawning any panelist, run the bundled
`scripts/check_required_agents.py` with the active role slugs and the
consumer's `.github/agents` directory as `--agents-dir`. The script emits
JSON and returns nonzero when any active role is missing. Stop and report
all missing roles; do not skip a required role or produce a partial review.
Run it from the consumer repository root, for example:

```bash
python3 .agents/skills/autopilot-pr-review-worker/scripts/check_required_agents.py \
--agents-dir .github/agents python-architect test-coverage-expert apm-ceo
```

Replace the example roles with the exact active roster for the selected mode
and surface.

| Mode | Roster | Context | Comment |
|------|--------|---------|---------|
| full | Surface-gated specialists + CEO | Shared brief + owned files | yes |
Expand Down Expand Up @@ -530,7 +550,7 @@ no comment can be rendered, an explicit `noop` (step 9) -- are emitted.
5. **Spawn the CEO synthesizer task.** Pass the spawned panelist JSON
returns (omitted personas are inactive; do not invent stub JSON)
to a `task` invocation that loads
`.apm/agents/apm-ceo.agent.md`. Run it as a BLOCKING task and WAIT
`.github/agents/apm-ceo.agent.md`. Run it as a BLOCKING task and WAIT
for its JSON return -- do NOT spawn it detached (background mode that
returns an `agent_id`) and do NOT end your turn while it runs. Its
return is required to render the comment; ending the turn here is the
Expand Down
6 changes: 3 additions & 3 deletions .agents/skills/autopilot-pr-review-worker/apm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ author: Microsoft
license: MIT
type: skill

# Stand-alone primitive: no transitive APM deps. The skill body honors
# the consumer repo's linting / encoding rules at runtime by activating
# whichever instructions the consumer has installed.
# Stand-alone primitive: no transitive APM deps. Specialist roles are
# consumer-provided companions checked in the deployed .github/agents/
# directory before the worker begins the panel.
dependencies:
apm:
- ../autopilot-comment
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,11 +128,11 @@
},
"proves": {
"type": "string",
"description": "One sentence in USER words naming the promise the test proves (or fails to prove if missing). MUST mirror a Scenario Evidence row from the PR body when one exists -- the rubric (.github/skills/pr-description-skill/assets/scenario-evidence-rubric.md) is the shared vocabulary."
"description": "One sentence in USER words naming the promise the test proves (or fails to prove if missing). MUST mirror a Scenario Evidence row from the PR body when one exists."
},
"principles": {
"type": "array",
"description": "APM principle taxonomy from the scenario-evidence rubric (Portability by manifest, Secure by default, Governed by policy, Multi-harness support, Vendor-neutral, DevX, OSS). Ranks the criticality of the proven (or missing) promise.",
"description": "APM principle taxonomy defined by the enum below. Ranks the criticality of the proven (or missing) promise.",
"items": {
"type": "string",
"enum": [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#!/usr/bin/env python3
"""Check that required Copilot agent files exist in a consumer repository."""

from __future__ import annotations

import argparse
import json
import re
import sys
from pathlib import Path

_AGENT_SLUG = re.compile(r"[a-z0-9]+(?:-[a-z0-9]+)*\Z")


def main() -> int:
"""Report available and missing required agent roles as JSON."""
parser = argparse.ArgumentParser(
description="Check required .github/agents/<slug>.agent.md files."
)
parser.add_argument(
"--agents-dir",
type=Path,
default=Path(".github/agents"),
help="consumer agent directory (default: .github/agents)",
)
parser.add_argument("roles", nargs="+", help="required agent role slugs")
args = parser.parse_args()

invalid = [role for role in args.roles if not _AGENT_SLUG.fullmatch(role)]
if invalid:
parser.error(f"invalid role slug(s): {', '.join(invalid)}")

roles = sorted(set(args.roles))
available = [role for role in roles if (args.agents_dir / f"{role}.agent.md").is_file()]
missing = [role for role in roles if role not in available]
print(
json.dumps(
{
"agents_dir": str(args.agents_dir),
"available_roles": available,
"missing_roles": missing,
"ready": not missing,
},
sort_keys=True,
)
)
if missing:
print(
f"Missing required agent roles in {args.agents_dir}: {', '.join(missing)}",
file=sys.stderr,
)
return 1
return 0


if __name__ == "__main__":
raise SystemExit(main())
35 changes: 17 additions & 18 deletions .agents/skills/autopilot-pr-triage-worker/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,9 @@ Rules:
and processing / classification labels. Never assign. Never
request reviewers. Do not call `gh pr comment` yourself.
Do not write `status/accepted`, `status/needs-design`, or
`status/needs-triage`. Write `status/deferred` only when this
PR is not labelled `status/accepted` and has no same-repo
linked issue labelled `status/accepted`.
`status/needs-triage` or `status/deferred`. A defer
recommendation belongs only in the advisory comment; a human
decides whether to apply `status/deferred`.
- `json` defaults to `off` when omitted or unknown. Omitted `json`
is not a missing-field stop.
- `json: off` -> no machine JSON receipt.
Expand Down Expand Up @@ -97,14 +97,14 @@ classification labels from the contract. Never write
`status/accepted`, `status/needs-design`, or
`status/needs-triage`.

Auto-defer: if this PR is not labelled `status/accepted` and
has no same-repo linked issue labelled `status/accepted`, add
`status/deferred` (`write: on` only).
Do not overwrite `status/accepted` already on the PR. Linked
means `Fixes` / `Closes` / `#N` in the body or commits, or
GitHub `closingIssuesReferences`, same repository. Any one
accepted linked issue or `status/accepted` on the PR blocks
auto-defer.
When neither this PR nor a same-repo linked issue is labelled
`status/accepted`, recommend `needs-issue` and explain that a
human must review and accept scope before implementation. If
deferral is appropriate, recommend it in the advisory comment;
never write `status/deferred`. Linked means `Fixes` / `Closes` /
`#N` in the body or commits, or GitHub `closingIssuesReferences`,
same repository. An accepted linked issue or `status/accepted` on
the PR blocks the `needs-issue` recommendation.

CODEOWNERS `reviewRequests` is runtime authority. Note owners in
the comment. Never add or remove review requests.
Expand All @@ -131,11 +131,11 @@ conversation, no-op (do not post a duplicate).
`auto-handle`.
4. Neither this PR nor a linked same-repo issue is
`status/accepted` -> recommend `needs-issue`,
add `status/deferred` when `write: on`, and thank the author.
Invite them to open an issue for maintainer review and
acceptance first, per CONTRIBUTING.md ("Start with an issue,
not an implementation."). Link
https://github.com/microsoft/apm/blob/main/CONTRIBUTING.md
thank the author, and invite them to open an issue for
maintainer review and acceptance first, per CONTRIBUTING.md
("Start with an issue, not an implementation."). Link
https://github.com/microsoft/apm/blob/main/CONTRIBUTING.md.
Do not add `status/deferred`; any deferral is a human decision.
5. `ready-for-review` when this PR or a linked same-repo issue is
`status/accepted`. It is not merge approval and is not a
request to run `autopilot-pr-review-scheduler`.
Expand All @@ -157,6 +157,5 @@ conversation, no-op (do not post a duplicate).
- Do not run `autopilot-pr-review-worker` or `autopilot-pr-merge-worker`.
- Do not contradict CODEOWNERS.
- Do not treat labels or this comment as `status/accepted`.
- Do not write `status/deferred` when a linked issue is
`status/accepted` or the PR already has `status/accepted`.
- Never write `status/deferred` or any other human-decision label.
- ASCII only.
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ Thank you for contributing this pull request. APM starts with an
issue, not an implementation
(https://github.com/microsoft/apm/blob/main/CONTRIBUTING.md).
Please open an issue describing the user problem so a maintainer
can review and accept the scope first. This PR is labelled
status/deferred until that happens.>
can review and accept the scope first. This PR is awaiting maintainer
review and acceptance of its scope.>
```
Loading
Loading