A Clean Run

A hand-written AI agent run, line by line. The lesson: think → act → observe → repeat.

task
Tests are failing in utils.test.ts — find out why and fix it.
Watch this run on the timeline →
plan
First, a plan. I think in my head too, but anything I don't write down is gone.
  1. Run the tests
  2. Read the failing test
  3. Find the bug
  4. Fix it
  5. Verify green
your call
Before I start: you decide what's broken. My method stays the same either way.
Pick the bug hiding in lib/utils.ts:
“a date that won't parse” or “a page that's one item short”
The script writes both paths. Beats tagged with a pick happen only on that path.
bashnpm test
see the failure myself before touching anything
if you picked “a date that won't parse
FAIL utils.test.ts — formatDate: expected 'Mar 14, 2024', got 'Invalid Date'
One failure. I have no eyes — the code only exists for me when a tool brings it back.
if you picked “a page that's one item short
FAIL utils.test.ts — paginate: expected 5 items, got 4
One failure. I have no eyes — the code only exists for me when a tool brings it back.
One failure. What does the test actually expect?
readutils.test.ts
the test defines what correct means
if you picked “a date that won't parse
expect(formatDate('2024-03-14T09:00:00Z')).toBe('Mar 14, 2024') — input is an ISO timestamp
It expects a formatted date from a timestamp.
if you picked “a page that's one item short
expect(paginate(items, 1, 5)).toHaveLength(5) — a page holds five items
It expects five items on a page of five.
That's the contract. Now read the implementation.
readlib/utils.ts
compare what it does to what it should do
if you picked “a date that won't parse
const d = new Date(str.replace(/-/g, '/')) — manual string surgery before parsing
Found it — the code rewrites the date first.
if you picked “a page that's one item short
items.slice(start, start + size - 1) — slice's end is already exclusive
Found it — the code counts one item short.
if you picked “a date that won't parse
The replace mangles ISO timestamps; Date parses them natively. My hunch felt like knowledge, and I sound just as confident when I'm wrong. Acting on a guess anyway is called a hallucination. Reading the file is what made it fact.
if you picked “a page that's one item short
slice already excludes the end; the -1 drops the last item. My hunch felt like knowledge, and I sound just as confident when I'm wrong. Acting on a guess anyway is called a hallucination. Reading the file is what made it fact.
if you picked “a date that won't parse
editlib/utils.ts — drop the replace, parse the string directly
smallest change that satisfies the test
if you picked “a page that's one item short
editlib/utils.ts — slice(start, start + size), drop the -1
smallest change that satisfies the test
1 file changed
The edit is in. Not done yet.
bashnpm test
the test that saw it fail must see it pass
12 passed, 0 failed
All 12 pass. I never trust a fix until the test that failed passes.
done
think → act → observe → repeat
  • ·I wrote the plan first — thoughts I don't write down are gone.
  • ·I never saw the code — I only knew what each tool brought back.
  • ·I read the file first — acting on a guess is a hallucination.

Every line above is a hand-written script; no model.

The same lesson with no code in sight: A Clean Run — “What can I make with what's in my fridge?

the other runs:
  • A Plan Fails — “/api/orders is returning 500s — fix it.
  • Memory Fills Up — “Rename getUser → fetchUser across the codebase — 14 files.
  • A Plan Fails — “I plan eight hours of work and get four. Figure out why.
  • Memory Fills Up — “I saved 14 apartment listings. Which ones should I actually tour?