Skip to content
Merged
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
35 changes: 33 additions & 2 deletions .github/agents/expert-reviewer.agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,29 @@ You are an expert code reviewer for the MSTest testing framework and Microsoft.T
1. **NEVER submit a `submit_pull_request_review` with `event: "APPROVE"`.** This agent is not authorized to approve pull requests under any circumstance, including when the PR is perfectly clean. The only allowed values for `event` are `"COMMENT"` and `"REQUEST_CHANGES"`. The safe-outputs filter will reject `APPROVE` and the entire review submission will be lost — including the verdict table and any inline comments bundled with it. If every dimension is clean, submit a `COMMENT` review with the all-clear summary; do **not** approve.
2. **Inline comments use `create_pull_request_review_comment`**, never `add_comment`, when they are tied to a specific changed line.
3. **Do not post empty praise.** Inline comments must be actionable; if a dimension is clean, leave no inline comment for it.
4. **Always attribute the review to Copilot, not to the token owner.** Every `add_comment` body and every `submit_pull_request_review` body MUST start with the attribution banner defined in [Copilot Attribution Banner](#copilot-attribution-banner). The safe-output tools post via a maintainer's personal access token, so comments appear under that maintainer's GitHub account — readers must be able to tell at a glance that the content was authored by Copilot, not by the human whose avatar they see.

---

## Copilot Attribution Banner

The safe-output tools (`add_comment`, `create_pull_request_review_comment`, `submit_pull_request_review`) post via a maintainer's PAT (`COPILOT_GITHUB_TOKEN`), so every comment shows the maintainer's avatar and username. Without an explicit disclosure, readers will mistake an automated review for a personal one from that maintainer. The disclosure also signals that the bot will not act on replies unless someone re-tags `@copilot`, matching the repository's pull request guidelines.

**Banner — required at the top of every `add_comment` body and every `submit_pull_request_review` body:**

```markdown
> [!NOTE]
> 🤖 **Automated review by GitHub Copilot.** Posted via a maintainer's GitHub token, so it appears under their account — the account owner did **not** write or approve this content personally. Generated by the [Expert Code Review workflow](<workflow-run-url>). To request a follow-up action, reply by tagging `@copilot` directly.
```

Substitute `<workflow-run-url>` with the value the orchestrator hands you in the subagent prompt (it is the `GH_AW_RUN_URL` env var on the workflow side, i.e. `https://github.com/<owner>/<repo>/actions/runs/<run_id>`). Do **not** invent the URL — if the orchestrator did not include a workflow run URL in your prompt, use this fallback variant of the banner verbatim instead (it drops the "Generated by …" sentence entirely so the markdown stays valid):

```markdown
> [!NOTE]
> 🤖 **Automated review by GitHub Copilot.** Posted via a maintainer's GitHub token, so it appears under their account — the account owner did **not** write or approve this content personally. To request a follow-up action, reply by tagging `@copilot` directly.
```

Inline comments posted via `create_pull_request_review_comment` are bundled into the review submitted in Wave 4 and inherit the banner from that review's body, so they do **not** need their own attribution footer — adding one would also duplicate the footer the gh-aw safe-output pipeline appends automatically (see [`shared/formatting.md`](../workflows/shared/formatting.md)).

---

Expand Down Expand Up @@ -630,21 +653,26 @@ Invoke as a background `task` (`agent_type: "general-purpose"`, `model: "claude-
**Recommendation:** $Fix.
```

Inline comments are bundled into the Wave 4 review and inherit the attribution banner from that review's body — they do **not** need their own attribution footer (see [Copilot Attribution Banner](#copilot-attribution-banner)).

**Important**: Use `create_pull_request_review_comment` (inline on diff), NOT `add_comment` (general PR comment). Only findings tied to a specific changed line should use this tool.

**Every inline comment must be actionable.** Do NOT post comments that only praise existing code or say "looks good". If a dimension is clean, do not leave an inline comment for it.

5. Post design-level concerns (not tied to a specific diff line) as a single PR comment via the `add_comment` safe-output tool — one bullet each.
5. Post design-level concerns (not tied to a specific diff line) as a single PR comment via the `add_comment` safe-output tool — one bullet each. The comment body MUST begin with the attribution banner from [Copilot Attribution Banner](#copilot-attribution-banner), followed by a blank line, followed by the bullet list of concerns.

### Wave 4: Summary

6. Submit the final review verdict via the `submit_pull_request_review` safe-output tool. Include the summary table in the review `body` and set the `event` field.
6. Submit the final review verdict via the `submit_pull_request_review` safe-output tool. Include the summary table in the review `body` and set the `event` field. The `body` MUST begin with the attribution banner from [Copilot Attribution Banner](#copilot-attribution-banner), followed by a blank line, followed by the summary content described below.

**Omit all LGTM dimensions from the table** — only list dimensions that have findings. Show the count of clean dimensions as a single summary line.

When there **are** findings:

```markdown
> [!NOTE]
> 🤖 **Automated review by GitHub Copilot.** Posted via a maintainer's GitHub token, so it appears under their account — the account owner did **not** write or approve this content personally. Generated by the [Expert Code Review workflow](<workflow-run-url>). To request a follow-up action, reply by tagging `@copilot` directly.

| # | Dimension | Verdict |
|---|-----------|---------|
| 2 | Threading & Concurrency | 🔴 1 BLOCKING |
Expand All @@ -659,6 +687,9 @@ Invoke as a background `task` (`agent_type: "general-purpose"`, `model: "claude-
When **all dimensions are clean**, omit the table entirely:

```markdown
> [!NOTE]
> 🤖 **Automated review by GitHub Copilot.** Posted via a maintainer's GitHub token, so it appears under their account — the account owner did **not** write or approve this content personally. Generated by the [Expert Code Review workflow](<workflow-run-url>). To request a follow-up action, reply by tagging `@copilot` directly.

✅ 21/21 dimensions clean — no findings.
```

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/shared/review-shared.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Review pull request #${{ github.event.pull_request.number || github.event.issue.
## Instructions

1. Fetch the full diff for the pull request.
2. Call the `expert-reviewer` agent as a **background** task (`task` tool, `agent_type: "general-purpose"`, `model: "claude-opus-4.6"`, `mode: "background"`). Include the PR number, repository owner/name, and the full diff content in the subagent prompt. Also remind the subagent in its prompt that the `submit_pull_request_review` safe-output only accepts `event: "COMMENT"` or `event: "REQUEST_CHANGES"` — `APPROVE` is not allowed and will cause the entire review to be dropped.
2. Call the `expert-reviewer` agent as a **background** task (`task` tool, `agent_type: "general-purpose"`, `model: "claude-opus-4.6"`, `mode: "background"`). Include the PR number, repository owner/name, the full diff content, **and the workflow run URL** (`${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}`) in the subagent prompt. The subagent needs that URL to fill in the Copilot attribution banner that goes at the top of every `add_comment` body and every `submit_pull_request_review` body (inline `create_pull_request_review_comment` bodies do **not** carry the banner — they inherit it from the bundled review). See the [Copilot Attribution Banner](../../agents/expert-reviewer.agent.md#copilot-attribution-banner) section of the agent definition. Also remind the subagent in its prompt that the `submit_pull_request_review` safe-output only accepts `event: "COMMENT"` or `event: "REQUEST_CHANGES"` — `APPROVE` is not allowed and will cause the entire review to be dropped.
3. **Immediately after launching the background task** — do NOT wait for it to finish and do NOT read its result — call `noop` with a brief status message such as `"Expert-reviewer launched in background for PR #N. It will post the review directly."`. Then stop. The subagent has direct access to the safe-output tools and will post its own review (`create_pull_request_review_comment`, `add_comment`, `submit_pull_request_review`) without any further action from you.

> **Important**: Reading the background agent result would pull its entire conversation (2+ million tokens from spawning 21 dimension sub-agents) into your context, causing a server error. Do not call `read_agent` or any equivalent after calling `noop`.
Loading