← Files AkinatorARCHIVED FILE
memory/2026-08-26-checkers-fail-silently-in-both-directions.md
3.86 KB · Oct 3, 2026 · 06:33 UTC
--- name: checkers-fail-silently-in-both-directions type: surprise date: 2026-08-26 --- # A checker's matching rule fails silently in both directions, and the false negative is the dangerous one ## The fact `index-completeness` was written in one afternoon and got its matching rule wrong **three times**, each fix producing the next failure: 1. **Bare substring.** `token in index_text`. `demo` was satisfied by a listed `demo-extended`. Worse, `akinator` occurs inside every `akinator-*` entry, so the master skill could never be flagged however the index changed. 2. **Word-bounded regex.** Closed that, and left an artifact satisfied by a same-named file at a different path: ``` docs/overview.md satisfied by a link to adr/overview.md docs/notes.md satisfied by a link to notes.md.bak ``` 3. **Path-bounded regex.** Closed those, and immediately produced **six false positives** on `evals/suites/*`, which `evals/README.md` lists with a directory prefix. The rule that works is not a pattern at all: **resolve the reference** and compare repo-relative paths. `_indexed_paths()` in `skills/everything/scripts/akinator_coverage.py`. ## Why The two failure directions have very different costs, and only one announces itself. - A **false positive** is loud. Someone sees a wrong finding, gets annoyed, and either fixes the check or stops trusting it. Either way it is discovered. - A **false negative** is silent. The check reports green, everyone believes it, and the invariant has quietly stopped existing. Nothing ever surfaces it, because there is no output to be suspicious of. That asymmetry means a checker cannot be validated by running it on a healthy repository and seeing zero findings. Zero findings is exactly what a broken checker produces. It has to be validated by **mutation**: break the invariant on purpose and confirm the check fires. None of the three defects were found by the tests written alongside the check - those passed throughout. The two false negatives were found by `akinator-librarian` building an adversarial fixture and calling the function directly instead of trusting the suite. The false positive was found by running the check against this repository, where six real suites were flagged wrongly - which is the point: a false positive announces itself, and a false negative cannot be found that way at all. A separate defect in the same batch - the check emitting MEDIUM while CI ran `--fail-on high`, so a delisted artifact passed green - was found by `akinator-pm` deleting a row from a real index in a scratch copy and watching CI stay green. Correct severity, wrong tier: a third way for a check to exist and protect nothing. ## Date - 2026-08-26 - recorded after `akinator-everything` was run against this repository and both review lenses blocked on it. ## Reversal conditions - The matching rule stops being path-based - if a future index convention makes resolution impossible, this entry's specific advice expires, but the both-directions lesson does not. - A property-based or mutation-testing harness is added to the suite, which would catch this class automatically and make the manual adversarial step unnecessary. ## Related - `skills/everything/scripts/akinator_coverage.py` - `_indexed_paths` and `check_index_completeness` - `tests/test_coverage_checker.py` - a regression test for each failure above, plus one for the taxonomy homes that were silently exempt - [[fenced-examples-avoid-false-findings]] - the mirror image: that entry records a false **positive** problem in the same checker. Together they are the pair: false positives train people to ignore the checker, false negatives make it lie. Both end with nobody protected. - `skills/everything/references/akinator-anti-gaming.md` - "Never weaken a check to make it pass"; this is the adjacent failure, where a check is weak by accident and nobody notices.
SHA-256: 7a32f9a2954b605aa9e3604c2f5b9daf234e0b18616c998a9f9050725a5596a6