Roles¶
A role is a named agent definition: a system prompt, an optional model override, and optional skills and per-agent tool permissions. It turns a plain agent into a specialized sub-agent for swarm delegation (see swarm.md). Examples: a researcher who searches the web and keeps findings, a writer who turns findings into prose, a referencer who extracts citations into a .bib file, and an editor who checks text against the original prompt.
What a role bundles¶
A role is a single reusable profile carrying several distinct axes of an agent.
| Axis | What it covers | Field |
|---|---|---|
| Persona | Identity and behavior - the agent's voice, tone, and communication style | system_prompt |
| Function | What the agent does - research, writing, review, implementation | system_prompt + the role's name and description |
| Authority | The scope it may act in - which tools it may use and which are denied | tool_permission |
| Capability | What it can run on - a model override and attached skills | model, skills |
| Expertise | The domains it is tagged for, used for grouping and filtering | tags |
| Archetype | A stored, reusable pattern that teams reference as a stage | the registry entry itself |
The bundled catalog ships two pre-carved teams plus an assistant, a composer, and a leader role, useful as delegation targets and as templates (see teams.md). The assistant is the REPL's default root identity, the composer designs and persists teams, and the leader supervises them. All leave model and skills empty (inheriting the caller's model) and differ mainly in tool_permission (leader also sets grant_permission/ask_policy, composer sets ask_policy):
| role | function | tags | edit | bash | web | read |
|---|---|---|---|---|---|---|
assistant |
REPL root: answers small tasks, delegates bigger work to a composer/leader | management | - | - | - | - |
code-reviewer |
auditor: reviews a change, returns findings | programming, review | deny | allow | deny | allow |
composer |
team composer: designs and persists a team (catalog allow, team deny) |
management | deny | deny | allow | allow |
editor |
auditor: checks a document against the prompt and sources | writing, review | deny | deny | deny | allow |
leader |
supervisor: coordinates teams and agents, delegates, parks asks | research, writing, programming, review | allow | deny | deny | allow |
planner |
decomposes a task into an ordered, verifiable plan | programming | deny | deny | allow | allow |
programmer |
implements a change and runs the tests until green | programming | allow | allow | deny | allow |
referencer |
resolves citations into a .bib file |
writing | allow | deny | deny | allow |
researcher |
gathers and evaluates web sources, returns findings | research, writing | deny | deny | allow | allow |
tester |
writes and runs tests, reports failures | programming | allow | allow | deny | allow |
writer |
turns a findings brief into a document, returns file path | writing | allow | deny | deny | allow |
allow echoes the caller's category default, deny is explicit, and - sets no carve (the caller's config applies unchanged). Override any role by creating a local (or global) entry with the same name.
Storage¶
Roles come from four layers, merged exactly like config: bundled, then plugin, then global, then local, local winning per field. Precedence mirrors bundled plugins (bundled < plugin < global < local):
- Bundled - the read-only default catalog shipped in the package (
src/polyglav/bundled_roles.json). Always present, never writable, overridable by any other layer. - Plugin - roles contributed by plugins via the
register_rolesentry hook (registry.add_plugin(...), see plugins.md). An in-memory layer: never written to anyroles.json, refreshed on/plugins install/update/uninstall. - Global -
~/.config/polyglav/roles.json. - Local -
.polyglav/roles.json.
Merging is field-by-field for the same name: an entry overrides only the fields it sets, so an unset field (e.g. no model) inherits from the layer below.
Schema (per entry):
{
"name": "researcher",
"system_prompt": "You are a web researcher. Gather sources, evaluate them, and report findings.",
"model": "deepseek-r1",
"skills": [],
"tags": ["research", "writing"],
"tool_permission": { "web": "allow", "delegate": "allow" },
"grant_permission": { "web": "allow", "delegate": "allow" },
"ask_policy": { "permission": "auto", "direction": "human" }
}
Fields:
name- unique key of the role.system_prompt- the role's system prompt, injected when it runs.model- optional. Overrides the caller's model when the role runs, falls back to the caller's when empty. Accepts aprovider/modelref (e.g.opencode-go/deepseek-v4-flash) to pin provider and model together. The model must be approved before the role runs (delegate//teams runask interactively, or pass--approve-modelheadlessly, see Model refs and approval).skills- optional list of standing skill names from the skills registry, resolved and injected into the role's sub-agent system prompt (and jobs with--role). A caller may layer additional skills per run throughdelegate/teamor a team stage, so one reusable role carries a stable identity while each task adds its own instructions.tags- optional list of tags for grouping and filtering (/roles list <tag>). The bundled set uses a controlled vocabulary:management,research,writing,programming,review.tool_permission- optional per-agent overrides oftool_permissioncategories. The per-agent permission profile.grant_permission- optional ceiling on the categories this role may hand down to sub-agents. Defaults to the role's owntool_permission, so it never widens delegation unless set explicitly. See Delegation and permissions.ask_policy- optional per-role override of theaskrouting by kind (permission/direction), merged over the configask_policy. See config.md.
Command¶
/roles manages the registry, and /role reports the active role:
/roles- list roles, marking each one's origin (bundled/plugin/local/global/merged) and tags./roles list <tag>- list only roles carrying the tag (e.g./roles list programming). Unknown tags print the known tags./roles new <name> [system prompt]- create a role in the local catalog (edit the JSON for full fields, including tags). Using an existing name overrides that role./roles remove <name>- remove a role from the local catalog. Bundled roles cannot be removed (override them instead)./roles show <name>- show a role's full definition./role- show the active run's role and session, so a focused or delegated run is identifiable at a glance.
Delegation and permissions¶
delegate resolves its permission from the target role rather than from a single tool-level default:
- A configured role uses its own
tool_permissionoverrides. The default for thedelegatecategory isallow(delegation runs without a prompt). Setdelegate: "ask"on a role to confirm each delegation to it. A role withdelegate: "deny"is refused as a delegation target and is not offered thedelegatetool itself. To bar a role from running team pipelines without blocking delegation to it, setteam: "deny"instead (theteamcategory gates only theteamtool). - A temporary role created only to run a task in parallel defaults to
denyuntil you opt in.
Sub-agent permissions are bounded by the caller: the effective carve is the caller's tool_permission, narrowed by the role's carve and capped by the caller's grant_permission ceiling (see config.md). grant_permission defaults to the caller's own tool_permission, so a role can never grant a sub-agent more than the caller holds. A role that sets grant_permission may delegate categories it does not use itself. For example, a supervisor that denies edit/bash for itself but allows them in its ceiling can hand them to an implementer while never running them. An approved ask(kind="permission") request creates a one-shot grant on the asking sub-agent, consumed by the next matching call. The operator may grant always for the rest of that sub-agent's run.
Relationship to /agent, skills, and fleets¶
/agentis the planned interactive way to pick a role and run with it. Today a role runs directly through thedelegatetool (the lead model proposes it, or/tool delegate {"role": ..., "task": ...}), which builds the in-process sub-engine from this catalog.- Skills (a dedicated registry) are a separate capability layer attached to a role, distinct from tools and plugins.
- A role runs either in-process as a sub-engine (the default for delegation) or as a scoped
polyglav serveprocess in a fleet. In-process variants share the caller's privileges, cross-process variants are confined by the target agent's worktree andtool_permission(see fleet.md).