The mainline of a session normally lives in exactly one place: the first message. Then context gets compacted, that message becomes a summary of a summary, and the session keeps working — confidently, competently — on something else. Nobody notices, because the AI never says "I have changed subject" and the founder is watching output, not direction.
So the mainline moves out of the conversation and into a file the harness restates every turn.
First principle: account, don't intercept. Detours are allowed by default. A gate that blocks teaches the model to satisfy the gate instead of doing the job, and it cannot win anyway — block Write and it uses a shell heredoc, block one tool and it picks another. What actually hurts is not the turn; it's the turn nobody wrote down and nobody came back from.
Opening a session — pin the charter first
Create MISSION.md in the repo root (one per session, git-ignored — it is a working file, not a deliverable). Template: templates/MISSION.template.md.
Do not hand the founder a form. When their first instruction arrives, draft the whole charter yourself from that message plus the state of the repo, then put only the one-line mainline in front of them, phrased so one word answers it:
Mainline: . Reply OK, or tell me in one sentence what you want instead.
Where you genuinely cannot tell, write - [ ] NEEDS FOUNDER: <the specific missing thing> — never invent it, never send back a list of questions.
Four required fields. Each heading is matched by keyword and accepts either its English or its Chinese form (# Mainline: / # 主线:, ## Done when / ## 完成判据, ## In scope / ## 范围内, ## Detour ledger / ## 岔道台账), so a charter can be written entirely in either language against the same installed gates:
| Field | Rule |
|---|---|
# Mainline: |
One line, this exact heading — the gate reads it |
## Done when |
- [ ] items, each observable. "Done"/"production ready" are banned; "suite passes, output pasted" is a criterion |
## In scope |
Paths you may edit, one per line. A scope of ** never fires — that is the same as not installing it |
## Red lines |
Stop and ask. Default-allow does not apply here |
Two more headings appear in the template. ## Detour ledger is parsed by the gates — they count what is still open in it. ## Red lines and ## Parking lot are for you and the founder to read; nothing parses them.
Mid-session — three states, decided in one question
Can the mainline still move today without this?
| Situation | Do |
|---|---|
| It is the mainline | Just do it |
| No — blocked without it | Do it, then log one line in ## Detour ledger: what you did | why the mainline was blocked | how you get back |
| Yes — merely noticed it | Stop now. One line in ## Parking lot, handed back at close. Do not open a second front |
| It touches a red line | Stop and ask the founder, regardless of the above |
When you can't tell, park it. Default to not widening.
Reading drifts too, not just writing. Repo-wide greps and whole documents read end-to-end import another area into context, and the model then takes it over — send wide reconnaissance to a dispatched agent and keep only its conclusion (dispatch-economics).
Closing — balance the ledger, in this order
- Settle detours. Tick
- [x]what's done; move the rest to the parking lot. - Check criteria one by one. Paste command output. Saying "all green" is not evidence (
bad-news-first). - Hand back the parking lot, each item with a suggested destination: new session / write it down / drop it.
- Name the gap. If the criteria are not all met, say so plainly. Detour results are never presented as the mainline delivery.
Failure modes we actually hit
- Mainline only in the first message — the whole reason this skill exists. It must be a file.
- Vague criteria — "make it work" can never be checked, so the charter silently stops meaning anything.
- Detours logged, never ticked — the ledger never balances and the anchor nags forever. That is intentional.
- Scope written too wide — the gate goes silent while still looking installed. List only what you truly intend to edit.
- A per-session instructions file is not a charter — that is read once at startup.
MISSION.mdis restated every turn. If the two disagree, fix it on the spot and tell the founder.
Hardware for all of the above — three gates, plus the parser and its regression suite — is in hooks/. This skill is the practice; those are the enforcement (rules-as-mechanism).