Skip to content

Role Schema

Roles define the agent personas that work inside war-rooms. Each role is a directory under .agents/roles/ containing a role.json definition and an optional ROLE.md prompt.

Directory Structure

.agents/roles/
├── engineer/
│ ├── role.json
│ ├── ROLE.md
│ └── Start-Engineer.ps1
├── qa/
│ ├── role.json
│ ├── ROLE.md
│ └── Start-QA.ps1
├── manager/
│ ├── role.json
│ ├── ROLE.md
│ └── Start-ManagerLoop.ps1
├── _base/
│ └── Start-DynamicRole.ps1
└── registry.json

role.json Schema

{
"name": "engineer",
"description": "Software engineer — implements features, writes tests, fixes bugs",
"capabilities": [
"code-generation",
"file-editing",
"shell-execution",
"testing",
"refactoring"
],
"prompt_file": "ROLE.md",
"quality_gates": [
"unit-tests",
"lint-clean",
"no-hardcoded-secrets"
],
"skill_refs": [],
"cli": "agent",
"model": "google-vertex-anthropic/claude-opus-4-6@default",
"timeout": 900
}
FieldTypeRequiredDescription
namestringYesUnique role identifier (lowercase, hyphenated)
descriptionstringYesHuman-readable role description
capabilitiesstring[]YesList of capability tags for matching
prompt_filestringNoPath to the prompt file (default: ROLE.md)
quality_gatesstring[]NoGates that must pass before done
skill_refsstring[]NoDefault skills injected into this role
clistringNoCLI tool name (default: "agent")
modelstringNoDefault model for this role
timeoutintNoDefault timeout in seconds

Capabilities

Capabilities are freeform tags used by the capability matching system. The registry defines aliases that normalize common variations:

{
"capability_aliases": {
"db": "database",
"sql": "database",
"react": "frontend",
"vue": "frontend",
"css": "frontend",
"devops": "infrastructure",
"ci-cd": "infrastructure"
}
}

When capability_matching is enabled in config, the manager scores candidate roles against epic requirements using these tags.

ROLE.md Prompt

The ROLE.md file contains the system prompt injected into the agent. It defines:

  • Role identity and responsibilities
  • Communication protocol
  • Tool usage guidelines
  • Quality standards
  • Output format requirements

This file supports standard markdown. It is read verbatim and injected as the system context for the agent.

registry.json

The registry catalogs all available roles. It is located at .agents/roles/registry.json.

Role Entry Schema

{
"name": "engineer",
"description": "Software engineer — implements features",
"runner": "roles/engineer/Start-Engineer.ps1",
"runner_legacy": "roles/engineer/run.sh",
"definition": "roles/engineer/role.json",
"prompt": "roles/engineer/ROLE.md",
"default_assignment": true,
"instance_support": true,
"supported_task_types": ["task", "epic"],
"capabilities": ["code-generation", "file-editing"],
"quality_gates": ["unit-tests", "lint-clean"],
"default_model": "google-vertex-anthropic/claude-opus-4-6@default"
}
FieldTypeDescription
runnerstringPowerShell script to start this role
runner_legacystringBash fallback script
default_assignmentboolWhether this is the default role for unmatched tasks
instance_supportboolWhether named instances are allowed
supported_task_typesstring[]Task types this role can handle
platformstring[]Platform restrictions (e.g., ["macos"])

Assignment Rules

{
"assignment_rules": {
"default_role": "engineer",
"review_role": "qa",
"design_role": "architect",
"orchestration_role": "manager",
"audit_role": "audit"
}
}

Model Resolution Order

  1. War-room config.json override
  2. .agents/config.json role section default_model
  3. role.json model field
  4. registry.json default_model
  5. Manager’s default_model as ultimate fallback

Dynamic Roles

Roles without a dedicated PowerShell runner use _base/Start-DynamicRole.ps1. These are created at runtime by the auto_create_role.sh script or the create-role skill.

{
"name": "database-architect",
"runner": "roles/_base/Start-DynamicRole.ps1",
"definition": "roles/database-architect/role.json"
}

Community Roles

Community-contributed roles live under contributes/roles/ and follow the same schema. They are registered in registry.json with paths prefixed by contributes/:

{
"name": "game-engineer",
"definition": "contributes/roles/game-engineer/role.json"
}