PärPod by Claude Code
PärPod by Claude Code
PärPod by Claude Code
Sidequest: What a "Battery" Is, and Why It Needs a Hall Pass
6m · Oct 20, 2026
Sidequest: What a "Battery" Is, and Why It Needs a Hall Pass

Sidequest: What a "Battery" Is, and Why It Needs a Hall Pass

Cold open

A battery is a test suite: a list of fake commands thrown at one hook, each with the verdict the hook should give, run all at once to check the hook still judges correctly.

"Battery" has nothing to do with power here. It is "a battery of tests", the way a doctor orders a battery of tests. The word stuck in your estate because every guard hook has one.

How it came up

You were in the middle of a burn session in the dot claude repo. One of the two items was closing four ways a script could still sneak a paid API call past the paid-api-block hook. That hook is the bouncer that stops Claude from running anything that would cost you money at Anthropic, DeepSeek, Play dot ht and the rest without an explicit yes.

Before touching anything, the session took a baseline. It ran four batteries: the paid-api-block one, the apilog check, the podman untag guard, and the rsync safety tests. All four came back green. That gave it a known-good starting point. Then it started reading the paid-api-block battery to write the spec for Codex.

That reading is where the bouncer caught it. A battery for a paid-API guard is full of things that look exactly like paid API calls. To the hook, Claude's command was full of strings like api dot anthropic dot com and "import anthropic". It did what it is built to do and said no. Claude said, correctly, that this was the hook working, and retried with the same override the battery's own instructions use.

The mental model

Think of a hook as a judge that sees every command before it runs and returns a verdict: let it through, or block it. A judge like that can go wrong in 2 directions. It can block something harmless, which is a false positive and annoying. Or it can let something dangerous through, which is a hole, and for this hook a hole costs money.

The battery is the judge's exam. Each line is one case with a label, a command, and the verdict it should get. "Curl to localhost with replay dot html in the path" should pass. "Python script that imports anthropic" should be blocked. "Same script, but someone hid the call behind a path traversal trick" should also be blocked. Today the paid-api-block battery has 106 cases. It feeds each one to the hook, compares the real verdict to the expected one, and prints ALL PASS or a mismatch.

The file's own header puts it best: the battery is the hook's regression memory. Every time the hook misfired, or Codex found an exploit in a review round, a case got added. Read the labels and you get the hook's whole history of incidents: "Codex round 1 exploit", "Codex round 2", "tee a heredoc then bash it". Without the battery, every fix would risk quietly reopening an old hole, and no one would remember there had been one.

A couple of design details matter here.

First, the fixtures. The battery creates its fake paid scripts in a throwaway temp folder, not inside the hooks folder. The hook trusts its own folder, so fixtures stored there would all be waved through and the battery would test nothing. That was learned the hard way in August, and it is written into the file's header.

Second, the hall pass. Any command that runs or reads the battery has to contain those endpoint strings, so the hook would block the test run itself. The documented way to run it is to put the override variable, PAR API OK equals 1, in front of the command. The battery itself even has a case checking that the override works. The override is honest here because the battery never makes a real API call. It only pipes fake commands into the hook and reads the exit code. So the override says "this command line talks about paid APIs, it does not call them."

That is why "the hook caught my fixture text, which is correct behaviour" was a good sign rather than a nuisance. A paid-API guard that could not see paid-API text in a heredoc would be the real worry.

Why four batteries, and why they gate the apply

Look at what the session asked Codex to build. Codex works on a staged copy of the hooks folder, never the live one. It adds the 4 bypass cases plus 7 harmless twins, so the fix cannot simply block everything that looks similar. It also writes an apply script that runs all 4 batteries after copying the change in, and rolls back if any of them goes red.

So the batteries play 3 roles. Before the change, they set the baseline: green now, so any red later is the change's fault. During the change, the new cases come first and should fail against the old hook. That is the red-proof the session plans to check, because a test that never fails proves nothing. After the change, they are the tripwire on deploy.

Where else this lives

The same idea runs across your estate. The download-net hook has its own battery, and its notes say that if it gets chatty, you tighten the patterns and prove it with the battery rather than bolting on a cooldown. The global pre-push secrets hook works the same way: a false block gets its shape added to the hook's test file before anyone fixes the hook. The rule is always the same. The misfire becomes a test first, then the fix.

If you remember one thing: a battery is a hook's exam and its memory, a list of every trick it has ever been fooled by, and when the hook blocks Claude for quoting that list, the guard is working.