The Turning language
Turning composes persistent coding agents into finite, ordered team trees. Each team runs its members from left to right for exactly its round count, so t("build",3,builder,critic) means six turns by two agents.
Grammar
team = (t | t:label) "(" [goal ","] [rounds ","] member ("," member)* ")"
member = model[:label] | team
goal = nonblank double-quoted JSON string; required at root, inherited when omitted in nested teams
rounds = integer >= 1; default 1
tokens = model: [A-Za-z_][A-Za-z0-9_.@+/-]*; label: [A-Za-z0-9_][A-Za-z0-9_.-]*; t is reserved- Labels are allowed on the root and on nested teams.
- Trailing commas and extra role suffixes are errors.
- A goal is data, never shell code.
- Base execution is sequential. Nested teams never imply parallel work.
Counting
Every leaf is a distinct persistent agent, even when model names repeat. Coming back to a leaf resumes that agent, while nested rounds multiply turns.
leaves(agent) = 1
turns(agent) = 1
leaves(team) = sum(leaves(children))
turns(team) = rounds * sum(turns(children))t("build",3,builder,critic)2 agents, 6 turns
Addresses and the schedule
Leaves get structural addresses such as root/02/01, and readable role names stay labels. Turns are numbered from 1 across the whole expanded run. In this example root/02/01 acts at turns 2 and 6.
t("Ship the change", 2,
builder:implementer,
t:review("Check the change",
critic:correctness,
critic:operations),
builder:integrator)- t("Ship the change", 2)root
- builder:implementerroot/01
- t:review("Check the change")root/02
- critic:correctnessroot/02/01
- critic:operationsroot/02/02
- builder:integratorroot/03
| Turn | Address | Agent |
|---|---|---|
| round 1 of 2 | ||
| 1 | root/01 | builder:implementer |
| 2 | root/02/01 | critic:correctness |
| 3 | root/02/02 | critic:operations |
| 4 | root/03 | builder:integrator |
| round 2 of 2 | ||
| 5 | root/01 | builder:implementer |
| 6 | root/02/01 | critic:correctness |
| 7 | root/02/02 | critic:operations |
| 8 | root/03 | builder:integrator |
Try an expression
Type an expression to see its tree, its counts and its numbered schedule. The checker runs in your browser and follows the grammar above; it allows spaces and line breaks around parentheses and commas.
4 agents, 8 turns
- t("Ship the change", 2)root
- builder:implementerroot/01
- t:review("Check the change")root/02
- critic:correctnessroot/02/01
- critic:operationsroot/02/02
- builder:integratorroot/03
| Turn | Address | Agent |
|---|---|---|
| round 1 of 2 | ||
| 1 | root/01 | builder:implementer |
| 2 | root/02/01 | critic:correctness |
| 3 | root/02/02 | critic:operations |
| 4 | root/03 | builder:integrator |
| round 2 of 2 | ||
| 5 | root/01 | builder:implementer |
| 6 | root/02/01 | critic:correctness |
| 7 | root/02/02 | critic:operations |
| 8 | root/03 | builder:integrator |
Sessions
Each leaf keeps one persistent session. When its turn comes back, the agent resumes that session and carries its earlier context forward. If the harness cannot resume a session, the coordinator must say that it is reconstructing context from saved records; it never claims private memory persisted. Sessions are never shared between leaves, and a resumed session never switches models.
The board
Every run keeps one message board that all teams can read. Teams keep their local conversations and export handoffs; consequential messages between teams go on the board. A message reaches its recipient at their next scheduled turn. An @mention does not launch a process, and only the assigned owner’s answer closes a request.
update · question · answer · blocker · decision · handoff · ack · steer
- events.jsonl
- The append-only record of messages, turns, decisions and terminal events. Only the coordinator writes it.
- board.md
- The readable board, rendered from the events.
- state.md
- The current goal, decisions, owners, blockers and open requests.
- teams/<address>/thread.md
- Each team’s local conversation.
- agents/<address>/
- Each agent’s role, session, envelopes, results and logs.
- outbox/<address>/
- Messages an agent submits. The coordinator commits them.
- artifacts/
- Versioned handoffs and evidence.
Review modes
Debate is the default review mode: a fixed rotation of lenses over bounded rounds, each turn building on a specific earlier claim, and a close with the decision, the strongest unresolved disagreement and one to three owned next actions.
Converge is an evidence relay: read-only explorers test the most load-bearing premise first while one editor keeps a ranked ledger of what is verified, partial, unverified or resolved. Both are review protocols, not operators in the language.
Finishing
When the planned turns are done, the run records schedule_exhausted. Completion is a separate decision: the coordinator checks the task’s actual acceptance criteria and writes final.md with the result, the evidence, what is unresolved and who owns it. Finishing the rounds is separate from proving that the goal was achieved.
Install the Turning Teams skill so your agent follows these rules.