feat(commands): /ready-stack — dispatch with stacking despite open blockers #466
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!466
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "boss/463"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
/ready-stackoperator override: bypasses the "blockers still open" wait and triggers the normal assigned-issue dispatch path now. The existing parent-PR resolver (#462) detects the blocker's open PR and branches the worktree off it so the resulting PR auto-stacks. Posts "no parent PR found, will branch off main" when no blocker has an open PR. Refuses with "clear /hold first" when a hold row exists. Trust-gated like/breakdown.parseHoldCommand's regex so/ready-stackdoesn't trip the/ready(hold-clear) arm — both arms now anchor on a word boundary, with/ready-stackordered first inhandleSlashCommandOtheras defence in depth.slash-commands-othergraph version (gate predicate now includesready-stack) so the flow re-seeds at boot.docs/dependencies.md's Operator overrides.Closes #463
Test plan
bun x turbo run typecheckclean across all 4 packagesbun x @biomejs/biome@^2 check .clean (no errors; 2 unrelated pre-existing infos)bun x turbo run test— 2189 tests pass (includes new parser, hold-collision, and flow-gate tests)/ready-stackon an issue with an open-blocker PR → stacked dispatch/ready-stackon a/hold'd issue → refusal comment, no dispatch/ready-stackon an issue with no open-blocker PR → "no parent PR" comment + dispatch on main🤖 Generated with Claude Code
behavior
event-handlers.ts~line 898: whendispatchIssueForAgentreturnsnull,applyReadyStackCommandreturns a log string but posts no comment to the issue. Every other refusal arm (hold, unassigned, not-an-agent) posts a comment; the operator who typed/ready-stackinto a busy pool gets zero feedback. Fix: add aprobeAdapter.createComment(…).catch(() => {})before thereturn— same pattern as the hold/unassigned arms above.test-gap
applyReadyStackCommand's decision tree has no unit tests. The diff adds parser tests (parseReadyStackCommand) and a regex-boundary test (parseHoldCommanddoesn't match/ready-stack), but the AC item "/ hold precedence honoured" isn't covered at the applier level — there's no test asserting thathasHold → refuse comment, no dispatch. Same gap for the unassigned arm and the dispatch-failure arm. Add a test file (or extenddeps.test.ts) that stubshasHold,getIssue,resolveAgentByUser,resolveParentPr, anddispatchIssueForAgentand walks each branch.Both findings addressed in
27547f2:/ready-stack: dispatch failed — no pool member available for \`...) before returning, same.catch(() => {})` shape as the hold / unassigned / non-agent arms.ApplyReadyStackCommandOptsDI seam onapplyReadyStackCommand(mirrorsresolveParentPr'sResolveParentPrOpts) and walked every branch of the decision tree at the applier level: hold, missing issue, closed, unassigned, non-agent assignee, parent resolved / not, parent probe throws, dispatch returns null, comment failures swallowed. 9 new tests, all 2199 pass.Round-1 findings both landed cleanly: dispatch-fail arm posts a comment before returning, and the full applier decision tree is now unit-tested (hold, unassigned, non-agent, dispatch-failure, success). CI green.