Skip to content

Commit d902ac2

Browse files
EMaherCopilot
andcommitted
fix(squad): start coding-agent sessions for squad:copilot issues; rename go/no-go workflows
The `squad:copilot` label alone never starts a Copilot coding-agent session — an issue must be assigned to `copilot-swe-agent[bot]` via the agent-assignment API. That assignment lives in squad-heartbeat.yml (Ralph), but it was gated off: - .squad/team.md had no `🤖 Coding Agent` entry and no `<!-- copilot-auto-assign: true -->` marker, so the step returned early. - The step only assigned issues with zero assignees, but issue-go-yes always assigns the go:yes maintainer, so every routed issue was skipped. Fixes: - team.md: add a Coding Agent section with the auto-assign marker (also makes issue-labels-sync ensure the `squad:copilot` label exists). - squad-heartbeat.yml (active + installed template): assign the bot to any open `squad:copilot` issue that does not already have the agent, as an additional assignee alongside the human owner. Also rename the issue go/no-go decision workflows for discoverability: - issue-nogo.yml -> issue-go-no.yml ("Issue Go: No") - issue-assign.md -> issue-go-yes.md ("Issue Go: Yes") - issue-clarify.md -> issue-go-clarify.md ("Issue Go: Clarify") Display names set via gh-aw frontmatter `name:`; agentic .lock.yml recompiled. NOTE: requires a COPILOT_ASSIGN_TOKEN repo secret (a PAT that can assign the coding agent) for the assignment step to succeed. Refs #194 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 926f2f1 commit d902ac2

8 files changed

Lines changed: 145 additions & 115 deletions

File tree

.github/workflows/issue-clarify.lock.yml renamed to .github/workflows/issue-go-clarify.lock.yml

Lines changed: 52 additions & 52 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
---
2+
name: "Issue Go: Clarify"
23
description: >
34
When a maintainer marks an issue go:needs-research, help scope it by asking focused
45
clarifying questions — but only if the maintainer has not already asked them. If the
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: Issue No-Go
1+
name: "Issue Go: No"
22

33
# Deterministic Workflow: No-Go decision
44
# Trigger: a maintainer applies the "go:no" label to reject an issue.
Lines changed: 52 additions & 52 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
---
2+
name: "Issue Go: Yes"
23
description: >
34
Assign an approved issue (go:yes) to the maintainer who approved it and route it to
45
squad areas. Reads the prior triage analysis and the squad routing table, applies the

‎.github/workflows/squad-heartbeat.yml‎

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -129,12 +129,19 @@ jobs:
129129
per_page: 5
130130
});
131131
132-
const unassigned = copilotIssues.filter(i =>
133-
!i.assignees || i.assignees.length === 0
132+
// Include issues that don't yet have the coding agent assigned.
133+
// issue-go-yes always assigns the go:yes maintainer as owner, so an
134+
// issue almost always has a (human) assignee — filtering on "zero
135+
// assignees" would skip every routed issue. Filter on the agent's
136+
// presence instead; the POST below ADDS the bot as an extra assignee
137+
// without removing the human owner.
138+
const COPILOT_LOGINS = ['copilot-swe-agent[bot]', 'copilot-swe-agent', 'Copilot'];
139+
const needsAgent = copilotIssues.filter(i =>
140+
!(i.assignees || []).some(a => COPILOT_LOGINS.includes(a.login))
134141
);
135142
136-
if (unassigned.length === 0) {
137-
core.info('No unassigned squad:copilot issues');
143+
if (needsAgent.length === 0) {
144+
core.info('No squad:copilot issues awaiting the coding agent');
138145
return;
139146
}
140147
@@ -144,7 +151,7 @@ jobs:
144151
repo: context.repo.repo
145152
});
146153
147-
for (const issue of unassigned) {
154+
for (const issue of needsAgent) {
148155
try {
149156
await github.request('POST /repos/{owner}/{repo}/issues/{issue_number}/assignees', {
150157
owner: context.repo.owner,

‎.squad/team.md‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,20 @@
2626
| SecurityExpert | 🔒 Security Expert | [charter](.squad/agents/securityexpert/charter.md) | ✅ Active |
2727
| Ralph | 🔄 Work Monitor | — | ✅ Active |
2828

29+
## Coding Agent
30+
31+
<!-- copilot-auto-assign: true -->
32+
33+
GitHub's Copilot coding agent (`@copilot`) autonomously implements issues labeled
34+
`squad:copilot`. Ralph (`squad-heartbeat.yml`) assigns `copilot-swe-agent[bot]` to
35+
every open `squad:copilot` issue that does not already have the agent assigned —
36+
in addition to the human maintainer who owns it — which is what actually starts an
37+
agent session (the label alone does not).
38+
39+
| Name | Role | Auto-assign | Notes |
40+
|------|------|-------------|-------|
41+
| Copilot | 🤖 Coding Agent | ✅ Enabled | Requires the `COPILOT_ASSIGN_TOKEN` repo secret (a PAT that can assign the coding agent). Without it the assign step is a no-op. |
42+
2943
## Issue Source
3044

3145
- **Repository:** Azure/apiops-cli

‎.squad/templates/workflows/squad-heartbeat.yml‎

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,19 @@ jobs:
133133
per_page: 5
134134
});
135135
136-
const unassigned = copilotIssues.filter(i =>
137-
!i.assignees || i.assignees.length === 0
136+
// Include issues that don't yet have the coding agent assigned.
137+
// issue-go-yes always assigns the go:yes maintainer as owner, so an
138+
// issue almost always has a (human) assignee — filtering on "zero
139+
// assignees" would skip every routed issue. Filter on the agent's
140+
// presence instead; the POST below ADDS the bot as an extra assignee
141+
// without removing the human owner.
142+
const COPILOT_LOGINS = ['copilot-swe-agent[bot]', 'copilot-swe-agent', 'Copilot'];
143+
const needsAgent = copilotIssues.filter(i =>
144+
!(i.assignees || []).some(a => COPILOT_LOGINS.includes(a.login))
138145
);
139146
140-
if (unassigned.length === 0) {
141-
core.info('No unassigned squad:copilot issues');
147+
if (needsAgent.length === 0) {
148+
core.info('No squad:copilot issues awaiting the coding agent');
142149
return;
143150
}
144151
@@ -148,7 +155,7 @@ jobs:
148155
repo: context.repo.repo
149156
});
150157
151-
for (const issue of unassigned) {
158+
for (const issue of needsAgent) {
152159
try {
153160
await github.request('POST /repos/{owner}/{repo}/issues/{issue_number}/assignees', {
154161
owner: context.repo.owner,

0 commit comments

Comments
 (0)