Agents
View as markdownAn agent is a role: a system prompt plus a set of skills. It is the "who" of a piece of work: the orchestrator that schedules, the developer that writes the code, the reviewer that checks it. An agent is deliberately not the issue it's handed, and not the slot it runs in. Those are separate things:
- The issue is the work: a markdown card with a prompt and a branch.
- The workspace is the capacity: a Shelbi session plus a git worktree on some machine.
- The agent is the role: the prompt and skills that decide how the work gets done.
Splitting these apart is what lets the same workspace run a developer agent on one issue and a reviewer agent on the next, and what lets a workflow say "this status is reviewed by the security agent" as a line of YAML rather than a paragraph of prompt prose.
The shipped agents
Every project ships with six agents. Three run the core loop, and three are specialized reviewers:
| Agent | Role |
|---|---|
orchestrator | The agent you talk to. Turns requests into cards, dispatches issues to free workspaces, tails the events log, reports back. Runs in its own orchestrator session (the Orchestrator row in the sidebar), never in a workspace. See Orchestrator. |
developer | The default workspace agent. Implements an issue on its branch, runs the project's checks, writes the review-ready marker. This is the agent the runtime dispatcher runs for an active-category status when no other is named. |
review | The agent named by a review status, run on a review workspace. Its charter is to make the finished branch runnable for a human: it runs the workflow's review: recipe and hands over the URL, or presents the diff when the workflow declares none. It doesn't write code (bar an explicitly requested tweak). |
qa | Exercises a finished change against its acceptance criteria and reports pass or fail with concrete repro steps. It verifies, it doesn't rewrite. |
security | A defensive-only review of the diff: injection, broken authorization, leaked secrets, unsafe deserialization, path traversal, risky dependencies. Reports findings with severity and location. It does not write exploits. |
adversarial | An automated skeptic. It tries to refute the change, defaulting to skeptical, and states what breaks and how to reproduce it, labeling confirmed versus suspected. |
developer runs most often; orchestrator and review bracket it. The
three reviewers ship materialized but unwired: they sit in the agents
directory ready to use, and none governs a column until you name it on a
status's agent: field. That keeps the
default board a plain developer → review loop, and makes adding a QA,
Security, or Adversarial gate a short YAML edit rather than a
shelbi agent new first.
Which role is loaded shows up in the sidebar next to each busy workspace. The
same slot runs developer on one issue and a reviewer role on the next:
Where agents live on disk
An agent is a directory under the project's Shelbi config
(~/.shelbi/projects/<project>/agents/ in global mode,
<repo>/.shelbi/agents/ in in-repo mode):
~/.shelbi/projects/<project>/agents/
├── _shared/
│ └── preamble.md # project-wide context, prepended to every agent
├── orchestrator/
│ ├── agent.yaml # manifest: preferred runner, model, effort
│ ├── instructions.md # the orchestrator's system prompt
│ ├── settings.json # per-agent runner settings
│ └── skills/ # agent-scoped skills (created for every default agent)
├── developer/
│ ├── agent.yaml
│ ├── instructions.md # the developer agent's system prompt
│ ├── settings.json
│ └── skills/
├── review/
│ ├── agent.yaml
│ ├── instructions.md # the Review agent's system prompt
│ ├── settings.json
│ └── skills/ # ships a `load-run-detection` skill
├── qa/ # shipped reviewer preset
│ ├── agent.yaml
│ ├── instructions.md
│ ├── settings.json
│ └── skills/
├── security/ # shipped reviewer preset
│ ├── agent.yaml
│ ├── instructions.md
│ ├── settings.json
│ └── skills/
├── adversarial/ # shipped reviewer preset
│ ├── agent.yaml
│ ├── instructions.md
│ ├── settings.json
│ └── skills/
└── perf/ # ← one you authored with `shelbi agent new`
├── instructions.md
└── skills/Each agent has at minimum an instructions.md: its system prompt. Every
default agent also ships an agent.yaml manifest (its preferred runner,
model, and effort; see Agents configuration),
materializes a settings.json (from its shipped settings
template) and a skills/ directory of agent-scoped skills the runner loads
when that agent is active. Most ship empty, but review/ seeds a
load-run-detection skill. The _shared/preamble.md file is special: its contents
are prepended to every agent's instructions, so project-wide context (the
repo layout, the house style, the test command) lives in one place instead of
being copy-pasted into four prompts. New projects ship it seeded with a short
Hub safety section: agents share one live hub, so a worker must never stop
the daemon or a session, or kill processes by name pattern, from its pane, and
daemon tests run under a temp SHELBI_ROOT with the hub sockets unset. Edit
or extend it freely. A project created before it shipped gets the file on its
next start if it has none, or a config-upgrade finding asking the orchestrator
to merge the section into the preamble it already has.
When an issue is dispatched, the agent named for that status (or developer
for an active-category status with no agent: named) has its rendered
prompt (_shared/preamble.md followed by the
agent's own instructions.md) handed to the runner in the workspace. The
orchestrator's own prompt
is rendered the same way; it's just the agent that runs in the orchestrator session.
Customizing an agent
Agents are project-local with shipped defaults. The first time a project
loads, Shelbi materializes the six default agents into the directory above.
From then on they're yours to edit: change developer/instructions.md to
bake in your repo's conventions, drop a skill into a role's skills/, tighten
the shipped security prompt to your threat model.
The defaults are seeded, and the self-heal on shelbi reload never
clobbers your edits — but that is not the same as "only writes files that
don't exist." Two cases rewrite an existing file:
- Untouched-but-stale files are auto-upgraded in place: if you never
edited an agent file and the shipped default has moved on, reload brings
your copy up to date (
PristineStale). - A customized orchestrator prompt has missing required sections merged
back from the shipped default (
RepairedRequiredSections,MigratedZenCommands), so runner-critical contracts survive an upgrade without discarding your prose.
A genuinely customized non-orchestrator file is left Preserved. New shipped
agents (or new skills) show up; your customizations stay put. If you want to
reset an agent to the current default, use Reset to default in
Settings ▸ Agents, or delete its instructions.md and reload.
Edit an agent by hand, in Settings ▸ Agents (desktop and TUI: instructions, the shared preamble, skills, and manifest fields, plus New, Duplicate, Rename, and Delete), or through the CLI:
shelbi agent list # the six shipped, plus any you've added
shelbi agent show developer # print instructions.md + skills list
shelbi agent edit developer # open instructions.md in $EDITOR
shelbi agent new perf # author a role of your ownSee the shelbi agent reference for the full command set.
Assigning an agent to work
You rarely assign an agent to an issue directly. Instead, a workflow status declares who owns it:
# workflow file: reference-only; name/category live in statuses.yaml
# (qa-review is declared there with category: active)
statuses:
- { id: todo, owner: agent, agent: orchestrator }
- { id: in-progress, owner: agent, agent: developer }
- { id: qa-review, owner: agent, agent: qa }
- { id: review, owner: user }
- { id: done, owner: user }
transitions:
- { from: in-progress, to: qa-review, actions: [push_branch, open_pr] }
- { from: qa-review, to: review, actions: [] }
- { from: qa-review, to: in-progress, actions: [] }
- { from: review, to: done, actions: [merge] }owner: agent makes a status the orchestrator's to act on; the agent:
field names which agent does it. Name it explicitly: a bare
owner: agent with no agent: fails the workflow load. (The runtime
dispatcher does default the primary active status to developer, which is
where the "omit it and you get developer" intuition comes from.) The
qa-review status above is an agent-owned active gate: a branch leaving
in-progress lands there, the daemon dispatches the shipped qa agent onto
it, and qa passes it forward to the human review lane or bounces it back
to in-progress. That's the whole "a reviewer is a role you can drop on a
status" idea, expressed declaratively. (Making the review handoff itself
owner: agent would replace the human review lane rather than add a pass
before it.)
Because qa, security, and adversarial already ship, opting one onto a
gate is a small YAML edit: name it on that status's agent: field. Point
an active-category gate status at agent: security for a defensive
diff pass, or at agent: adversarial for an automated skeptic, and the
daemon dispatches that role onto a free workspace when a branch lands there. No
shelbi agent new first. See
owners for the
rules, and Doing more with agents for a
worked wiring example.
See also
- Workspaces: the capacity an agent runs in, and the agent/workspace split (role vs. slot).
- Workflows: the
owner+agentfields that route work to a named agent. - Orchestrator: the agent in the orchestrator session, and how its prompt is wired.
shelbi agent: list, show, scaffold, and edit agents.