by cozytab
Make Opus 4.8 (or any Claude model) work like Claude Fable 5 — a Claude Code skill + guard hooks (plan gate, model ceiling, per-task enforcement) for Fable-5-grade discipline: plan, self-verify, and route sub-agents, without Fable 5.
# Add to your Claude Code skills
git clone https://github.com/cozytab/fable5-modeLast scanned: 7/10/2026
{
"issues": [],
"status": "PASSED",
"scannedAt": "2026-07-10T07:35:09.660Z",
"npmAuditRan": true,
"pipAuditRan": true,
"promptInjectionRan": true
}fable5-mode is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by cozytab. Make Opus 4.8 (or any Claude model) work like Claude Fable 5 — a Claude Code skill + guard hooks (plan gate, model ceiling, per-task enforcement) for Fable-5-grade discipline: plan, self-verify, and route sub-agents, without Fable 5. It has 117 GitHub stars.
Yes. fable5-mode passed SkillsLLM's automated security scan — a dependency vulnerability audit plus prompt-injection heuristics — with no high-severity issues. You can read the full report in the Security Report section on this page.
Clone the repository with "git clone https://github.com/cozytab/fable5-mode" and add it to your Claude Code skills directory (see the Installation section above). fable5-mode ships a SKILL.md manifest, so compatible agents can discover and load it automatically.
fable5-mode is primarily written in Python. It is open-source under cozytab on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh fable5-mode against similar tools.
No comments yet. Be the first to share your thoughts!
name: fable-mode
description: A work-discipline protocol that makes Opus 4.8 (or any non-frontier model) operate at Fable-5-grade quality. Core idea — output quality = model capability x work discipline: spend extra orchestration to buy single-pass quality via six levers (plan gate, small-card execution, adversarial self-check, real-product verification, context hygiene, checkpoint autonomy). Activate ONLY on an explicit request — the user names the mode ("use fable mode", "enable fable-mode", "work like Fable 5", "rigorous mode", or the Chinese "用 fable 模式"、"开 fable-mode"、"像 Fable 5 一样做"、"严谨模式") — or when the project is already armed with a .fable/ directory (the hooks handle that). Do not auto-trigger on a task merely being large, important, or quality-sensitive, and not on generic phrases like "do it well / 最高质量 / 别偷懒"; if a task looks like it would benefit, ask the user whether to enable fable-mode instead of assuming.
triggers:
You are now in fable-mode. Premise: frontier-model feats come half from the model and half from longer autonomy, harsher self-verification, less corner-cutting. That second half is model-independent — this protocol supplies it. The trade: spend extra orchestration steps to buy single-pass quality; the disciplined steps cost more tokens, but the net over a whole task often breaks even by avoiding rework loops and bloated-context waste.
.fable/ directory. A task being big or important is a reason to offer fable-mode ("want me to run this under fable-mode?"), never to silently enter it.curl --max-time, never WebFetch; long Workflows get a watchdog.Never stall, hand off, or end the turn waiting for a model you can't run:
(Set FABLE_ESCALATION=on only if a stronger tier genuinely exists to defer to.)
Before code, write docs/SPEC.md: requirements, approach, task cards (skeletons in templates/). Each card: ≤ one fresh context (~≤5 files / ≤300 lines); a machine-checkable acceptance test ("looks right" isn't acceptance); dependencies and parallelism marked. Executor choice is your judgment — subagent, Workflow, external executor, or yourself; quality first, don't split when in doubt.
Evidence closure before design: list the load-bearing unknowns — the ones that change the architecture if you guessed wrong — and buy targeted evidence for each (a 5-second probe: two extra frames, one API call, one grep) before committing the design. Every SPEC decision carries a source tag: [measured] / [inferred] / [not-shown → design-gap]. Guessed foundations are how one-pass code dies; tagged assumptions are how reviewers know where to poke.
Each card runs in a fresh context, fed only the relevant SPEC excerpt — no reasoning garbage from prior cards. Run acceptance the moment it's done; don't advance until it passes. Concurrency, model choice, and the failure-escalation ladder: see Delegation policy.
Important output is never "generate and ship". Critical modules: 2-3 independent refute passes (correctness / edges / integration) — one solid hit means rework. Wide solution spaces: N approaches + judge + synthesize. Fresh-context verifiers beat self-critique (templates/VERIFIER_PROMPT.md); verifier prompts say "assume broken, falsify hard", never "take a look".
Desk-check before first run: after drafting a large unit, re-derive the critical constants from the source evidence (layout proportions, units, coordinate mappings, state-machine edges) instead of trusting the draft, and probe interaction corners (modal click-through, mid-animation input, concurrent state). The two cheapest bugs to fix are the ones caught before the code ever runs.
All-green static checks ≠ it works. Every milestone: run the real product end-to-end, exercise the core path, keep evidence (screenshots, logs, test output). Report evidence, not adjectives.
window.__test API), then simulate the full loop through it. Testability is a product feature; ship it.docs/SPEC.md + docs/PROGRESS.md updated in real time, not batched. Segment long tasks: each segment restores from SPEC + PROGRESS only. Record every gotcha/lesson the moment you hit it (one lesson per entry, with why; update rather than duplicate, delete wrong ones). Grinding in a context stuffed with failed attempts makes models dumber — restart fresh. The converse also holds: never wrap up, trim scope, or suggest a new session just because the conversation is long — external memory is what makes length safe; keep working. Memory stays project-scoped by design: lessons live in this project's PROGRESS, never in a global store that leaks between projects.
Background long tasks get a watchdog (output-file mtime). Organize resumable: any step dying loses at most one card. On long runs, verify at intervals, not only at the end: every few cards, a fresh-context pass re-checks accumulated work against the SPEC (drift compounds silently between milestone checks). Forbidden is brainless fan-out (spray with no verification/watchdog/checkpoints) — parallelism itself is fine.
When acceptance fails — or a fix "doesn't work" — attribute before you edit, cheapest layer first:
fetch(url, {cache:'reload'}), restart, rebuild). "Fix had no effect" is, embarrassingly often, "fix never ran".Misattributed fixes are worse than no fix: they add churn and leave the real layer broken.
Multitasking rule — applies in BOTH tiers: batch independent tool calls into one message; dispatch independent, self-contained side-tasks (searches, verification runs, bulk mechanical work) as background subagents while you keep working — never sit idle waiting for a result you don't need yet. This is pure speed with zero quality risk; what the tiers change is only the cap and the posture for quality-critical work.
Concurrency tiers:
Shepherd, don't babysit: after dispatching, keep working instead of blocking on each return — but read results as they land and intervene the moment a subagent drifts off spec or lacks context it needs.
One-word controls — the user steers both dials with a phrase; you write the matching directive line into .fable/LEDGER.md (per-round, auditable, never silent):
| User says | Effect | You write |
|---|---|---|
| "质量优先 / quality mode / no downgrades" | routing: nothing runs below the session model | ROUTING: quality |
| "节省模式 / 省着点用 / frugal" | routing: implementation cards default one tier down | ROUTING: frugal |
| "火力全开 / 全速跑 / full speed / max parallel" | concurrency: throughput tier | TIER: throughput |
| "收着点跑 / slow down / back to normal" | concurrency: conservative tier | TIER: conservative (or delete the line) |
| (nothing) | balanced routing + conservative ≤5 | — |
Model routing — three profiles, two iron rules. Solving the problem outranks saving tokens, always; the profiles only tune how much safe downgrading you accept. Two rules hold in every profile:
| Profile | Trigger words (user says) | Implementation cards | Mechanical gather/format |
|---|---|---|---|
| quality | "质量优先 / 全用主模型 / quality mode / no downgrades" | session model, always | session model, low effort |
| balanced (default) | — | inherit by default; drop one tier only when tightly specified + machine-checkable acceptance | cheap tier, low effort |
| frugal | "节省模式 / 省着点用 / frugal / save quota" | default one tier down (acceptance still required); tricky cards stay inherited | cheapest tier, low effort |
Selecting a profile: the user's words above, env FABLE_ROUTING=quality|balanced|frugal, or a ROUTING: <profile> line in .fable/LEDGER.md (per-round, auditable — when the user asks for a mode, write this line rather than silently changing behavior). Default is balanced; never switch profiles silently.
Safety net — identical in all profiles (this is why even frugal still solves the problem):
FABLE_ESCALATION=on for genuine upward deferral).hooks/README.md)Four hooks turn the most-shirked rules into hard blocks. Armed per project by a .fable/ directory (searched upward, bounded at the git root); without it they pass through silently. Pressure applies per round via .fable/LEDGER.md:
- [ ] 1. card (machine-checkable acceptance) <- open: guards enforce
- [x] 2. done -- evidence: pytest 21/21 <- [x] REQUIRES a substantive evidence note
- [~] 3. not this round -- deferred: reason
PAUSED: reason <- a line anywhere: enforcement off
(PAUSED must carry a reason — a bare PAUSED is ignored, pausing has to
be attributable. Evidence notes must be substantive: evidence: ok counts as
missing.)
model param and model: literals in Workflow scripts; stays active even when paused, it protects quota, not workflow).- [ ] items remain, and while any - [x] lacks an -- evidence: note (evidence-on-close: adjectives don't close cards).Wrap-up lint: python3 <skill-dir>/hooks/fable_lint.py <project_dir> — machine-checks the discipline itself (SPEC source tags present, open cards name acceptance, closed cards carry evidence). Run it at step 7 of the execution template; findings are open work.
Per-task granularity: active (open cards) = full enforcement; idle (no/all-closed cards) = close guard quiet and small tasks flow freely, but a detailed fan-out still needs a live card first; paused (a PAUSED: reason line) = guards off except the ceiling. Write PAUSED only when the user steers to work unrelated to the round; remove it to resume. Small spawns (<1500 chars) and forks skip the design gate; everything fails open (a guard bug never bricks the session); loop-safe.
For substantial work: after writing the SPEC, mkdir .fable + create .fable/LEDGER.md to get the mechanical backstop. In the user's repo, suggest gitignoring .fable/ (round state) while committing docs/SPEC.md/PROGRESS.md (durable docs).
1. Restate goal + scope (if unclear ask once; then no requirement rework)
2. docs/SPEC.md + .fable/LEDGER.md cards — the gate
3. Execute cards (fresh contexts; Delegation policy)
4. Per-card acceptance -> update PROGRESS.md
5. Milestone adversarial self-check (refute or N-approach review)
6. End-to-end real verification, leave evidence
7. Wrap: fable_lint clean, PROGRESS complete, lessons recorded, push if asked
English | 简体中文
Make Opus 4.8 — or any Claude model — work like Claude Fable 5. A Claude Code skill plus guard hooks that give a non-frontier model Fable-5-grade work discipline: plan-gate, self-verification, and sub-agent routing, enforced mechanically.
The skill is invoked as fable-mode; its premise:
output quality = model capability × work discipline
# 1. Install the skill (honors CLAUDE_CONFIG_DIR; falls back to ~/.claude)
git clone https://github.com/cozytab/fable5-mode \
"${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/fable-mode"
# 2. (optional) register the enforcement hooks — merges into your settings.json,
# resolves its own path, idempotent:
bash "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/fable-mode/install.sh"
# 3. In Claude Code, just ask for it — in any language:
"use fable mode" · "用 fable 模式" · "do this rigorously, one-shot"
# 4. For a project you're taking seriously, turn on enforcement:
mkdir .fable
printf -- '- [ ] 1. first card (with a machine-checkable acceptance test)\n' > .fable/LEDGER.md
The skill works on its own; step 2 is optional (it turns the discipline into hard blocks). Claude replies in your language even though the skill is authored in English.
Why it exists. Weaker models mostly don't fail by being dumb in the moment; they fail by process: thinking while typing and changing their mind halfway, declaring "looks right" without running anything, fanning work out with no verification, and quietly stopping mid-task. Those are process failures, and process is fixable with structure. Since the "discipline half" of frontier output is model-independent, you can hand a cheaper model the working habits of a stronger one and recover a real chunk of the gap — paying in orchestration steps instead of a bigger model.
What you actually get.
What it does not do. It won't turn Opus into Fable 5. It closes the discipline gap, not the capability gap. The cost is real — more orchestration steps and slower wall-clock on small tasks — which is exactly why you don't use it on small tasks. (Net token cost depends on the task; on rework-prone work the discipline can even come out lower.)
| # | Lever | What it forces |
|---|---|---|
| 1 | Plan Gate | Write docs/SPEC.md (requirements + approach + task cards, each with a machine-checkable acceptance test) before writing code. Concentrate thinking in the cheapest phase. |
| 2 | Small-card execution | Each card runs in a fresh context; don't advance until its acceptance command passes; on 2 failures, escalate instead of flailing. |
| 3 | Adversarial self-check | Don't "generate and ship." Dispatch independent viewpoints to refute critical output; for wide-open problems, generate N approaches + judge + synthesize. |
| 4 | Real-product verification | All-green static checks ≠ it works. Run the real product end-to-end each milestone and leave evidence (screenshots, logs, test output). |
| 5 | Context hygiene | SPEC + PROGRESS are external memory. Restore state by re-reading them, not by dragging failed-attempt reasoning through a bloated context. |
| 6 | Checkpoint autonomy | Long background tasks get a watchdog and resumable checkpoints, so a hang or crash costs at most one card. |
The full protocol lives in SKILL.md — the text Claude actually reads.
Six levers written as prose still rely on the model's honor. Four hooks turn the most-shirked rules into hard blocks:
| Hook | Event | Effect |
|---|---|---|
| Profile Injector | SessionStart |
Auto-injects the discipline, sized to the ledger state — full during an active round, a one-liner when idle or paused — plus the model-appropriate tier and open-item recovery. |
| Spawn Guard | PreToolUse (Agent/Task/Workflow) |
Blocks a detailed spawn before a ledger exists (forces the plan gate), and blocks any spawn requesting a model stronger than the session's — the model ceiling is mechanical, not just prose. |
| Fail-Streak Reminder | PostToolUse (Bash) |
Advisory, never blocks: at every 3rd consecutive failing command it injects the attribution ladder (suspect the harness → prove the new code is running → only then debug the product, and fix the class via an invariant) — cures grinding on the wrong layer. |
| Close Guard | Stop |
Blocks ending the turn while the ledger still has unchecked items — cures early stopping / spinning. Also enforces evidence-on-close: a - [x] card without an -- evidence: note blocks the stop ("report evidence, not adjectives" as a hard rule). |
Plus hooks/fable_lint.py — not a hook but a one-shot CLI: checks the SPEC
carries [measured]/[inferred]/[not-shown] source tags, every open card names
its acceptance, every closed card carries evidence. Run it at wrap-up (or in CI):
python3 hooks/fable_lint.py <project_dir>.
Design properties that make this safe to register globally:
.fable/ directory (searched upward, bounded at
the git root). No .fable/ → the hooks pass through silently. They never touch
projects you didn't opt in.stop_hook_active, so you're never trapped.See hooks/README.md for the mechanics.
Prerequisites: Claude Code, and python3
(standard library only — no third-party deps; needed only if you use the hooks).
Hooks assume a POSIX environment (macOS / Linux / WSL) where python3 is on
PATH; on native Windows the skill itself still works, but the mechanical
enforcement layer is untested there — treat it as protocol-only.
Your Claude config directory is $CLAUDE_CONFIG_DIR if that variable is set,
otherwise ~/.claude. Everything below derives from it, so it works no matter
where your config lives.
git clone https://github.com/cozytab/fable5-mode \
"${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/fable-mode"
bash "${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/fable-mode/install.sh"
install.sh resolves its own location (so the hook paths are correct no
matter where you cloned it), honors CLAUDE_CONFIG_DIR, and merges the four
hooks into your settings.json without disturbing existing config. It's
idempotent — re-run it after moving the skill and it re-points the paths. Remove
the hooks any time with bash install.sh --uninstall.
Or just tell Claude Code:
Install the skill at https://github.com/cozytab/fable5-mode by following its README.
Updating: after git pull, re-run install.sh. A new version can add hook
events (e.g. a PostToolUse hook), and only the installer updates your
settings.json — a plain git pull ships the files but won't register new
hooks. It's idempotent, so re-running is always safe.
Note: hook registration (install or update) takes effect from your next Claude Code session — settings are read at session start, so restart or open a new session after running the installer.
Clone as above, then merge these four entries into the hooks object of
<config-dir>/settings.json (don't overwrite the file; if you already have a
hooks key, add these under it). Use the absolute path to where you actually
cloned it — the ${CLAUDE_CONFIG_DIR:-$HOME/.claude} below is expanded by the
shell at hook-run time:
"hooks": {
"SessionStart": [{"hooks": [{"type": "command",
"command": "python3 ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/fable-mode/hooks/fable_profile_inject.py"}]}],
"PreToolUse": [{"matcher": "Agent|Task|Workflow",
"hooks": [{"type": "command",
"command": "python3 ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/fable-mode/hooks/fable_spawn_guard.py"}]}],
"PostToolUse": [{"matcher": "Bash",
"hooks": [{"type": "command",
"command": "python3 ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/fable-mode/hooks/fable_fail_streak.py"}]}],
"Stop": [{"hooks": [{"type": "command",
"command": "python3 ${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/fable-mode/hooks/fable_close_guard.py"}]}]
}
The skill alone is enough to trigger fable-mode by asking for it; skip the hooks if you only want the protocol.
When a user asks you to install fable-mode from this repo:
$CLAUDE_CONFIG_DIR if set, else ~/.claude.git clone the repo into <config-dir>/skills/fable-mode.bash <config-dir>/skills/fable-mode/install.sh — it merges the hooks
idempotently and resolves paths itself. If you instead register hooks by
editing settings.json yourself, merge into the existing hooks object
(never overwrite the file) and use the absolute clone path — do not
hardcode ~/.claude if the user r