never-again

v0.1.2 · free · open source · MIT

Your coding agent fixes a bug, then makes the same mistake next week.

Mistakes that can't repeat.

never-again writes that fix down as a rule the agent cannot skip. When a script can catch the mistake, it becomes a Claude Code hook that blocks the wrong action before it happens. When the rule needs judgement, it becomes one short line in LESSONS.md instead of another paragraph in CLAUDE.md that the agent re-reads, and pays for, every single turn.

$git clone --depth 1 https://github.com/malaysherasia-ai/claude-never-again.git && bash claude-never-again/install.sh

macos, linux, wsl and windows · python 3.7+ · runs entirely on your machine

how it works

One question per bug.

Can a script catch this before it happens? If it can, the lesson becomes a hook, and a hook costs nothing to carry. If it cannot, the lesson becomes one line in a rule file. That file is capped, ordered by what fires most, and scoped per package, because models follow fewer of their instructions as the list gets longer.

Pipeline: capture, triage, hook, warn, block, with an advisory branch to LESSONS.md A packet moves left to right through five nodes. At triage it may branch upward to LESSONS.md instead. LESSONS.md advisory 17/40 loaded 17 Capture symptom · cause · rule on: "never again" Triage can a script catch it? before X, fail if Y Hook hooks/na/L001.sh PreToolUse · git commit * Warn decision: ask ok 0 / 5 Block decision: deny warn

    
in flightasksdeniedenforced
0
tokens per turn, enforced
40
rules per file, default cap
ask → deny
warn first, human promotes
$0
forever, mit licensed

install

Two minutes, using tools you already have.

If you have not installed a Claude Code skill before, this is the whole process. Open a terminal in your project folder, pick the column that matches your computer, and run the commands in order. You can run the installer again whenever you want a newer version: it adds a marked block to CLAUDE.md instead of overwriting the file, and it leaves an existing LESSONS.md alone.

macOS · Linux · WSL

requires git, bash, python 3.7+

  1. Clone and install into the repo you want guarded.
    # from your project root
    $ git clone --depth 1 https://github.com/malaysherasia-ai/claude-never-again.git
    $ bash claude-never-again/install.sh .
  2. Commit what it wrote. LESSONS.md, .claude/ and the hooks are team knowledge. Only fires.log stays local, and the installer gitignores it for you.
  3. Fix a bug, then say "never again." Claude captures the symptom, cause and rule, then decides whether a script can catch it.
  4. Grade the first fires with na ok L001 or na wrong L001. Five correct fires make a hook eligible for promotion from ask to deny.

Windows

requires git for windows, python 3.7+ · fixed in v0.1.1

  1. Install Git for Windows (it includes Git Bash, which runs the hooks). You can stay in PowerShell.
  2. Check Python actually runs. python -c "import sys" must exit 0. If Windows opens the Microsoft Store instead, that is the alias stub — disable it under Settings → Apps → App execution aliases, or point NA_PYTHON at a real interpreter.
  3. Clone and install.
    git clone --depth 1 https://github.com/malaysherasia-ai/claude-never-again.git
    & "C:\Program Files\Git\bin\bash.exe" claude-never-again/install.sh .
  4. Commit, then fix a bug and say "never again." Identical from here on.
    Stats: python .claude\never-again\na.

why it exists

A note costs tokens every turn. A hook costs nothing until it fires.

Five reasons the same lesson works better as a script than as a sentence.

01

Your instructions file is a subscription you forgot you were paying.

A 200-line CLAUDE.md costs roughly 2,500 tokens on every turn. Over a 100-turn session that's 250,000 tokens spent re-reading advice.

basis: ~12 tokens per line

200
lines
~2,500
tokens per turn
100
turns
250,000
tokens re-reading advice
02

A hook costs zero tokens until it fires. A rule costs tokens forever.

The protection is the same either way. A hook lives outside the context window, so it never competes with your code for room.

03

The agent can ignore a note. It cannot ignore a denied tool call.

permissionDecision: deny runs before every permission mode, including --dangerously-skip-permissions.

04

Rules are capped, ordered and scoped, because models follow fewer of them as the list grows.

IFScale (Distyl AI, 2025) measured 20 models against 10 to 500 concurrent instructions. At 500 the best model followed 68% of them, and instructions placed earlier were followed more reliably than later ones.

So the rule file has a cap, na sort puts the most-fired rules first, and rules load per package.

20
models measured
10 → 500
concurrent instructions
68%
best model, at 500
05

The tool makes no network calls. Your stats come from a Python script that counts lines.

There is no account to create and no network call anywhere in the tool. The fire log is a single local file.

0
network calls
0
accounts
1
local file

comparison

Why not just write it in CLAUDE.md?

Often you should, and never-again will tell you when. The difference is what happens to the rule after you write it.

  A line in CLAUDE.md A never-again hook
Cost per turn ~12 tokens, on every turn, forever 0until it fires
When it is wrong The agent may follow it anyway The tool call is denied and Claude is told why
Survives a long session Competes with everything else in context Outside the context window entirely
Survives a permission bypass No deny runs before every permission mode
Ordering Whatever order it was written in na sort ranks by real fire counts
Scope Loaded everywhere, always Per package, and only for matching tool calls
Evidence it works None A fire log, counted by na
Best for Judgement: taste, naming, architecture, tone Anything a script can check

None of this is an argument against CLAUDE.md. Plenty of rules need judgement that no script can make, and those belong in prose. never-again keeps its own LESSONS.md for exactly that, capped and ordered, and one of the four rungs on its triage ladder is to file nothing at all. The narrower claim is that when a script can check a rule, paying tokens to remember it is a choice.

questions

Questions worth asking first.

Does this replace CLAUDE.md?

No. It adds a marked block to your existing CLAUDE.md pointing at LESSONS.md, and never edits outside that block. Rules needing judgement still live in prose. What changes is that enforceable rules stop being prose.

What happens when a hook is wrong?

Every new hook starts in warn mode. It asks rather than blocks. You answer the prompt and grade it with na wrong L001, which resets its promotion count. A hook that cries wolf gets narrowed, not promoted. Promotion to deny is always a human command, and na demote always reverses it.

Will it slow down every command?

No. Hooks register with an if condition, so the process only spawns for the commands that matter. A commit hook never runs on a file read. A hook that fires on everything gets resented within a day, and the skill says so explicitly.

Does it work on Windows?

Yes, from v0.1.1. Before that it did not work. On Windows, command -v python3 resolves to the Microsoft Store alias stub, which exits without running anything, and every hook swallowed the failure and exited silently. Hooks appeared installed and never fired. The resolver now requires an interpreter that actually executes a statement and exits 0, and a hook with no usable interpreter says so instead of dying quietly.

What leaves my machine?

Nothing. There is no account, no telemetry and no network call anywhere in the tool. na is a Python script that counts lines in files you already have. The fire log is local and gitignored; LESSONS.md and the hooks are committed, because they are team knowledge.

What happens when LESSONS.md hits the cap?

You cannot add another rule until one is promoted to a hook or retired, and Claude has to say so plainly and propose which to drop. The default is 40 per file. The number that actually matters is how many rules load per turn from where you are working. na reports that as "loaded here" and warns above 60. When the warning fires, split by package, retire or promote. Do not raise the threshold.

Can hooks promote themselves to blocking?

No, and that is deliberate. After five correct fires the tool offers promotion once; you run na promote L001 or you don't. Nothing in the tool escalates enforcement on its own.

Is it really free?

MIT licensed, no paid tier, no hosted component to pay for later. It is a skill, a shell template and a Python script in your repo.