Skip to content

feat(task-board): put a code agent's PR on the board for review - #6344

Open
guitavano wants to merge 1 commit into
mainfrom
guitavano/code-agent-board-tools
Open

feat(task-board): put a code agent's PR on the board for review#6344
guitavano wants to merge 1 commit into
mainfrom
guitavano/code-agent-board-tools

Conversation

@guitavano

@guitavano guitavano commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Summary

A GitHub-imported (or template-clone) coding agent had no way to record work for review after opening a PR. This does the board bookkeeping in code, triggered off the existing PR-open signal, so it's deterministic — with a single focused LLM call for the one judgement that isn't mechanical: is this work already tracked by a card?

Design chosen after discussion: not an always-on system-prompt instruction (the main loop skips it, and it taxes every turn of every coding agent), and not a blind auto-create (loses the dedup judgement). A code hook fires reliably and still delegates the create-vs-update decision to the model.

What changed

  • Reaction on PR-open. reactToPrOpenedForBoard is wired into the PR-open MCP hook (cluster-mcp-tool-hooks.ts onPrOpened). It no-ops for a run that already has a linked card (the Super Agent path — handled by advanceTaskBoardForRun/capturePrForRun), so it can't double up. For an ad-hoc chat with no card it: loads the org's open cards → one generateObject call on the cheap fast tier decides create vs update(taskId) → acts in code: create/update the card in review, link the PR and the thread, and post an optional reviewer note. Best-effort — it never throws into the run that opened the PR.
  • Split for testability. applyBoardDecision (no LLM) performs the storage writes and is covered by a real-Postgres integration test (create; update from an earlier lane; unknown-taskId → fallback create; never regress a done card). The LLM decision (decideBoardActionForPr) is best-effort and degrades to no-op without a model provider.
  • prUrl on CREATE/UPDATE. TASK_BOARD_ITEM_CREATE/UPDATE accept an optional prUrl to link a PR in one call (parsed before any write, so a bad/non-PR URL fails without orphaning a card). Used by the reaction and available for an explicit user request.
  • Scoped board tools at runtime. codeAgentBoardConnection grafts an in-memory SELF connection scoped to TASK_BOARD_ITEM_LIST/CREATE/UPDATE + COMMENT_CREATE onto agents with a checkout — for explicit user asks ("open a PR and put it in review"). Never REVIEW_DECISION/PROMOTE: an agent must not sign off on its own work. Nothing is persisted on the agent, so it covers existing and new agents with no backfill.

Why code, not prompt

  • Reliability — the org-tracking value depends on the card actually reflecting reality; a system-prompt instruction is best-effort per turn. A hook always fires.
  • Cost/latency — the instruction taxed every turn of every coding agent forever; the hook pays one cheap call only when a PR is actually opened.
  • Right trigger — hangs off the existing onPrOpened signal (a real PR was opened), not onThreadFinished (most threads finish without a PR).

Testing

  • Integration (real Postgres): pr-open-board-reaction.integration.test.ts — create / update / fallback / no-regress.
  • Unit: codeAgentBoardConnection inject/skip decision.
  • E2E: prUrl linking on create/update, and rejection of a non-PR URL.
  • bun run check (api/web/e2e), fmt, lint, knip clean.

Follow-up (not in this PR)

  • Tell the user in the chat. There's no SSE-aware "append assistant message" helper, and onPrOpened fires mid-run, so injecting a chat line ("Task created: …") is a separate, delicate change (best done at thread-finish). For now the new/updated card broadcasts live to the board and carries the agent's note as a comment.
  • In a plain chat the closesOwnReview guard doesn't apply, so an imported agent could move its own card in_review → done; left as-is since a human drives the chat.

🤖 Generated with Claude Code

@github-actions github-actions Bot added the claude PR authored by a coding agent label Aug 20, 2026
A GitHub-imported (or template-clone) coding agent had no way to record
work for review after opening a PR. Do the board bookkeeping in code,
triggered off the existing PR-open signal, so it's deterministic — with a
single focused LLM call for the one judgement that isn't mechanical
(is this work already tracked?).

- New reaction reactToPrOpenedForBoard wired into the PR-open MCP hook
  (cluster-mcp-tool-hooks onPrOpened). No-ops for a run that already has a
  linked card (Super Agent), so it can't double up. For an ad-hoc chat with
  no card it: loads open cards → one generateObject "fast"-tier call decides
  create vs update(taskId) → acts in code (create/update the card in review,
  link the PR + thread, post an optional reviewer note). Best-effort; never
  throws into the run. applyBoardDecision is split out (no LLM) and covered by
  a real-Postgres integration test.
- TASK_BOARD_ITEM_CREATE/UPDATE accept an optional prUrl to link a PR in one
  call — used by the reaction and available for an explicit user request.
- Coding agents still get scoped board tools at runtime
  (codeAgentBoardConnection) for explicit asks; the always-on system-prompt
  instruction is dropped in favour of the deterministic hook.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@guitavano
guitavano force-pushed the guitavano/code-agent-board-tools branch from 95a11e3 to 9d4a869 Compare August 20, 2026 17:38
@guitavano guitavano changed the title feat(task-board): let coding agents open a PR into review feat(task-board): put a code agent's PR on the board for review Aug 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

claude PR authored by a coding agent

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant