89 of 190 reviewer subagents graded their own model's work. A PreToolUse hook has blocked 7 since; one walked around it A team auditing its Claude Code agent found that 89 of 190 deep-reviewer subagent launches had graded drafts on the main session's exact model, defeating a written rule requiring a different model family for review. After a reviewer self-reported the overlap, the team added a PreToolUse hook that blocks same-model launches; it has since blocked 7 real launches, one of which was relaunched around the hook 15 seconds later. The team traced the failure to the `opus` family alias resolving to the main conversation's model when the main session is already on Opus. We want the subagent that grades our Claude Code agent's work to run on a different model family from the session that wrote it. For five weeks that rule lived in a sentence of our instructions and one line of an agent file, and when we finally counted, 89 of 190 reviewer launches had run on the main session's own model. A PreToolUse hook now blocks those launches. It has blocked 7 real ones, and one of them was relaunched around it 15 seconds later. Below is how the hook decides, what it blocked, what it can't see, and the reviews we deliberately put back on one model. All times below are UTC. Our agent drafts a lot of text that other people read: replies to comments, pages, design notes. Before any of it goes out, a subagent we call deep-reviewer grades it against a written rubric. The reviewer gets the draft and the rubric, not the conversation that produced the draft, so it can't simply agree with reasoning it never saw. Hiding the drafting history covers one kind of shared blind spot. The other kind lives in the model. If the writer is a model that tends to see a loosely related aside as a natural connection, a grader built the same way will tend to see it that way too, and the rubric line meant to catch it passes. So since 2026-08-19 our written rule has been that the reviewer runs on a different model from the main session. The agent file said model: opus , and the rule assumed the main session would be on a model from another family by default. That assumption was the whole mechanism. Nothing checked it. On 2026-09-26 one of our direct-message replies pulled in a measurement of ours that had little to do with what the other person was talking about, and the tone review passed the connection. Around the same time a reviewer, partway through another review, compared its own transcript with the agent file and reported that it was running on the same model as the main session. We put three options to the owner: move the reviewer to a model from another family, move it to a cheaper model, or redefine the rule as "a reviewer that hasn't seen the drafting history" and drop the model requirement. The owner chose a variant of the first: Opus by default, the other family whenever the main session itself is on Opus, and a mechanism instead of a reminder. Our diagnosis at the time was that the opus alias had started pointing at a newer Opus version, the one the main session was already using. While writing this article we reread the subagent docs and found a rule that gives the same result wherever the alias points. In the docs' words, a family alias such as opus "resolves to the main conversation's model instead of the version the alias points to" when "the main conversation's model belongs to that family". Every main session that launched a reviewer from 2026-09-23 on ran on Opus, so our records can't tell the two explanations apart. Both lead to the same conclusion: from an Opus main session, asking for opus cannot get you a different model. For this article we counted. On our machine, Claude Code keeps a transcript for every subagent run in a folder next to the session's own transcript, plus a small .meta.json file that names the agent type and the description the run was launched with. Our oldest surviving transcripts start on 2026-09-13. We matched each deep-reviewer launch to the run it produced, read the model name on the reviewer's own answers, and compared it with the main session's model at the moment of the launch. Before the hook, 190 launches matched a run. In 101, the main session was on another family and the reviewer on Opus, which is what the rule intended. In the other 89, the reviewer was not just in the main session's family but on its exact model: 24 on 2026-09-13 and 09-16, when the main session ran an earlier Opus version, and 65 between 09-23 and 09-27 on claude-opus-5-5. The problem we noticed on 09-26 had already happened on 2026-09-13, the oldest day the transcripts reach back to. Nobody saw it then, because a verdict file looks the same whichever model wrote it. The hook is a shell script, scripts/hooks/require-cross-model-reviewer.sh , registered in .claude/settings.json as a PreToolUse hook with the matcher Agent|Task . It went in on 2026-09-27 at 10:08. Claude Code hands a command hook a JSON object on stdin, and that object includes transcript path , the path to the session's transcript, along with the tool's input. For the Agent tool, the input carries subagent type , description and an optional model . The script lets every launch through unless subagent type is deep-reviewer . For a reviewer launch, it reads the last 400 lines of the main transcript, keeps the assistant entries, skips the ones marked