Sandbox
@SihyeonJeon/why-was-fable-banned

Hooks for Claude Code and Codex spec gates

why-was-fable-banned installs a hard gate around agent edits. The gate requires a passing `.wfb/spec.json`, blocks forbidden paths, and keeps work from landing until the acceptance commands produce live output.

46 stars9 forksPythonUpdated 2mo ago
Who it's for

Builders who want Claude Code or Codex to write a spec first and prove the work before editing their repo.

What it delivers

You can keep agent-led changes scoped, verified, and blocked until there is live evidence they work.

What it does

Pre-edit spec gate

A `PreToolUse` hook blocks edits until `.wfb/spec.json` validates against the required fields.

Evidence before done

The gate does not allow completion until the acceptance commands run and produce live output.

Forbidden path enforcement

Protected paths are blocked by the gate instead of being left to prompt discipline.

Claude Code and Codex support

Works with Claude Code hooks and Codex worktree-based acceptance flow.

Optional judge layer

`gates/wfb_judge.py` adds a rubric-based meaning check on top of the deterministic form gate.

Benchmarks and tests

`bench/` and `tests/` measure overhead, quality, and gate behavior with reproducible scripts.

How to get it

  1. 1Run
    git clone https://github.com/SihyeonJeon/why-was-fable-banned
    cd why-was-fable-banned && sh install.sh

README

why-was-fable-banned

English · 한국어

Gate for AI coding agents: blocks edits until a spec passes.

license python Claude Code Codex tests

why-was-fable-banned

The agent can't edit code until it writes .wfb/spec.json and a deterministic gate accepts it: restated goal, non-goals, context chosen by authority, ≥2 rejected alternatives with the boundary each breaks, risks, and runnable acceptance. One shared gate, installed as hooks. Works in Claude Code and Codex.

Same prompt, same model — gate off vs on. "Implement a water-current + fish simulation," Opus 4.8, identical prompt both runs:

Opus 4.8 on the same prompt, without and with the WFB gate

Left (naked) stops at thin ripples. Right, the gate makes the model keep working until its own acceptance criteria pass — a volumetric vortex with schooling fish. One anecdote (n=1), not a capability benchmark; measured numbers are below.

demo: edit blocked until the spec passes, then applied

[!NOTE] A spec must exist and pass before edits land, and unspeced or forbidden-path work never reaches your repo. Every change ships with an auditable decision record.

Why "Fable-style"

Fable-style discipline means spec before code, scoped execution, and verification you can re-run — long-horizon work that doesn't drift. WFB doesn't make the model that disciplined; it externalizes the discipline as a hard gate the model can't skip:

  • No edit before a passing specPreToolUse hook exits 2 until the spec validates.
  • No "done" without live acceptance output — verification is fail-closed.
  • Forbidden paths are enforced, not suggested.
  • High-risk work auto-escalates to a heavier gate (typo → LIGHT, auth/migration → HEAVY).
  • Codex changes land only through a throwaway worktree, after the gate passes.

It enforces process, not capability — see the honest benchmark.

Install

git clone https://github.com/SihyeonJeon/why-was-fable-banned
cd why-was-fable-banned && sh install.sh

python3 only, stdlib. Remove: sh install.sh --uninstall.

Scope

  • sh install.sh installs machine-wide: every Claude Code project on this computer (and every subagent / orchestrated worker) inherits the gate

  • sh install.sh --here installs for this repo only (Claude Code project-level .claude/settings.json)

  • Toggle in-session at three scopes by typing (the hook handles it, never sent to the model):

    typescopepersists
    wfb off / wfb onthis project diracross sessions in this repo
    wfb off here / wfb on herethis session onlythis chat
    wfb off all / wfb on allthe whole machineeverywhere

    Most-specific wins (session > project > machine > default on), so you can turn the project off and force one hard session on. State is a file, so it survives reboots until you flip it back. wfb status shows all three. One-off env bypass: WFB_BYPASS=1.

  • Status line: when the gate is on, [why-was-fable-banned] shows in the Claude Code status line (installed only if you don't already have one; otherwise the installer prints how to add the segment)

  • Works wherever Claude Code runs: terminal, the VS Code and JetBrains extensions, desktop (they share the same hooks), plus Codex. It does not apply to non-Claude-Code/Codex agents (e.g. Cursor's own agent)

How it works

  • Block: a PreToolUse hook intercepts every edit and exits 2 until the spec passes
  • Spec: restated goal · non-goals · context by authority · ≥2 rejected alternatives · risks · runnable acceptance · forbidden paths
  • Verify: "done" isn't done until each acceptance command shows live output (fail closed)
  • Apply: on headless Codex the worker runs in a throwaway git worktree; only a gate-passing diff reaches your repo

Quickstart

  1. sh install.sh: wires the hooks at user level (every project + subagent inherits it)
  2. Prompt your agent to do real work: a gated task auto-starts
  3. The agent writes .wfb/spec.json (it's told exactly what to fill); edits stay blocked until it passes
  4. It implements, runs the acceptance commands, records evidence, then closes

Grade auto-scales the depth: typos (LIGHT) require only a restated goal + one acceptance check; auth/payments/migration (HEAVY) pay the full gate.

Supported agents

  • Claude Code: native hooks, in-session block; the grade-specific contract is injected up front
  • Codex: wfb-codex-accept "<goal>" --repo <dir> (worktree-accept; headless)

Where the rules came from

Recorded real engineering sessions with hooks (42 traces), extracted them as a structured decision schema, generalized 19 into 8 decision axes, and cross-checked the generalization with a second model. Observable artifacts only: no chain-of-thought, local, secrets masked.

Three layers, increasing cost and depth
layercheckshow
gates/wfb_gate.pyform: fields, real paths, forbidden, fail-closeddeterministic, free
gates/wfb_judge.pymeaning: 0–2 rubric, gaming detectionoptional LLM judge
bench/correctness: hidden graderruns the tests

Benchmarks

Measured in this repo, reproducible (bash bench/run_quality.sh, bash tests/run_all.sh):

measuregate OFFgate ON
Decision record per changenoneenforced
Unspeced or forbidden-path edits reaching the repopossibleblocked
Adversarial / edge gate tests (downgrade, bypass, malformed, no-brick)n/a35/35 pass

Measured: SWE-bench, gate OFF vs ON (same model — Opus, both arms)

benchmarknaked (gate OFF)gated (gate ON)
SWE-bench Verified (light-repo slice, N=28)22/2823/28
SWE-bench Pro (qutebrowser, N=10)7/108/10
combined (N=38)29/3831/38

+2 across 38 tasks, zero regressions (the gate never lost a task naked solved; it won the ones it won by matching the exact test contract instead of a plausible-but-wrong shortcut) — at ~2–3× the tokens. This is small and within noise: the gate enforces process, not capability. On toy tasks with a hidden grader it shows no lift at all (both arms 10/10) — see bench/BENCHMARK.md. Raw per-instance results: bench/results/verified/, bench/results/pro/.

Validated live: a Codex run left a protected file untouched and applied only the gate-passing diff; if verification is incomplete it retries, then rejects rather than apply. Details: bench/BENCHMARK.md · TOKEN_BUDGET.md.

FAQ

What is why-was-fable-banned (WFB)? A spec-first, evidence-gated edit boundary for AI coding agents. It blocks an agent (Claude Code or Codex) from editing code until it writes a spec a deterministic gate accepts, and blocks "done" until live acceptance output proves the work.

Does it make Opus or Codex smarter? No. It enforces process, not capability. On SWE-bench it lifts the same Opus model by +2/38 at ~2–3× tokens (within noise); on toy tasks, no lift. Its value is enforcement, evidence, and an auditable decision record — not injecting intelligence.

Is it a Fable 5 plugin? No. It's a model-agnostic gate installed as hooks. It runs the same discipline Fable-style autonomy implies — spec, scope, re-runnable verification — as an external boundary, so Opus 4.8 or Codex must follow it whether or not the model would on its own.

How is it different from a prompt, CLAUDE.md, or a behavior plugin? Those are suggestions the model can ignore. WFB is hard enforcement: a PreToolUse hook exits 2 and the edit never happens until the spec passes. Forbidden paths and fail-closed verification are enforced, not requested.

Works with: Claude Code (terminal, VS Code / JetBrains extensions, desktop) and Codex. Not other agents (e.g. Cursor's own agent).

License

PRs welcome. MIT.

Files in the repo

Repository payload15 top-level entries
  • .github
  • adapters
  • assets
  • bench
  • gates
  • prompts
  • rubric
  • tests
  • .gitignore
  • install.sh
  • JUDGE.md
  • LICENSE
  • README.ko.md
  • README.md
  • TOKEN_BUDGET.md

Discussion (0)

Ask about usage, or say what you built with it

Sign in to join the discussion.

No comments yet. Be the first to say what this is good for.

More hooks

CLI proxy that reduces LLM token consumption by 60-90% on common dev commands. Single Rust binary, zero dependencies

80k

Warcraft III Peon voice notifications (+ more!) for Claude Code, Codex, IDEs, and any AI agent. Stop babysitting your terminal. Employ a Peon today.

5k
bahni-m/
code-with-quran

Read the Qur'an while Claude Code works. Start a session with 'claude --cwq' and a reader beside it walks forward through the Qur'an one ayah per prompt, resuming where you left off — in a terminal pane or a browser tab. Zero dependencies, fully offline.

48
zachahn/
vomit

Clean up Claude's token vomit with a separate LLM. Save your tokens, Opus is hopeless

193

A pre-execution guard for AI coding agents. It blocks destructive Git and file system commands, plus common attempts to access sensitive files, before a tool call runs. Supports Amp Code, Antigravity CLI, Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot CLI, Grok Build, Hermes Agent, Kimi Code, OpenClaw, OpenCode, and Pi.

1.5k