Agents
PABLO ships five agents, run by OpenCode, Claude Code or GitHub Copilot CLI (see agent_runtime). Four read and analyse, and never touch your code; the fifth resolves rebase conflicts. Each one is launched by a specific state, with the right link and the right worktree, so you read results instead of writing prompts.
The agents#
| Agent | Launched on | What it does |
|---|---|---|
| task-analyst | in-progress, once per task | Reads the issue (GitHub, Jira or Linear), its parents, linked pull requests and the relevant code, and writes a summary and a grounded action plan. For a prompt task, it applies the same method to your prompt. |
| ci-analyst | ci-red | Fetches the failing checks and their logs, ties each failure to the responsible code, and proposes a fix plan. It never changes the pull request. |
| pr-feedback | request-changes | Reads unresolved review threads, review bodies and comments, and turns them into a fix plan grouped by topic. When it finishes, the pull request goes back to draft. |
| task-feedback | testing-failed | Compares QA's feedback with what the pull request really ships, classifies each point, and drafts a reply in the language QA used. When it finishes, the pull request goes back to draft. |
| rebase-conflict-resolver | a sync rebase hits a conflict | Replays the rebase, resolves every conflict and pushes with --force-with-lease. See below. |
Open an agent's session in Orca or OpenChamber to read its result and keep the conversation going: ask questions, push back, refine the plan. A headless Claude Code run reopens with claude --resume <session id> in the worktree, a Copilot one with copilot --resume=<session id>.
The rebase-conflict resolver#
The single deliberate exception to the read-only rule. When an applied sync hits conflicts, git aborts cleanly and PABLO launches this agent headless. It may edit files and run git, because that's its job, but it is denied anything that acts as you in front of other people: no gh pr merge, review, comment, edit, ready or close, no issue commands, no Jira commands. If a conflict needs a human, it stops and pushes nothing. It has no step limit, so it never stops halfway through a rebase.
Everything it does lands in your pull request, which you review before merging. The dashboard's “Last sync” card shows the command to open its session: opencode -s <id>, claude --resume <id> under Claude Code, or copilot --resume=<id> under Copilot (its handle is recorded as copilot:<uuid>, so it can't be mistaken for a Claude Code session).
Read-only, enforced#
The analysis agents can't edit files and can only run read-only commands, by permission rules in their OpenCode frontmatter, not just by instructions in their prompt. Even if a ticket says “just fix it quickly”, they can't. Under Claude Code the same rules are translated and enforced by Claude Code itself (below), and under Copilot by Copilot CLI (below).
permissions:
- { action: edit, resource: "*", effect: deny } # edit, write, patch
- { action: shell, resource: "*", effect: deny } # nothing runs by default…
- { action: shell, resource: "git *", effect: allow } # …except git
- { action: shell, resource: "git push *", effect: deny } # …but never a pushEvery agent also follows shared house rules: use tools sparingly (batched calls, bounded logs and diffs), write in English, never post or edit anything on GitHub without your explicit approval in the session (they draft the text, you post it), and never commit or push.
Context fetched up front#
Every step an agent takes re-reads its whole context, so steps are what cost tokens. Before launching an analyst, PABLO fetches the obvious context with read-only commands and appends it to the prompt (up to about 24,000 characters):
- task-analyst, task-feedback: the issue's title, details, description and latest 15 comments;
- ci-analyst: the failing checks (minus ignored ones) and, for up to 3 GitHub Actions jobs, their error lines and the end of their logs;
- pr-feedback: unresolved threads, review bodies and comments.
It's best-effort: if fetching fails, the agent fetches by itself. It's skipped with Orca, where the prompt travels on a command line.
Step limits#
Analysts have a step budget (30 for task-analyst and ci-analyst, 25 for pr-feedback and task-feedback). On the last step OpenCode removes their tools and forces a written answer. Sending them a new message resets the budget.
Claude Code and Copilot CLI have no per-agent step limit, so there the budget becomes an instruction at the end of the agent's prompt: write the deliverable at the latest on the last step. It is followed, not enforced; the watcher's one-hour timeout stays the hard backstop.
Which model#
The model is picked at launch time, from your configuration: the project's default_model, else the one for the project's type in default_model_by_type, else the global default_model. See Choose the agent model.
The commit command#
/pablo-commit-and-pr commits, pushes, opens a draft pull request and moves the task to draft. It's the only part of PABLO that runs as an agent command (OpenCode, Claude Code, or a skill under Copilot), because writing a good commit message and pull request description is where an agent beats plain code. It never changes your git identity. How to use it: Ship your work.
The skill#
The pablo-task skill teaches your other agents one thing: how to create a PABLO task (pablo task:start with an issue link, or --project and a prompt). The installer links it into ~/.config/opencode/skill/, into ~/.claude/skills/ under Claude Code, or into ~/.copilot/skills/ under Copilot.
Under Claude Code#
With agent_runtime: claude-code, the same templates are translated rather than rewritten, so the runtimes always run the same prompts and the same guardrails.
- Where the agents live.
pablo system:generate-agentswrites all five into~/.pablo/claude/agents.json, which every launch passes with--agents. The same agents are also rendered aspablo-<agent>.mdfiles in the git-ignoredclaude/agents/and linked into~/.claude/agentsby the installer, so they show up in/agentsand the@picker of your own sessions. Those files only carry tool-level limits: the per-command shell denies (such asgit push) are launch flags and apply only to PABLO's own launches. - How they launch.
claude -p --agents … --agent <name> --model <default_model> --session-id <id> --strict-mcp-config, plus the permission flags below. - No permission prompts. The analysts run with
--permission-mode dontAsk(anything not allowed is denied), the resolver withacceptEdits.
The permissions map as follows:
| OpenCode rule | Claude Code |
|---|---|
read, grep, glob, webfetch | the Read, Grep, Glob, WebFetch tools |
edit * | Edit, Write and NotebookEdit |
skill * | Skill |
shell * allowed | Bash |
shell "git commit*" denied | Bash(git commit*) and Bash(rtk git commit*) in --disallowedTools |
Whole tools are allowed or denied both in the agent definition and on the command line. Command patterns only go on the command line: in an agent definition, a Bash(…) entry removes the whole Bash tool. Claude Code matches * anywhere, so patterns such as *acli jira workitem edit* keep their meaning.
The commit command is rendered into claude/commands/ (git-ignored) and linked into ~/.claude/commands/. Its body, the !`…` context injection and $ARGUMENTS work as in OpenCode, and its allowed commands become allowed-tools (raw and rtk forms again). One limit: a Claude Code command can't deny a tool, so “no edits” is an instruction in its hard rules rather than a permission.
Under GitHub Copilot CLI#
With agent_runtime: copilot, the same templates are translated once more, so all three runtimes run the same prompts and the same guardrails.
- Where the agents live.
pablo system:generate-agentsrenderscopilot/agents/pablo-<agent>.agent.md(git-ignored) for the five agents, and the installer links them into~/.copilot/agents/. Unlike Claude Code, they're deliberately visible, with apablo-prefix, so you can pick them in your own Copilot sessions too. - What an agent file holds.
name,descriptionandtools(Copilot aliases:read,search,execute,web,edit), and nomodel:line: in Copilot an agent file's model would override--model. - How they launch.
copilot --agent pablo-<agent> --model <default_model> --session-id <uuid> --no-ask-user --no-auto-update --no-color --disable-builtin-mcps --available-tools … --allow-tool … --deny-tool … -p '<prompt>'.--available-toolslists exactly the built-in tools the agent may use (the analysts:view,grep,glob,web_fetch,bash; the resolver:view,bash,edit,create), which also hides your MCP tools;--disable-builtin-mcpsturns off Copilot's built-in MCP servers. Your own custom instructions (AGENTS.md…) and hooks still load.
The permissions map as follows:
| OpenCode rule | Copilot CLI |
|---|---|
read * allowed | tool view, --allow-tool read |
grep, glob | tools grep, glob |
webfetch | tool web_fetch, --allow-all-urls |
shell * allowed | tool bash, --allow-tool shell |
edit * allowed | tools edit, create, --allow-tool write |
edit * denied | --deny-tool write |
skill denied | skill left out of the available tools |
shell "git push*" denied | --deny-tool 'shell(git push)' and 'shell(git push:*)', plus shell(rtk git push) and shell(rtk git push:*) |
Copilot matches a command prefix, so leading and trailing * are dropped: *acli jira workitem edit* becomes acli jira workitem edit. A pattern with a * in the middle can't be translated, and generation fails. In Copilot a deny always wins over an allow. The command patterns only exist on PABLO's launches: when you run a pablo-* agent by hand, only the visible tools from its agent file apply.
The step budget works as under Claude Code: no per-agent limit, so it becomes an instruction at the end of the prompt.
Copilot has no !`…` context injection, so the commit command becomes a skill, copilot/skills/pablo-commit-and-pr/SKILL.md, linked into ~/.copilot/skills/. Its context section tells the agent to run those commands first, and disable-model-invocation: true keeps the model from running it on its own: only you typing /pablo-commit-and-pr does. The “no code edits” rule is restated in its hard rules, and --force still works as part of your request.
Customise the agents#
The agent files are generated, not written by hand. Edit the sources in the repository, then regenerate:
pablo system:generate-agentsopencode/agents/*.md.template: one per agent, with its own description and prompt;opencode/agents/shared/analysts.frontmatter.md: the read-only permissions shared by the four analysts;opencode/agents/shared/resolver.frontmatter.md: the resolver's permissions;opencode/agents/shared/housekeeping.body.md: the house rules appended to every agent.
The same sources produce the Claude Code agents.json and command when agent_runtime is claude-code, and the Copilot agent files and skill in copilot/ when it is copilot. Templates pull these in with {{SHARED_FRONTMATTER:<profile>}} and {{SHARED_BODY:<profile>}}, and the task agents get tracker-specific instructions through {{ISSUE_TRACKER_SECTION}} and {{ISSUE_TRACKER_NAMES}}, filled in for the trackers your projects use. Generation runs on install, and again when pablo project:new or pablo project:remove changes the set of trackers. Never edit the generated .md files: they're overwritten.