
One Package Per Outcome
Side-chat sprawl ends in one six-field package — or a deleted thread
Side chats feel cheap. They are not.
Each one borrows attention, splits context, and leaves tomorrow-you hunting for the conclusion across tabs. When Codex — or any coding agent — is cheap to restart, the default becomes another thread “just for this bit.” Soon you have three half-answers and no place to say yes or no.
One outcome gets one package. Everything else merges into it or dies.
What sprawl looks like
Thread A: the real ask, already drifting. Thread B: a “quick” tangent that grew a branch. Thread C: a paste dump of logs with no owner. None of them has goal, done-when, changed files, verify, or rollback at the top. Review means archaeology.
Productivity here is not opening fewer chats forever. It is refusing to leave an outcome without a single still frame.
Merge or kill
When you notice a side chat, you do exactly one of two things.

Merge. Copy the useful scraps — the real constraint, the file path, the failed command — into the six-field package for the outcome:
- Goal
- Done when
- What changed
- What did not change
- How to verify
- Risk and rollback
Point every related thread at that package (link, path, or PR body). Then close the side chats. The package is the decision surface; the threads are disposable traces.
Kill. Delete the side thread when it has no new goal, duplicates an existing package, is a taste debate without acceptance, or is orphan context with no owner. Keep the files if they matter. Do not keep the chat as a shrine.
If you cannot decide merge vs kill in a minute, the side chat is incomplete. Ask: what outcome does this serve? If none, kill. If one, merge into that outcome’s package.
Why six fields, not a summary
A narrative summary hides missing pieces. The six fields fail closed. Empty verify means the package is not ready for a review clock. Empty “what did not change” means blast radius is unknown. You send it back for packaging — not for more features.
Side chats are where fields go to die. “We talked about rollback somewhere in B” is not rollback. Put it in field six or admit you do not have it.
Rules of thumb
One package per outcome — not per day, not per agent, not per repo. Two outcomes in one PR means two packages, or one outcome was too big.
Do not start a side chat to “ask a quick question” about an active package. Ask inside the package’s thread, or write the one legal question on the package itself.
Do not keep a side chat open as a scratch buffer. Scratch belongs in the working tree or in the package’s “what changed” draft. Chat scratch evaporates.
When an agent offers to “continue in a new conversation,” treat that as a fork. Either the new conversation owns a new outcome card, or it must merge back before review.
Where it usually breaks
Parallel polish: three threads improving the same UI. Freeze one package. Kill the other two after merging any real constraint.
Log pastes as threads: a dump is an artifact. Save it to a file, link it from verify or risk, delete the chat.
Fear of deleting: you keep dead threads because they might contain a sentence. Merge the sentence. Kill the thread. Search is not a package.
You became the merge clerk: every side chat waits for you to reformat it. Paste a blank six-field template into project instructions once. Make packaging the last step of any run that claims an outcome.
A few sharp edges
This pairs with a review gate. The gate needs a package; sprawl is how packages never form. You can run merge-or-kill without a timer — but without it, review stays a reread.
Exploratory threads are allowed. Give them a done-when like “three options ranked, no code.” When that check is met, package the ranking or kill the explore thread. Do not let explore quietly become build.
One package does not mean one file forever. The package can live in the PR body today and a REVIEW.md tomorrow. Continuity is the fields, not the filename.
Stop collecting threads. Collect packages. Merge or kill — then decide.