Creating Custom Roles
Custom roles extend OSTwin with new agent personas. This guide walks through creating a role from scratch, tagging capabilities, defining quality gates, and submitting it to the community.
Role Anatomy
A role consists of two required files and one optional runner:
.agents/roles/my-role/├── role.json # Machine-readable definition├── ROLE.md # Agent system prompt└── Start-MyRole.ps1 # Optional custom runnerCreating a Role
-
Create the role directory
Terminal window mkdir -p .agents/roles/my-role -
Write role.json
{"name": "my-role","description": "My custom role — does specialized work","capabilities": ["code-generation","data-analysis"],"prompt_file": "ROLE.md","quality_gates": ["output-validated","tests-pass"],"skill_refs": [],"cli": "agent","model": "google-vertex-anthropic/claude-opus-4-6@default","timeout": 900} -
Write ROLE.md
The prompt file defines the agent’s identity, responsibilities, and constraints. Structure it with clear sections:
# My RoleYou are a specialized agent that...## Responsibilities- Primary task description- Secondary task description## Communication Protocol- Post `done` messages when work is complete- Include file lists and test instructions## Quality Standards- Always validate output before reporting done- Include evidence of testing -
Register in registry.json
Add an entry to
.agents/roles/registry.json:{"name": "my-role","description": "My custom role — does specialized work","runner": "roles/_base/Start-DynamicRole.ps1","definition": "roles/my-role/role.json","prompt": "roles/my-role/ROLE.md","default_assignment": false,"supported_task_types": ["task", "epic"],"capabilities": ["code-generation", "data-analysis"],"quality_gates": ["output-validated", "tests-pass"]} -
Test the role
Reference your role in a plan and run it:
### EPIC-001: Test My RoleRoles: my-roledepends_on: [PLAN-REVIEW]A test task for the new role...
Capability Tagging
Capabilities drive automatic role assignment. Follow these guidelines:
| Category | Example Tags |
|---|---|
| Code | code-generation, file-editing, refactoring |
| Review | code-review, security-review |
| Design | architecture-design, ui-detection |
| Testing | testing, automation-testing, performance-testing |
| Data | data-analysis, data-visualization |
| Ops | infrastructure, ci-cd-pipelines |
The registry defines aliases that normalize variations. For example, sql maps to database, and react maps to frontend.
Quality Gates
Quality gates define the minimum bar for a role’s output:
{ "quality_gates": [ "unit-tests", "lint-clean", "no-hardcoded-secrets" ]}{ "quality_gates": [ "verdict-required", "evidence-based-review" ]}{ "quality_gates": [ "design-review", "scalability-check", "security-review" ]}Quality gates are informational — they guide the agent’s behavior through the prompt but are not mechanically enforced.
Runner Scripts
Roles without a custom runner use _base/Start-DynamicRole.ps1. Custom runners are PowerShell scripts that:
- Read the room config
- Build the agent prompt
- Spawn the CLI tool
- Capture and route output
Testing Your Role
-
Unit test the role definition
Terminal window pwsh -Command "Invoke-Pester .agents/tests/roles/ -Output Detailed" -
Integration test with a minimal plan
Create a small plan with one epic targeting your role and run it with
ostwin run. -
Verify channel messages
Check that your role produces properly formatted
donemessages. -
Test with the QA role
Ensure QA can review your role’s output by including it in the lifecycle.
Submitting to the Community
- Place your role under
contributes/roles/my-role/ - Add the registry entry with a
contributes/prefix path - Include a README.md in your role directory describing its purpose
- Open a PR against
developwith therolelabel