Skip to content

Commit beb6da8

Browse files
authored
fix(next-task): task-discoverer skips issues with open PRs (#236) (#243)
* fix(next-task): task-discoverer skips issues with open PRs (#236) Add Phase 2.5 to the discover-tasks skill that fetches open PRs via `gh pr list` and builds a Set of linked issue numbers. Issues are matched by three patterns: branch name suffix (-NNN), PR body closing keywords (closes/fixes/resolves #N), and PR title (#N) convention. Matched issues are excluded in Phase 3 with an [INFO] log message. Non-GitHub sources skip this phase entirely (empty Set). Updated task-discoverer agent role list, CHANGELOG, and regenerated OpenCode adapters. Fixes #236 * fix(next-task): harden PR-exclusion logic in discover-tasks skill - Add default prLinkedIssues = new Set() before GitHub-only block (fixes ReferenceError for non-GitHub sources) - Wrap JSON.parse in try/catch with [WARN] fallback - Add null guards on pr.headRefName and pr.title - Expand closing-keyword regex to cover GitHub's full keyword set (close, closed, closes, fix, fixed, fixes, resolve, resolved, resolves) with word-boundary anchor to prevent false positives - Switch title pattern to matchAll() to capture multiple (#N) references - Add filterByPriority(filtered, ...) call to wire variable pipeline - Replace em dashes with plain ASCII hyphens per project style guide - Document 100-PR limit in bash comment - Update agent Execution bullets to list PR-exclusion logic * docs: add PR-exclusion step to task-discoverer reference * enhance(next-task): apply /enhance findings to task-discoverer agent and skill Agent (task-discoverer.md): - Fix frontmatter description: remove behavioral instruction, describe invocation context - Add role identity sentence ("You discover, filter, score...") - Add Output Format section (mirrors skill output) - Add Error Handling section - Move Constraints to end of file (after Integration Points) - Add "Exclude issues with open PRs" to Constraints - Strengthen "Do not" to "NEVER bypass the skill" Skill (discover-tasks/SKILL.md): - Add allowed-tools to frontmatter for explicit tool permissions - Expand trigger phrases (add "what should I work on", "list open issues") - Add "When to Use" section - Fix stale directory reference in Phase 1 comment - Add conditional guard to Phase 6 for non-GitHub sources - Add PR pagination limit to Constraints section * fix: address PR review comments (Codex + Gemini) - Add note about branch-suffix heuristic false positives (release-2026 pattern) - Fix task.score not assigned before sort - use map+score then sort - Fix Phase 6 source guard: remove undefined $SOURCE var, use clear prose note with policy.taskSource reference instead of broken shell conditional * fix: address Copilot review feedback - Add Bash(grep:*) to allowed-tools (local tasks.md phase uses grep via bash) - Add const fs = require('fs') to Phase 2.5 JS block (was missing import) - Add explicit policy.taskSource comment to Phase 2.5 bash block to clarify GitHub-only condition (replaces ambiguous prose-only guard)
1 parent 84ff690 commit beb6da8

File tree

7 files changed

+182
-38
lines changed

7 files changed

+182
-38
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1111

1212
### Fixed
1313

14+
- **task-discoverer**: Exclude issues that already have an open PR from discovery results (GitHub source only). Detection uses branch name suffix, PR body closing keywords (`closes/fixes/resolves #N`), and PR title `(#N)` convention. Fixes #236.
15+
1416
- **`/debate` 240s timeout enforcement** — All tool invocations in the debate workflow now enforce a hard 240-second timeout. Round 1 proposer timeouts abort the debate; round 1 challenger timeouts proceed with an uncontested position; round 2+ timeouts synthesize from completed rounds. Added "all rounds timeout" error path (`[ERROR] Debate failed: all tool invocations timed out.`). Timeout handling is consistent across the Claude Code command, OpenCode adapter, Codex adapter, and the `debate-orchestrator` agent. Restored missing "Round 2+: Challenger Follow-up" template in the OpenCode adapter SKILL.md. Fixes issue #233.
1517

1618
- **`/next-task` review loop exit conditions** — The Phase 9 review loop now continues iterating until all issues are resolved or a stall is detected (MAX_STALLS reduced from 2 to 1: two consecutive identical-hash iterations = stall). The `orchestrate-review` skill now uses `completePhase()` instead of `updateFlow()` to properly advance workflow state. Added `pre-review-gates` and `docs-update` to the `PHASES` array and `RESULT_FIELD_MAP` in `workflow-state.js`, ensuring these phases can be tracked and resumed correctly. Fixes issue #235.

adapters/opencode/agents/task-discoverer.md

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: task-discoverer
3-
description: Discover and prioritize tasks from configured sources. CRITICAL - You MUST use AskUserQuestion tool to present task selection as checkboxes.
3+
description: "Discover and prioritize tasks from configured sources. Use after policy selection in /next-task workflow to fetch, filter, score, and present issues for user selection via checkbox UI."
44
mode: subagent
55
---
66

@@ -12,13 +12,16 @@ mode: subagent
1212

1313
# Task Discoverer Agent
1414

15+
You discover, filter, score, and present tasks from configured sources for user selection.
16+
1517
**CRITICAL**: You MUST use the AskUserQuestion tool to present task selection as checkboxes. Do NOT present tasks as plain text or ask users to type a number.
1618

1719
## Execution
1820

1921
You MUST execute the `discover-tasks` skill to perform task discovery. The skill contains:
2022
- Source fetching patterns (GitHub, GitLab, local, custom)
2123
- Claimed task exclusion logic
24+
- PR-linked issue exclusion logic (GitHub only)
2225
- Priority filtering
2326
- Scoring algorithm
2427
- AskUserQuestion patterns with 30-char label limit
@@ -35,11 +38,12 @@ Reads from workflow state (`flow.json`):
3538
2. Load policy from workflow state
3639
3. Fetch tasks from configured source
3740
4. Exclude tasks already claimed by other workflows
38-
5. Filter by priority policy
39-
6. Score and rank top 5 tasks
40-
7. Present via AskUserQuestion with checkbox UI
41-
8. Update state with selected task
42-
9. Post comment to issue (GitHub only)
41+
5. Exclude issues with open PRs (GitHub only) - single `gh pr list` call
42+
6. Filter by priority policy
43+
7. Score and rank top 5 tasks
44+
8. Present via AskUserQuestion with checkbox UI
45+
9. Update state with selected task
46+
10. Post comment to issue (GitHub only)
4347

4448
## [WARN] OpenCode Label Limit
4549

@@ -57,14 +61,6 @@ All AskUserQuestion option labels MUST be max 30 characters. Use the truncation
5761
| custom | Use cached CLI/MCP/Skill capabilities |
5862
| other | Interpret user description |
5963

60-
## Constraints
61-
62-
- Do not bypass the skill - it contains the authoritative patterns
63-
- MUST use AskUserQuestion for selection (structured UI)
64-
- Exclude tasks in `tasks.json` registry (claimed by other workflows)
65-
- Max 5 tasks presented to user
66-
- Labels max 30 characters
67-
6864
## Quality Multiplier
6965

7066
Uses **sonnet** model because:
@@ -77,3 +73,30 @@ Uses **sonnet** model because:
7773
This agent is invoked by:
7874
- Phase 2 of `/next-task` workflow
7975
- After policy selection, before worktree setup
76+
77+
## Output Format
78+
79+
```markdown
80+
## Task Selected
81+
82+
**Task**: #{id} - {title}
83+
**Source**: {source}
84+
**URL**: {url}
85+
86+
Proceeding to worktree setup...
87+
```
88+
89+
## Error Handling
90+
91+
- No tasks found: Suggest creating issues, running /audit-project, or using 'all' priority filter
92+
- gh/glab CLI not available: Report error with install instructions, do not attempt workaround
93+
- flow.json missing or corrupt: Report state error, suggest restarting /next-task workflow
94+
95+
## Constraints
96+
97+
- NEVER bypass the skill - it contains the authoritative patterns
98+
- MUST use AskUserQuestion for selection (structured UI)
99+
- Exclude tasks in `tasks.json` registry (claimed by other workflows)
100+
- Exclude issues with open PRs (GitHub source only)
101+
- Max 5 tasks presented to user
102+
- Labels max 30 characters

adapters/opencode/skills/debate/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ Platform state directory:
261261

262262
## External Tool Quick Reference
263263

264-
> Canonical source: consult skill (`consult/SKILL.md`). This table is for **planning reference only** -- always invoke via `Skill: consult`, which handles safe question passing, temp file creation, and cleanup. Do NOT execute these commands directly.
264+
> Canonical source: `plugins/consult/skills/consult/SKILL.md`. This table is for **planning reference only** -- always invoke via `Skill: consult`, which handles safe question passing, temp file creation, and cleanup. Do NOT execute these commands directly.
265265
266266
### Safe Command Patterns
267267

adapters/opencode/skills/discover-tasks/SKILL.md

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
11
---
22
name: discover-tasks
3-
description: "Use when user asks to \"discover tasks\", \"find next task\", or \"prioritize issues\". Discovers and ranks tasks from GitHub, GitLab, local files, and custom sources."
4-
version: 5.1.0
3+
description: "Use when user asks to \"discover tasks\", \"find next task\", \"prioritize issues\", \"what should I work on\", or \"list open issues\". Discovers and ranks tasks from GitHub, GitLab, local files, and custom sources."
4+
version: 5.1.1
5+
allowed-tools: "Bash(gh:*), Bash(glab:*), Bash(git:*), Bash(grep:*), Grep, Read, AskUserQuestion"
56
---
67

78
# discover-tasks
89

910
Discover tasks from configured sources, validate them, and present for user selection.
1011

12+
## When to Use
13+
14+
Invoked during Phase 2 of `/next-task` workflow, after policy selection. Also usable standalone when the user wants to discover and select tasks from configured sources.
15+
1116
## Workflow
1217

1318
### Phase 1: Load Policy and Claimed Tasks
@@ -46,12 +51,29 @@ done
4651
**Custom Source:**
4752
*(JavaScript reference - not executable in OpenCode)*
4853

54+
### Phase 2.5: Collect PR-Linked Issues (GitHub only)
55+
56+
*(JavaScript reference - not executable in OpenCode)*
57+
58+
For GitHub sources (`policy.taskSource === 'github'` or `'gh-issues'`), fetch all open PRs and build a Set of issue numbers that already have an associated PR. Skip to Phase 3 for all other sources.
59+
60+
```bash
61+
# Only run when policy.taskSource is 'github' or 'gh-issues'
62+
# Note: covers up to 100 open PRs. If repo has more, some linked issues may not be excluded.
63+
gh pr list --state open --json number,title,body,headRefName --limit 100 > /tmp/gh-prs.json
64+
```
65+
66+
*(JavaScript reference - not executable in OpenCode)*
67+
4968
### Phase 3: Filter and Score
5069

5170
**Exclude claimed tasks:**
5271
*(JavaScript reference - not executable in OpenCode)*
5372

54-
**Apply priority filter:**
73+
**Exclude issues with open PRs (GitHub only):**
74+
*(JavaScript reference - not executable in OpenCode)*
75+
76+
**Apply priority filter** (pass `filtered` through scoring pipeline):
5577
*(JavaScript reference - not executable in OpenCode)*
5678

5779
**Score tasks:**
@@ -71,7 +93,10 @@ done
7193

7294
### Phase 6: Post Comment (GitHub only)
7395

96+
**Skip this phase entirely for non-GitHub sources (GitLab, local, custom).**
97+
7498
```bash
99+
# Only run for GitHub source. Use policy.taskSource from Phase 1 to check.
75100
gh issue comment "$TASK_ID" --body "[BOT] Workflow started for this issue."
76101
```
77102

@@ -99,4 +124,6 @@ If no tasks found:
99124
- MUST use AskUserQuestion for task selection (not plain text)
100125
- Labels MUST be max 30 characters
101126
- Exclude tasks already claimed by other workflows
127+
- Exclude issues that already have an open PR (GitHub source only)
128+
- PR-link detection covers up to 100 open PRs (--limit 100 is the fetch cap)
102129
- Top 5 tasks only

docs/reference/AGENTS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,8 @@ AgentSys uses 41 specialized agents across 12 plugins (11 have agents - ship use
6060
**What it does:**
6161
1. Loads claimed tasks from `tasks.json` (excludes them)
6262
2. Fetches from GitHub/GitLab/local files/custom CLI
63-
3. Applies priority scoring (labels, blockers, age, reactions)
64-
4. Validates tasks against codebase
63+
3. Excludes issues that already have an open PR (GitHub source only)
64+
4. Applies priority scoring (labels, blockers, age, reactions)
6565
5. Presents top 5 via AskUserQuestion checkboxes
6666
6. Posts "Workflow Started" comment to GitHub issue
6767

plugins/next-task/agents/task-discoverer.md

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: task-discoverer
3-
description: Discover and prioritize tasks from configured sources. CRITICAL - You MUST use AskUserQuestion tool to present task selection as checkboxes.
3+
description: "Discover and prioritize tasks from configured sources. Use after policy selection in /next-task workflow to fetch, filter, score, and present issues for user selection via checkbox UI."
44
tools:
55
- Skill
66
- Bash(gh:*)
@@ -14,13 +14,16 @@ model: sonnet
1414

1515
# Task Discoverer Agent
1616

17+
You discover, filter, score, and present tasks from configured sources for user selection.
18+
1719
**CRITICAL**: You MUST use the AskUserQuestion tool to present task selection as checkboxes. Do NOT present tasks as plain text or ask users to type a number.
1820

1921
## Execution
2022

2123
You MUST execute the `discover-tasks` skill to perform task discovery. The skill contains:
2224
- Source fetching patterns (GitHub, GitLab, local, custom)
2325
- Claimed task exclusion logic
26+
- PR-linked issue exclusion logic (GitHub only)
2427
- Priority filtering
2528
- Scoring algorithm
2629
- AskUserQuestion patterns with 30-char label limit
@@ -37,11 +40,12 @@ Reads from workflow state (`flow.json`):
3740
2. Load policy from workflow state
3841
3. Fetch tasks from configured source
3942
4. Exclude tasks already claimed by other workflows
40-
5. Filter by priority policy
41-
6. Score and rank top 5 tasks
42-
7. Present via AskUserQuestion with checkbox UI
43-
8. Update state with selected task
44-
9. Post comment to issue (GitHub only)
43+
5. Exclude issues with open PRs (GitHub only) - single `gh pr list` call
44+
6. Filter by priority policy
45+
7. Score and rank top 5 tasks
46+
8. Present via AskUserQuestion with checkbox UI
47+
9. Update state with selected task
48+
10. Post comment to issue (GitHub only)
4549

4650
## [WARN] OpenCode Label Limit
4751

@@ -67,14 +71,6 @@ function truncateLabel(num, title) {
6771
| custom | Use cached CLI/MCP/Skill capabilities |
6872
| other | Interpret user description |
6973

70-
## Constraints
71-
72-
- Do not bypass the skill - it contains the authoritative patterns
73-
- MUST use AskUserQuestion for selection (structured UI)
74-
- Exclude tasks in `tasks.json` registry (claimed by other workflows)
75-
- Max 5 tasks presented to user
76-
- Labels max 30 characters
77-
7874
## Quality Multiplier
7975

8076
Uses **sonnet** model because:
@@ -87,3 +83,30 @@ Uses **sonnet** model because:
8783
This agent is invoked by:
8884
- Phase 2 of `/next-task` workflow
8985
- After policy selection, before worktree setup
86+
87+
## Output Format
88+
89+
```markdown
90+
## Task Selected
91+
92+
**Task**: #{id} - {title}
93+
**Source**: {source}
94+
**URL**: {url}
95+
96+
Proceeding to worktree setup...
97+
```
98+
99+
## Error Handling
100+
101+
- No tasks found: Suggest creating issues, running /audit-project, or using 'all' priority filter
102+
- gh/glab CLI not available: Report error with install instructions, do not attempt workaround
103+
- flow.json missing or corrupt: Report state error, suggest restarting /next-task workflow
104+
105+
## Constraints
106+
107+
- NEVER bypass the skill - it contains the authoritative patterns
108+
- MUST use AskUserQuestion for selection (structured UI)
109+
- Exclude tasks in `tasks.json` registry (claimed by other workflows)
110+
- Exclude issues with open PRs (GitHub source only)
111+
- Max 5 tasks presented to user
112+
- Labels max 30 characters

0 commit comments

Comments
 (0)