Real-World Validation Gauntlet
Unit tests with self-made fixtures prove the code matches your imagination, not
that it works. This skill runs a gauntlet: real third-party inputs, evidence
captured, failures fixed, then re-run. Every rule below was paid for by a real
bug (see references/bug-case-studies.md).
The validation ladder
Know which rung you are on, and never claim a higher one:
- L1 unit tests — logic correct. Input is yours. Weakest evidence.
- L2 real-world gauntlet (this skill) — third-party inputs test
compatibility, false-positive rate, and platform behavior.
- L3 dogfooding — you depend on the tool daily; telemetry accumulates.
- L4 external users — strangers install it and file issues. The only
terminal proof. Everything before it is your own judgment.
Designing the gauntlet
Pick 2–4 attacks per tool, each using an input you do not control:
| Tool type |
Real-world attack |
| CLI that parses files |
Run against 2–3 popular real repositories (one huge, one quirky) |
| Client of a protocol/server |
Run against the official reference server, not a mock |
| Version-sensitive tool |
Exercise two real published versions (old vs new) |
| CI/gate tool |
Run against real public PRs via the platform API |
| Scheduler/runner |
Run a real useful job with real side effects, twice (idempotence) |
| Anything cross-platform |
Push to both Linux and Windows CI before trusting local runs |
Hard rules:
- Never simulate the real thing when the real thing is reachable.
npx the
real package, gh the real PR, clone the real repo. Mocks hide exactly the
bugs you are hunting.
- Measure false positives explicitly. Run against inputs known-good in
reality (popular repos, official servers). Every finding on a known-good
input is a false positive — fix the tool, do not whitelist the input.
- Capture evidence per attack: exact command, exit code, key output. If
you cannot re-run it, it did not happen.
- Fix-then-rerun: a gauntlet finding is only closed after the fixed tool
re-passes the SAME real-world attack, plus a regression test derived from it.
Platform-only bugs: the debug-branch technique
When something fails on CI (Linux) but not locally (Windows), do not guess.
Create a throwaway branch that adds diagnostics at the failure point (print
the rendered command, child stderr, env vars), push it, let the real runner
execute it, read the log, then delete the branch. Ten minutes of ground truth
beats an hour of local theorizing. Real example: a sh: 3: Replace: not found
line in CI logs revealed a multi-line prompt being executed as shell commands
(""path"" double-quoting) — invisible on Windows where cmd.exe forgives it.
Common real-world-only failure classes
- Normalized echoes — your detector strips the payload you sent, but the
real system returns it transformed (Windows
/→\, case changes, wrapper
text). Strip on normalized forms, not exact strings.
- Shell quoting asymmetry — Windows
cmd.exe forgives nested quotes;
POSIX sh executes the tail of a split command. Test prompt-carrying
command lines on Linux always.
- Vocabulary vs data-flow — a scanner that fires on words ("env vars")
will flag debugging lessons in popular repos. Gate on actual data flow
(file paths,
$VAR expansions, network sinks).
- Runner-injected environment — CI sets
GITHUB_EVENT_PATH/GITHUB_TOKEN
in every step; tests asserting "no environment" flip code paths. Strip the
runner's injected variables in the test launcher.
- Cold-start vs warm timings — first
npx run downloads packages and
blows handshake timeouts. Warm the cache, or raise the specific timeout.
Exit criteria
The gauntlet is done when: every attack has captured evidence, every finding
is fixed with a regression test, known-good inputs produce zero false
positives, and both OS CI matrices are green. Then say exactly what was
validated and what was not — "not-inspected ≠ clean" applies to gauntlets too.
See references/bug-case-studies.md for the five bugs this method caught:
each has symptom → investigation → root cause → fix → generalized lesson.
1---2name: real-world-gauntlet3description: Validates a tool against real-world third-party inputs instead of self-made fixtures: official servers, real repositories, real PRs, real version drift, and cross-platform CI. Use when unit tests are green but you need evidence the tool works outside the lab — before publishing, after a major refactor, or whenever a security/precision claim needs to hold on data you did not invent. Catches the class of bugs fixtures structurally cannot contain.4license: MIT5---67# Real-World Validation Gauntlet89Unit tests with self-made fixtures prove the code matches your imagination, not10that it works. This skill runs a **gauntlet**: real third-party inputs, evidence11captured, failures fixed, then re-run. Every rule below was paid for by a real12bug (see `references/bug-case-studies.md`).1314## The validation ladder1516Know which rung you are on, and never claim a higher one:17181. **L1 unit tests** — logic correct. Input is yours. Weakest evidence.192. **L2 real-world gauntlet** (this skill) — third-party inputs test20 compatibility, false-positive rate, and platform behavior.213. **L3 dogfooding** — you depend on the tool daily; telemetry accumulates.224. **L4 external users** — strangers install it and file issues. The only23 terminal proof. Everything before it is your own judgment.2425## Designing the gauntlet2627Pick 2–4 attacks per tool, each using an input you do not control:2829| Tool type | Real-world attack |30|---|---|31| CLI that parses files | Run against 2–3 popular real repositories (one huge, one quirky) |32| Client of a protocol/server | Run against the **official reference server**, not a mock |33| Version-sensitive tool | Exercise two **real published versions** (old vs new) |34| CI/gate tool | Run against **real public PRs** via the platform API |35| Scheduler/runner | Run a **real useful job** with real side effects, twice (idempotence) |36| Anything cross-platform | Push to **both Linux and Windows CI** before trusting local runs |3738Hard rules:3940- **Never simulate the real thing when the real thing is reachable.** `npx` the41 real package, `gh` the real PR, clone the real repo. Mocks hide exactly the42 bugs you are hunting.43- **Measure false positives explicitly.** Run against inputs known-good in44 reality (popular repos, official servers). Every finding on a known-good45 input is a false positive — fix the tool, do not whitelist the input.46- **Capture evidence per attack**: exact command, exit code, key output. If47 you cannot re-run it, it did not happen.48- **Fix-then-rerun**: a gauntlet finding is only closed after the fixed tool49 re-passes the SAME real-world attack, plus a regression test derived from it.5051## Platform-only bugs: the debug-branch technique5253When something fails on CI (Linux) but not locally (Windows), do not guess.54Create a throwaway branch that adds diagnostics at the failure point (print55the rendered command, child stderr, env vars), push it, let the real runner56execute it, read the log, then delete the branch. Ten minutes of ground truth57beats an hour of local theorizing. Real example: a `sh: 3: Replace: not found`58line in CI logs revealed a multi-line prompt being executed as shell commands59(`""path""` double-quoting) — invisible on Windows where `cmd.exe` forgives it.6061## Common real-world-only failure classes62631. **Normalized echoes** — your detector strips the payload you sent, but the64 real system returns it transformed (Windows `/`→`\`, case changes, wrapper65 text). Strip on normalized forms, not exact strings.662. **Shell quoting asymmetry** — Windows `cmd.exe` forgives nested quotes;67 POSIX `sh` executes the tail of a split command. Test prompt-carrying68 command lines on Linux always.693. **Vocabulary vs data-flow** — a scanner that fires on words ("env vars")70 will flag debugging lessons in popular repos. Gate on actual data flow71 (file paths, `$VAR` expansions, network sinks).724. **Runner-injected environment** — CI sets `GITHUB_EVENT_PATH`/`GITHUB_TOKEN`73 in every step; tests asserting "no environment" flip code paths. Strip the74 runner's injected variables in the test launcher.755. **Cold-start vs warm timings** — first `npx` run downloads packages and76 blows handshake timeouts. Warm the cache, or raise the specific timeout.7778## Exit criteria7980The gauntlet is done when: every attack has captured evidence, every finding81is fixed with a regression test, known-good inputs produce zero false82positives, and both OS CI matrices are green. Then say exactly what was83validated and what was not — "not-inspected ≠ clean" applies to gauntlets too.8485See `references/bug-case-studies.md` for the five bugs this method caught:86each has symptom → investigation → root cause → fix → generalized lesson.