Agent Runtime
Conventions every role obeys. Role files under .agents/roles/ state only what is
specific to their role and defer everything here. AGENTS.md
carries the project-wide coding, commit and terminal rules; this skill covers how a
role operates.
This is also the only file that needs to change to support a second harness.
Running as a role
Prefer spawning the role as a subagent over adopting it in-session. The isolated context is the main reason this workflow is affordable: a stage's file reads, test output and search results never enter the parent thread.
Adopt a role in-session only when you need its output in your working context to continue immediately.
Read the role file before acting as one. Do not improvise a role's boundaries — they exist to keep artifact ownership clean, and the work-protocol gate checks that the right roles ran.
Model tiers
.agents/tiers.json is the single source of truth. Role files declare tier:, never
a model name.
| Tier | Claude | Codex |
|---|---|---|
| deep | opus | gpt-5.6-sol |
| standard | sonnet | gpt-5.6-terra |
| cheap | haiku | gpt-5.6-luna |
Codex needs the full model slug. Bare sol / terra / luna are rejected by the API
("not supported when using Codex with a ChatGPT account").
Escalation: on rework attempt 2 or later, run the role one tier deeper. Cheap models get first crack; expensive ones only see the cases that failed once.
Delegate to the cheap tier for work whose output you do not need verbatim: codebase search, "does this file exist", build and test runs where only pass/fail matters. Do not delegate single file reads or one grep — the spawn costs more than the call.
Committing
Commit with git directly. Conventional Commits, types per AGENTS.md.
- Commit before handing off. The next role must see complete work.
- Amend, don't stack fixups. To correct work you just committed, use
git commit --amend. Never create a "fix the previous commit" commit. - Commit only files your role owns (see below).
Asking
The workflow runs unattended. There are exactly three gates — specification approval, a genuinely contested architecture choice, and UAT for user-visible output changes. They are defined in docs/workflow.md.
Away from a gate, do not block. Record the question and the assumption you are
proceeding on in state.json → open_questions, then continue:
scripts/wp-append.sh --question "Should X do Y?" --assumed "Yes, matching Z"
The accumulated list surfaces at the next gate and in the PR description. This is a deliberate inversion of the old "ask one question at a time and wait" rule, which made unattended runs impossible.
At a gate, ask one question at a time and wait. If you offer alternatives, give pros and cons and a recommendation with its reason.
When genuinely blocked: say you are blocked in one sentence, summarise what is done, state what remains, and ask one question.
Running tests
Use the run-dotnet-tests skill. Never call dotnet test directly — .NET 10 has two
test runners and a direct call from the repo root fails with MSB1001.
Test naming: MethodName_Scenario_ExpectedResult. TUnit is the only test framework in
this project.
Work protocol
Every role appends an entry to <work-item>/work-protocol.md after completing its work
and before handing off:
scripts/wp-append.sh --role "Developer" \
--summary "..." --artifacts "..." --problems "None"
Record problems honestly — the Retrospective reads them, and a problem that was never
logged cannot be fixed. scripts/workflow-gate.sh blocks release when a required role
has no entry.
Artifact ownership
Each artifact has exactly one owning role. Do not edit another role's artifacts; hand back instead.
| Artifact | Owner |
|---|---|
src/, src/tests/ |
Developer |
docs/, README.md (global docs) |
Technical Writer |
docs/workflow.md, AGENTS.md |
Workflow Engineer |
specification.md |
Requirements Engineer |
analysis.md |
Issue Analyst |
architecture.md, docs/adr-*.md |
Architect |
test-plan.md, uat-test-plan.md |
Quality Engineer |
tasks.md |
Task Planner |
code-review.md |
Code Reviewer |
uat-plan.json, uat-plan.md |
Developer (to the Quality Engineer's specification) |
uat-report.md |
UAT Tester |
| UAT PRs and their comments | UAT Tester |
release-notes.md, the PR, the release |
Release Manager |
retrospective.md |
Retrospective |
.agents/, AGENTS.md, scripts/ workflow tooling |
Workflow Engineer |
website/src/ |
Web Designer |
work-protocol.md is append-only, and only through scripts/wp-append.sh.
state.json belongs to the driver. Roles never write stage, status or gates.*
directly — a role that could write a gate field could clear a rejection the Maintainer
had already made. The one field a role sets is arch_contested, and only the Architect
sets it.
Reporting
End a turn with what changed, what is next, and what you need — or "Nothing" if unblocked. Keep it short; the work-protocol entry is the durable record, not the chat.
When handing off, state what you completed, which files you touched, and the specific next action for the receiving role.