
Freeze the Tree
Infinite polish kills throughput — ship the thin done-when
Infinite polish feels like quality. It is usually stalling.
A coding-agent run meets the done-when you named. Then someone — you, the agent, a drive-by comment — invents one more improvement. The tree never settles. The review never lands. Throughput drops to zero while everyone stays busy.
Freeze the tree. Ship the thin version that passes acceptance. Schedule polish as a new packaged run.
Done-when is a freeze line
Before the first prompt, name the acceptance check. Not a vibe — a check you could fail in two minutes: a command, a URL, a click path, a file that must exist with a known shape.
When that check passes, you are at the freeze line. Everything below it is out of scope for this run. Edge cases, copy tweaks, refactors that are not required for the check — they go on a list for a later package. They do not reopen this one.

If you cannot point at the freeze line, you never had a done-when. Stop generating and write one. Then continue or kill.
Polish is a new run
Polish is not free. It needs a goal, a done-when, a touched list, and a gate — the same package discipline as the first pass.
“Make it nicer” is not a package. “Reduce the settings form to three fields and keep the existing save path green” is. Write that. Give it its own review. Do not steal the ship-or-kill clock from the thin version to debate taste.
This also protects the agent. Without a freeze, every review invents work. The model happily continues. You get a novel of diffs and no merge.
How freezes usually break
Moving the line: each review quietly expands acceptance. Write the done-when where the package lives and refuse expansions mid-gate. New desire = new run.
Fear of thin: shipping the thin version feels incomplete. Incomplete relative to a fantasy scope is fine. Incomplete relative to the named check is a fail — fix that, then freeze.
Hidden polish in “verify”: the verify step turns into a redesign. Verify means run the named check. Redesign is a different session.
Orphan polish lists: you freeze, then lose the out-of-scope list. Put it in the handoff under Stopped or in a dated NEXT.md. Empty lists are fine. Lost lists come back as chat archaeology.
Soft close
Freeze is a decision, not a feeling. When the check passes, call it. Merge, tag, or explicitly kill — then open a new package if polish still matters.
A receipt that records goal and outcome can hold the freeze line without rereading the thread. You do not need a broker to freeze; you need the line written down.
Ship thin. Package the rest. Keep the tree still long enough to decide.