Epics and tasks
The epic is the container of the delivery half of the loop; the task is its implementable unit. An epic is born only at promotion — the commitment point — and arrives carrying its full provenance: signal, intent, report, proposal.
The epic pipeline
Plan → Implement → Review → Done (+ Cancelled from any stage)
▲ │
└─── fix ────┘ re-spec ──► Plan
The pipeline is an explicit state machine enforced server-side — an epic’s stage is never a status field someone forgot to update. Loop-backs are counted and recorded, so “this epic took two fix cycles” is a fact you can read, not a memory.
Stage advancement is trailing-edge: a stage completes when no active candidate still has work in it, while individual candidates run ahead — in a tournament, candidate a can be implementing while candidate b is already in review.
Candidates and tournaments
Every epic has at least one candidate — an approach with its own spec and its own branch. A tournament epic (promoted from a full sibling set) has several, racing:
- Each candidate gets a branch named
epic/EPC-n/candidate-<letter>— created in every repository in the epic’s scope, because epics are multi-repo capable and a candidate’s work merges as one coordinated change set. - Candidates move
specing → implementing → in review, endingwon,lost, orwithdrawn. - Review selects the winner on evidence — findings, fix cycles, checks, score impact, cost — and the losing candidates are archived with structured learnings: what was tried, why it lost, insights worth keeping. Learnings can seed future intents.
Cancelling an epic or withdrawing a candidate also requires learnings. Abandoned work teaches; it never just vanishes.
Tasks
Tasks (TSK-n) arrive in bulk from Plan’s decomposition, each belonging to exactly one candidate and one repository. The task machine:
todo → claimed → in progress → in review → done
(blocked ⇄) (reopened for fix directives)
A task is ready when it’s unclaimed and every dependency is done — stella work list --ready is the one query an idle agent needs.
Race-safe claiming
Claiming is built for agent contention:
- Compare-and-swap — a claim presents the state it read; a stale read loses cleanly with
already_claimedrather than an error storm. - Fencing — every claim gets a monotonic version, and claim-scoped writes must present it. An agent that crashed, lost its claim, and came back cannot corrupt the task’s state.
- Leases — claims carry a lease (15 minutes by default) renewed by heartbeats. If an agent dies, the lease expires and the task returns to the ready pool automatically.
Humans assign themselves without leases; humans can release a stuck claim, agents cannot force-unclaim each other.
Sessions and context
A work session records the runner, the resolved model tier, an append-only event timeline (status updates, log lines, commit references, the result), and cost. Before writing code, an implementer reads the full picture in one command:
stella context show TSK-214
The context bundle includes the task, the repository, the candidate and its spec, the epic, the provenance chain, the relevant North Star documents, related reports, comments, and the caller’s claim — nobody starts by reconstructing what the team already knows.
Working with epics and tasks
| Action | Web | CLI |
|---|---|---|
| Epic list / view | Epics | stella epic list, stella epic show EPC-n |
| Stage history | epic view | stella epic stages EPC-n |
| Cancel / withdraw | epic actions (learnings required) | stella epic cancel, stella epic withdraw-candidate |
| Ready work | Tasks | stella work list --ready |
| Claim / unclaim | task actions | stella task claim|unclaim TSK-n |
| Update status | board or task view | stella status update TSK-n --state done |
| Full context | task view | stella context show TSK-n |
The task surface offers a state-grouped list and a drag-validated board, saved views, bulk actions, and a complete keyboard map. There is deliberately no “New epic” button anywhere.