-
Notifications
You must be signed in to change notification settings - Fork 2
Concepts
The model in one page. Everything else is detail.
Blueprint first, model second. TRON's founding principle: a deterministic blueprint — a closed word grammar and an explicit flow table — decides what happens; the model is called only to build and to answer bounded, well-scoped judgments, never to choose a step.
Your work is a pipeline of blocks. Each block ties to a spec and carries a status; the pipeline is
the project's own git-tracked pipeline.md register, written only by the engine. Pipeline order is
your preference; a block's dependencies are the hard gate — a block is dispatchable once its file is
ready and every dependency has landed on trunk.
- Architect — one persistent agent, excluded from the worker pool, forward-looking only. It authors the next block's file (scoping the work ahead) and turns reviewer findings into upcoming blocks. It never reopens finished work — remediation is always a new block ahead. It is also the first responder for anything a worker can't interpret or decide.
- Engineers — build one block each: read the spec, work on their own branch in an engine-made worktree arena, validate against every acceptance criterion, report done. Fresh worker per block.
-
Reviewers — one runs as the
reviewverdict phase on each block's delivery, judging in its own detached checkout pinned to the engine-attested sha, and records a verdict. Want more lenses (code · security · data …)? Add verdict phases in a projectworkflow.toml— there is no scheduler. The engine ships a 5th ready-made persona,auditor(engine/prompts/persona_auditor.md): an independent second review lens that assumes the obvious was already checked and hunts for what a first pass misses — edge cases, spec drift, weak or missing tests, letter-not-intent. Wire it as a second verdict phase when one lens isn't enough.
Engineers and reviewers share the worker pool (max_parallel). The architect does not.
Agents speak to the engine in one closed grammar (engine/glossary.py, rendered in
docs/GLOSSARY.md). The engine reads
exactly one >>WORD field=value line per reply; a word must be legal for the sender's role. Everything
else is void to the engine.
| Sender | Words |
|---|---|
| worker |
>>WORKING · >>QUESTION · >>DONE · >>CONFIRMED · >>MERGED · >>WRAPPED
|
| reviewer |
>>APPROVED · >>REJECTED
|
| architect |
>>TRANSLATED · >>ANSWER · >>ESCALATE
|
| aide |
>>ADVICE (bootup counsel only) |
An uninterpretable reply is not guessed at — it routes sender → architect (translate · answer · escalate) → operator.
engine/workflow.toml composes the process as data; the engine walks it. Each phase is one seat of
work closed by exactly one word:
-
build (work) — the worker delivers, then must answer
>>CONFIRMEDwith per-criterion evidence. The truth gate checks commits exist, the trunk is untouched, and the engine's own test run is green before a>>DONEstands. -
review (verdict) — a reviewer judges the delivery;
>>APPROVEDadvances,>>REJECTEDroutes the findings back to the worker with the branch unchanged. Every verdict is recorded inreviews.md. - merge (work) — the same worker owns the merge inside a single engine-wide window; it brings trunk into the branch, resolves conflicts, proves the suite green, then the engine performs the mechanical land and re-runs the suite on trunk.
- wrap (work) — still in the window: session log + docs + clean working tree. Only then does the arena retire.
Done = landed + trunk-green + wrapped. Bounds are the operator's: phase_turns, review_cycles,
gate_fails, max_parallel (see Configuration).
The pass spine, generated from engine/workflow.toml (the single source — edit there, regenerate, and this stays in sync). Explore it interactively at tron.42labs.io/workflow.
flowchart TD
DISPATCH(["engine: dispatch — fresh arena, branch feat/<block> off main"])
build["BUILD — worker<br>closes >>DONE ⊢ verify_done + AC challenge"]
review{"REVIEW — reviewer<br>>>APPROVED / >>REJECTED (recorded)"}
merge["MERGE — worker<br>closes >>MERGED ⊢ verify_merged<br>window: one at a time"]
wrap["WRAP — worker<br>closes >>WRAPPED ⊢ verify_wrapped<br>window: one at a time"]
LAND["engine: mechanical land + suite re-run ON the trunk"]
REGISTER(["engine: register stamped done"])
DISPATCH --> build
build -->|">>DONE ✓ verify_done"| review
build -.->|"bounce ≤2, then operator"| build
review -->|">>APPROVED"| merge
review -.->|">>REJECTED ≤2 → fix"| build
merge -->|">>MERGED ✓ verify_merged"| LAND
merge -.->|"bounce ≤2, then operator"| merge
wrap -->|">>WRAPPED ✓ verify_wrapped"| LAND
wrap -.->|"bounce ≤2, then operator"| wrap
LAND --> REGISTER
A reviewer's >>REJECTED sends findings back within a block; across blocks, the architect turns real
findings into new upcoming blocks. The fleet keeps moving forward — finished work is never reopened.
Separately from the pass flow, workflow.ESCALATION declares where a stuck or uninterpretable signal
goes — architect-first, always. The architect translates, answers, or escalates. Only what the
architect genuinely can't resolve — an operator-only task, an external blocker, a true impasse — reaches
you. The engine draws this spine as the diagram's exception overlay, from the same table it executes.
Every engine decision is one typed JSON line in events.jsonl (the single measurement source). Crashed
runs recover at boot: stray agent processes are killed, unverified branches are preserved as orphan/*,
and their blocks are re-dispatched fresh — no double-spawn, no lost work.
See also: Architecture · Operations.