Run the roles¶
Each role runs in its own session (P2). The session that writes the code does not write its tests
or review it. This page shows how to start each role today, after stone render wrote the role
files into your repo.
Checked with Claude Code 2.1.302. The --agent flag loads one role file from .claude/agents/.
Before you start¶
- Make sure that the repo has
.claude/agents/and.cornerstone/manifest.yaml. If not, follow Add Cornerstone to a repo. - Make a branch for the ticket, for example
fix/<slug>. - Have the ticket ready: an issue number, or the ticket text in a file.
Start a role¶
Start each role in a new terminal session. Do not reuse a session from an earlier role.
| Role | Command | Give it |
|---|---|---|
| shaper | claude --agent shaper |
The ticket. Answer its questions until the ticket is ready. |
| planner | claude --agent planner |
The ready ticket. Answer its open questions. App-slice only. |
| implementer | claude --agent implementer |
The ticket, and the plan if one exists |
| tester | claude --agent tester |
The ticket and the branch name. It reads the diff. |
| reviewer | claude --agent reviewer |
The ticket, the branch, the check output, and the decision log |
| investigator | claude --agent investigator |
The ticket or the bug report, and the question to answer. It writes a report. |
The protected-path hook finds the role of the session in this order:
- The role file that the harness loaded. With
--agent, or in a subagent, the hook input names it. - The environment variable
STONE_ROLE, for exampleSTONE_ROLE=tester claude. implementer, if neither names a role.
If the hook blocks a tester or a planner edit with an implementer message, your harness version
does not send the role. Then start the role with STONE_ROLE=<role> claude --agent <role>.
The role sets which paths the session can change:
| Role | Can change |
|---|---|
| planner | The plans path only. Not the specs path. |
| implementer | All paths except tests, checks, CI, .claude/, and .cornerstone/ |
| tester | The test paths only |
| reviewer | No path |
| investigator | The reports path only (paths.reports, default docs/reports/). On a spike/ branch, all paths except .claude/ and .cornerstone/. |
A session with no role is an implementer for the hook. It cannot change .claude/ or
.cornerstone/. Change those files with stone render.
The investigator is the only role with a branch rule. Code on a spike/ branch never merges (K16).
See K16 and the spike branch.
To run a role with no human at the terminal, add -p and the prompt:
claude --agent tester -p "Write the tests for issue #42 on branch fix/login-timeout."
Keep the cost low¶
- Do one ticket in a session. When the role finishes, end the session. Run
/clearor start a new one. - Run the tester and then the reviewer for one ticket. Do not run the roles of many tickets at once.
- Run 2 or 3 sessions at the same time at most. Each session pays the full cost of the always-on context.
- Use a stronger model only for the roles that reason: the shaper, the planner, and the reviewer. The
model profile sets the model of each role (
defaults.role_models). - Show only failures and a summary when a role runs the checks. For example, run
python stone/tests/run_parallel.py -q.
Start a role as a subagent¶
Use this path if you cannot start a session with --agent, for example in the desktop app.
- Start a session with no role.
- Ask it to start the role as a subagent. For example: "Use the tester subagent. Write the tests for issue #42 on branch fix/login-timeout."
- Start a new session for the next role.
The subagent has a fresh context, and the hook uses the role of the subagent. This path is weaker for P2, because the lead session starts the subagent and gives it its prompt. These are the limits:
- Start a role subagent only from a session with no role. If an implementer session starts a tester subagent, the hook lets the subagent change the tests. No check finds this. The reviewer and G4 are the control.
- The lead can change the prompt of the subagent. Give the lead the same ticket text that you give a role session.
- The subagent commits with its own
Role:trailer. If the lead commits the files of the subagent, use the trailer of the subagent role.
Commit with trailers¶
The repo config can change this. With commits.by: human, the implementer and the tester do not
commit. They end with a proposed message, and you commit it. With commits.trailers: notes, the
role goes in a git note, not in the message. With commits.trailers: none, nothing records the
role, and there is no K6. See Commits.
Check K6 reads two trailers on each commit. The agent roles add them. Add them to your own commits too:
git commit -m "fix(auth): renew the token before it expires" \
--trailer "Role: implementer" --trailer "Actor: human"
| Trailer | Values |
|---|---|
Role: |
implementer, tester, investigator, generator (output of stone render, stone spec apply, or stone spec sync), or another role from the workflow model |
Actor: |
human or agent |
A commit with no Role: trailer counts as an implementer commit. K6 fails if an implementer commit
changes a test or a check.
A ticket from another tracker¶
The roles need the ticket text, not a GitHub issue. Save the ticket in a file, for example
.claude/prompts/PROJ-123.txt. Set tickets.source: file and tickets.path:
docs/tickets/{id}.txt in .cornerstone/config.yaml, and render again. The shaper then writes the
Definition of Ready fields into the file, in the section ## Definition of Ready. The other roles
read the ticket from the same path. See Tickets as files.
Run the checks¶
Run commands.all_checks from .cornerstone/config.yaml before you open the PR. CI runs the same
checks again (G3). The CI result is the evidence, not a statement from an agent (P1). With delivery: local, there
is no CI job. Run stone gate and put its output in the PR.
Open the PR¶
Run /cornerstone:ticket-delivery in a new session. It collects the tester, reviewer, and check
evidence for each acceptance criterion. Then it opens the PR. It does not
write tests or a review itself. If one is missing, it tells you which role to start.
Put a Profile: <id> line in the PR body, for example Profile: single-ticket. Check K7 reads it
to find the size limit.
A human approves the PR (G4). A solo developer can approve their own human-centric work only under the solo developer rule.
If a role stops¶
| Stop reason | Action |
|---|---|
| The hook blocked an edit to a protected path | The role must not change that path. If the change is necessary, start the role that owns the path. |
| The checks failed 3 times | Stop the loop. You decide the next step. Record it in the decision log. |
| The tester and the implementer disagree on expected behavior | You decide from the ticket. Add the answer to the ticket, so the next run has it. |