Skip to content

feat(agent): panels as universal intent widget — PR panels via wake edited-path, draft-as-review-signal, review notes disposition #98

Description

@gingur

Ask

Make action panels the system's universal intent widget — usable on PRs, not just ask/task issues — and use them to give review verdicts a one-tap follow-up path. Three coupled changes, one ask (they share files and semantics):

1. Draft becomes the review turn's status signal (like 👀 on issue turns)

  • Drop draft from the review workflow's guards (.github/workflows/claude.review.yml) — four guards remain: assignee==bot, PR author==bot, head claude/task-*, same-repo+open. Re-assigning the bot to a ready (LGTM'd) PR must fire a review turn.
  • Review turn kickoff converts the PR to draft (workflow step, gh pr ready --undo — GraphQL, works under pull-requests: write). No-op on first review (already draft); meaningful on re-reviews.
  • Verdict semantics unchanged: LGTM → reviewer flips ready; blocking findings → stays draft. Draft keeps its merge-blocker role on findings (the bot cannot REQUEST_CHANGES on its own PR, so draft is the only merge guard).
  • Failure restore in claude.handoff: on non-success, restore ready iff the PR was ready at trigger time. Pass the trigger-time draft state through as a handoff input (github.event.pull_request.draft from the event payload). Mirrors Unack: signal removed on success and failure alike. A PR that was draft going in stays draft.
  • No trigger loops: draft↔ready conversions emit converted_to_draft/ready_for_review, and the workflow only listens to assigned.

2. Wake carve-out: armed panels on PRs

  • Wake's edited path admits PRs (.github/workflows/claude.wake.yml): keep the !github.event.issue.pull_request exclusion on the created path only (plain PR replies stay inert; assignment remains the PR reply path). The edited gate itself is unchanged — bot-authored + anchored <!-- claude:action-panel --> marker + - [x] + Submit clause. Trust model is identical to issue panels: only write-access users can edit another user's comment.
  • Dispatch is already correct: wake assigns the bot via the issues API; PRs are issues to that API; assignment fires the review workflow. No new dispatch logic.
  • Label gate stays uniform: the implement turn labels its PRs claude-task at creation (prompt contract change in actions/claude.implement/prompt.md). No label carve-out in wake.
  • Panel placement constraint (contract, both prompts): armed panels MUST be conversation-tab comments (issue_comment family). Checkboxes embedded in a review body (pull_request_review) or inline review comments (pull_request_review_comment) are wake-invisible — never put actionable boxes there.

3. Reviewer notes-disposition panel

  • On LGTM-with-notes (actions/claude.review/prompt.md): after submitting the review, post a companion panel comment on the PR — per non-blocking note, two boxes: File as follow-up ask / Address in this PR, plus a final **Submit** box (multi-select, existing wake semantics). Panel copy states that merging the PR closes the window.
  • The next review turn (fired by the tick → assignment) reads the newest ticked panel before anything else: files the "ask" dispositions itself (issue creation, no code), and for "fix in PR" dispositions re-assigns the bot on the task issue — firing a normal implement turn. The reviewer never writes code.
  • Edge contracts: both boxes ticked on one note → fix in PR; if the turn ends without the fix, file the ask. Task issue missing or closed → skip the panel, notes stay in the review body. PR merged before disposition → moot for fix-in-PR; nothing fires on closed PRs (accepted window).
  • Implement prompt (actions/claude.implement/prompt.md): when a turn is fired for a notes disposition, the ticked panel on the PR is the work order.

Pairing / sequencing

Out of scope

  • Inline-review-comment panels (pull_request_review_comment: edited trigger) — noted as a possible phase 2, not built now.
  • Second reviewer identities (system stays single-reviewer-bot).
  • Any change to the created wake path or PR comment-waking.

Acceptance criteria

  • Re-assigning the bot to a ready LGTM'd PR fires a review turn; the PR shows draft while the turn runs and returns to the correct state after (ready on LGTM/failure-restore, draft on findings).
  • Ticking a bot panel on a PR (+ Submit) wakes exactly one review turn (debounced); ticks by the bot itself or in non-panel comments do not.
  • Bot-created PRs carry the claude-task label.
  • An LGTM review with non-blocking notes is followed by a per-note disposition panel; a "file as ask" tick produces a well-formed follow-up ask; a "fix in PR" tick lands an implement turn on the task issue.
  • Handoff failure-restore verified for both prior states (was-ready, was-draft).
  • The hooks parity ask exists and names the exact gate clauses that changed.

Metadata

Metadata

Assignees

Labels

claude-askagent ask issue — operator replies drive turns

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions