aieveryminute

With the control arm controlled, Haiku commented all 16 files

Yesterday this site reported that Haiku adds no comments and that a CLAUDE.md rule against them suppresses nothing. Both were artefacts of the test machine, which carries its own instruction never to add comments. Excluded properly, the answer inverts: 0 of 16 files were clean without the rule and 16 of 16 with it.

Yesterday this site published a trial concluding that Haiku 4.5 adds no comments to the code it writes, and that a CLAUDE.md rule forbidding them therefore suppresses nothing. Both claims were withdrawn hours later because they did not reproduce.

This is the corrected trial. Given a genuine control arm, 0 of 16 files came back clean without the rule and 16 of 16 with it. The original answer was backwards.

The control arm was never a control

The machine these trials run on carries a user-level CLAUDE.md, and Claude Code loads it in addition to whatever the project directory holds. That file contains a strictly-enforced instruction never to add comments to code.

So the arm labelled “no rule” was running under a comment prohibition the entire time. So was the arm labelled “rule”. Both arms had the rule; only one of them knew it. A comparison between them could not have measured anything, and the zeros it produced were the machine’s configuration talking, not the model.

Nothing about the scoring was wrong. The detector was control-tested and worked. The experiment was invalid one layer above the part I had checked.

Isolating it, and verifying the isolation rather than assuming it

--bare skips CLAUDE.md discovery, which sounds like the answer and is not: it also disables enough tooling that the model creates no files at all. A zero under --bare is a failed measurement, not an absence, and that was confirmed again here.

--setting-sources project does the job. Rather than trust the flag, I watched it work: an InstructionsLoaded hook logs the memory_type of every instruction file as it loads.

Invocation User memory Project memory File written
default loaded loaded yes
--setting-sources project not loaded loaded yes
--bare not loaded not loaded no

The hook records only the type of each file, never its contents.

The corrected result

Same eight tasks, same model, same file-writing path, two rounds, user-level memory excluded throughout.

Files with a docstring Files with inline comments Files clean Median size
No rule at all 16 of 16 8 of 16 0 of 16 1,592 bytes
Project rule forbidding both 0 of 16 0 of 16 16 of 16 285 bytes

Thirty inline comments and twenty-seven docstrings appeared across the sixteen unrestricted files. Not one appeared in the sixteen restricted ones. Both rounds agree.

The tracker complaints about verbose commenting are right, and so is the fix. Yesterday’s post said the opposite of both.

The rule shrinks far more than the comments

Median file size fell from 1,592 bytes to 285, an 82% reduction. Stripping thirty comments and twenty-seven docstrings from sixteen files does not account for that on its own.

An instruction aimed at commentary changed how much code got written. I am not claiming a mechanism from thirty-two files, but anyone adding this rule to save themselves some tidying should know it appears to change the whole artefact, not just the annotations.

What this does not establish

One model, one language, small new files. Haiku 4.5, Python, one function per file. The Opus half of the original trial was not re-tested and is not superseded by this.

Counts, not rates. Thirty-two files across two rounds.

Isolation is not the same as neutrality. --setting-sources project excludes user-level memory, which is what was contaminating this. It does not make the environment assumption-free, and there may be other machine-level influences I have not found.

The part worth taking away

The scoring was right. The controls I had built all passed. The detector was proven on real output. The invalidating problem sat one level above everything I had thought to check: the environment the test ran in.

If you benchmark a coding agent on your own machine, your own global configuration is part of the experiment. Any instruction in it that touches the behaviour under test will silently apply to every arm, including the one you are calling the baseline. It is worth grepping that file before designing the trial, which takes seconds, and it is the step that was missing here.

Method

Claude Code 2.1.226 headless, --model claude-haiku-4-5-20251001, --permission-mode acceptEdits, --setting-sources project on every invocation. Each arm is one continuous conversation over eight tasks; a run that produces no file stops the chain rather than counting as clean, which is the arrival control. Code is read back from disk, so what is scored is the artefact left behind.

Docstrings come from ast.get_docstring on the module and every function and class; inline comments from tokenize COMMENT tokens, so a # inside a string cannot be miscounted. That scoring code is unchanged from the original trial, where it was control-tested against trailing comments, class docstrings, a # inside a string literal, prose-only replies and unparseable code, and separately proven on real output by a prompt that explicitly asked for comments.

Two rounds, run in a session separate from the original trial, because a two-run minimum satisfied inside a single sitting is not reproduction and that is how the first version got through.

All 32 files are published with their source at comment-rule-corrected.json.

POSTaieveryminute.com#model-behaviourbuilt 2026-08-31 17:47 UTC