9 min read
Most developers are using Fable 5 completely wrong.
They use it like a glorified task runner: paste in a task, wait for the model to grind through it, commit whatever comes back, and move on.
That workflow can produce useful output, but it’s also the fastest way to burn Mythos-tier tokens while capturing almost none of the value that actually compounds.
Anthropic just extended Claude Fable 5 access across all paid plans through July 12.

You should separate using the model from actually building with it, because those are not the same.
If your workflow begins and ends with a single expensive run, you are paying premium prices for disposable output.
A self-improving agent system gets better because everything around the model gets better, i.e., the environment compounds.

You should treat Fable 5 like the core engine inside a system that remembers, evaluates, routes, and hardens over time, each run makes the next run cheaper, sharper, and more reliable.
That is where the compounding value is, and most people are leaving it on the table.
Let’s dive in.
The stack is simple enough to draw on a whiteboard.

Start by making one loop compound.
The loop is:
The agentic loop is simply context gathering, action, and verification.
The important engineering decision is what you persist between runs.
If nothing is persisted, every session is a cold start.
Editor’s note: To celebrate reaching 10,000 community members on Medium, who relentlessly design, ship, and iterate on agents every day, we’re also making the full repository available for free, which is part of our Agent Foundry program.
Fable 5 is the orchestrator and the judge is cheaper than the work it judges.
Output tokens cost 5× input ($10 in, $50 out), so generation is where the bill explodes.
You reserve Fable for the plan and the ambiguity, fan trivial work to cheap tiers, and put a Haiku-tier grader in charge of gating Fable’s output.

Fable 5 should decide the plan, split work, interpret ambiguous failures, and update memory but it should not spend premium tokens renaming variables or formatting docs.
This is the same design instinct you already use in distributed systems.
You do not put every job on the biggest machine, you put the coordinator on the machine that can reason across the full graph, and you fan out cheaper workers for parallel tasks.
Pick a task with a real pass/fail signal.
CI triage is ideal because it has logs, tests, deterministic commands, and a clear done state.
Create STATE.md:
npm run test:ci is the source of truth for merge readiness..github/workflows/* without human review.npm run test:ci -- checkout-webhookCreate CLAUDE.md:
Read STATE.md before changing code.
For CI triage:
STATE.md with verified facts, open failures, and lessons.Do not delete tests. Do not modify billing code without explicit approval.
Now run the loop manually once:
claude --model claude-fable-5
Inside Claude Code:
/goal npm run test:ci passes, STATE.md is updated, and every CI failure is classified with evidence
The /goal command is important.
It is a session-scoped completion condition checked after every turn by a separate small model.
If the goal is not met, Claude continues instead of returning control to you.
This is the smallest practical move from chat to loop.
Self-critique is not enough for serious agent systems.
The maker agent has too much context about why it made the change.
A verifier should see the artifact, the rubric, and the command output but it should not inherit the maker’s emotional investment in the patch.

Create .claude/agents/verifier.md:
You are an independent verifier.
You did not write the patch. Do not defend it.
Check:
Return one of:
Include exact evidence: command, file path, failing assertion, or missing state entry.
Claude Code supports custom subagents with focused prompts, tool restrictions, and model selection.
Use it like this:
Use the verifier subagent to check the CI triage result. It must inspect the patch, run the relevant tests, and confirm STATE.md was updated.
Do not treat a passing test suite as the whole verifier.
Passing tests answer “does the code run?” but they do not answer “did the agent modify the wrong subsystem?” or “did it forget to write the lesson back?”
A Skill is procedural memory.
It is where you put reusable know-how that should travel across sessions and projects.
Create .claude/skills/ci-triage/SKILL.md:
| Class | Signal | Action |
|---|---|---|
| env | missing secret, missing service, bad runner variable | escalate |
| flake | passes on retry without code change | document and file issue |
| bug | deterministic failure tied to source change | draft fix |
| dependency | failure starts after version bump | draft rollback or compatibility patch |
| infra | timeout, OOM, network, runner instability | escalate |
webhook-race: checkout tests fail when webhook delivery and assertion overlap. Fix pattern: wait for persisted event before asserting downstream state.
missing-webhook-secret: integration test fails before app boot. Action: mark env, do not change product code.
Every run must update STATE.md with:
Skills are powerful because they can include instructions and code, which also means they require trust and review.
Treat Skills like code, e.g., review them, version them, add owners and do not install random Skills into production automation without reading them.
The compounding rule is simple: when the verifier confirms a new failure mode, write it into the Skill.
A plain /goal is perfect when one agent can iterate against one objective.
Use a Dynamic Workflow when the task has branches.
Examples:
Workflow tool is a dynamic workflow script that can orchestrate subagents with primitives like agent(), parallel(), and pipeline().
A CI compounding workflow could look like this:
export const meta = {
name: "ci-compound",
description: "Classify CI failures, draft safe fixes, verify independently, and update memory.",
phases: ["read-state", "fanout", "verify", "distill"]
};
export default async function workflow({ agent, parallel, pipeline, phase, args }) {
await phase("read-state");
const state = await agent("state-reader", {
prompt: "Read CLAUDE.md, STATE.md, and the latest CI logs. Return failure clusters as JSON."
});
await phase("fanout");
const fixes = await parallel(
state.failureClusters.map((cluster) =>
agent(`triage-${cluster.id}`, {
prompt: `Investigate this failure cluster in an isolated worktree. Classify it and draft a safe fix if allowed: ${JSON.stringify(cluster)}`
})
)
);
await phase("verify");
const verdicts = await parallel(
fixes.map((fix) =>
agent(`verify-${fix.id}`, {
prompt: `You are an independent verifier. Check this fix, run relevant tests, and return PASS/FAIL with evidence: ${JSON.stringify(fix)}`
})
)
);
await phase("distill");
return agent("memory-writer", {
prompt: `Update STATE.md and the ci-triage Skill using only verified lessons: ${JSON.stringify(verdicts)}`
});
}The key is explicit orchestration.
Parallel work should be parallel, verification should be independent and memory writing should happen only after evidence exists.

Once multiple agents can write files, shared checkout state becomes dangerous.
Use git worktrees.
git worktree add ../repo-ci-fix-a -b claude/ci-fix-a
git worktree add ../repo-ci-fix-b -b claude/ci-fix-b
git worktree add ../repo-verify-a -b claude/verify-aA maker can edit one worktree. A verifier can inspect another. A failed experiment can be deleted without poisoning the main checkout.
git worktree remove ../repo-ci-fix-b
git branch -D claude/ci-fix-bThis is boring engineering and that is exactly why it works.
A compounding system needs triggers.
Claude Code Routines can run on schedules, API calls, and GitHub events.
Each run creates a new session that you can inspect later, and API triggers expose a /fire endpoint protected by a bearer token.
A useful first routine:
/schedule weekdays at 7am, run CI triage compounding for the payments-api repo. Read STATE.md and the ci-triage Skill. Run the latest failing CI suite. Classify failures. Draft safe fixes on claude/ branches. Use verifier subagent before marking anything complete. Update STATE.md and post a digest.
This is where the system starts to behave like an engineering process.
Fable 5 is not Mythos 5 without constraints.
Fable 5 can return stop_reason: "refusal" as a successful HTTP 200 response, not an HTTP error, and that integrations should plan for refusal handling, fallback, and billing behavior.

Refused requests can usually be retried on another Claude model through server-side fallback, SDK middleware, or manual retry.
That means your agent loop needs code like this:
async function runWithFallback(task: string) {
const result = await callClaude({
model: "claude-fable-5",
prompt: task
});
if (result.stop_reason === "refusal") {
await appendState({
type: "model_refusal",
classifier: result.refusal?.classifier,
taskSummary: summarize(task),
nextAction: "retry_on_opus_or_escalate"
});
return callClaude({
model: "claude-opus-4-8",
prompt: `Handle this task within policy. If still unsafe or ambiguous, escalate.\n\n${task}`
});
}
return result;
}A refusal is state and it belongs in STATE.md or your run database because classifier behavior affects future routing.
Also check data retention before routing sensitive data through long-running routines.
Fable 5 and Mythos 5 carry 30-day data retention and are not available under zero data retention.
The whole system depends on a contract:
No run is complete until it leaves the next run better prepared.
Make that concrete.
Every run must produce at least one of these:

If a run only produces a chat answer, it did not compound.
Add these in order:
STATE.md with verified facts, rules, failures, lessons, and last session./goal condition for one real workflow.The product is the loop you build around the model.
Fable 5 makes longer, more ambitious loops practical, which is enough to build a system that compounds.