Summary
Replace the fixed worker pipeline (agent → commit → push → PR) with a capability-based model where the agent decides which actions to take. The worker provides tools (push code, post review, leave comment, etc.) and the agent invokes whichever combination makes sense.
Motivation
Today the worker unconditionally runs: run_agent → prepare_commit → push_branch → pr_create. Every run produces a branch and PR, even when the right response might be a review comment, an approval, or doing nothing.
This prevents use cases like:
@bot mentioned on a PR the bot didn't create → agent reviews and comments
- Agent finds nothing to fix → posts "looks good" instead of an empty PR
- Agent finds a bug AND fixes it → pushes code AND explains the fix in a comment
- Future actions we haven't thought of yet
Rather than adding mode flags (--review, --comment-only) and deciding upfront, the agent should assess the situation and pick the right actions.
Design
Current flow (fixed pipeline)
trigger → run agent → prepare_commit → push_branch → pr_create → done
Proposed flow (agent-driven)
trigger → set up workspace → run agent with available actions → report outcomes
Worker becomes a capability provider
The generic part stays: clone repo, checkout branch, set up workspace, write instructions. After that, the agent runs with a set of available actions it can invoke:
| Action |
What it does |
push_changes |
Stage, commit, push branch, create/update PR |
post_review |
Submit a PR review with inline file/line comments |
post_comment |
Post a general comment on the issue/PR |
approve |
Approve the PR |
request_changes |
Request changes on the PR |
| (future) |
Whatever new capabilities we add |
The agent can invoke any combination — push a fix AND leave a comment, or just approve, or do nothing.
How actions are exposed to the agent
This depends on the agent runtime:
- Claude/direct runtimes: Tool definitions passed to the model. Agent calls them as tool use.
- Goose: Extensions or shell commands the agent can invoke.
- Any runtime: At minimum, the agent can write structured output (e.g., a JSON actions file) that the worker interprets post-run.
The simplest starting point is probably a structured output contract: the agent writes an actions.json (or similar) declaring what it wants to do, and the worker executes those actions. This works across all runtimes without runtime-specific tool integration.
Worker post-agent execution
Instead of hardcoded stages, the worker reads the agent's requested actions and executes them:
1. Parse agent output / actions file
2. For each action:
- push_changes → git add, commit, push, create/update PR
- post_review → GitHub API: create review with inline comments
- post_comment → GitHub API: post comment
- approve → GitHub API: submit approval
3. Record all executed actions in meta.json
If the agent requests no actions (or no actions file exists), the worker falls back to current behavior for backwards compatibility.
meta.json changes
Currently records PRNumber, PRURL, HeadSHA. Extend to capture all actions taken:
{
"actions_taken": ["push_changes", "post_review"],
"pr_number": 42,
"pr_url": "...",
"head_sha": "abc123",
"review_id": 789,
"comments_posted": 1
}
Orchestrator changes
finalizeDetachedRun() currently derives status from whether a PR was created. With multiple action types:
- Any action succeeded →
StatusSucceeded
- PR created →
StatusReview (existing, preserved)
- No actions, no error →
StatusSucceeded
- Error →
StatusFailed
Notification posting adapts based on which actions the agent took — don't post a completion comment if the agent already posted its own.
Relation to #191
Issue #191 (configurable bot identity) gives the agent a name and identity. This issue gives it agency. Together they enable: @my-agent on any PR → agent assesses the situation → takes whatever actions make sense → posts under its own identity.
The bot identity work (#191) should land first since the agent needs a token to post reviews/comments as itself.
Key files
internal/worker/worker.go — Pipeline stages to refactor into conditional actions
cmd/rascal-runner/main.go — Runner entry point
internal/orchestrator/execution.go — finalizeDetachedRun() status logic
internal/orchestrator/notifications.go — Post-run comment logic
internal/orchestrator/webhook.go — Trigger handling (needs @mention support)
internal/github/client.go — Needs PR review API support (create review, inline comments)
Implementation phases
- Action contract — Define the structured output format agents use to declare actions
- Worker refactor — Make post-agent stages conditional based on agent output
- Review/comment actions — Implement
post_review and post_comment via GitHub API
@mention trigger — Webhook handler recognizes bot mentions on any PR/issue
- Agent instructions — Update instruction templates to explain available actions
- Backwards compat — If no actions declared, fall back to current push+PR behavior
Summary
Replace the fixed worker pipeline (
agent → commit → push → PR) with a capability-based model where the agent decides which actions to take. The worker provides tools (push code, post review, leave comment, etc.) and the agent invokes whichever combination makes sense.Motivation
Today the worker unconditionally runs:
run_agent → prepare_commit → push_branch → pr_create. Every run produces a branch and PR, even when the right response might be a review comment, an approval, or doing nothing.This prevents use cases like:
@botmentioned on a PR the bot didn't create → agent reviews and commentsRather than adding mode flags (
--review,--comment-only) and deciding upfront, the agent should assess the situation and pick the right actions.Design
Current flow (fixed pipeline)
Proposed flow (agent-driven)
Worker becomes a capability provider
The generic part stays: clone repo, checkout branch, set up workspace, write instructions. After that, the agent runs with a set of available actions it can invoke:
push_changespost_reviewpost_commentapproverequest_changesThe agent can invoke any combination — push a fix AND leave a comment, or just approve, or do nothing.
How actions are exposed to the agent
This depends on the agent runtime:
The simplest starting point is probably a structured output contract: the agent writes an
actions.json(or similar) declaring what it wants to do, and the worker executes those actions. This works across all runtimes without runtime-specific tool integration.Worker post-agent execution
Instead of hardcoded stages, the worker reads the agent's requested actions and executes them:
If the agent requests no actions (or no actions file exists), the worker falls back to current behavior for backwards compatibility.
meta.json changes
Currently records
PRNumber,PRURL,HeadSHA. Extend to capture all actions taken:{ "actions_taken": ["push_changes", "post_review"], "pr_number": 42, "pr_url": "...", "head_sha": "abc123", "review_id": 789, "comments_posted": 1 }Orchestrator changes
finalizeDetachedRun()currently derives status from whether a PR was created. With multiple action types:StatusSucceededStatusReview(existing, preserved)StatusSucceededStatusFailedNotification posting adapts based on which actions the agent took — don't post a completion comment if the agent already posted its own.
Relation to #191
Issue #191 (configurable bot identity) gives the agent a name and identity. This issue gives it agency. Together they enable:
@my-agenton any PR → agent assesses the situation → takes whatever actions make sense → posts under its own identity.The bot identity work (#191) should land first since the agent needs a token to post reviews/comments as itself.
Key files
internal/worker/worker.go— Pipeline stages to refactor into conditional actionscmd/rascal-runner/main.go— Runner entry pointinternal/orchestrator/execution.go—finalizeDetachedRun()status logicinternal/orchestrator/notifications.go— Post-run comment logicinternal/orchestrator/webhook.go— Trigger handling (needs@mentionsupport)internal/github/client.go— Needs PR review API support (create review, inline comments)Implementation phases
post_reviewandpost_commentvia GitHub API@mentiontrigger — Webhook handler recognizes bot mentions on any PR/issue