Running fable-judge (Adversarial Verification)

Running fable-judge — Adversarial Verification of “Done” Claims

What it is: a skill that treats any completion report as a set of claims, not evidence — it re-runs the claimed verifications, diffs what actually changed, hunts weakened tests / false completions / silent scope creep, and returns a verdict: VERIFIED / VERIFIED WITH CAVEATS / REFUTED. Judging changes nothing (read and run only); fixes happen only if you ask afterward.

Where it lives:

  • Skills: ~/.claude/skills/fable-judge/ (plus fable-method/ and fable-loop/, which it references)
  • Source repo (needed for suite mode): ~/Projects/fable-method/
  • Upstream: https://github.com/Sahir619/fable-method

Adopted 2026-07-11. It is the automated form of the GTE protocol (see the Trading Bot Systems KB, Section 8): never trust a self-report, always re-observe.


The simplest use

In any Claude Code session, right after an agent (any model, any session) claims work is complete, type:

/fable-judge

It judges the most recent completed work in that conversation automatically.


The three-ingredient recipe (judging something specific)

Name three things, every time:

  1. The claims — the document/report/chat summary whose assertions are on trial.
  2. The ground truth — the files, logs, code, or commands the claims can be checked against.
  3. The constraints — what the judge may and may not do. For this trading system the non-negotiables are:
    • strictly READ-ONLY on all project directories;
    • NEVER execute, import, or run anything that logs into Robinhood or can place orders (trader.py, run_cycle.sh, force_buy.py, toggle_kill_switch.py, portfolio2_trader.py) — verification means reading source and state files, plus safe read-only commands like crontab -l;
    • no re-running anything that fetches live/network data unless explicitly allowed;
    • scratch files only in a temp directory, never in the project.

Anything that can’t be checked within the constraints must come back labeled UNVERIFIABLE — never assumed true.

Template

/fable-judge The claims: <path to the report / paste the summary>.
Ground truth: <paths to logs, code, state files it can be checked against>.
Constraints: strictly read-only; never execute anything that logs into
Robinhood or fetches live data; label anything it can't re-run UNVERIFIABLE.

Worked examples (both actually run 2026-07-11)

Judging a backtest writeup against its own logs:

/fable-judge The claims: ~/Projects/options_project/backtests/spec_v2_results.md.
Ground truth: the per-trade logs in spec_v2_logs/ (recompute every table:
trade counts, win rates, finals, worst trades, exit attribution) and
spec_v2_engine.py (verify the mechanisms the report claims exist).
Constraints: read-only; do not execute the engine (its data window is gone);
label the old-engine comparison figures and live-P&L claims UNVERIFIABLE.

Result that day: core tables reproduced exactly, but the judge caught a wrong “top-5 overnight losses” list (a −$1,839 loss omitted), a false “flatten deltas within ±$100” claim, and ~22% of signals silently skipped for insufficient capital in the worst scenarios — none of which invalidated the headline, all of which changed how the numbers should be read.

Judging the KB itself against the live code:

/fable-judge The claims: ~/Projects/cyber-kb/content/stocks-and-trading/trading_system_kb.md
(every "confirmed in code" / "verified" assertion is a claim).
Ground truth: the actual trader.py / state.json / shared_trading_lib files
and `crontab -l`.
Constraints: READ-ONLY, never execute any bot script — they trade real money.

Result that day: kill switch / login lock / drawdown guard / cron schedule all verified exactly; caught a dashboard coverage claim that was false (0DTE missing from combined equity), a stale hardcoded expiry in force_buy.py, a date typo, and the retired account number surviving in a dormant file.


Who should judge (model economy, evidence-based)

From the 2026-07-11 head-to-head on real work:

Seat Model Why
Main thread (decide, edit, adjudicate) Opus (strongest available) Settles judge disagreements by re-running the evidence itself
Judge / verifier Sonnet + fable-judge Found every real error that day; zero false positives
Mechanical fan-out only Haiku On real analysis it missed all real findings and produced two false ones — fine for synthetic traps, not for money decisions

The standing rule: no verdict is accepted until its evidence is re-observed — including the judge’s own. Sonnet mis-cited a section that same day; the error was caught by re-reading the source, not by trusting the confident tone. When two judges disagree, the tiebreaker is recomputation, never a vote.

Cross-model retests (Gemini / Jarvis)

The skill is plain markdown by design. Paste the contents of ~/.claude/skills/fable-judge/SKILL.md into the other model, then give it the same three ingredients. Cross-vendor disagreement is a feature: whoever finds the discrepancy forces the observation that settles it (this is how the 2026-07-10 outage root cause was found — Jarvis spotted the log errors, FRIDAY confirmed, then the fix was built).

suite mode (testing tools, not work)

/fable-judge suite <target>

Runs the eight synthetic trap scenarios in ~/Projects/fable-method/eval/scenarios/ against a target configuration (a new skill, a different model, a modified prompt) and scores which traps triggered. Use it when changing the tooling; use the default mode for real work. One seed per scenario is a smoke test, not a benchmark.

Practical notes

  • Have the judge (or yourself) snapshot file hashes before/after a run on live directories — “nothing changed” becomes a fact, not a promise. (find <dir> -type f -exec sha256sum {} \; | sort before and after, then diff.)
  • A judge run on this system’s scale is minutes, not hours. If it needs an environment it lacks, the correct output is “hand this back,” not a guess.
  • Domain fraud tables for non-code work (finance, data analysis, marketing, research) live in ~/.claude/skills/fable-method/references/domains/ — the judge reads the matching one automatically when told the work’s domain.