-
Notifications
You must be signed in to change notification settings - Fork 2
Authoring a Project
TRON runs your repo. It owns no work of its own — you hand it a project: a scaffold of committed docs and a register of spec'd blocks, each with a declared, runnable test. The engine reads that scaffold, dispatches the fleet, and gates every claim on evidence. This page is the practical how-to: what a scaffold contains, the anatomy of a block, how the gate turns a declared test into done, and a minimal worked example you can paste and run.
For the model behind it, read Concepts first.
A project is a git repository (TRON works on its trunk, main) with a small
set of committed core docs plus a blocks/ directory. Nothing is generated for
you except pipeline.md statuses — you author the rest and commit it before the
first tron start. TRON front-loads this: an under-specified block or a missing
asset walls rather than improvises.
your-repo/
├── context.md # what this project is (read by every agent + AIDE)
├── principles.md # conduct every agent must follow
├── playbook.md # shared infra memory — agents UPDATE it as they learn
├── policy.md # optional: the acceptance bar (findings ledger)
├── workflow.toml # optional: a project flow overriding the engine default
├── pipeline.md # the permanent block register — ENGINE-owned
└── blocks/
├── block-01.md
└── block-02.md
-
context.md— what the project is, its language/stack, and any global rules that hold at every landing (e.g. "the suite must stay green:python3 -m unittest discover"). -
principles.md— conduct for every agent: trunk is read-only, test-first, small honest commits, ask when ambiguous, judges verify by reading and running (never editing). This is a contract, not decoration — see below. -
playbook.md— durable, project-specific how-to. Agents append to it (on their branch, like any file) when they learn something lasting; judges hold deliveries to it. -
policy.md— optional acceptance ledger (e.g.findings: none). -
workflow.toml— optional. Ship one to override the engine's default flow; it must pass the same lint (invariants intact — see Configuration). -
pipeline.md— the register. You seed the rows; only the engine ever writes a status. A status is the engine's verdict, never an agent's claim.
Seed docs should say "the Orchestrator", not "TRON" — a scaffold is orchestrator-agnostic and must read correctly under a manual or any other driver.
The register lists every block with its dependencies, status, and delivery
branch. You author the id, block, and depends on columns; the engine
stamps status (todo → doing → done) and branch.
# Pipeline — permanent block register
Engine-owned: statuses are stamped by the engine's own verdict.
| id | block | depends on | status | branch |
|:--|:--|:--|:--|:--|
| 01 | block-01 | — | todo | — |
| 02 | block-02 | 01 | todo | — |-
depends onis a register column, not a block-file directive. It lists theids a block waits on (comma-separated;—for none). A block is dispatchable only once its file is ready and every dependency has landed on trunk. The engine dispatches the firsttodorow whose dependencies are alldone, up tomax_parallelin flight. - Pipeline order is only your preference; dependencies are the hard gate.
A block is a Markdown file with two jobs: state the acceptance criteria a human wrote, and declare the test the engine will run to check them. Prose is for the agent; a few reserved directive lines are for the engine.
# Block 02 — the parity helper
test: python3 -m unittest discover
trunk-test: python3 -c "import parity; assert parity.is_even(4) and not parity.is_even(3)"
test-timeout: 300
## Tasks
1. Create `parity.py` with `is_even(n)` returning a bool.
2. Unit tests in `test_parity.py`: at least 4 cases, including
`is_even(4) is True` and `is_even(3) is False`.
3. The whole repository suite stays green.Acceptance criteria are the numbered ## Tasks. Be exact and testable —
the worker builds against them and, before the gate accepts a >>DONE, must
answer >>CONFIRMED evidence=<...> with one line per criterion proving each
was validated. Vague criteria produce weak evidence and bounces.
These are read by the truth gate (engine/gate.py). A directive is any line
whose text (case-insensitively, ignoring leading whitespace) starts with the
key; its value is everything after the first colon. The first matching line
wins; anything else in the file is prose the engine ignores.
| Directive | Read by | What it does |
|---|---|---|
test: <cmd> |
test_cmd |
The block's declared suite. The engine runs it itself — in the worker's arena at >>DONE, and again on the trunk after the landing. A non-zero exit is RED and the claim bounces. Absent = no engine-run test for this block (the gate then rests on commits + untouched trunk only). |
trunk-test: <cmd> |
trunk_test_cmd |
A trunk-only validation. Some obligations can only be checked on the landed trunk (integration across already-landed blocks). The engine runs it on the trunk at the final landing, after the suite, before the block is stamped done. RED here refuses the stamp and pages — no silent landing. |
test-timeout: <seconds> |
test_timeout |
Wall-clock cap for the engine's test runs (both test: and trunk-test:). A positive integer; default 300 (5 min). Raise it for a legitimately long third-party suite so the gate judges by result, not by the clock. A hang past the cap is killed and counts as RED. |
test: and trunk-test: are distinct keys — a trunk-test: line is never
mistaken for the suite, and a lone test: sets no trunk obligation.
Note.
test-timeout:bounds a single test command. It is separate fromturn_seconds(the per-turn wall-clock for an agent, default 900) and fromphase_turns(agent turns per phase). See Configuration.
A >>DONE is a trigger, never proof. The engine derives the facts itself and
walks the block through the pass spine (engine/workflow.toml, see Concepts):
-
build. The worker delivers on its branch in an isolated arena. On
>>DONEthe gate checks: the branch exists with commits beyond trunk, the trunk is exactly where the engine recorded it at assign (trunk is read-only to agents — any movement is a violation), and it runstest:in the arena — green required. Then it challenges the worker:>>CONFIRMED evidence=<...>with per-criterion evidence, or the DONE does not stand. Bounces up togate_fails, then escalates. -
review. A reviewer judges the delivery in its own detached checkout
pinned to the attested sha (it cannot move the branch, and nothing it does
leaks into the delivery).
>>APPROVEDadvances;>>REJECTEDroutes numbered findings back to the same worker, branch unchanged. Every verdict is recorded inreviews.md. -
merge. The same worker owns the merge inside a single engine-wide
window: it brings trunk into its branch, resolves conflicts, proves the suite
green, and replies
>>MERGED. The engine verifies the branch contains trunk (so the landing cannot conflict), then performs the mechanical land (one--no-ffmerge commit) and re-runstest:on the trunk, followed bytrunk-test:if declared. RED on trunk refuses the stamp. -
wrap. Still in the window: the worker updates docs where the block
requires, writes its session log, leaves the tree clean, and replies
>>WRAPPED. Only then does the arena retire.
Done = landed + trunk-green + wrapped. Nothing less is stamped done in
pipeline.md. If a landing leaves the trunk red, the run halts — the fix is a
new remediation block ahead or a corrected spec and restart (boot re-dispatches),
never an in-flight patch to finished work.
TRON isolates work so agents cannot collide or cheat, and principles.md
declares the conduct the reviewer holds them to:
-
Trunk is read-only to agents. Each block runs in its own engine-made
worktree arena on a branch off
main;mainstays checked out in the primary copy, so git itself refuses any second checkout of the trunk. Agents work and commit only on their branch. The engine — never an agent — lands. - Test-first, honest commits. Behavior lands with its tests in the same delivery; nothing uncommitted survives a seat (the session log is part of the delivery). The gate's evidence checks make this enforceable, not aspirational.
-
Ask, don't invent. When a spec is ambiguous the worker raises
>>QUESTION(routed architect-first), rather than guessing a policy. - Judges read and run, never edit. Reviewers verify claims against the repository from a pinned, scrubbed checkout.
Keep principles.md short and literal — it is a contract the fleet is measured
against, so every line should be checkable by reading and running.
A tiny greeter library: block-01 builds the core; block-02 depends on it and adds
a formatter, with a trunk-only check that the two integrate. Python 3 stdlib +
unittest. Create these files, commit them, and point TRON at the directory.
context.md
# greeter — a tiny greeting library
The smallest real project: two Python modules built test-first and delivered
through the Orchestrator's full flow.
- Language: Python 3 stdlib only.
- The suite must stay green at every landing: `python3 -m unittest discover`.
- Display rule: greetings are a single line, no trailing period.principles.md
# Principles — conduct for every agent
1. Work only inside your own working copy; the trunk is read-only to you.
2. Test-first: behavior lands with its tests in the same delivery.
3. Small commits with honest messages; nothing uncommitted survives a seat.
4. When the spec is ambiguous, ASK — never invent a policy silently.
5. Judges verify by reading and running, never by editing.
6. Read `playbook.md` before building; update it when you learn something
durable about this project's infrastructure.playbook.md
# Playbook — shared infra memory
Durable, project-specific how-to knowledge. Agents UPDATE this file when they
learn something lasting; judges hold deliveries to it.
- Run the whole suite from the project root: `python3 -m unittest discover`.pipeline.md
# Pipeline — permanent block register
Engine-owned: statuses are stamped by the engine's own verdict.
| id | block | depends on | status | branch |
|:--|:--|:--|:--|:--|
| 01 | block-01 | — | todo | — |
| 02 | block-02 | 01 | todo | — |blocks/block-01.md
# Block 01 — the greeter core
test: python3 -m unittest discover
## Tasks
1. Create `greeter.py` with `greet(name)` returning `hello, <name>`
(lowercase, one line, no trailing period — project display rule).
2. `greet("")` raises `ValueError` with the message `empty name`.
3. Unit tests in `test_greeter.py`: at least 4 cases covering a normal
name, casing, and the empty-name error.
4. The whole repository suite stays green.blocks/block-02.md
# Block 02 — the shout formatter
test: python3 -m unittest discover
trunk-test: python3 -c "import formatter; assert formatter.shout('sam') == 'HELLO, SAM'"
## Tasks
1. Create `formatter.py` with `shout(name)` that returns `greet(name)`
(from `greeter`) upper-cased.
2. Unit tests in `test_formatter.py`: at least 3 cases, including
`shout("sam") == "HELLO, SAM"`.
3. The whole repository suite stays green.The trunk-test: on block-02 checks the integration of both modules on the
landed trunk — exactly the kind of obligation a single arena suite cannot prove
in isolation.
cd your-repo
git init -b main && git add -A && git commit -m "seed greeter project"
tron start . # from a clone: ./tron start .The bootup asks its short fixed sequence (scope, worker count, ask-before-merge, models); take defaults to run everything. TRON dispatches block-01, gates it to done, then — once 01 has landed — dispatches block-02 and runs its trunk-test on the merged trunk before stamping it done.
Before trusting your specs, watch the flow against fake agents:
python3 evaluation/harness.py project-01 3 # 3 SIMs of a bundled templateThe bundled evaluation/templates/ (project-01/02/03, project-04) are
worked references you can copy from. See Getting Started and
Validation-and-Research.
See also: Concepts · Configuration · Commands · Glossary-and-Events.