Stop 3 of 7
One session, end to end
A harness session is a cycle you re-enter, not a checklist you finish. The steps below run in this order every time, and the ones that feel like ceremony are the ones carrying the value.
- 1 · Orient
- 2 · Verify git identity
- 3 · Smoke test
- 4 · Worker epoch check
- 5 · Set effort
- 6 · Decide mode
- 7 · Work (TDD)
- 8 · Close out
The steps, and why each one is there
-
Orient
The SessionStart hook has already injected feature status, the next claimable feature, the last handoff, Active Context, a git-identity warning on mismatch, and any
SESSION_INCOMPLETEgaps left by the previous session. Use the injected block rather than re-reading the files — and resolve surfaced gaps before starting new work. -
Verify git identity
The hook already compared
git config user.emailagainstharness.json. It does not check the SSH identity, so that one is still on you:ssh -T git@github.com. In a multi-account setup this is the difference between a push landing and a push landing as the wrong person. -
Smoke test — a gate, not a diagnostic
Run
./.harness/init.sh smoke_testwithin the first five actions of every session. Its purpose is not to find bugs. It is to establish that the environment was already good before you touched it, so any later failure is provably yours. Fifteen seconds spent here prevents fifteen-minute debugging sessions later.Footgun — pass the argumentinit.sh's own default target isfull_test, notsmoke_test. Run it bare and you silently execute the entire suite instead of the fast gate this step describes. -
Worker epoch check
Compares the live CLI version against the
workerblock recorded inharness.jsonand prompts for a requalification pass on a large delta. It degrades silently when the block is absent or the version will not parse — a prompt, never a gate. The thesis behind it: hold the worker constant for one epoch, and requalify on every material change. -
Set effort
High for architecture decisions, debugging failing tests, and reviewing returned agent work. Medium for the TDD loop and refactoring. Low for formatting, linting, and boilerplate. Adjust as you move between phases — it is not a session-level setting.
-
Decide mode
Single-session or workflow. Declare the choice out loud — "running in single-session mode, I'm both lead and implementer" — so it is a decision rather than a default. The full rule is on the parallel work page.
-
Work, with TDD
Write the failing test that defines done. Confirm it fails — that is what proves the test is valid. Write the minimum code to pass. Confirm it passes. Refactor. Then run the full suite and check coverage on the code you touched.
Treat
context_summary.mdupdates as part of the task, not after it. After any bug fix that reveals a non-obvious root cause, write the gotcha down before moving on. Thirty seconds now, permanent value later. -
Close out
Full suite, then audit
features.jsonagainst what you actually did — touched a tracked feature, update its status,test_fileandcoverage; did work that maps to no feature, create one withdiscovered_via. Then the retrospective, the MLD file, the handoff, and the commit. The checklist is in the reference.
Three files, three different jobs
Newcomers conflate these constantly. They are distinct by design, and all three are
lead-owned: enforce-scope.sh blocks edits to them
regardless of the editing agent's assigned scope. A spawned implementer physically
cannot write them. That is what stops five parallel agents racing on one JSON file.
| File | Read when | Answers |
|---|---|---|
features.json |
Every session start | What is the work, and where does it stand? |
context_summary.md |
Every session start | What did we learn that isn't in the code? |
claude-progress.txt |
Every session start | What was the last shift doing, and what's next? |
mld/<date>-<session>.md |
Never — by guarantee | Raw Mistakes / Learnings / Desires, for human review |
The retrospective and the MLD file are not the same thing. The retrospective is
cumulative analysis appended to context_summary.md that future sessions
read. MLD is a raw, undigested per-session log that nothing reads back into
model context — session-start.sh carries a hard, tested guarantee never
to read .harness/mld/. Writing one does not excuse skipping the other.
Compaction is a planned event
Most people meet compaction by accident, mid-task, and lose the thread. In the harness it is a move you make deliberately at a clean breakpoint — after tests pass for a subtask, after a phase completes — with a focused instruction:
/compact Focus on: current feature F003 state, TDD progress,
decisions made about auth architecture
Context window → compact → re-injection
compact matcher re-injects a
recovery block plus fresh orientation. It is a recovery path, not a crash.
The rule that falls out of this, and the one worth memorizing:
files and tasks survive compaction; conversation prose does not.
If a decision matters, it belongs in context_summary.md or a task —
not in a message you hope stays in the window.