agentleFS
mralexivymralexivy/AutoMode/.claude/CLAUDE.md

AutoMode

CLAUDE.md8 starsChanged 10 days agoMITView on GitHub

AutoMode is a Claude Code mod: a plugin whose TypeScript registers event handlers. It picks a model and an effort for each prompt, runs a plan, build, verify and review workflow, and watches the session with a guardian. The mod has no install step and no build step. Claude Code loads the .ts files directly. npm tooling exists for development only, and it needs Node 23.6 or later. Run all four checks before you call a change to hooks/ done:…

  • Reads credentials
  • Installs packages

The file

We split this CLAUDE.md into the rules it gives an agent

7 rules. About 0 are common, 2 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Run all four checks before you call a change to hooks/ done: npm run typecheck, npm test, the validator and claude plugin test ..

    line 25
  2. Very specific:

    Validator rules: Write every mods API call in full ($.fs.read(...), never const fs = $.fs).

    line 82
  3. Very specific:

    Follow the ship-change skill for every change: one issue, one branch and one pull request per task.

    line 94
  4. Very specific:

    Do not change version in .claude-plugin/plugin.json.

    line 96
  5. Very specific:

    Do not claim a cost saving without a repeatable benchmark run.

    line 98
  6. Distinctive:

    Add or update a test with every behavior change.

    line 99
  7. Distinctive:

    Write comments and docs in short sentences, in active voice, with one idea per sentence.

    line 100

≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
CLAUDE.md

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

What this is

AutoMode is a Claude Code mod: a plugin whose TypeScript registers event handlers. It picks a model and an effort for each prompt, runs a plan, build, verify and review workflow, and watches the session with a guardian. The mod has no install step and no build step. Claude Code loads the .ts files directly. npm tooling exists for development only, and it needs Node 23.6 or later.

Commands

npm install                          # dev tools only
npm run check                        # type check, then the Node tests
npm run build                        # release bundle in dist/, validated
npm run typecheck
npm test                             # tests/*.test.mts and bench/*.test.mts
node --test tests/bands.test.mts     # one Node test file
node --test tests/claims.test.mts    # every public page shows the numbers in bench/results/headline.json
node --test --test-name-pattern='demandBand' tests/bands.test.mts   # one Node test by name
claude plugin validate . --strict    # reads the mod the way Claude Code does
claude plugin test .                 # tests/*.test.ts and *.test.tsx
claude --plugin-dir .                # load the working tree; it reloads on save

Run all four checks before you call a change to hooks/ done: npm run typecheck, npm test, the validator and claude plugin test ..

Two test runners. The extension decides which one runs a file:

  • *.test.mts runs under node --test. Use it for pure modules, and for anything with no engine.
  • *.test.ts and *.test.tsx run under claude plugin test, with the claude-code/testing kit. tests/harness.ts stands in for the engine. This runner takes a folder only, so it cannot run one file or one test by name.

What the type check misses. tsc starts from .mts files and follows their imports into hooks/, with claude-code stubbed as any in bench/stubs.d.ts. So it does not check *.test.ts files or the mods API calls. The validator and claude plugin test cover those. strict is off. Write erasable TypeScript only: no enum, no namespace, no constructor parameter properties. 33 older files start with // @ts-nocheck TODO(types). A new file must pass without that line.

Architecture

hooks/hooks.json names one module, hooks/register.ts. Its register function binds every engine event. The guardian sees each prompt first, and then the router decides the route.

LayerFilesRole
Wiringhooks/v4.ts, hooks/guardian.tsOwn all $ engine calls and module state. They move values between the engine and the pure modules.
Pure logichooks/lib/*.tsNo $ and no I/O. Each file opens with a comment that states its contract. lib/io.ts is the one exception.
UIhooks/ui/publish.ts writes the automode.view atom, and every drawing reads it. A drawing never calls publish.
Workflowworkflows/run.js, agents/*.mdThe automode:run workflow and its six agents. It runs in a different runtime from the hooks and shares no imports with them.
User scriptsscripts/*.mjsRun through a user's node, which may be older than 23.6.
Evidencebench/Benchmarks and offline transcript tools. Most of bench/external/ is vendored upstream code with checksums. Do not edit it.
Marketingmarketing/Listings registry, post drafts, GitHub metrics snapshots and the Buffer client. Not shipped. The growth skill runs it. tests/marketing.test.mts checks every post's numbers against the benchmark.

How a route is decided. v4PromptSubmit runs decideAuto under policy auto, the shipped policy. Policy legacy is the interval optimizer in lib/optimizer.ts.

  1. Two Haiku judges give evidence: the effortless judge (lib/effortless.ts) and the AutoMode judge (lib/classify.ts).
  2. lib/consequence.ts and lib/risk.ts set quality floors.
  3. optimizeAuto in lib/auto.ts picks the weakest eligible model, at that model's own effort. Eligibility reads one verdict asked with a fixed anchor, so the route follows the task, not the model the session started on.
  4. resolve in lib/authority.ts applies the order that matters: a user override or workflow role is final, the floor lifts the candidate, and the switch check in lib/policy.ts then holds or switches on cache cost. A hold never drops below the floor.

Effort can change per prompt while the model holds, because an effort change keeps the cache where the provider shares it. v4TurnStep applies the route to each request.

How a read is delegated. delegation is off, shadow or on, and config.json ships off. readGate in v4.ts runs from the main-session branch of guarded, and gateRead in lib/delegation.ts decides.

  1. A full read of a text file at or above delegationGateTokens stops once per file and task. It returns a free outline from outlineOf. The size comes from bytes, not lines, so a minified file counts.
  2. A second read of that file runs, so the model can always get the exact text. The gate also passes a file edited in the task, the debug, reconsider and review stages, and any task with a risk rating.
  3. v4Extract serves mcp__automode__extract. It asks $.tool.check about each path, so Read deny rules hold. It makes one Haiku call with no tools.
  4. verifyEvidence keeps a finding only if its quote is in the file at or near the cited lines. A kept claim is still Haiku's reading, so the model must read the lines before it relies on them.

Hooks record each step as kind: 'delegation', with the action gate, read-again or extract. The gate only saves money, so it fails open. Shadow registers no tool, because a tool definition changes the request.

How Haiku is reached. reachHaiku, on in config.json, makes Haiku eligible for T0 to T2 work without critical risk, unless the need names Opus. It also makes T2 with need=opus require Opus. Haiku solved 64 of 65 screen tasks, so a judge's "Sonnet" often overstates the need. bench/classify-eval.mts tests the judges and rules without running a task, and costs cents.

How routes learn. lib/learn.ts keeps a per-project memory in learned-<hash>.json. noteLearned in v4.ts files each task after every turn and after a correction. A task is bad when it moved up to Opus after an escalation, or when the person corrected or retried it. It is ok when a check passed. Once a bucket (tier and need) has 2 bad tasks and a 40% bad share in 30 days, decideAuto excludes the cheaper models for that bucket. Learning only raises a route, and a pin keeps its model.

Settings precedence, lowest first: code defaults, config.json, the plugin userConfig, then environment switches such as AUTOMODE_ROUTER and AUTOMODE_POLICY. See lib/settings.ts.

Failure behavior. Hooks fail open: a routing error falls through to next(e), and a failed judge never blocks a prompt. The tool guards fail closed, Bash included: tool.call denies the call if the guard throws before the call runs.

Pins and the ladder. lib/pins.ts reads the person's /model and /effort from command.run and from the app's value on main requests. In tests, h.step takes the app's model, not the routed one: never pass the routed model back, because the app's value never echoes a rewrite. escalation() in lib/failures.ts rates the evidence weak or strong, ladderStep in lib/bands.ts turns it into one step, and failureStep only reports and diagnoses, plus the legacy floor.

Traps

  • Keep this file in .claude/. A CLAUDE.md at the repository root is a warning to claude plugin validate, so --strict fails, and CI runs --strict.
  • Stale comments. The headers of register.ts and v4.ts describe an AutoMode picker row, but activation now defaults to always. hooks/options.ts names hooks/ui/settings.tsx, which does not exist. The "external signals writer" in v4.ts is not in this repository.
  • Two routers in register.ts. The classic judge router runs only with "router": "judge". config.json ships "v4", so routing changes belong in v4.ts and lib/.
  • Duplicated risk patterns. HIGH_RISK in register.ts and RISK_RULES in workflows/run.js hold the same S3 text regexes. A comment says a test keeps them identical, but no test does. Change both by hand. V4 routing itself uses lib/risk.ts and lib/consequence.ts.
  • Validator rules. Write every mods API call in full ($.fs.read(...), never const fs = $.fs). Pass event names and $.env.get names as string literals.
  • The calls: line. The validator cuts this line at 1,000 characters, and the mods catalogue refuses a cut line. CI fails on it too. Busy host calls therefore go through the function declarations in lib/io.ts. Keep them as declarations that pass $ through.
  • The directory branch. The Anthropic directory reads $ only within one file, so tools/release.mts directory publishes the shipped files with hooks/ bundled into one module. Pure lib/ files stay separate. Never name a local variable on or next in hooks/. The portal's Validate button accepts owner/repo@branch, so try a change there first.
  • lib/effortless.ts is a verbatim port. tests/effortless-fidelity.test.mts fails if its code differs from the vendored source. Put changes in lib/effortless-adapt.ts, each with its reason and a test.
  • The delegated reads estimate runs low. tokensOf uses 3.5 chars per token, and code runs denser. EXTRACT_MAX_TOKENS leaves a wide margin, because Haiku's price rises fivefold above 100k prompt tokens.
  • tests/golden/decisions.json pins optimizer and switch-check behavior. When a change to the assumptions moves a case, update that case on purpose.
  • Benchmark tracks stay apart. The AutoMode study uses claude -p, the neutral track uses bench/runners/neutral-agent.mts, and a report never compares across them. Never weaken a rule in bench/README.md under "What keeps a run honest". Safety tasks run only on a sandboxed runner.
  • npm test globs one level. It runs bench/*.test.mts, so a test in a bench/ subfolder does not run.
  • workflows/run.js has a top-level return. tests/workflow.test.mts wraps it in an AsyncFunction with mocked globals. Keep it as JavaScript.

Repository rules

  • Follow the ship-change skill for every change: one issue, one branch and one pull request per task. The branch holds the task's code, tests and benchmark. Nothing writes to main directly.
  • Publish every result everywhere. After a benchmark run that changes a public number, before a release PR merges, and for any edit to the benchmark docs or the website, follow the publish-results skill. It updates the README, docs/compare.md, every website page, the website's FAQ data, the sitemap and the report in the same PR. bench/results/headline.json holds the public numbers, and tests/claims.test.mts fails CI when any page drifts from the rows or keeps a stale claim. Never deliver a result to one page and leave the rest.
  • Do not change version in .claude-plugin/plugin.json. The release PR raises it, and also updates the README. Add a line under [Unreleased] in CHANGELOG.md when you change a shipped path.
  • CI rejects personal absolute paths anywhere in the repository, and a "text": field in bench/results/*.json. Never save model reply text or real session transcripts.
  • Do not claim a cost saving without a repeatable benchmark run. Under 30 tasks, a run is a pilot. See bench/README.md.
  • Add or update a test with every behavior change. Keep one task per pull request. A plan with phases is still one task: its phases are commits on one branch, never separate pull requests.
  • Write comments and docs in short sentences, in active voice, with one idea per sentence.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.