feat(workflow): /next-issue and /wrap-up, with priority labels and an issue claim protocol - #508
Merged
Merged
Conversation
… issue claim protocol
Work is queued on the issues themselves -- priority-0..3, hold, in-progress,
and GitHub's native blocked-by -- instead of hand-maintained tracking issues
whose mirror of the underlying issues drifts.
- .claude/skills/next-issue: a stateless dispatcher. Selects open, unheld,
unclaimed, unblocked issues by lowest priority then oldest; claims by
pushing the branch, labelling in-progress and posting a marker comment;
resolves races earliest-claim-wins; takes over claims silent for 3 days;
dispatches to a new session via Start-IssueAgent.ps1, a subagent for
small settled work, or this session ("here").
- .claude/skills/wrap-up: merges this session's PRs whose exit criteria hold,
parks the rest with a hand-off comment and a claim release, files loose
ends as issues, then reports.
- Sync: the two skill directories are upstream-managed by exact name; the
rest of .claude/ stays the consumer's. Delivery pinned through
Get-UpstreamOps and Invoke-PullSDLC against fixture repos.
- Instructions: the claim protocol and label contract; generic standing
rules (Pester FailedContainersCount, stale issue inventories, hand-applied
rebase is new authorship); repo-specific traps in project.instructions.md.
Closes #498
Closes #500
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fda3nBeB9rJBPdJSmD7sRN
…asserting it; scope the skill tests The independent review (Sonnet 5) raised two Important findings on this PR, and both were accepted. - The wrap-up skill claimed that merging "is pre-authorized by the Merge Step in the shared instructions". Whether that is true depends on each repository's instructions and their version, so the skill cannot assert it. Step 2 now checks the instructions for an explicit merge-without-asking grant. Without one it does not merge. It lists the PR under Needs you as ready to merge, with its evidence and the exact merge command. - The next-issue selection tests matched qualifiers anywhere in the body, so a qualifier that appeared only in prose still passed. The tests now extract the fenced gh issue list block under Step 1 and assert the exact --search argument. The ranking and launcher assertions are scoped to their own sections. - Shipped skill text cites no issue number; example lines use placeholders. Each ablation ran in a scratch copy: - Moving -is:blocked from the command into prose fails the exact-search test. - Reinstating the unconditional claim fails all four new wrap-up assertions. Refs #498, #500 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Fda3nBeB9rJBPdJSmD7sRN
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This replaces hand-maintained tracking issues with a queue that lives on the issues themselves, and adds the two commands that work it.
/next-issue: a stateless dispatcher. It selects open issues that are not held, not claimed and not blocked, ordered by lowestpriority-Nand then oldest, and claims each one before dispatching it. Each issue goes to a new named session (through the existingStart-IssueAgent.ps1), to a background subagent when the work is small and settled, or to this session (here).in-progress, and post a marker comment./wrap-up: for each of this session's PRs whose exit criteria all hold, it checks the repository's shared instructions for an explicit merge-without-asking grant..claude/skills/, which Claude Code turns into slash commands. The sync manifest names exactly those two directories, so the rest of a consumer's.claude/(settings, hooks, its own skills) is never touched.FailedContainersCount; re-scan stale issue inventories; a hand-applied rebase is new authorship.project.instructions.md.Owner decisions (recorded on #498)
/next-issue,/wrap-up.claude/skills/next-issue/and.claude/skills/wrap-up/, by exact directoryIndependent review
The review ran on Sonnet 5, a different model from the Opus 5 author, under an explicit model override. It passed selection (verified live, with #117 on top), the claim race, sync delivery, leak hygiene, and the no-new-command-line-options check. It returned changes requested, with two findings, both accepted and fixed test-first in
d0cf8a7:/wrap-upasserted that merging "is pre-authorized by the Merge Step in the shared instructions". That isn't true onmain, because the grant lives in the held PR fix(dev-loop): merging a finished PR is pre-authorized -- merge, close, clean up, then report #507. Step 2 now checks for the grant and, without it, lists the PR under Needs you instead of merging. Shipped skill text no longer cites any issue or PR number, and a scoped assertion pins that./next-issueselection tests matched qualifiers anywhere in the body. They now extract the fencedgh issue listblock under Step 1 and assert the exact--searchargument. The ranking and launcher assertions are scoped to their own sections.While fixing (2), the first version of the section helpers used
break/continue, which Pester 6 reports as an escaped loop label and fails the whole block. The helpers are now regex-based.Verification
GitHub Actions is billing-blocked, so every result below is a local run with its scope named. All were re-run at
d0cf8a7:.githubsuiteInvoke-Pester -Path .\.githubInvoke-Pester -Path (Resolve-Path .\Pull-SDLC.ai.Tests.ps1).Path.github/agents/tests/issue-queue-skills.Tests.ps1(inside the 71 above)validate-instructions.ymlpatterns and link check, run locally with bashnamematches the directory;descriptionpresentFalsification. Every ablation ran in a scratch copy, never in the worktree:
.claude/prefix fails 9 of 11 sync tests. The 2 that still pass are the "treats as upstream-managed" cases, which a wider prefix also satisfies.-is:blockedout of the Step 1 command and into the surrounding prose fails the exact-search assertion. A qualifier mentioned only in prose no longer satisfies it./wrap-up's unconditional "merging is pre-authorized" sentence fails all four of the new/wrap-upassertions.Functional dry run. I ran the skill's selection query against this repository: 72 candidates. #500, which has open blockers, was correctly excluded.
Assumptions
-Sweephere" (concurrent sessions' branches) is inferred. feat(workflow): replace tracking issues with priority labels, issue claims, and a /next-issue dispatcher #498 states the rule without a reason.Closes #498
Closes #500
🤖 Generated with Claude Code
https://claude.ai/code/session_01Fda3nBeB9rJBPdJSmD7sRN