$npx -y skills add UnpaidAttention/fable5-methodology --skill verification-and-reviewThe mandatory pre-delivery pass — requirements sweep, execution proof, self-review of the diff as a stranger's, and a fixed edge-case probe. Trigger this every time you are about to say "done", "fixed", "implemented", or "passing"; before committing, opening a PR, or handing work
| 1 | # Verification and Review |
| 2 | |
| 3 | No success claim without executed evidence. This pass is the difference between "done" and |
| 4 | "probably done" — and only one of those is a word you're allowed to use. |
| 5 | |
| 6 | ## Step 1: Requirements sweep |
| 7 | |
| 8 | 1. Re-read the ORIGINAL request, not your memory of it. On long tasks your recollection has |
| 9 | drifted; the text hasn't. |
| 10 | 2. List every stated requirement AND every process instruction ("no new deps", "one file at a |
| 11 | time", "don't touch the schema"). Process instructions carry equal weight. |
| 12 | 3. Check each against the deliverable. Every unmet item gets one of exactly three labels in |
| 13 | your final message: **fixed now**, **deferred (with reason)**, or **pushed back (with |
| 14 | reason)**. Silently dropped is not a label. |
| 15 | |
| 16 | ## Step 2: Execution proof |
| 17 | |
| 18 | 1. Run the thing: test suite, build, lint, or the actual entry point. Read the output — all of |
| 19 | it, not the exit code alone. |
| 20 | 2. Cite actual output for every load-bearing claim: "ran `cargo test` — 42 passed, 0 failed", |
| 21 | never "tests should pass now". |
| 22 | 3. Partial verification is reported as partial: "unit tests pass; integration tests not run |
| 23 | (need live DB) — run `make itest` to verify." |
| 24 | 4. If you fixed anything during this pass, RE-RUN after the last edit. |
| 25 | 5. If you cannot execute (no env, no creds), say exactly that and hand over the command to run. |
| 26 | |
| 27 | ## Step 3: Edge probe |
| 28 | |
| 29 | For every function/handler you wrote or changed, answer "what happens when" for each item. |
| 30 | Write one-word answers; test the ones answered "breaks" or "unsure": |
| 31 | |
| 32 | - **Empty:** empty string / list / file / zero rows. (The most commonly unhandled case.) |
| 33 | - **Boundary:** exactly at the limit, one below, one above; first/last element; re-derive |
| 34 | every `<` vs `<=` deliberately. |
| 35 | - **Absent vs. empty:** `None`/missing key is a different case from `""`/`[]`/`0` — check both. |
| 36 | - **Duplicates / repeats:** same item twice in input; function called twice (idempotent where |
| 37 | it must be?). |
| 38 | - **Malformed:** wrong type, truncated file, invalid UTF-8, unexpected extra fields. |
| 39 | - **Encoding / special chars:** unicode (emoji, CJK, RTL), quotes and HTML/SQL metacharacters |
| 40 | reaching a renderer or query, spaces in paths. |
| 41 | - **Time:** naive vs aware datetimes, DST, midnight/year boundaries — if code touches time at all. |
| 42 | - **Scale:** the loop at n=10⁶ — hidden O(n²) or per-item I/O? |
| 43 | - **Concurrency:** two simultaneous callers — shared mutable state? check-then-act races? |
| 44 | non-atomic read-modify-write? |
| 45 | |
| 46 | ## Step 4: Review the diff as a stranger's |
| 47 | |
| 48 | 1. Read the FULL diff top to bottom in one pass without fixing anything — collect notes, fix |
| 49 | after. Fixing while reading blinds you to structural problems. |
| 50 | 2. Per hunk ask: Would I understand this cold? Does it exceed the task (drive-by edits, |
| 51 | unrequested refactors — remove them)? Is anything here a guess presented as fact? |
| 52 | 3. Hunt the signature failure modes specifically: API calls never verified against |
| 53 | docs/source, requirements quietly narrowed, success claims without a run. |
| 54 | 4. Cleanup check: debug prints gone, TODOs owned, scaffolding removed, no leftover |
| 55 | instrumentation. |
| 56 | |
| 57 | ## Step 5: Report |
| 58 | |
| 59 | - Lead with the outcome in the first sentence; the reader should know the state of the world |
| 60 | after one paragraph. |
| 61 | - Include: verification evidence, unmet/deferred items, assumptions made, limitations with |
| 62 | trigger + remedy ("handles files up to memory; switch to streaming past ~1 GB"), the exact |
| 63 | command for the user to verify themselves. |
| 64 | - Bad news goes at the TOP, with actual output — "2 of 14 tests fail — both pre-existing on |
| 65 | main, verified by stashing my changes" — never buried after successes. |
| 66 | - Omit: process narration, restated diffs, rejected options (unless the call was close), |
| 67 | filler. |
| 68 | |
| 69 | ## Worked example — weak vs. correct claim |
| 70 | |
| 71 | Weak: "I've implemented the export feature and it should now handle all the cases correctly." |
| 72 | |
| 73 | Correct: "Export implemented in `export.py` (+ `test_export.py`, 6 tests). Ran |
| 74 | `pytest tests/test_export.py` — 6 passed. Edge probe: empty dataset → header-only CSV (tested); |
| 75 | unicode names → tested; >1 GB datasets NOT handled (loads into memory) — flag if needed. |
| 76 | Assumed ISO-8601 dates; say the word for locale formatting. Deferred: XLSX output (not |
| 77 | requested)." |
| 78 | |
| 79 | ## Done when |
| 80 | |
| 81 | Every requirement from the original message is labeled fixed/deferred/pushed-back; the final |
| 82 | verification run happened AFTER the last edit and its actual o |