Chapter 13 · Reps

Iterative Refinement — Reps

← Back to Chapter 13

Chapter 13 — Reps

Conditioning, not grading. AI is on — this is Phase 2 — but every rep below has a budget. Each rep tells you the maximum number of prompts you’re allowed to send. If you blow the budget, the rep is failed; reset and try again. The constraint is the point.

You will need an AI assistant for these. See Appendix A for the course default and how to configure it.

Each rep gives you a starting file (code/) and a JUnit test file. Run the tests. Drive to green using only prompts. Log your prompts in rep-NN-prompts.txt. Compare your log against the reference solution for each rep only after you’ve finished.


Ground rules

  1. You may not edit the code by hand unless the rep explicitly allows it.
  2. You must log every prompt in rep-NN-prompts.txt, in chronological order.
  3. Re-run the full test suite after every accepted change. Not just the test you were working on.
  4. If you blow the budget, reset. Restore the starting file, restart, do not exceed the budget. The whole point is bounded debugging.

Rep 1 — Off-by-one in a factorial

Budget: 3 prompts.

Starting file: Factorial.java — a method factorial(int n) that uses i < n instead of i <= n in its loop.

Test file: FactorialTest.java — three tests, two failing.

Drive to green in three or fewer prompts. The bug is one character. You should be able to solve this in one diagnostic prompt and one targeted-fix prompt.

If you used three prompts, ask yourself: what made the first prompt vague? Fix it next time.


Rep 2 — Null returned where empty list expected

Budget: 4 prompts.

Starting file: Filter.java — a filter(List<String>, Predicate<String>) method that returns null when the input is empty. Test file: FilterTest.java.

Test file expects List.of() (empty list) for an empty input, not null. Two of five tests fail.

Drive to green in four or fewer prompts. Use the diagnostic prompt first (Template 1 from §13.11): ask the AI to trace what happens on the empty-input case. Don’t tell it the bug. Let it surface the bug, then ask for the fix.


Rep 3 — Oscillating fix

Budget: 5 prompts.

Starting file: Parser.java (test file: ParserTest.java) — a parse(String) method that fails one of two tests:

  • parse("") should return List.of().
  • parse("a") should return List.of("a").

Two passes give you two oscillating failed states. Your first prompt will probably fix one and break the other. Your second prompt will probably reverse the oscillation.

After two oscillating fixes, recognize the loop (§13.6). Send the “joint constraint” prompt (Template 4) to break it. Then verify both tests pass.


Rep 4 — Hallucinated API

Budget: 4 prompts.

Starting file: DateUtil.java (test file: DateUtilTest.java) — a parseDate(String) method using LocalDate.fromString(s), which does not exist in java.time. The correct method is LocalDate.parse(s). (This starting file is intentionally uncompilable — the compile error is the point.)

The compile error is informative. Your job is to drive to green using a prompt that explicitly constrains the AI to real java.time APIs (§13.10). Do not just tell it the name of the correct method — let the constraint do the work.

If your prompt produces a fix that uses any other non-existent method, you’ve done it wrong even if it compiles. Diagnostic constraint, not directive guess.


Rep 5 — Rewriting half the class

Budget: 4 prompts.

Starting file: AccountLedger.java (test file: AccountLedgerTest.java) — a 5-method class. Only withdraw(double) is buggy (allows negative balances). The other 4 methods are fine.

Send a prompt that says “fix it” without scoping. Note what comes back — almost certainly a rewrite of multiple methods, possibly the whole class. Do not accept that response. Reset.

Now send the scoped prompt (Template 3): “modify only withdraw. Do not change other methods. Output only the new method body.” Compare.

The rep teaches you the cost of an unscoped prompt — by making you wear it once.


Rep 6 — Show the test in the prompt

Budget: 3 prompts.

Starting file: RomanNumerals.java (test file: RomanNumeralsTest.java) — a toRoman(int n) method that handles 1–10 but fails on subtractive notation (4, 9, 40, etc.).

Round 1: send a prompt without the failing test included. Note what comes back. Probably a fix that’s still wrong somewhere.

Round 2: reset. Send a prompt with the failing test pasted in (§13.4). Note the difference.

Round 3: confirm green.

This rep is graded on whether your Round 2 prompt was structurally better than your Round 1 prompt, not on whether you reached green. Both rounds should converge — but the second one should converge faster.


Rep 7 — The rubber duck prompt

Budget: 4 prompts.

Starting file: StringCompressor.java (test file: StringCompressorTest.java) — a compress(String) method that produces wrong output on inputs with single-character runs.

Use the rubber duck prompt (§13.5): ask the AI to trace compress("aabba") step by step without proposing a fix. Read the trace carefully. The trace should expose the bug.

Then, only after the trace, send a targeted fix prompt.

The rep is failed if you ask for a fix in your first prompt. The trace-first discipline is the point.


Rep 8 — Stop and write it

Budget: 0 prompts. You write the fix yourself.

Starting file: SwapValues.java (test file: SwapValuesTest.java) — a swap(int[], int, int) method missing the temp variable.

Look at the code. You can describe the fix in one sentence: “store a[i] in a temp, then assign.” You don’t need the AI for this.

Type the fix. Run the tests. Confirm green.

The rep teaches that not every bug is for the AI. When the fix is one sentence and you can type it in 30 seconds, just type it.

If you reached for the AI here, you’ve identified a bad habit. Notice it.


Rep 9 — Test as spec

Budget: 3 prompts.

Starting file: CsvParser.java — a parseRow(String) method that handles unquoted CSV but fails on quoted fields containing commas.

The test file (CsvParserTest.java) has six tests; four pass, two fail. The two failing tests fully specify the missing behavior.

Send one prompt that includes:

  1. The current implementation.
  2. The list of failing test names.
  3. The full text of those two tests.
  4. The constraint that the passing tests must continue to pass.

Get the fix. Run all six tests. Should be green.

This is the canonical P13 prompt shape. Get it in your fingers.


Rep 10 — Catch the regression

Budget: 5 prompts.

Starting file: Account.java (test file: AccountTest.java) — has a bug in deposit(double) (no validation on negative amounts). Test deposit_rejectsNegative fails.

Drive to green. Then run the full test suite again. The AI’s fix may have broken deposit_addsToBalance or withdraw_decreasesBalance (this rep is rigged to trigger an over-eager refactor on one common AI pattern).

If a previously-passing test now fails, send a targeted prompt that pastes both tests and says: “make deposit_rejectsNegative pass while keeping deposit_addsToBalance passing.”

The rep grades you on catching the regression yourself, not on reaching green on the first try.


Rep 11 — Two prompts, one bug, compare

Budget: 2 prompts (one each).

Starting file: Inventory.java (test file: InventoryTest.java) — a findItem(String name) method that does string comparison with ==. Easy bug to identify.

Send Prompt A (directive): “The findItem method uses == to compare strings. Replace with .equals().”

Reset. Send Prompt B (diagnostic): “The findItem method’s test fails. Trace what happens when we look for an item with name "sword". Do not propose a fix yet.”

Both prompts will reach green. The directive is faster. The diagnostic is more educational.

Which one would you use if the bug had been subtler? Write your answer in a comment at the bottom of your prompt log.


Rep 12 — Build a personal prompt template

Budget: open. This rep doesn’t have a fixed budget.

Create a file my-prompts.txt with five prompt templates that you found useful. Adapted from §13.11 or invented yourself. For each template, include:

  • The prompt text (with placeholders like <methodName>).
  • One concrete example of where it would apply.
  • One failure mode (when it would not work well).

This is your personal prompt library. You will reuse it in P13 and beyond.

A great my-prompts.txt has prompts that are yours — slightly different from the textbook templates, tuned for the kinds of bugs you encounter. The point is internalization, not transcription.


Done? One Last Thing.

Open the file from Rep 9. Read your prompt log. For each prompt, ask:

  1. Could I have made this prompt 20% shorter without losing meaning?
  2. Was there a constraint missing that the next prompt should add?
  3. Did this prompt assume a hypothesis that turned out to be wrong?

If you can’t find improvements, you didn’t read carefully enough. The reflection is the rep.


Up next: Project 13 — Project 13: Drive AI to Green.