Objective
Ordering: dependencies before dependents
Plan order isn't always execution order
If the plan adds a new function to validators.py and then calls it from api/routes.py, validators.py has to be modified first — otherwise the test run after step 1 (modifying routes.py to call a function that doesn't exist yet) fails for a reason that has nothing to do with whether the change itself is correct. A simple heuristic: steps that CREATE new files or functions referenced by other steps go first; this course doesn't build full dependency-graph analysis, but the planning engine's risk_notes field (Lesson 3) is exactly where the model can flag "step 2 depends on step 1" for the executor to respect.
Rollback: all-or-nothing per plan, not per step
def execute_plan(client, repo_path: str, plan, task: str) -> bool:
completed_files = []
for step in plan.steps:
success = execute_step_with_fix_loop(client, repo_path, step.file_path, ..., task)
if not success:
print(f"Step failed on {step.file_path}. Rolling back {len(completed_files)} prior changes.")
for path in completed_files:
restore_from_backup(os.path.join(repo_path, path))
return False
completed_files.append(step.file_path)
return True
This is the actual "multi-file" part: completed_files tracks every step that already succeeded, and if ANY later step fails, all of them get rolled back — not just the one that failed. Leaving steps 1-2 applied while step 3 fails means the repo is in a state the plan never intended and the tests may not have validated; a plan is a single unit of work, and it succeeds or fails as one.
This is where Lesson 4's discard_backup matters
Once a step's tests pass, Lesson 4's discard_backup removes its .bak file -- which means it's no longer restorable by the time a LATER step fails. This lesson's rollback needs its own bookkeeping (the completed_files list, or keeping backups until the whole plan finishes) rather than relying on Lesson 4's per-step cleanup, which was correct for the single-file case but not sufficient for a multi-file rollback. If you don't adjust this, you'll roll back the immediately-preceding file but silently leave earlier successful steps applied.
Git staging as changes complete
Should the agent git add each file immediately after its individual step succeeds, or wait until the entire multi-file plan succeeds before staging anything?
If step 2 fails and triggers a rollback of step 1's already-staged file, you'd need to git reset that file too -- extra bookkeeping for no benefit. Staging only after the full plan succeeds (Lesson 6's job) keeps the git index and the working directory's actual, final state in sync with a single, simple rule: nothing gets staged until everything the plan intended is done and verified.
What you're building
multi_file_executor.py: execute_plan, extending Lesson 4's single-step executor to run every step in a plan, track completed files, and roll back everything if any step fails — tested against a real 3+ file task on your test repo, both a fully-successful run and one deliberately broken at the 2nd step to verify full rollback.
Unlock the full lesson
You've read the first 2 sections. The rest of this lesson covers The Problem, Build, Check Yourself, Key Terms & Next — plus a hands-on lab, quiz, and project artifact.
Create a free account — the opening phases of 29 of 35 courses are free, no credit card.