← All skills

It Worked Yesterday

Finds what changed when, as far as you know, nothing changed.

debuggingregressioninvestigationenvironmenta work session

When to reach for it

When something that ran fine last session now does not, and your commits since then look unrelated to it.

What changes

  • The symptom is pinned as an exact command and exact output, reproduced at least twice, before anything is touched.
  • "It worked yesterday" gets checked against a specific commit and environment instead of being taken as given.
  • You get a worked-through list of change surfaces beyond your own code: lockfile, runtime version, environment variables, data, external service, and the clock.
  • The cause is proved by reverting one thing and watching the symptom return — not assumed from the first plausible candidate.

Pairs with

SKILL.mdpaste into your agent

It Worked Yesterday

"Nothing changed" is always false. Find the surface that moved.

1. Pin the symptom

Write the exact command, route, or action, and the exact output or error — copied, not paraphrased. Then run it twice. A failure that happens once in three attempts is a different investigation from one that happens every time, and knowing which comes first.

2. Verify that it did work

"Worked yesterday" is a claim. Establish when, on which commit, in which environment, and by whom. Then check it out and run it there. It either still works — which localises the problem — or it does not, and the premise was wrong.

3. Enumerate the change surfaces

Your code is one of these, and often not the one:

  • Commits since the last known-good point
  • Uncommitted edits, stashes, and untracked files
  • Dependencies — lockfile diff, install timestamps, postinstall scripts
  • Runtime versions — language, package manager, browser auto-update
  • Environment — variables, dotfiles, secrets rotated, flags flipped
  • Data — a new row, a migration, a stale cache, a full disk
  • External services — API version, expired token or certificate, rate limit, DNS, an upstream deploy
  • Time — anything date-dependent, a timezone, an expiry, a month boundary
  • The machine — port already in use, another process, permissions

4. Bisect the cheapest surface first

Stash local changes and retest. Restore the previous lockfile and retest. Then walk history — bisect if the range is more than a few commits. Each step should take a minute and eliminate a whole surface.

5. Prove the cause

Revert exactly the suspected change, alone, and confirm the symptom returns. A candidate that explains the failure is not the same as the cause, and reverting is the only cheap way to tell them apart.

6. Write down the cause and the guard

One line for what changed and why it broke. One line for the check that would have caught it — a pinned version, an assertion, a test, a startup validation.

Rules

  • Do not fix before the symptom can be produced on demand. Without a reproduction there is no way to know a fix worked.
  • Do not delete build caches or reinstall dependencies as the first move. It destroys the evidence and frequently hides the cause under a working state that will fail again next week.
  • Do not accept "must have been a fluke" without recording how many attempts were made.
  • Do not stop at the first change that could explain it. Confirm by reverting.
  • Do not fix the symptom in a way that also removes the ability to detect it — an added retry or a widened catch ends the investigation rather than the bug.