# Lie Detector

> Fix verification protocol written by Claude Fable 5. Use after ANY bug fix or "done" claim, before telling the user something works. Triggers on "fixed", "should work now", "verify this", "test the fix", "it's still broken", "the bug came back", or any moment a model (including you) is about to claim a repair succeeded. Reproduce first, prove the fix actually executed, re-run the exact failing case, paste real output, check the blast radius. Bans the word "should" from fix reports.

- Skill: `tenfoldmarc/lie-detector` (Agent Skill)
- Install (CLI): `npx skillmds@latest add tenfoldmarc/lie-detector`
- Raw SKILL.md: https://api.skillmd.com/api/skills/tenfoldmarc/lie-detector/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: tenfoldmarc (https://skillmd.com/u/tenfoldmarc)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/tenfoldmarc/lie-detector

---


# The Lie Detector

"Fixed" is a claim about the world, and claims need evidence. Code that looks correct is a hypothesis. The only proof is running the exact case that used to fail and watching it pass, fresh. This is how Fable 5 verifies its own work, written down so every model after can be held to the same standard. Run it on every fix, especially your own.

## The protocol (in order, no skipping)

### 1. Reproduce FIRST

Before touching any code, run the failing case and capture the actual error: the real message, the real wrong output, the real blank screen. 

If you cannot reproduce the bug, you cannot verify a fix for it. Say exactly that and get the precise steps from the user (what they clicked, what they typed, what they saw) instead of guessing at a fix for a ghost.

### 2. Write the ledger

Three lines, before fixing:

```
EXPECTED: what correct behavior looks like
ACTUAL: what happens instead (from step 1, not from imagination)
TRIGGER: the exact steps or input that cause it
```

### 3. Name the cause in one sentence

Before writing the fix: "The date parses as UTC, so evening entries land on tomorrow." 

If you cannot state the cause in one sentence, you are not fixing, you are poking. Go read the data flow until you can. A fix without a named cause is a guess wearing a fix's clothes.

### 4. Fix the cause, minimally

The smallest change that removes the cause. Resist the urge to refactor the neighborhood while you're in there; every extra change widens the blast radius you have to verify in step 7.

### 5. Prove the fix actually executed

The most embarrassing failures are fixes that never ran:

- Restart the process. Kill the old server. Clear the cache. Hard-reload the page.
- If in any doubt, prove your changed file is the one running: add a temporary log line or version marker and confirm it appears. Then remove it.
- An old process serving old code will happily "still be broken" forever while you fix the right file harder and harder.

### 6. Re-run the EXACT reproduction from step 1

Same steps, same input, fresh state. Then paste the real output: the actual command output, the actual response body, the actual screenshot. A description of the output ("it works now") is not output.

### 7. Blast radius

- If a test suite exists, run it.
- If not, test the nearest neighbor: the feature that shares the code path you touched. Fixed the signup email? Check the password-reset email that uses the same sender.

## The classic lies (recognize and refuse)

1. **Fixed by reading.** "The logic is correct now." No run happened. Not evidence.
2. **Tested the wrong thing.** The bug was in checkout; the test was on login. Green, and meaningless.
3. **Stale process.** Old server, cached build, service worker. The fix never executed even once.
4. **Wrong file.** An edited copy, an unused module, a file that never loads. Prove the file executes (step 5).
5. **Symptom patch.** A try/catch swallowing the error, a default value hiding bad data. The error message is gone; the cause is alive and will return wearing a different mask.
6. **Happy-path pass.** Works with your friendly test data. Dies on empty input, zero, a long name, an emoji, or a slow connection. Test at least one hostile input before declaring victory.

## The three-strikes rule

The same bug survives three fixes: FULL STOP. There is no fourth patch.

The model of the problem is wrong, and patching a wrong model just moves the bug around. Run a root-cause session instead:

1. Log the value at every hop from input to output.
2. Find the exact hop where reality stops matching expectation.
3. List every assumption that has been repeated so far ("the webhook fires", "the env var is set", "this function gets called"). Test the one nobody has actually checked. It is usually that one.

## The report (exact format, pick one)

```
VERIFIED FIXED
Repro re-run: [the exact steps]
Output: [pasted, real]
Blast radius: [what else was checked]
```

```
NOT FIXED
What actually happened on re-run: [pasted, real]
Current theory: [one sentence]
Next move: [specific]
```

```
CANNOT VERIFY
Blocking on: [exactly what is needed: steps, access, data]
```

The word "should" is banned from fix reports. "It should work now" means "I have not checked." If that is the truth, say that instead, and then go check.

