An 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 task it's handed, and not the slot it runs in. Those are separate things:

  • The task is the work: a markdown card with a prompt and a branch.
  • The workspace is the capacity: a tmux pane 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 task 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:

AgentRole
orchestratorThe agent you talk to. Turns requests into cards, dispatches tasks to free workspaces, tails the events log, reports back. Runs in window 1, never in a workspace. See Orchestrator.
developerThe default workspace agent. Implements a task on its branch, runs the project's checks, writes the review-ready marker. This is the agent an agent-owned status uses when no other is named.
reviewThe agent named by a review status, run on a review workspace. Its charter is to make the finished branch runnable for a human. The dev server itself is booted by the status's transition commands, and it hands over a working URL. It doesn't write code (bar an explicitly requested tweak).
qaExercises a finished change against its acceptance criteria and reports pass or fail with concrete repro steps. It verifies, it doesn't rewrite.
securityA 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.
adversarialAn 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 one-line 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 task and a reviewer role on the next:

jlong@hub — shelbi
Tasks · my-project 34 total Workflow: All ▾ Workspace: All ▾ BACKLOG (10) TO DO (9) IN PROGRESS (4) REVIEW (5) DONE (6) Rework onboarding UX Add API ratelimit Deploy staging env Cold-start cache Migrate to PG 16 app app app ⎇ shelbi/deploy… app ⎇ shelbi/cold-s… app Audit OSS licenses Fix mobile nav Wire up OAuth flow CSV import fix Ship dark mode app app app ⎇ shelbi/wire-u… app ⎇ shelbi/csv-im… app Draft Q3 roadmap Wire webhook retries Backfill order index Nightly report Retry dead-letters app app app ⎇ shelbi/backfi… app ⎇ shelbi/nightl… app Migrate CI to arm64 Split OTel spans Trim vendor bundle Validate webhook Redis cache /profile app app app ⎇ shelbi/trim-v…payloads app app ⎇ shelbi/valida… Sunset legacy v1 API Sync i18n strings Add audit logging app app Harden token refresh app app ⎇ shelbi/harden… Add SSO for admins Paginate search API Fix flaky CI tests app app app Prune stale flags Cache user sessions app app Dedupe error reports Add health probes app app Archive S3 buckets Debounce autosave app app Refresh brand assets app
h/l col j/k row open n new f filter r refresh

Where agents live on disk

An agent is a directory under the project's Shelbi config:

~/.shelbi/projects/<project>/agents/
├── _shared/
│   └── preamble.md          # project-wide context, prepended to every agent
├── orchestrator/
│   └── instructions.md      # the orchestrator's system prompt
├── developer/
│   ├── instructions.md      # the developer agent's system prompt
│   └── skills/              # agent-scoped skills (optional)
├── review/
│   ├── instructions.md      # the Review agent's system prompt
│   └── skills/              # ships a `load-run-detection` skill
├── qa/                      # shipped reviewer preset
│   └── instructions.md
├── security/                # shipped reviewer preset
│   └── instructions.md
├── adversarial/             # shipped reviewer preset
│   └── instructions.md
└── perf/                    # ← one you authored with `shelbi agent new`
    └── instructions.md

Each agent has at minimum an instructions.md: its system prompt. It may also carry a skills/ directory of agent-scoped skills the runner loads when that agent is active. 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.

When a task is dispatched, the agent named for that status (or developer by default) 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 happens to run in window 1.

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, not enforced. On upgrade, Shelbi only writes an agent file that doesn't already exist. It never clobbers a file you've edited. New shipped agents (or new skills) show up; your customizations stay put. If you want to reset an agent to the current default, delete its instructions.md and reload.

Edit an agent by hand, 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 own

See the shelbi agent reference for the full command set.

Assigning an agent to work

You rarely assign an agent to a task directly. Instead, a workflow status declares who owns it:

# workflow file — reference-only; name/category live in statuses.yaml
statuses:
  - { id: todo,        owner: agent, agent: orchestrator }
  - { id: in-progress, owner: agent, agent: developer }
  - { id: review,      owner: agent, agent: qa }
  - { id: done,        owner: user }

owner: agent makes a status the orchestrator's to act on; the optional agent: field names which agent does it. Omit agent: and the developer agent is used. The review status above is auto-reviewed by the shipped qa agent before a human ever sees it. That's the whole "a reviewer is a role you can drop on a status" idea, expressed declaratively.

Because qa, security, and adversarial already ship, opting one onto a column is a one-line edit: name it on that status's agent: field. Point a handoff- or active-category status at agent: security for a defensive diff pass, or at agent: adversarial for an automated skeptic, and the orchestrator loads that role into the workspace it dispatches. 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 + agent fields that route work to a named agent.
  • Orchestrator — the agent in window 1, and how its prompt is wired.
  • shelbi agent — list, show, scaffold, and edit agents.