Trunk-based
View as markdownTrunk-based development keeps a single always-releasable trunk
(main) and merges small, short-lived branches into it as fast as they go
green. There's no long-lived integration branch and no drawn-out review
column. Work goes from in progress to merged the moment checks pass.
In Shelbi this is the feature-branch model
with the Review handoff collapsed: the merge action moves onto the
InProgress → Done edge. Because
Zen Mode's confidence bar is action-based
(it gates any transition whose actions include merge, regardless of
which statuses sit on either side), that collapsed edge trips exactly the
same high-confidence probe the review-gated model does. Trunk-based is
where Zen auto-merge
earns its keep: the whole point is to land green work without a manual
accept step.
The board
Four columns, no Review. A task branch is cut off main at
In Progress and squash-merged straight back into main at Done,
the moment checks pass and Zen clears the bar.
The workflow
Trunk-based reuses the shipped status catalog
(workflows/statuses.yaml). It just leaves the review status out of the
flow. Identity (name, category) stays in the catalog; the workflow
references statuses by id and adds only owner and agent::
# workflows/trunk.yaml — reference-only (identity lives in statuses.yaml)
name: trunk
description: Trunk-based — short-lived branches, merge to main on green.
git:
base_branch: main
merge_strategy: squash # one squashed commit per task on trunk
statuses:
- { id: backlog, owner: user, agent: orchestrator }
- { id: todo, owner: agent, agent: orchestrator }
- { id: in-progress, owner: agent, agent: developer }
- { id: done, owner: user }
- { id: canceled, owner: user }
initial_status: backlog
transitions:
- from: in-progress
to: done
actions: [push_branch, open_pr, merge, delete_branch]
- from: in-progress
to: canceled
actions: [close_pr, delete_branch]
zen:
checks:
local:
- cargo build --workspace
- cargo test --workspaceThe single in-progress → done transition does the whole cycle: push the
short branch, open a PR into main, squash-merge it, and delete the
branch. There is no handoff-category status because there's no separate
review stage. The zen.checks that run before
the merge bar are the gate.
Orchestrator adjustments
Trunk-based only pays off with auto-merge on, so the orchestrator prompt's
Zen judgment
does the accepting a human would otherwise do at a Review column. Two
tweaks are worth encoding:
## Zen Mode — trunk-based
### Merge conditions
A task on the `InProgress → Done` edge may auto-merge when **all** hold:
1. The workspace has written its review marker (work is complete).
2. `shelbi zen probe` reports every local check green.
3. The diff touches no path in the danger set (migrations, auth, CI).
Otherwise, hold the card in `InProgress` and surface it: "`<task>` is
green but touches `<danger-path>` — merge to main?" Trunk stays
releasable because nothing lands without a green probe.Keep branches short. If a card sits in InProgress long enough to drift
from main, prefer restacking or re-cutting it over a big catch-up merge.
That's the discipline trunk-based trades the review column for.
See also
- Feature-branch — the review-gated version of the same branch-per-task shape.
- Zen Mode — the confidence bar and the
zen.checksthat stand in for a review column here. - Workflows: what fires the high-confidence bar:
why a collapsed
InProgress → Donemerge still trips the probe.