Course · Codex · Daily workflow
Recover when a run goes sideways
Even with sharp briefs and the right posture, runs go sideways. The agent latches onto a fix that doesn’t hold and keeps retrying it. It misreads the taxonomy and starts recategorising in the wrong direction, confidently, across a hundred rows. It edits a file, the test fails, it edits it back, the test fails again - a loop. None of this is a crisis. It’s the ordinary failure mode of working with an agent, and the recovery is a small, repeatable procedure. The operators who trust the tool are not the ones whose runs never go wrong; they’re the ones who notice early, assess cheaply, and choose the right reset.
Interrupt the moment you see the loop
Section titled “Interrupt the moment you see the loop”The expensive mistake is watching. A loop costs tokens and time for every turn you let it spin, and the diff grows with each pass, so the cleanup you’ll owe later is bigger the longer you wait. The moment you recognise the pattern - the same edit reappearing, the same failing test rerun with a cosmetic tweak - interrupt. Don’t wait to see if the next iteration is the one that works; you’ve already seen it won’t.
Interrupt, then look before you speak. The instinct is to immediately type “no, stop, do it differently,” but that’s a nudge on top of a confused context, and the last lesson explained why nudging a misread run is the slow road. First find out what actually happened.
Review the damage cheaply
Section titled “Review the damage cheaply”Before you read a single line of the diff, get the shape of it. git diff --stat tells you which files changed and by how much, in one glance:
> !git diff --stat
src/importers/monzo.py | 42 ++++++++++++----------- src/budgetcli/categorise/rules.py | 8 ++--- tests/test_categorise.py | 3 +- 3 files changed, 26 insertions(+), 27 deletions(-)That one command answers the first question - how big is this, and where - without reading anything. Three files, modest churn, and the test file barely moved, which already tells you the agent was editing implementation against an unchanged expectation. Only now do you read, and you read targeted: the specific hunk that’s wrong, not the whole diff top to bottom. git diff src/budgetcli/categorise/rules.py for the one file you suspect, or your editor’s diff view for the rest. The discipline is the same one you’d apply to a colleague’s pull request - survey first, then zoom into the suspicious part - and it’s faster here because you’re the one who has to decide whether to keep any of it.
This is also where the budget-audit profile pays off in reverse: if the run was exploratory and you’d kept the sandbox read-only, there is no diff to review at all, and “recovery” is just asking a better question.
Steer the session, or clear it
Section titled “Steer the session, or clear it”With the damage assessed, you have two choices, and the decision is simpler than it feels.
Steer the current session when the context is still mostly right and only the last move went wrong. The agent knows the codebase, the brief, the constraints - you just need to point it off the one bad path. A short, specific correction works: “the running balance is per-account; you’re summing across accounts. Fix only rules.py.” Steer when the loop was a local mistake in an otherwise sound run, because you’d otherwise throw away good context to fix a small error.
Start a fresh session when the context itself is poisoned - the agent has talked itself into a wrong interpretation, the loop has run several turns and the transcript is now mostly noise about the wrong approach, or you simply can’t tell what it still believes. A fresh session with a sharper brief is then cheaper than steering, because every correction you type into a confused context has to fight the wrong turns already in it. You met this in sessions & context: launch a new codex invocation and re-enter with the brief you wish you’d written the first time.
The tiebreaker is a single question: is the wrong part small relative to the whole context? Small - steer. The whole thing has drifted - clear. And when you do clear, fold what you learned into the new brief: the misreading that caused the loop becomes an explicit constraint this time, so the restart isn’t just fresh, it’s sharper.
Why the ladder doesn’t compose perfectly
Section titled “Why the ladder doesn’t compose perfectly”Stack the last two lessons and the arithmetic looks tidy: 11 turns cold, minus 5 for the rules file and the profile together, minus 4 more for the skill, lands exactly on the 2 chapter 1 promised. That arithmetic is real, but it hides something worth saying plainly. Chapter 7 measured the combination of AGENTS.md and the profile against a plain prompt, not either one alone against a truly bare Monday - so you know the checkpoints, 11 then 6 then 2, and you know the ladder holds between them, but you can’t cleanly say how many of those five turns were the rule’s and how many were the profile’s. That’s not a flaw in the measurement. It’s what happens when techniques get built and tested together instead of in isolation, and it’s the honest version of a story that would otherwise sound tidier than it is.
The effort dial doesn’t show up in that arithmetic at all, and that’s worth saying too. Route the fourth-bank job through low effort or high and chapter 5’s own finding still holds - the turn count doesn’t move, because this task shape is pattern-following, the same corner as the accounts endpoint. What the dial buys is invisible on the turns column and real on the tokens one: matched effort keeps each of those 2 turns cheap instead of quietly overpriced. A single ladder of turns can’t show every instrument’s contribution, because not every technique spends the same one.
And the ladder assumes the fifth bank looks enough like the first four that the skill actually fires and fires correctly. Say it doesn’t - the new export encodes negative amounts in parentheses instead of a minus sign, a shape the skill’s column-mapping never saw. The skill either mismaps the amount or the run stalls on a check it can’t satisfy, and you’re back to something closer to the six-turn shape from two lessons ago: interrupt, size the damage with git diff --stat, and steer or restart with a sharper brief. That costs turns the target didn’t budget for. What doesn’t regress is the reintroduction count - AGENTS.md’s rule holds regardless of which bank you’re onboarding, so even a bad run on an unanticipated format is very unlikely to cost you a fourth float-bug reintroduction.
The target is 2 turns and 0 reintroductions on the case the week actually built for. On a case it didn’t, the reintroduction count still holds, and the turn count is what you’re negotiating with the recovery habit above.
Pass or fail
Section titled “Pass or fail”Run the fourth-bank job on a format the skill already knows - a bank that writes its columns the way the other three did - and the target passes: 2 turns, matching the number chapter 7 measured and chapter 1 promised, 0 reintroductions, because the rule that prevents the float bug doesn’t care which bank triggered the run. Run it on a shape the skill has never seen, and the reintroduction half of the target still passes, but the turn count fails - you’ll spend the extra turns this lesson’s recovery habit is for, and that’s still a fair trade against Monday’s 11, just not the number stated up front.
That’s the honest reading. Every technique in this stack came from a chapter that quantified it once, on the case it was built for, and none of them promised more than that. Close the course - look back at the whole week on budgetcli and where to go from here.