You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
They all have worktrees. They all fork from the same local `main`. They all run tests, rebase, fix conflicts, and eventually want to land. And because this is real life, `main` is also supposed to stay clean enough to push upstream all day.
5
+
Git is not a coordinator.
6
6
7
-
Git gives you the primitives for that world. It does not give you a coordinator.
7
+
That distinction does not matter when one person is working in one checkout.
8
+
It matters a lot when one machine is running five agents, ten worktrees, a
9
+
factory daemon, and a protected local `main` that still needs to stay clean and
10
+
pushable all day.
8
11
9
-
That coordinator is `mainline`.
12
+
That is what `mainline` is for.
10
13
11
-
`mainline` is a local control plane for parallel worktree development. It keeps topic work in topic worktrees, serializes integrations onto protected `main`, coalesces publishes so only the newest protected tip matters, and stores queue state durably so the machine can still explain itself after a crash.
14
+
`mainline` is a repo-local control plane for parallel worktree development. It
15
+
keeps feature work in feature worktrees, serializes integrations onto protected
16
+
`main`, coalesces publishes so only the newest protected tip matters, and keeps
17
+
the whole queue durable so the machine can still explain itself after a crash.
12
18
13
-
This is not a new VCS. It is the missing piece between "Git has branches" and "ten humans and agents are all landing work on the same box."
19
+
This is not a new VCS. It is the missing piece between “Git has branches” and
20
+
“many humans and agents are all trying to land code on the same box.”
14
21
15
22
---
16
23
17
-
## The Bug Is Not In Git
24
+
## The Bug Is Local Coordination
18
25
19
-
The failure mode here is subtle.
26
+
The default workflow looks reasonable:
20
27
21
-
Nothing is obviously broken. Everyone is doing normal Git things:
28
+
1. branch off `main`
29
+
2. work in parallel
30
+
3. rebase occasionally
31
+
4. merge or push when done
22
32
23
-
- branch off `main`
24
-
- work in parallel
25
-
- rebase occasionally
26
-
- merge or push when done
33
+
That works for one person.
27
34
28
-
That workflow is fine for one person.
35
+
It degrades fast under local parallelism:
29
36
30
-
It gets sloppy fast under local parallelism:
37
+
- one worktree rebases while another keeps building on stale `main`
38
+
- conflicts get discovered on the protected branch instead of in the source worktree
39
+
- two publish attempts race even though only one protected tip actually matters
40
+
- an agent gets interrupted and nobody knows what was queued, blocked, retried, or cancelled
31
41
32
-
- one worktree rebases while another is still building on stale `main`
33
-
- conflicts are discovered late, on the protected branch, in the wrong checkout
34
-
- two publish attempts race even though only the newest protected tip matters
35
-
- an agent gets interrupted and nobody can tell what was queued, what was blocked, or what is safe to retry
42
+
The failure mode is not dramatic. It is just expensive. `main` stops being
43
+
boring. Queue state lives in scrollback. Humans and agents start doing careful
44
+
Git surgery by hand.
36
45
37
-
The result is not some dramatic distributed systems incident. It is worse: low-grade local chaos. `main` stops being boring. People start treating the protected branch as a scratchpad. Queue state lives in scrollback and memory.
46
+
`mainline` makes that coordination problem explicit and mechanical.
38
47
39
-
`mainline` takes that coordination problem and makes it explicit.
40
-
41
-
## The Core Idea
48
+
## The Model
42
49
43
50
There is one rule that matters:
44
51
45
52
**`main` is not where feature work happens.**
46
53
47
-
Once you enforce that, the rest becomes mechanical:
54
+
Once that line is real, the rest follows:
48
55
49
-
- feature work happens in feature worktrees
56
+
- feature work happens in topic worktrees
50
57
- submissions are recorded durably
51
-
-integrations happen one at a time
52
-
- conflicts are resolved back in the source worktree
58
+
-integration is serialized
59
+
- conflicts are resolved in the source worktree
53
60
- publish is a separate queue
54
-
- operators can see the queue, retry items, cancel items, and watch the system progress
61
+
- operators can see, retry, cancel, and stream what is happening
55
62
56
-
That is the whole shape of the tool.
63
+
Git still owns refs, rebases, fast-forwards, pushes, and worktrees. SQLite owns
64
+
queue state, locks, and event history. `mainline` coordinates the two.
57
65
58
-
Git stays in charge of refs, rebases, fast-forwards, pushes, and worktrees. SQLite stores the queue, locks, and event history. `mainline` coordinates the two.
66
+
## The Daily Shape
59
67
60
-
## What Using It Feels Like
68
+
The short CLI is `mq`, because that is what it is: the main queue for one
69
+
machine.
61
70
62
-
You do your normal work in a feature worktree. You commit there. Then you hand that branch to the local queue.
The demos are generated from source-controlled VHS tapes in [`docs/demos/tapes/`](docs/demos/tapes/) and can be re-rendered with:
107
+
The demos are generated from source-controlled VHS tapes in
108
+
[`docs/demos/tapes/`](docs/demos/tapes/) and can be re-rendered with:
89
109
90
110
```bash
91
111
./docs/demos/scripts/render.sh
92
112
```
93
113
94
-
## Why The Model Holds Up
114
+
## Why It Holds Up
95
115
96
-
The model is intentionally conservative.
116
+
Because the model is conservative in the right places.
97
117
98
118
- Git is still the source of truth
99
-
-`go-git` handles ordinary repository inspection and config work
100
-
-native `git` is used where exact write-path behavior matters
101
-
-SQLite gives durable local state instead of shell folklore
102
-
-the protected branch stays clean because it is treated as infrastructure, not a workspace
119
+
-the protected branch is treated as infrastructure, not as a workspace
120
+
-the queue survives crashes and restarts
121
+
-conflicts get pushed back to the worktree that owns them
122
+
-publish is coalesced instead of “whatever finished pushing last”
103
123
104
-
That matters if your machine is running Codex, Claude, factory daemons, humans, or all of them at once. `mainline` does not ask those actors to become perfectly disciplined. It gives them a coordinator that turns the safe path into the normal path.
124
+
This is exactly what you want when the machine is running Codex, Claude,
125
+
factory daemons, humans, or all of them at once. `mainline` does not ask those
126
+
actors to become perfectly disciplined. It turns the safe path into the normal
127
+
path.
105
128
106
129
## What Ships
107
130
108
131
`mainline` is already a real toolchain:
109
132
110
-
-repo discovery for standard repos and bare-clone-plus-worktree layouts
133
+
- standard repo and bare-clone-plus-worktree discovery
111
134
- durable SQLite queue state in shared Git storage
112
135
- serialized integration and publish workers
113
-
-`land` for one-command submit-plus-integrate-plus-publish
114
-
-`submit`, `run-once`, `publish`, `retry`, and `cancel`
115
-
-`status`, `watch`, `logs`, `events`, and `confidence`
136
+
-branch submission from topic worktrees and detached SHAs
137
+
-`submit --check-only`, `submit --wait`, and one-shot `land`
138
+
-`status`, `watch`, `logs`, `events`, `doctor`, and `confidence`
116
139
- daemon mode through `mainlined`
140
+
- retry and cancel as real operator controls
117
141
- policy checks, hook coordination, and repo-managed hooks
- versioned GitHub release package assets for package-manager automation
142
+
- Homebrew, Nix, GitHub release archives, checksums, and release manifests
120
143
121
-
This repo also dogfoods the workflow. The committed worktree instructions live in [SKILL.md](/Users/devrel/Projects/recallnet/mainline/.agents/skills/worktree/SKILL.md), and the repo-specific guardrails live in [AGENTS.md](/Users/devrel/Projects/recallnet/mainline/AGENTS.md).
122
-
123
-
It also ships evidence, not just claims: stress runs, soak runs, certification runs against real repo layouts, and a `mq confidence` gate that tells you whether the current build has enough proof behind it.
144
+
This repo dogfoods that workflow. The repo-local worktree instructions live in
That init commit matters. It turns the repo’s queue policy into versioned,
183
+
reviewable state instead of one more local convention that agents have to infer.
160
184
161
-
```bash
162
-
cd /path/to/topic-worktree
163
-
mq submit --check --json
164
-
mq submit --check-only --json
165
-
mq submit --json
166
-
mq submit --wait --timeout 10m
167
-
mq land --json --timeout 30m
168
-
mq run-once --repo /path/to/main
169
-
mq publish --repo /path/to/main
170
-
```
185
+
## The Core Commands
171
186
172
-
For factory or daemon callers, the intended handoff is:
187
+
Setup:
173
188
174
-
-`mq submit --check --json` to fast-fail deterministic problems before queue mutation
175
-
-`mq submit --check-only --json` for the stricter dry-run path: clean worktree, current protected tip included, and no duplicate active submission for the same branch SHA
176
-
-`[integration].MaxQueueDepth` to stop dead queues from silently accumulating unbounded queued branches
177
-
-`mq submit --json` to record the branch and get a stable `submission_id`
178
-
-`mq submit --wait --timeout 10m` when an agent needs a blocking landed-or-blocked answer without implementing its own poll loop
179
-
-`mq events --follow --json --lifecycle` to subscribe once instead of polling
180
-
-`mainlined` or `mq land` to carry the branch the rest of the way to integrated and published state
If `origin/main` advances before your branch reaches the front of the queue, that is normal queue work, not a manual repair job. `mainline` syncs protected `main` from upstream before integration when policy allows it, records that as a durable event, and only blocks if the branch now has a real rebase conflict.
214
+
## Repository Layouts
197
215
198
-
`mq submit --wait` is integration-scoped, not publish-scoped. It exits `0` when the branch is integrated, `1` for blocked/failed/cancelled outcomes, and `2` on timeout.
216
+
`mainline` supports both:
199
217
200
-
If a repo sets `[integration].MaxQueueDepth`, `mq submit` will reject new queued work once that many submissions are already waiting. Use `mq submit --check-only --json` when an agent wants a cheap preflight without consuming queue capacity.
218
+
- normal repos with `.git/` inside the checked-out worktree
219
+
- bare-clone storage with linked worktrees, such as
220
+
`~/Projects/.bare/owner/repo.git` with `~/Projects/owner/repo`
201
221
202
-
`[checks].CommandTimeout` is per-repo and now defaults to `5m`, which is a better fit for real pre-integrate gates. `mainline` still enforces a hard ceiling of `15m`, and a hung pre-integrate check blocks the submission with `blocked_reason = "check_timeout"` instead of letting one branch freeze the queue forever.
222
+
For bare-clone layouts, queue state and locks live with shared Git storage so
223
+
every worktree sees the same queue truth.
203
224
204
-
Observe and control:
225
+
## Architecture
205
226
206
-
```bash
207
-
mq status --repo /path/to/main --json
208
-
mq watch --repo /path/to/main
209
-
mq logs --repo /path/to/main --follow
210
-
mq retry --repo /path/to/main --submission 17
211
-
mq cancel --repo /path/to/main --publish 4
212
-
mq confidence --repo /path/to/main --json
213
-
mq version
214
-
```
227
+
The design is intentionally small.
215
228
216
-
Daemon mode:
229
+
-`go-git` handles ordinary inspection and config work
230
+
- native `git` is used where exact write-path behavior matters
231
+
- Git answers topology and branch semantics
232
+
- SQLite answers ordering, durability, coordination, and audit history
0 commit comments