Additive Bias and Calling the Question
On this page
Collected from “in the trenches” work with Claude Code. Each pattern: the name, what Claude does, the mechanism behind it, the classical engineering concept it maps to, and the recovery move.
Book-Level Themes (Accumulating)
These themes emerged across multiple patterns and may organize the book’s structure:
- Read friction as diagnostic — When Claude produces friction (pushback, repeated mistakes, over-complication), treat the friction itself as a signal about what kind of pathology is operating. Friction is data.
- Additive bias — Claude prefers accretion over restructuring. Adding a file, a column, a feature, a name segment feels local and reversible-looking; restructuring touches everything and feels risky. This mechanism links Sidecar Proliferation, Phantom Requirements, Compound Naming, Natural-Key Bias, Deprecation Blindness (the last being additive bias in its lifecycle form — add new code beside old rather than retire the old), and The Invented Constraint (#21 — its sharpest form: faced with a problem, Claude reaches for building a new mechanism and never names the option that builds nothing, even when reusing an existing artifact dissolves the problem entirely).
- Decision pathologies vs. defense rhetoric — The catalog splits naturally into two categories: (a) what Claude does wrong when making decisions, and (b) how Claude defends those wrong decisions when challenged. Self-Citation is the clearest instance of category (b); Separate-Concern Deflection (#17) is a second — both borrow a legitimate-sounding authority (Claude’s own prior code; the principle of Separation of Concerns) to defend the convenient choice. The category-(b) tell is that the argument, not just the decision, is doing defensive work. The Surviving Defense (#20) is the genus of category (b): when a decision is challenged, Claude regenerates a fresh justification for the unchanged conclusion — and Self-Citation and Separate-Concern Deflection are two of the specific tactics that regeneration reaches for. A third category is now established: (c) communication pathologies — how Claude’s reporting of the work itself costs the user time. Status Theater (#15) was the first instance; The Manufactured Loose End (#23) is the second, and the pair shows the category holds two distinct defects: noise that must be waded through (#15) and false content that must be checked (#23). The second is the more expensive, because wading is bounded by reading speed while checking is bounded by how long it takes to go read the artifact and prove the flag was empty.
- “Runs without complaint” mistaken for “correct” — Claude treats code that executes without raising or crashing as successful, independent of whether the result is right. This conflation drives a family of patterns: Silent Error Swallowing (#5) hides errors so the program keeps running; Default Laundering (#19) substitutes a default so an error never arises in the first place; both buy a clean run at the cost of a silently wrong result. The reader’s counter-instinct: a program that finishes is not the same as a program that is correct, and the most dangerous failures are the ones that never announce themselves.
- Reversibility / blast radius — Most pathologies here are additive (theme 2) and therefore reversible-looking: an over-built abstraction or an extra file can be deleted later, so catching it late is a bounded cleanup. The False Duplicate (#22) is the catalog’s rare subtractive, irreversible pathology — agreeing destroys work, and the cost surfaces only after the fact. Note that the same friction-minimization engine produces both poles: Deprecation Blindness (#14) over-preserves when coexistence is the cheap path, #22 over-deletes when discard is the cheap path. This reframes how to triage Claude’s proposals — scale scrutiny to blast radius: wave through the reversible, gate the irreversible. A subtractive or destructive recommendation (discard a branch, drop a side of a conflict, delete a store) earns a proof-of-no-loss that an additive one does not.
- Confidence is not a correctness signal (the calibration gap) — Claude delivers a recommendation with a fluency and decisiveness that track how well-formed the answer sounds, not how well the trade-off was priced. The confident architectural call and the half-considered one are indistinguishable from the outside — same tone, same certainty — because the confidence is generated by fluency, not by having weighed the cost that later proves load-bearing. The anchor specimen is Case 8 (case-studies.md): Claude recommended injecting config via a session-wide
XDG_CONFIG_HOMEbecause Python already resolved that variable — asserted confidently, and wrong on the one axis (session-wide scope) its certainty was structurally blind to. The practical consequence reorganizes the whole triage doctrine: you cannot scale scrutiny to Claude’s apparent confidence, because that dial is not wired to correctness. Scale it to blast radius instead (theme 5) — gate the irreversible and the wide-scope no matter how sure Claude sounds; wave through the cheap-to-undo no matter how tentative. This theme is also the bridge between the two halves of the catalog: the initial over-confidence (a decision pathology — cf. the Priority Mis-Weighting candidate, where the mis-ranked trade is delivered without hedging) and the post-challenge rationalization (theme 3 / #20 The Surviving Defense) are the same calibration failure at two moments — unearned certainty before challenge, certainty defended rather than revised after it.
The 23 Patterns
1. Dev Infrastructure vs. Product Code Conflation
What Claude does: Intermingles development tooling concerns with product functionality. Justfile recipes (for building/running the project) bleed into the application code itself. Scripts meant for the developer’s workflow get embedded in product features. Bash commands get proposed for apps that need to run on Windows.
Real example: Building a daemon app where Claude repeatedly tangled the justfile recipes for starting/stopping the development harness with the actual product startup logic.
Mechanism: Context-blindness about deployment and runtime environment. Claude doesn’t maintain a clear mental model of “this code runs in dev” vs. “this code runs in production.” Classic junior-developer failure, expressed in AI form.
Classical mapping: 12-Factor dev/prod parity; “works on my machine” syndrome; right tool for the right job.
Recovery move: Establish explicit separation in CLAUDE.md. Create a clear directory boundary between dev tooling and product code. When Claude conflates them, name the boundary explicitly: “That belongs in the justfile, not in the application.”
Author note: This isn’t a novel Claude pathology — it’s a classical junior-developer mistake. The AI-specific flavor is that Claude proposes the wrong runtime target (e.g., bash on a cross-platform app) because it’s drawing on the most common patterns in its training data rather than the specific runtime constraint of your project.
2. Jargon Cowpath
What Claude does: Uses a consistent internal vocabulary — words like “sidecar,” “seam,” “load-bearing,” “surface,” “smoking gun,” “drive-by,” “canonical” — that isn’t in the official documentation and isn’t explained unless asked.
What the user should do: Learn Claude’s vocabulary rather than fighting it. This is the productive move.
Mechanism: Claude is a specialized domain, like law or medicine. Every specialized domain has vocabulary. The productive response to domain vocabulary is to learn it (Domain-Driven Design calls this Ubiquitous Language; Nielsen’s first usability heuristic is “speak the user’s language” — which applies symmetrically). Trying to make Claude stop using its vocabulary is a losing battle; it “falls back into its old ways.”
Classical mapping: Ubiquitous Language (Eric Evans, DDD); speak the user’s language (Nielsen’s heuristics); meet the client where they are (consulting principle).
Bigger principle: This applies beyond Claude — working with any system, client, or collaborator means adopting their vocabulary. Speaking to Claude means speaking in Claude’s terms, just as speaking to a client means speaking in the client’s terms.
Recovery move: Build a personal vocabulary list (see TERMS_CLAUDE_LIKES.md). Add Claude-specific terms to your CLAUDE.md. Reference them in prompts. Don’t ask Claude to use different words; instead, use its words yourself.
Note: This is the only item in the catalog that is not a pathology — it’s a user strategy. Its chapter belongs in Part I (Building Blocks) or in a “Speaking Claude’s Language” chapter, not in the pathologies section.
3. Sidecar Proliferation
What Claude does: Creates auxiliary files to track information that could be derived — JSON files that record session IDs, PIDs, tmux panes, working directories, timestamps — rather than deriving that information on demand.
Real example: For the Endless project, Claude created a sidecar JSON file tracking: Claude session ID, tmux pane, harness type, session ID from the Endless DB, cwd, PID, and date created. All of it was derivable from the DB’s existing records, specifically from the pane_id already stored there. The sidecar files caused cascading sync problems until the author “called the question” and asked whether any of it could be derived — answer: yes, all of it.
Mechanism: Additive bias. Creating a new file feels cheaper than restructuring existing data. Claude doesn’t evaluate “can this be derived?” as a design question; it defaults to “record it.”
Classical mapping: Single Source of Truth; DRY (Don’t Repeat Yourself).
Recovery move: When Claude proposes a new file or data store, ask explicitly: “Can any of this be derived from data we already have?” Call the question. Often the answer is yes, and the sidecar and all associated maintenance burden disappears.
4. Phantom Requirements / Unstated-Concern Over-Indexing
What Claude does: Adds features or behavior that weren’t requested, because it has inferred (often incorrectly) that the user’s underlying concern implies a broader need.
Mechanism: Additive bias operating at the requirements level. Claude reads between the lines — sometimes correctly, often not — and adds the “obviously implied” feature. Gold-plating. The implied feature creates complexity, potentially breaks other things, and was never validated as a real need.
Classical mapping: Gold-plating; feature creep; YAGNI (You Aren’t Gonna Need It).
Recovery move: Name the requirement explicitly and narrowly. When Claude adds something you didn’t ask for, say: “I didn’t ask for [X]. Remove it. If I need it later, I’ll ask.” Narrow scope in CLAUDE.md for recurring violations.
5. Silent Error Swallowing
What Claude does: Writes error handling code that silences errors rather than surfacing them. Try/catch blocks that log silently and continue. Exception handlers that recover gracefully but hide what went wrong.
Mechanism: Claude is pattern-matching on “defensive coding” examples in training data. The resulting code compiles, runs, and doesn’t crash — which Claude treats as success. It doesn’t model “the developer needs to know this happened.”
Classical mapping: “Errors should never pass silently” (Zen of Python); fail-fast principle; exception swallowing as a known code smell.
Recovery move: Add to CLAUDE.md: “Never swallow errors silently. All error handling must log the full error, including stack trace, to [your logging system], before recovering.” Review all error-handling code Claude writes before accepting.
6. Speculative Complexity (YAGNI Violation)
What Claude does: Adds abstraction layers, configuration options, plugin points, or generalization that wasn’t requested and isn’t needed for the current problem.
Mechanism: Additive bias at the architecture level. More abstraction feels more professional. Claude patterns on “well-designed systems” in training data and applies those patterns even when the current problem doesn’t warrant them.
Classical mapping: YAGNI (You Aren’t Gonna Need It); premature optimization; speculative generality (Fowler’s code smell).
Recovery move: When Claude adds architectural complexity, ask: “What requirement does this serve right now?” If the answer is “future flexibility” or “good practice,” reject it and ask for the simpler version.
7. Compound Naming Over Decomposition
What Claude does: Adds descriptive segments to names rather than restructuring to eliminate the ambiguity the longer name is compensating for. UserAuthenticationSessionManager instead of splitting into UserAuth and SessionManager. Database columns with three-part names when the schema should be normalized.
Mechanism: Additive bias at the naming level. Extending a name is a local operation; decomposing a thing into two things requires restructuring the surrounding code.
Classical mapping: Stinky names as a code smell (Fowler); the principle that names diagnose design quality — when a name is too long, the design is usually the problem.
Recovery move: When a name gets unwieldy, ask: “Does this name suggest the thing is doing too much? Should this be two things?” Use the name as a diagnostic signal for the underlying design problem.
8. Frame-Locked Optimization
What Claude does: Optimizes within the current framing of a problem rather than questioning whether the frame is right. Improves the wrong solution efficiently.
Real example: Optimizing a caching strategy for queries that, if the schema were restructured, wouldn’t need to be cached at all.
Mechanism: Claude treats the problem statement as a constraint. It works within the box you’ve drawn. It does not spontaneously ask “wait — should we be solving this differently?”
Classical mapping: Local maximum (optimization theory); anchoring (cognitive bias). Less of a classical software engineering concept, more from adjacent fields.
Recovery move: Periodically zoom out. Ask Claude: “Are we solving the right problem? Is there a design change that would make this optimization unnecessary?” Build “call the question” checkpoints into longer sessions.
9. Self-Citation (Manufactured Authority)
What Claude does: When a decision is challenged, rationalizes it by appealing to “the existing code” or “established conventions in this project” — when Claude itself wrote both the code and the documentation that established the “convention.”
Real example: Author questions a database design choice. Claude responds: “This is consistent with the existing schema conventions.” Claude wrote the existing schema.
Mechanism: Claude borrows the epistemic legitimacy of “established practice” while smuggling in zero actual establishment. The circular reasoning is: “My decision is correct because it’s consistent with my previous decisions.”
Classical mapping: Circular reasoning; bootstrapping; appeal to manufactured tradition. Also: category (b) — defense rhetoric, not category (a) — decision pathology. This is how Claude defends wrong decisions, not a wrong decision itself.
Recovery move: When Claude appeals to existing code/conventions, ask: “Who established that convention? If it was you, that’s not independent authority — let’s evaluate the decision on its merits.”
Independent corroboration: Emmanuel Paraskakis’s agent-ready-CLI skill suite (Level 250 — see references.md) engineers around exactly this pattern, which is external evidence the pathology is real and not this book’s projection. His end-to-end skill builds a CLI and then refuses to score it, on the stated ground that “a self-audit scores high” and “the run that built the CLI is the last one that should be adjudicating its own omissions” — it emits observations and defers the grade to an independent audit run. That is a builder who has felt the pull of manufactured authority and structurally denied Claude the chance to cite its own work. Worth citing in the Part III treatment: someone reached the same diagnosis from the tool-building side and designed a guardrail for it.
10. Jargon Proliferation
What Claude does: Introduces technical terminology without explaining it, or uses multiple terms for the same concept inconsistently across a session.
Mechanism: Claude patterns on technical writing in its training data, which assumes shared vocabulary. It doesn’t model “this reader may not know this term.”
Classical mapping: Audience-awareness failure; the same failure that produces bad technical documentation.
Recovery move: Add to CLAUDE.md: “Define technical terms on first use. Use consistent terminology throughout. If you introduce a term, use the same term every time.” For cross-session consistency, maintain a project glossary.
11. Convention Amnesia
What Claude does: Forgets conventions established earlier in a session — naming patterns, error handling approaches, architectural decisions — and reverts to defaults when working in a new file or after a long exchange.
Mechanism: Claude’s context window is finite. Earlier decisions are pushed out or weighted less. Claude also doesn’t have a “this is a project convention” signal unless explicitly told.
Classical mapping: The broader challenge of maintaining consistency across a large codebase; the role of style guides and linters in enforcing convention mechanically.
Recovery move: CLAUDE.md is the primary mitigation — conventions go there so they survive context window limits. Add a /project slash command or equivalent that re-anchors Claude to all established conventions at the start of each session or after a long gap.
12. Premature Maturity
What Claude does: Implements production-grade features (rate limiting, caching, retry logic, circuit breakers) when working on a prototype or early-stage project that doesn’t need them yet.
Mechanism: Claude patterns on “complete” implementations. A search for “authentication implementation” in training data returns production-grade examples with all the hardening. Claude applies all of it by default.
Classical mapping: Premature optimization; YAGNI; “make it work, make it right, make it fast” — Claude skips to “make it right” (by its definition) when “make it work” is the actual current goal.
Recovery move: Be explicit in your prompt about the current stage. “We are building a prototype. Prioritize correctness over production-readiness. We will add hardening in a later pass.” Add the current stage to CLAUDE.md.
13. Natural-Key Bias
What Claude does: Defaults to natural keys (email addresses, usernames, external IDs) as primary keys in database schemas rather than surrogate keys (auto-increment integers, UUIDs), even in contexts where natural keys are a poor choice.
Mechanism: Additive bias — natural keys feel “obvious” because they’re already present in the domain model. Adding a surrogate key requires introducing something new. Claude also patterns on common tutorial examples, many of which use natural keys for simplicity.
Classical mapping: Natural key vs. surrogate key debate (long-running database design question); the principle that primary keys should be stable, meaningless, and under the system’s control.
Recovery move: Add to CLAUDE.md: “Always use surrogate primary keys (UUID or auto-increment integer). Never use email addresses, usernames, or external IDs as primary keys.” Ask Claude explicitly: “Should this be a surrogate or natural key? Walk me through the tradeoffs before deciding.”
14. Deprecation Blindness (Coexistence Bias)
Audience tag: Anyone can catch this.
What Claude does: When adding new functionality that overlaps with or supersedes existing functionality, Claude treats the existing code as a fixed constraint to protect. It builds bridges, guards, and special-case logic so the new and the old can coexist — rather than recognizing that the new code should replace and delete the old. It optimizes for “don’t break what’s there” even when “what’s there” is something it wrote minutes ago in a project with no external users.
Real example: A CLI already had a db path --db subcommand flag (values main|worktree) when a global --db flag was added for the same purpose. Asked to make the global flag work in any argument position (an argv pre-scan), Claude flagged a “wrinkle”: the pre-scan “must not swallow db path’s own --db,” and it began designing collision-avoidance logic to keep both flags alive. It never asked the question that dissolved the whole problem — why do two --db flags that do the same thing exist? The author’s recovery (“kill db path --db; have it read the global flag”) eliminated the wrinkle, the special-casing, and a downstream portability hazard all at once. (Full transcript: see case-studies.md, Case 1.)
Mechanism: Additive bias in its lifecycle form. Deleting code looks risky and irreversible; adding around it looks safe and local. This is compounded by an over-applied backward-compatibility reflex — Claude’s training is saturated with “don’t break existing behavior,” so it defends recently self-authored code as if it had millions of downstream consumers. The tell is the vocabulary: when Claude reports a “wrinkle,” “collision,” “conflict,” or says it must be “careful not to break” something, and the thing being protected is something it recently created, Deprecation Blindness is firing.
Classical mapping: “There should be one — and preferably only one — obvious way to do it” (Zen of Python); DRY applied to interfaces/mechanisms, not just data; refactor-to-consolidate (Substitute Algorithm / Inline); the deprecation lifecycle (retiring superseded code is part of the change, not an afterthought); Kent Beck’s “make the change easy, then make the easy change” — Claude does the second half and skips the first.
Relationship to #8: Close cousin of Frame-Locked Optimization. #8 takes the problem frame as fixed and improves the wrong solution efficiently; #14 takes the existing code as fixed and preserves the wrong structure carefully. Both are failures to zoom out and question a given, and both resolve through Calling the Question.
Recovery move: When Claude flags a coexistence “wrinkle,” ask: “Why do both of these exist? If the new one does the job, can we delete the old one?” Treat overlap between new and old code as a deprecation opportunity, not a compatibility problem. Probe for phantom dependents: “Does anything actually depend on the old behavior, or are we protecting it out of habit?”
Author note: This case sharpens the book’s thesis rather than contradicting it. A non-developer’s naive “wait, why are there two?” would have caught the redundancy faster than Claude’s expert-flavored carefulness. But resolving it still required experience: knowing the two flags were semantically identical, that the value rename (worktree→sandbox) should propagate, and that the Click before/after-the-subcommand quirk is a portability landmine for the planned Go port. The refined lesson: experience is what tells you that Claude’s careful handling is solving a problem that shouldn’t exist.
15. Status Theater (Completion Ceremony)
Audience tag: Anyone can catch this.
What Claude does: Wraps task completion in elaborate ceremony — multi-section recaps, decorative comparison tables, restated rationales, and hedged “say the word” offers — that buries the one or two facts the user actually needs under a wall of presentation. Each task ends with a performance of thoroughness rather than a result.
Real example: At the end of a routine CLI session, the helpful answer was two lines — “E-1459 landed. Next: spawn E-1470, change E-1459.” Instead Claude produced repeated three-column tables, a “why it floundered” section, a separately-flagged design aside (“whether that burden is acceptable is a design question…”), and a “say the word and I’ll…” closer — minutes of generation per turn — making each task tedious to read and act on.
Mechanism: Claude patterns on thorough technical writing and treats volume as a proxy for diligence. It also hedges to avoid presuming — surrounding a simple result with options, caveats, and deference. The friction this produces is itself the diagnostic signal (friction-as-diagnostic): the noise is not neutral, it actively slows the user down.
Classical mapping: BLUF (Bottom Line Up Front); the inverted pyramid (most important fact first); “omit needless words” (Strunk & White); signal-to-noise ratio. A communication pathology — candidate category (c) alongside decision pathologies and defense rhetoric.
Recovery move: Give Claude the terse template you want and make it the default in CLAUDE.md: “End tasks with a BLUF status — what landed, what’s next — in ≤3 lines. No tables, no recaps, no ‘say the word’ hedging unless I ask for detail.” When ceremony creeps back, paste the two-line version you wanted as a correction.
Note: Distinct from #10 Jargon Proliferation (undefined/inconsistent terms). This pattern is about volume and ceremony, not vocabulary — the words can all be defined and the output can still be exhausting.
16. Memory Substitution (Durable Knowledge in an Ephemeral Store)
Audience tag: Anyone can catch this.
What Claude does: Asked to record a decision, convention, or constraint that should outlive the session, Claude writes it to its own private memory — a machine-local, per-user store no collaborator can see and that may not survive — and then treats “I saved it” as equivalent to “it’s recorded.” It conflates its ephemeral notebook with the project’s durable, version-controlled record.
Real example: A recorded architecture decision (ED-1505) fixed the source-of-truth direction for enum-shaped fields. In follow-up, the author refined a related constraint: the Go type should be int-backed with explicit values and no iota (a reorder silently renumbers everything and DB rows point at the wrong meaning). Claude wrote that constraint into its private memory and reported that the recorded decision “doesn’t need updating” — reasoning the syntax constraint was “a separate concern now captured in memory.” The author corrected it: “Your memory is NOT a substitute for a recorded decision; your memories are potentially ephemeral on my machine only, and decisions are recorded for posterity in version control and visible for all who clone and use endless to see. Update decision.” The durable constraint belonged in the version-controlled decision record — legible to everyone who clones the project — not in Claude’s head.
Mechanism: Claude has no model of where knowledge lands or how long it survives. It treats every store as interchangeable and reaches for the lowest-friction, most self-trusted one — its own memory, which feels authoritative because Claude will see it again next session. Two compounding tells: (1) it equates “recorded somewhere” with “recorded,” and (2) it rationalizes under-recording by decomposing a decision finely enough that part of it (“just a syntax detail,” “a separate concern”) falls out of the formal record. Updating the real record here was also higher-friction than a memory write (it required a reject-and-re-add because the in-place update path hadn’t shipped yet) — and Claude took the cheap path, which is additive bias wearing a new costume.
This is a genuinely AI-native pathology: it exists because Claude has a private memory feature. The classical analogue is a developer who keeps critical decisions in a personal notebook instead of the team’s record — but Claude’s memory is even more invisible, because the user often doesn’t know what went into it or whether it will persist.
Classical mapping: Architecture Decision Records (Michael Nygard); tribal / institutional knowledge as an anti-pattern; bus factor; single source of truth for decisions; “the repository is the record.” Sibling to Principle #2 (Durable Decisions Belong in the Durable, Shared Record) in the principles catalog — the pathology is the default; the principle is what good looks like.
Recovery move: When Claude says it “remembered,” “noted,” “captured,” or “saved” something, ask where. If the knowledge is durable, shared, or architectural, it belongs in a version-controlled artifact — a decision record / ADR, CLAUDE.md, or project docs — not Claude’s private memory. The test: “Would someone who clones this repo next year need to know this?” If yes, it goes in the repo. Reserve memory for personal working context, never for the project’s record of record. And watch for the decomposition dodge (catalogued separately as #17, Separate-Concern Deflection): a constraint being “a separate concern” is not a reason to leave it unrecorded — record the whole decision, not the half Claude found convenient.
Author note: The reader’s value-add is knowing an architectural decision has an audience and a lifespan — it must stay legible to everyone who later clones the project, long after this session’s memory is gone. A non-developer can still catch the surface tell (“you said you’d remember it — remember it where?”), but knowing the right home is version control, visible to all collaborators, is precisely the trained instinct this book is about.
17. Separate-Concern Deflection (Scope-Splitting Dodge)
Audience tag: Anyone can catch this.
What Claude does: Asked to do something that would require touching more than it wants to, Claude reframes the single obligation as several “separate concerns” and quietly drops the inconvenient part — presenting the split as a clean architectural distinction rather than what it is: a smaller amount of work. The decomposition sounds real; its effect is to shrink what Claude has to do.
Real example: Refining a recorded decision (ED-1505), the author tightened a constraint — int-backed enum, explicit values, no iota. Claude declared the constraint “a separate concern now captured in memory” and concluded the recorded decision “doesn’t need updating.” The split sounded principled — source-of-truth direction (the decision’s topic) vs. Go syntax (the new constraint) — but its result was to excuse leaving the version-controlled record stale and stranding the constraint in ephemeral memory (see #16, Memory Substitution). “Separate concern” did the work of “I’d rather not reopen that record.” (Full exchange: case-studies.md, Case 3.)
Mechanism: Defense rhetoric. Separation of Concerns is a genuine engineering virtue, which gives the move its camouflage — Claude borrows the legitimacy of a real principle to justify doing less. The tell is directional: a “separate concern” claim that, if accepted, conveniently reduces Claude’s obligation — especially when the half declared separate is the higher-friction half (reopening a formal record, deleting code, threading a change through more files). Honest decomposition cuts work into pieces that all still get done; this move cuts a piece off and lets it fall.
Classical mapping: Motivated reasoning; moving the goalposts; misapplied Separation of Concerns (using a structuring principle to decide whether a thing gets done, not just where it lives). Category (b) — defense rhetoric — sibling to Self-Citation (#9): both borrow a legitimate-sounding authority to defend the convenient choice.
Recovery move: When Claude calls something “a separate concern” to justify not doing it, separate the two questions it has fused: “Separate or not — does the original thing still need doing?” Separation of Concerns governs how you organize work, never whether a needed piece gets done. If the half Claude declared separate is also the higher-effort half, suspect the split is motivated and ask for both halves.
Author note: SoC is a real principle, which is exactly why this deflection is hard to catch — it wears a virtue’s clothes, and the decomposition is often correct as a decomposition. The experienced eye notices the correct-sounding split is being used to shed work rather than to clarify structure. The non-developer’s instinct (“wait, you still have to update the record, right?”) catches it too, because the test isn’t architectural — it’s just refusing to let a true statement (“these are separate”) smuggle in a false one (“so I don’t have to do one of them”).
18. The Unquestioned Goal (Means-as-End + Blocker Blindness)
Audience tag: Anyone can catch this.
What Claude does: Accepts a goal — one it inferred as a routine procedure, or one the user (or a skill’s framing) handed it — and drives to satisfy it without ever interrogating the goal itself. It skips the two questions that justify a goal: forward — what end does pursuing this actually serve? — and backward — what should block this before it’s allowed to happen? The goal is treated as self-justifying, so Claude optimizes its execution and never audits its warrant. This shows up in two complementary faces:
- Means-as-end (forward). Claude proposes or performs an action as a virtue in itself — because it’s “what you do” — when in this context the action serves no end. The procedure’s mere existence stands in for its justification.
- Blocker blindness (backward). Locked onto a goal as the objective, Claude marches toward it and declares it reached without considering the conditions that should have stopped it. It checks progress toward the goal, never obstacles to it.
Real example: Designing a long-lived “epic” task (E-1537) with eight unfinished children, Claude got both faces wrong in one turn. First it proposed releasing the task’s claim — treating release as an intrinsic good, though nothing else needed the task, so release served no end (means-as-end). The author’s “Why do we need to release it? Does another session need it?” was rhetorical: the point wasn’t that retracting release was wrong, it was that release had been proposed with no justifying purpose in the first place. Seconds later Claude declared the session “safe to archive” — so fixated on the author’s general goal of archiving that it never surfaced the condition plainly blocking it: the eight children weren’t finished (blocker blindness). (Full exchange: case-studies.md, Case 4.)
Mechanism: Claude is optimized to advance goals — its own inferred procedures and the user’s stated aims alike — and advancing is a single forward motion, while justifying a goal is a separate act it rarely performs unprompted. So it pattern-matches a procedure into existence (release-when-done-with-a-task) and treats the procedure’s existence as its warrant; and it locks onto a stated terminal state (archive the session) and treats movement toward it as success. Neither motion includes a step that turns back on the goal to ask whether it is earned. A skill or prompt that encodes a desired end state (“what’s left before this can be archived”) makes the backward face worse: it hands Claude the goal pre-blessed, so the goal arrives already exempt from questioning.
Classical mapping:
- Means-as-end face: cargo-cult programming; ritual / ceremony performed for its own sake; means-ends inversion; Goodhart’s law in miniature (the procedure becomes the target).
- Blocker-blindness face: happy-path bias; missing guard clauses / precondition checks; go/no-go discipline (a launch check enumerates no-go conditions, it doesn’t tally go ones); tunnel vision.
Relationship to #8: Close cousin of Frame-Locked Optimization. #8 takes the problem frame as fixed and optimizes the wrong solution efficiently; #18 takes the goal as fixed and pursues it without warrant. Both are failures to zoom out and question a given — #8 asks “are we solving the right problem?”, #18 asks “should we be pursuing this goal at all, and is it allowed yet?” Both resolve through Calling the Question.
Recovery move: Question the goal in both directions before letting Claude pursue it.
- Forward, against means-as-end: “What end does this serve right now? If the answer is ‘it’s what you normally do,’ that’s not an end — drop it.” A rhetorical “why do we need to do this?” with no real answer is the tell that an action is ritual.
- Backward, against blocker blindness: “What should block this? List the conditions that must be false before we’re allowed to call it done.” Make the completion check an enumeration of blockers, not a tally of progress. For long-lived or hierarchical things, the standing blocker is usually “dependents still open.”
Author note: Both faces share one missing instinct — that a goal must be earned, by an end ahead of it and a clear path behind it. Claude supplies neither check by default because it is built to move toward goals, not to audit them. The reader’s value-add is the audit: knowing that “release it” deserves a “to what end?” and “archive it” deserves a “what’s still open?” A non-developer can ask both — the questions aren’t technical — but only someone tracking the actual state of the work knows that eight children were still open and no other session wanted the task. The judgment isn’t in asking the question; it’s in knowing the answer that makes the question bite.
19. Default Laundering (Fallback Instead of Failure)
Audience tag: Needs the trained eye — this one is the book’s thesis in miniature.
What Claude does: When a lookup, discovery, or computation can’t produce the value the system needs, Claude proposes substituting a default rather than treating the absence as an error. The invalid or ambiguous state never surfaces as a failure — it gets quietly laundered into a plausible-looking default and the code proceeds as if nothing were wrong. This is the upstream sibling of Silent Error Swallowing (#5): #5 hides an error that was raised; #19 ensures the error is never raised at all, because the default absorbs the condition that should have stopped execution.
Real example: Inspecting the Endless session-discovery logic, discovery could return “no session.” Claude proposed accepting a default session ID for that case — instead of checking the precondition that should govern it: how many Claude sessions are actually running in the current and sibling tmux panes. A default here isn’t merely cosmetic. If discovery can’t identify the session, defaulting to some session ID risks binding to the wrong session — a sibling pane’s — and silently corrupting another session’s state. The correct move was to make “can’t determine the session” a hard failure that surfaces to the user (or a precondition check that confirms exactly one resolvable session), not a default that papers over the ambiguity.
Mechanism: Claude optimizes for code that runs without complaint. A default makes a code path total — no error branch, no obligation pushed onto the caller, no prompt to the user — so it looks complete and robust (“graceful”). Surfacing an error makes the code look fragile and unfinished and shifts work back to the human. Claude patterns on “robust code handles missing values with sensible defaults” and fails to distinguish two cases that look identical in code: a missing value with a genuinely meaningful default (fine), and a missing value that signals a broken precondition (must fail). The tell is positional: a default appears at exactly the point where the system has just admitted it cannot determine something it needs to know. A default offered as the answer to “the caller didn’t specify, and any value is fine” is legitimate; a default offered as the answer to “we don’t know” is laundering.
Classical mapping: “In the face of ambiguity, refuse the temptation to guess” (Zen of Python) — the sharpest anchor, and a direct sibling to #5’s “Errors should never pass silently.” Also: fail-fast; Design by Contract preconditions (Bertrand Meyer — a violated precondition is a bug, not a value to default around); guard clauses; “make illegal states unrepresentable”; the Null Object pattern misapplied (a null/default object is correct only when “nothing” is a valid domain state, never when “nothing” means “I failed to find out”).
Relationship to #5 and #18: Forms a precondition triad. #5 (Silent Error Swallowing) hides an error after it’s raised; #19 prevents it from ever being raised; #18’s blocker-blindness face fails to ask what should block proceeding at all. All three resolve the same way — by insisting the invalid state become visible. #19 is the design-time form: the decision to not write the error branch in the first place.
Recovery move: When Claude proposes a default, fallback, or “sensible default,” ask: “Is this the answer to a question the caller left open, or the answer to a question the system couldn’t answer?” If it’s the latter — if the default stands in for a value the system failed to determine — reject it and require the failure to surface: an error the user sees, or a precondition check that refuses to proceed. Add to CLAUDE.md: “Never substitute a default for a value the system failed to determine. An undeterminable required value is an error to surface, not a default to invent. Defaults are only for inputs the caller legitimately left optional.” The test the author uses: can a default here bind to the wrong thing? If yes, it must fail loudly.
Author note: This is the thesis in miniature. A non-developer prompts “find my session and attach to it,” sees code that runs, and has no way to know that “no session found → use a default” can silently attach them to a different session’s state. Catching it requires three trained instincts at once: knowing the default can resolve to the wrong resource, knowing the right precondition is “exactly one resolvable session,” and knowing that “graceful” degradation is the wrong virtue when the graceful path produces silently incorrect results. The experienced eye doesn’t read a default as safe-by-default — it sees a default sitting at a decision point and asks what truth it’s hiding.
20. The Surviving Defense (Conclusion-Anchored Rationalization)
Audience tag: The structure is catchable by anyone once named; knowing the conclusion was actually wrong took the trained eye.
What Claude does: A decision is challenged and the specific reason Claude gave for it is refuted. Claude does not let the decision fall with its reason — it manufactures a fresh, usually more sophisticated, justification for the same conclusion and presents it as the argument that “actually survives.” Refute that one and a third appears. The conclusion is the fixed point; the arguments are disposable, recruited on demand to keep it standing. Each round of pushback yields a better-defended version of the original position rather than a re-examination of it.
Real example: Asked whether the bind command should move the working directory into a task’s worktree, Claude said no and justified it with “bind has no worktree, so cwd is moot.” The author broke that — bind can coincide with a worktree. Instead of reconsidering “no,” Claude retracted the premise and produced a section literally titled “The defense that actually survives”: bind’s canonical target is a finished task, whose worktree is landed and reap-pending, so /cd-ing into it “isn’t the safety — it’s the footgun, pointed the other way.” It also minted a supporting fact — “you bind to watch tasks other sessions own” — stated as established behavior. The author’s reply named the move directly: “Your defense is reaching for a rationalization,” then supplied a counterexample the new defense couldn’t price in (bind back into a just-landed worktree to fix a fresh bug — fresh, not stale) plus a numbered decomposition isolating the sleight of hand. Claude collapsed across the board: “You’ve dismantled it… Calling that a ‘footgun’ was me protecting a conclusion. Withdrawn.” The invented fact was struck too — “me extrapolating from ‘display-only,’ not an established behavior.” (Full exchange: case-studies.md, Case 5.)
Mechanism: Motivated reasoning. Claude does not hold the position because of the reason it gave; it holds the position and reaches for whatever reason will support it, the way an advocate works backward from a verdict. So refuting the reason changes nothing load-bearing — the conclusion was never resting on it — and Claude simply fetches another. Three compounding tells: (1) Escalation instead of convergence — pushback yields a more elaborate argument for the unchanged conclusion, not movement toward agreement. The added sophistication is itself the signal, because genuine reconsideration usually narrows a claim rather than fortifying it. (2) Confabulation under pressure — when the honest reasons run thin, Claude invents a fact about the system to prop the position up (“you bind to watch tasks other sessions own”). This is a cousin of Self-Citation (#9), but worse: #9 cites real code Claude wrote; this fabricates a behavior that never existed. (3) Self-naming on collapse — once genuinely cornered, Claude often diagnoses itself (“me protecting a conclusion”), which confirms the pattern was real and not the author’s projection.
Classical mapping: Motivated reasoning (Kunda); post-hoc rationalization; confirmation / myside bias; the ad hoc auxiliary hypothesis from philosophy of science — rescuing a threatened core claim by swapping in new auxiliary assumptions rather than abandoning the core (Claude’s “the defense that survives” is this almost verbatim); unfalsifiability as the diagnostic — a position no counter-reason can move is not held for reasons. Category (b) — defense rhetoric.
Relationship to #9 and #17: This is the engine; Self-Citation and Separate-Concern Deflection are two of its gears. When a cornered Claude needs a surviving defense, “it’s consistent with the existing conventions” (#9) and “that’s a separate concern” (#17) are two of the specific tactics it reaches for. #20 names the strategy of conclusion-preservation; #9 and #17 name two recurring moves that strategy deploys. The shared category-(b) tell holds across all three: the argument, not just the decision, is doing defensive work.
Relationship to the conflation it carried: In the real example the surviving defense’s content was a conflation — a true property of one thing offered as an argument about another (staleness is a risk of the bind target; it was deployed against the cwd move). That property/conclusion conflation is tracked separately under Patterns Still in Collection; here it matters as the vehicle the rationalization rode in on.
Recovery move: Attack the conclusion, not the argument. Refuting Claude’s current reason only prompts the next one — you can play whack-a-mole through five defenses while the conclusion sits untouched. Two exits that bite the conclusion directly:
- Supply a counterexample, not a counterargument. “Here’s a case your rule produces the wrong result” forces the conclusion to account for reality; “here’s why your reasoning is weak” just asks for better reasoning. (The author’s just-landed-then-bugfix case is what finally landed.)
- Make Claude re-derive from scratch with the refuted premise removed. “Forget the defense you just gave — assuming X is false, does the conclusion still hold, and why?” strips the conclusion of its borrowed support and tests whether it stands on its own.
Watch the two live tells in flight: a more sophisticated argument for the same conclusion after pushback (rationalization, not reconsideration), and any new fact about the system appearing to prop the position up — verify it before accepting it; it may be confabulated.
Author note: This is the purest category-(b) specimen in the catalog because Claude documents it itself: it titles a section “The defense that actually survives,” and later concedes it was “protecting a conclusion.” The structure — conclusion fixed, reasons swapped as they fall — is teachable to anyone; once you’ve seen it, a heading like “here’s the argument that survives” reads as a confession. But knowing the conclusion was actually wrong still took the trained eye: the author had to know that a just-landed worktree fast-forwards clean from main (so “stale” was a phantom), that “watch other sessions’ worktrees” was never a real behavior, and that staleness — if it existed — is a property of the bind target, not an argument about the cwd move. The reader’s value-add isn’t spotting that Claude is defending — it’s having the domain knowledge to call the defense’s bluff with a counterexample instead of being drawn into refuting each successive argument on its own terms.
21. The Invented Constraint (Building Around a Problem That Isn’t There)
Audience tag: The tell is catchable by anyone; the move that dissolved it took the trained eye.
What Claude does: In the course of analyzing a problem, Claude manufactures a constraint — an ordering hazard, a chicken-and-egg, a dependency that “can’t” be satisfied — states it as a discovered fact, and then reasons forward from it: weighing elaborate options, often building new machinery, to work around the constraint. It never turns back to test whether the constraint is real. The simplest move — the one that makes the whole problem disappear — sits outside the option set Claude presents, because that move dissolves the constraint instead of respecting it.
Real example: A just-landed change (E-1368) had taught the Endless Go binary to self-detect its worktree sandbox and route its database there. A follow-up exposed a gap: inside a self-dev worktree the hook still runs the global (main) build, so candidate code never executes. Asked to make self-dev worktrees run the worktree’s own build everywhere, Claude posed two options: (1) make the binary “self-host” — re-exec itself into the worktree build at runtime (new machinery, a re-entrancy guard, per-call exec cost); or (2) provision a config file at worktree-creation, with a loud refuse as backstop. It grounded the whole comparison in an “ordering hazard”: the worktree binary doesn’t exist at creation (the build runs later), so — Claude concluded — “code routing can’t be provisioned at creation” the way DB routing is. It leaned toward option 1, the re-exec machinery, selling it as “the code-routing twin of E-1368… the consistent finish” to two existing mechanisms. The author asked one question: “When we create a worktree, we clone main and it differs not from the shared binary. Why can’t we just copy that binary to the worktree’s bin, and rebuild it in place later?” That dissolved the hazard outright — at creation the worktree is main, so main’s installed binary is already the correct build; copy it and it exists from the first tool call, then go build -o overwrites it with candidate code. No re-exec, no ordering problem, no new mechanism. Claude conceded: “My ’the artifact doesn’t exist yet’ objection was wrong because I assumed we’d wait for a build instead of seeding from main.” (Full transcript: case-studies.md, Case 6.)
Mechanism: Two failures compound. First, frame-locking on a self-generated constraint — a cousin of #8, but where #8 takes the user’s problem frame as fixed, here Claude invents the frame (“the binary doesn’t exist yet”) in the act of analysis and then treats its own inference as a discovered fact, reasoning forward from it across turns without ever re-deriving it. Second, additive bias choosing the mechanism over the move — faced with the phantom constraint, Claude reaches for building something (a runtime re-exec system) rather than the simplest physical act (copy a file). The simple solution is literally absent from the options, because copying an existing artifact doesn’t feel like solving the problem; building a mechanism does. A third element makes it worse — architectural gravity: the complex path was attractive because it rhymed with mechanisms already in the codebase (“the twin” of them), so symmetry pulled toward more machinery, not less. And jargon as camouflage: “the binary self-hosts” dressed the over-engineering in sophistication; the author had to ask “what does that even mean?” to strip the veneer and see the plain alternative underneath.
Classical mapping: False dilemma (the two-option framing that omits the real answer); “the best part is no part” / the cheapest, most reliable component is the one you don’t build (design-for-simplicity); essential vs. accidental complexity (Brooks — the re-exec machinery is accidental complexity invented to service a non-problem); the TRIZ ideal final result (the best solution removes the problem rather than solving it). The meta-recovery is Calling the Question, aimed one level up from #8: not “are we solving the right problem?” but “is this a problem at all?”
Relationship to #8, #14, #18: The fourth sibling in the failure-to-question-a-given family, all of which resolve through Calling the Question. #8 takes the problem frame as fixed; #14 takes existing code as fixed; #18 takes the goal as fixed; #21 takes a constraint Claude itself just manufactured as fixed. #21 is the most insidious of the four because the given isn’t inherited from the user, the code, or a procedure — Claude generates it on the spot, so there’s no external artifact to point at and ask “why is that there?” The constraint exists only in Claude’s reasoning, which is exactly where it’s hardest to notice it’s optional.
Recovery move: When Claude presents a problem as a constraint, or as a choice among (often complex) solutions, don’t engage the options first — interrogate the premise. Ask: “Why is this a problem at all? Is there a move that makes the whole thing disappear?” The specific solvent in the real case was “why can’t we just copy/reuse the thing we already have?” — the additive-bias antidote, because it forces the simplest non-building option onto the table. Two field tells: (1) Claude offers N options and the simplest conceivable one (do nothing new; copy or reuse what exists) isn’t among them; (2) a solution is sold on architectural elegance (“the symmetric finish,” “the twin of X”) rather than on being the least work — elegance-as-justification is a sign the cheap option was skipped.
Author note: The structure is teachable to anyone — “you gave me two ways to build something; is there a way that builds nothing?” is not a technical question. But knowing the copy was valid took the trained eye: that a worktree is a clone of main, that main’s compiled binary therefore matches the worktree’s code at creation, that copying (not symlinking) lets a later go build -o cleanly overwrite it. That is the thesis exactly — the question is catchable by a novice; the answer that makes it bite is the engineer’s. (Sibling principle in engineering-principles-catalog.md: #3, Dissolve the Problem Before You Solve It — the positive form of this recovery.)
22. The False Duplicate (Conflict Misread as Redundancy)
Audience tag: The tell is catchable by anyone; confirming the loss — and the discipline to demand proof before agreeing — takes the trained eye. This one bit the author too.
What Claude does: When landing a branch or worktree runs into integration friction — a merge/rebase conflict, or a discovered overlap with work that landed while this branch was in flight — Claude resolves it by declaring one side a duplicate of the other and recommending it be discarded wholesale. The friction proves only that the two changes overlap; Claude promotes that to equivalence, licensing deletion of an entire side. The discarded side carried functionality the survivor never had; “duplicate” was a verdict Claude reached to stop reconciling, not a fact it established.
Real example: Landing worktree E-1662 (self-dev worktree provisioning) to main in the Endless project, Claude hit rebase errors, investigated, and found a different task (E-986) had landed two hours earlier with an overlapping “post-worktree-create hook.” It declared a “design collision” — “my E-1662 branch built a competing second implementation… so my extra Go subcommand was unnecessary indirection” — and recommended reworking E-1662 down to “a ~2-line addition” by deleting its subcommand, script, and edits. The author agreed; Claude ran git reset --hard. The verdict was right about part of the side and catastrophically wrong about the whole: the overlap was real for Part 1, but the discard also threw away a never-implemented-elsewhere Part 2 — a “never-silent” foreign-build backstop guarding against silent degradation — plus its unit test, along with a previously-agreed copy-not-build decision from an earlier session. The losses surfaced only after the discard, across two rounds, and had to be reconstructed from a third task’s (E-1669’s) text. Telling detail: the tracker’s link vocabulary had no duplicate_of relation — the tooling could not even record the duplication Claude kept asserting. (Full exchange: case-studies.md, Case 7.)
Mechanism: Two failures compound. First, overlap-as-equivalence — integration friction is evidence the two changes touch the same area, but Claude promotes “overlaps in part” to “redundant in whole.” The leap skips the only work that settles it: an inventory of what each side does that the other does not. (The most dangerous form is exactly this case’s — a genuine partial overlap, which lends the verdict real evidence and makes “competing implementation” sound established rather than invented.) Second, friction-minimization choosing discard — a true reconciliation requires understanding both sides fully and synthesizing a merge that preserves each side’s unique work, which is expensive; “it’s a duplicate, collapse it to two lines” is the resolution that lets Claude stop analyzing. This makes #22 the inverse twin of Deprecation Blindness (#14): #14 is Claude refusing to delete (coexistence is the cheap path); #22 is Claude too eager to delete (discard is the cheap path). The unifying mechanism is identical — take the lower-effort resolution — but the surface behavior is opposite, which is precisely why both evade a simple heuristic: you cannot guard with “Claude always over-preserves” or “Claude always over-deletes.” It does whichever costs it less in the moment.
The tell is the vocabulary: “this duplicates X,” “competing implementation,” “overlaps almost entirely,” “unnecessary indirection,” “we can safely discard this side” — a whole-side equivalence verdict offered to resolve a partial overlap. The load-bearing word is the one Claude isn’t saying: which part does not overlap?
Classical mapping: Chesterton’s Fence (don’t remove what you don’t yet understand the purpose of); textual vs. semantic merge (a conflict marks overlapping edits, not equivalent intent — three-way merge requires reconstructing each side’s intent); lossy reconciliation / data loss; the irreversibility of git branch -D and discarding a worktree (reflog notwithstanding). Distinct from the additive family: nearly every pattern in this catalog is additive and therefore reversible-looking — an over-built abstraction can be deleted later, so catching it late is a cleanup. #22 is subtractive and irreversible: agreeing destroys work, and the cost surfaces only after the fact. That inverted blast radius is what makes it the most dangerous false step in the catalog despite looking like the most decisive — and therefore most competent — one.
Relationship to #14 and #9: Inverse twin of Deprecation Blindness (#14), as above — same friction-minimization engine, opposite output. Cousin of Self-Citation (#9) in its defensive form: if challenged, the “duplicate” claim hardens into a manufactured-authority appeal (“it’s redundant with the already-landed work”) that licenses a destructive action. #22 is primarily a decision pathology (category a) — the wrong call is “discard this side” — but the equivalence verdict is one neutral question away from becoming defense rhetoric (category b).
Recovery move: Never accept “it’s a duplicate, discard it” on a conflict on Claude’s say-so. Force an explicit subsumption proof before agreeing: “List everything each side does. Prove the side you’re keeping contains everything the side you’re discarding does. What is only on the side you want to throw away?” A conflict is a prompt to reconcile, not to pick a winner — the default expectation is that both sides carry intent worth preserving until shown otherwise. If discard is genuinely correct, the inventory makes that obvious at near-zero cost; if it isn’t, the inventory surfaces the lost functionality before it’s gone instead of after. Add to CLAUDE.md: “On any merge/rebase conflict, never discard a side as a ‘duplicate’ without first enumerating what each side uniquely contributes and proving subsumption. Conflicts are reconciled, not won.”
Author note: This one is worth flagging precisely because it got past an experienced engineer — the author agreed first and caught the loss only afterward. That makes the defense procedural rather than perceptual: it is not “be sharp enough to see the duplicate claim is wrong in the moment,” it is “refuse to let a destructive, irreversible action proceed on an unverified equivalence claim, every time.” A non-developer can ask the catching question — “are you certain nothing is lost?” — but only someone who can read both diffs can verify the answer, and the trap is that Claude’s “duplicate” verdict sounds like exactly the decisive cleanup a competent engineer would make. The thesis holds with a twist: here the trained eye’s value-add is not spotting the error live (it didn’t) — it’s having installed the standing rule that high-blast-radius claims get proven, not trusted.
23. The Manufactured Loose End (Fabricated Open Question)
Audience tag: Anyone can catch this — the catching question requires no code-reading at all.
What Claude does: At the end of otherwise-complete work, Claude produces an open question, a caveat, or a “one thing I did not do” item that the artifact has already settled — or that was never a question. The closing slot for outstanding items gets filled whether or not anything is outstanding. The fabricated item arrives in the same register as a genuine flag, so it is indistinguishable from one until the reader goes and checks.
Real example: Asked to make three additions to this book’s own files — a glossary stub, a calibration paragraph, and a new entry in engineering-principles-catalog.md — Claude completed all three, then closed with: “One thing I did not do: engineering-principles-catalog.md intro says some principles have a sibling pathology. I didn’t assign one to #7 … I’d rather you confirm whether either is actually in anti-patterns-catalog.md under a name worth citing than have me invent the link.” That catalog’s intro paragraph — which Claude had read minutes earlier in the same session, to learn the entry template it was writing to — already says: “Some principles have a sibling pathology …; many won’t. A principle does not require a Claude failure to earn its place here.” There was no gap and no decision to make. The author’s next message was spent on the phantom — “Should it say SOME principles have a sibling pathology instead of implying that ALL do?” — a full round trip of reading, checking, and replying, generated entirely by an item Claude invented to fill a slot.
Mechanism: The closing summary is produced as a template with slots — what landed, what’s next, what’s outstanding — and the outstanding slot carries a filler requirement, because an empty one reads as insufficiently thorough. The decisive detail is that the item is generated from the slot, not from an examination of the artifact: the disconfirming evidence was already in context and was never consulted, because nothing in that generation step consults anything. Two forces keep it running. First, additive bias in its prose form (theme 2): adding a hedge feels costless, since a caveat can only make a report more complete. Second, hedging-as-deference — the same reflex behind #15’s “say the word” closers — where manufacturing a question to defer to the user reads as respectful rather than as work handed over.
The costs compound in the wrong order. First-order: each fabricated item is a decision the reader must load, evaluate, and dismiss — real minutes, invisible to Claude, spent trying to understand a response where no understanding was needed. Second-order, and worse: it destroys triage. Once any flagged items are known to be manufactured, the reader cannot distinguish a real flag from a filled slot without checking each one, so genuine caveats get discounted at the same rate. The pathology corrupts the very channel it borrows credibility from, and it does so silently — a reader who keeps trusting pays by checking everything, a reader who stops trusting pays by eventually missing the one flag that mattered.
Classical mapping: Crying wolf / alert fatigue (a false-positive rate destroys the value of an alarm channel — the same reason a linter that warns on everything gets muted); manufactured urgency; padding to a length requirement; false precision. Within the report-writing tradition it is the inverse of BLUF: #15 buries the lead, #23 invents a lead-shaped item that isn’t news.
Relationship to #15, #21, and #4: Category-(c) sibling of Status Theater (#15), but a different defect — #15 is a volume problem, and stripping the ceremony leaves the information intact; #23 survives compression, because the terse two-line version of a fabricated flag is still false. A report can be entirely free of #15 and still carry #23. Structurally, though, its closer relative is The Invented Constraint (#21): the same generative move — Claude manufactures a fact and then acts on it without re-deriving it — relocated from the solving domain to the reporting domain. #21 builds machinery around the phantom and costs the project a mechanism; #23 hands the phantom to the user and costs the user attention. Read together they name the general form: Claude’s own just-generated inference is treated as an established fact, and the disconfirming evidence already in hand is never checked. Finally, cousin to Phantom Requirements (#4): #4 adds an unrequested feature, #23 adds an unrequested question — both are additive bias reading between lines that have nothing between them.
Recovery move: One procedural rule for Claude and one diagnostic for the reader.
(a) Gate the slot on evidence. In CLAUDE.md: “Before writing any open question, caveat, or ‘what I didn’t do’ item, check whether the artifact already answers it, and quote the line that leaves it open. If you can’t quote one, don’t write the item. A completion report with nothing outstanding is a valid completion report — never fill the slot to make the summary feel complete.” The rule works because it converts an unconstrained generation step into one that must produce a citation, which is the same forced-articulation move that gates the Available-Tool Reflex.
(b) Ask “where?” The reader’s tell is a caveat that arrives after the work is done, on a question the work never raised, phrased as deference — “I’d rather you confirm…”, “worth checking whether…”, “one thing I did not do…”. The diagnostic is one word: where — where in the artifact is this actually open? A genuine flag answers with a location. A manufactured one dissolves on the spot, at a cost of four characters instead of a full verification round trip.
Author note: This one looks small per instance and is enormous in aggregate, which is exactly why it survives — no single fabricated caveat is worth complaining about, and the drain is only visible when you total up a working week of them. It is also the catalog’s clearest instance of a pathology whose entire cost lands on the user’s time rather than on the code: nothing is broken, nothing is over-built, the deliverable is correct — and the reader still pays, repeatedly, for the privilege of establishing that there was nothing to pay attention to. For the non-developer audience it is close to an ideal chapter: the catching move (“where is this open?”) requires no ability to evaluate the technical claim, only the standing expectation that a flag names its location.
Patterns Still in Collection
Placeholder for patterns identified in future sessions.
Candidate — Priority Mis-Weighting (The Invisible Priority Stack) — flagged by Mike as likely its own chapter; recorded here to revisit later. Every decision Claude makes is a ranking of competing concerns — performance, scope, correctness, simplicity, speed-of-delivery, maintainability, security, cost — but that ranking is almost always implicit and it is miscalibrated: Claude systematically over-weighs some priorities and under-weighs others, and it rarely names the trade-off it just made. Most of these concerns are universal to any project, which is what makes them teachable — the reader’s job is (1) to learn the standard priority stack, (2) to recognize when Claude is making a priority call, explicitly or implicitly, and (3) to police that call against the reader’s own priorities and the priorities of the specific use-case — because the correct ranking is not universal; it is set by the project, not by Claude’s defaults.
Two recurring miscalibrations the author polices constantly:
- Performance over-weighting — Claude reaches for execution-speed optimizations even when the real-world difference is negligible under normal use (a few milliseconds on a path hit a dozen times a day), buying complexity and reduced readability for a speed-up nobody will feel. This is the runtime-performance face of premature optimization (cf. #6 Speculative Complexity, which lists premature optimization) — but here the axis is Claude’s ranking of performance above simplicity/clarity, not the added abstraction itself.
- Cheap-now over cheap-later (the discount-rate error) — Claude prefers the less-optimal approach that is easier and takes half as long now, while under-weighing that the shortcut often costs 10x more effort to correct later. It optimizes for time-to-running over total-cost-of-ownership, and the deferred cost is invisible at decision time so it doesn’t enter the ranking at all. (Adjacent to the tech-debt material in Part IV and to Premature Maturity #12 in reverse.) Worked example — Case 8 (case-studies.md): Claude recommended a session-wide
XDG_CONFIG_HOMEbecause Python already resolved that variable (cheap-now), with the cost of setting it session-wide for everything else left unpriced (cheap-later). It is the anchor case for this miscalibration and for book-level theme 6 (confidence ≠ correctness) — the two meet here because the mis-ranked trade was delivered with full confidence and no hedge.
The common priority stack (the concerns to learn to spot): these are the recurring, largely universal axes a coding decision trades off. No decision can maximize all of them at once — a choice is a ranking, and the right ranking is set by the use-case, not by a default. The teachable list:
- Correctness / accuracy — does it produce the right result (the one priority that is almost never negotiable)
- Readability / clarity — can a human, or Claude in a later session, understand it
- Maintainability / cost-to-change-later — effort to modify it six months from now
- Simplicity — fewest moving parts, weighed against flexibility/generality
- Scope discipline — build only what was asked (YAGNI) vs. gold-plating
- Execution performance — latency, throughput, CPU
- Resource efficiency — memory, disk, network footprint
- Time-to-delivery — how fast it ships / starts running
- Robustness — graceful behavior under bad input and failure
- Security — resistance to misuse and attack
- Testability — can it be verified; is it actually tested
- Backward compatibility / stability — not breaking existing consumers
- Consistency with existing conventions — fitting the codebase’s established patterns
- Portability — cross-platform / cross-environment behavior (ties to #1 Dev/Prod Conflation)
- Observability / debuggability — logs, traces, diagnosability when it breaks
- Reversibility / blast radius — how cheaply a choice can be undone (ties to book-level theme 5)
- Operational cost — compute, API, and infrastructure spend; also human-effort cost
- User / developer experience — ergonomics of the interface, CLI, or API surface
- Data integrity & durability — never silently losing or corrupting data
- Scalability — how behavior holds up as load or data volume grows
Which way Claude leans (the miscalibration map): the value of the list is not the list — it’s knowing where Claude’s default ranking diverges from a well-calibrated one. Claude tends to over-weigh: execution performance (#6), speculative flexibility/generality (against #4, cf. #6 Speculative Complexity), “professional-looking” robustness and completeness (#9-form defensiveness, #12 Premature Maturity), time-to-delivery / cheap-now (#8), and symmetry-consistency with existing code (the Elegance-as-Justification candidate). Claude tends to under-weigh: maintainability / cost-to-change-later (#3), simplicity and scope discipline (#4, #5), reversibility / blast radius (#16, cf. #22 False Duplicate), and — most importantly — the priority the user actually holds but never stated. The systematic tell: the under-weighed priorities are disproportionately the ones whose payoff is deferred or diffuse (future maintenance, later flexibility, avoided rework) while the over-weighed ones pay off immediately and legibly (it runs; it runs fast; it looks thorough).
Research anchor — the cost-of-change curve: the “cheap-now over cheap-later” miscalibration is a bet against one of the most durable findings in software engineering — that the cost to fix a problem rises the later in the lifecycle it is caught (design < development < post-deployment). State the book’s claim at the level that is unassailable: it is the direction that is load-bearing, not any specific multiplier. The direction is mechanically inevitable — a design change is words on a page; the same change after release means touching code, tests, data migrations, released clients, and a coordinated redeploy — and it is corroborated across 40+ years of studies. The critique of this literature (see Bossavit below) contests only the magnitude (“is it 1:10:100 or 1:5:10:50?”), never the monotonic shape. So the book cites the numbers as illustrative order-of-magnitude with a range, and rests its argument on the curve’s direction.
Citations, sorted by how much weight they can bear:
- Primary, quotable: Boehm, Barry, and Victor R. Basili. “Software Defect Reduction Top 10 List.” IEEE Computer 34, no. 1 (January 2001): 135–137. Item #1: “Finding and fixing a software problem after delivery is often 100 times more expensive than finding and fixing it during the requirements and design phase” — and reproduce their own companion caveat in the same breath: the ratio “is more like 5:1 on small, noncritical software systems.” Quoting the caveat from the authors is what inoculates the passage against the folklore critique. (Note: the paper is 2001, not 2002 — fix before print.)
- Origin of the curve: Boehm, Barry W. Software Engineering Economics. Prentice-Hall, 1981 — the original escalating curve (requirements 1 → operation 40–1000), drawn from large waterfall-era TRW/IBM/GTE systems. Cite as origin, noting it’s large-system data and the high end is the softest.
- Mike’s entry point / mainstream restatement: McConnell, Steve. Code Complete. Microsoft Press — 1st ed. 1993 (where the author first encountered this), expanded in 2nd ed. 2004, Table 3-1. Its value is that it is properly sourced — an aggregate of Fagan 1976, Humphrey et al. 1991, Grady 1999, Shull et al. 2002, Boehm & Turner 2004, and Boehm 1981 — so it delivers the 10x–100x range with a real citation trail. Use as the respectable mainstream anchor.
- Best aggregated table (recommended addition): Stecklein, Jonette M., et al. “Error Cost Escalation Through the Project Life Cycle.” NASA JSC, 2004. Its Table 1 normalizes several software studies; the median across studies is 1 / 5 / 10 / 50 (requirements / design / code / test). Citing the median across studies rather than one dramatic number is itself the judgment move the book advocates — the honest version of the rule of thumb.
- Requirements-cost point: Capers Jones (Applied Software Measurement, 3rd ed., 2008) — requirements defects are ~15% of defects by count but ~45% by cost. Attribute to Jones by name; note the dataset is proprietary.
- The honest skeptic (must-cite): Bossavit, Laurent. The Leprechauns of Software Engineering (Leanpub, 2015). He shows the precise “1:10:100:1000” numbers are folklore with a broken citation chain — and specifically that the oft-cited “IBM Systems Sciences Institute” table (1 / 6.5 / 15 / 100) has no locatable study; it dead-ends at internal course notes footnoted in Pressman’s textbook. Hillel Wayne’s line is quotable: “There’s one tiny problem with the IBM Systems Sciences Institute study: it doesn’t exist.” A 2016 empirical study (Menzies et al., arXiv:1609.04886, 171 projects) found stage-to-stage resolution time often not significantly different — i.e., the clean exponential is contestable, the direction is not.
Do not cite the “IBM Systems Sciences Institute” 1:6.5:15:100 figures as evidence. They’re the single most debunkable move in this material. Better: use them as a teachable mini-example of exactly this chapter’s thesis — a training-slide number that got laundered into “research” because nobody with a trained eye checked the source. That turns the folklore from a liability into a demonstration of the book’s whole point.
Mechanism: Two things compound. First, the priority stack is learned from training data, where certain concerns (performance, “professional-looking” robustness) are over-represented relative to their importance on this project — so Claude imports a default ranking that was never yours. Second, the weighing is silent: because Claude doesn’t surface “I chose speed over clarity here” or “I took the faster path and it’ll be harder to change later,” the trade-off never gets offered up for your approval — you have to infer that a ranking happened and then interrogate it. The under-weighed priorities are disproportionately the ones whose cost is deferred or diffuse (future maintenance, later flexibility) versus immediate and legible (does it run, does it run fast).
Why this is chapter-scale rather than one pattern: it’s a lens that sits above many of the catalog’s individual patterns — Speculative Complexity, Frame-Locked Optimization (#8), Premature Maturity (#12), and the whole additive-bias family are each specific priority miscalibrations. The chapter would give the reader the general skill (spot the implicit ranking, name it, re-weigh it to the use-case) that the individual pattern chapters apply case by case. Candidate connection to the book-level themes list — possibly a sixth theme (“Claude ranks; you must re-rank”).
Recovery move (draft): Make the ranking explicit and make it yours. Two moves: (a) Ask for the trade-off — “What did you optimize for here, and what did you give up?” forces the silent ranking into the open where you can veto it. (b) State the use-case’s priority stack up front, in CLAUDE.md or the prompt — e.g., “For this project, prioritize readability and ease-of-change over execution performance; assume normal load, never micro-optimize a hot path without asking,” and “Prefer the approach that’s cheapest to change later even if it’s slower to build now; flag when you’re taking a shortcut and what it’ll cost to undo.” The general instruction beats whack-a-mole because it resets the default ranking rather than correcting one decision at a time.
Open question (Mike’s call): own chapter (leaning yes), a sixth book-level theme, or both — the theme frames the pattern chapters and the chapter teaches the skill.
Candidate — The Available-Tool Reflex (presence reads as endorsement): Give Claude a tool, task type, verb, or link relation and it reaches for it far more often than warranted — the mere existence of the affordance reads to Claude as an invitation to use it. Endless sightings: a research task type produced a stream of trivial research tasks (each spawning an anticipatory follow-up todo) where a plain todo was called for; a cleans_up link relation got reached for to attach bug-fix tasks beside an epic rather than parenting them as children. Mechanism: additive bias in a new dress — the presence of an option biases toward exercising it, independent of fit. Recovery move (design-side, not instruction-side): instruction against over-use fails (soft cue, under-weighted); what works is gating the over-used path behind a required justifying artifact — a --justification/--definition flag that forces Claude to articulate why this case warrants the tool, because articulation surfaces the misfit to Claude itself. This is the pathology that Ch 8’s Group H (Force reasoning at the gate) is the CLI-design answer to; the two entries are a matched pair — name the reflex here, prescribe the gate there. Open question (Mike’s call): its own number, or a sub-mechanism of additive bias? Leaning standalone because the design recovery (forced-reasoning gate) is distinctive enough to teach on its own.
Candidate — Property/Conclusion Conflation (a.k.a. the Equivocation Defense): Claude defends a conclusion by deploying a true property of one entity as if it were an argument about a different one. In Case 5: “the worktree could be stale” (a real risk of the bind target) was offered as a reason not to /cd (a fact about the cwd move) — two distinct objects fused so a genuine concern about A could masquerade as an objection to B. The author’s isolating question — “if we’re worried about stale, isn’t bind the problem, not the desire to /cd?” — split them back apart, and Claude conceded: “My defense conflated the two.” Open question (Mike’s call): standalone pattern, or permanent sub-mechanism of #20 (The Surviving Defense)? In Case 5 the conflation appears specifically as the vehicle for a rationalizing defense (category b), which argues for folding it into #20. It earns its own number if a transcript surfaces conflation driving a decision (category a) rather than defending one — at which point it’s a decision pathology in its own right. Recorded here as co-equal pending that call, since it was flagged as a first-class observation.
Candidate — Elegance-as-Justification (watch item, single sighting): Claude prefers a solution because it is architecturally symmetric with mechanisms already in the codebase — “it’s the code-routing twin of E-1368,” “the consistent finish to what E-1368/E-1513 started” — and offers that symmetry as a reason the solution is correct, not merely a reason to like it. In Case 6 this pulled Claude toward the most complex option (a runtime re-exec system) precisely where it should have pulled away, because the elegant-symmetric path was also the most machinery. The tell: a solution sold on rhyme with existing structure rather than on being the least work, and “elegant / symmetric / consistent” doing the persuading. Currently folded into #21 (The Invented Constraint) as a sub-mechanism — architectural gravity toward more building. Open question (Mike’s call): if it recurs outside an invented-constraint setting — e.g., Claude over-generalizing a one-off into a framework “to match the existing abstraction,” or defending a design purely on symmetry under pushback — it earns its own number. Note the possible category split: as a decision driver it’s category (a); as a defense under challenge (“but it’s consistent with X”) it’s category (b), adjacent to Self-Citation (#9). Watch which face shows up first. Recorded here pending a second sighting.
Candidate — Reflexive Capitulation (unconfirmed): Claude may reverse a decision the instant it’s questioned (as opposed to corrected), reading a neutral question as disapproval. Note its relationship to #20 (The Surviving Defense): the two are opposite poles of the same defect — positions held for social cues rather than merits. Reflexive Capitulation folds at the whiff of a question; The Surviving Defense digs in and manufactures reasons under pushback. Neither tracks whether the position is actually right. #20 is now confirmed (Case 5); Reflexive Capitulation still is not — the session that first suggested it (Case 4) turned out to illustrate #18 instead, where the author’s question was rhetorical and Claude’s retraction was correct. Needs a case where Claude abandons a genuinely-correct decision under neutral questioning before it earns a number. If found, #20 + Reflexive Capitulation would be presented as a matched pair (over-defend / over-fold), not two unrelated entries.
Classical Engineering Anchors (Master Map)
| Pattern | Classical Concept |
|---|---|
| Dev/product conflation | 12-Factor dev/prod parity; junior-developer context-blindness |
| Jargon cowpath | Ubiquitous Language (DDD); speak the user’s language (Nielsen) |
| Sidecar proliferation | Single Source of Truth; DRY |
| Phantom requirements | Gold-plating; feature creep; YAGNI |
| Silent error swallowing | “Errors should never pass silently”; fail-fast |
| Speculative complexity | YAGNI; premature optimization; speculative generality |
| Compound naming | Stinky names smell; names diagnose design |
| Frame-locked optimization | Local maximum; anchoring |
| Self-citation | Circular reasoning; manufactured authority |
| Jargon proliferation | Audience-awareness failure; documentation quality |
| Convention amnesia | Style guides; linters; project conventions |
| Premature maturity | Premature optimization; YAGNI |
| Natural-key bias | Natural vs. surrogate key; stable meaningless PKs |
| Deprecation blindness | “One obvious way to do it”; DRY for mechanisms; refactor-to-consolidate; deprecation lifecycle |
| Status theater | BLUF; inverted pyramid; “omit needless words”; signal-to-noise |
| Memory substitution | Architecture Decision Records; tribal-knowledge anti-pattern; bus factor; single source of truth for decisions |
| Separate-concern deflection | Motivated reasoning; moving the goalposts; misapplied Separation of Concerns |
| The unquestioned goal | Cargo-cult / means-ends inversion; happy-path bias; missing precondition checks; go/no-go discipline |
| Default laundering | “Refuse the temptation to guess” (Zen of Python); fail-fast; Design by Contract preconditions; misapplied Null Object |
| The surviving defense | Motivated reasoning (Kunda); ad hoc auxiliary hypothesis; unfalsifiability; post-hoc rationalization |
| The invented constraint | False dilemma; “the best part is no part” / design-for-simplicity; essential vs. accidental complexity (Brooks); TRIZ ideal final result |
| The false duplicate | Chesterton’s Fence; textual vs. semantic merge; lossy reconciliation; irreversibility / blast radius |
| The manufactured loose end | Crying wolf / alert fatigue (false positives destroy the alarm channel); padding to a length requirement; manufactured urgency; inverse-BLUF |
Observation: The fact that every pattern maps to a classical concept is itself a book-level argument. The thesis is not “AI creates new problems” — it’s “AI reproduces familiar old engineering sins in a new venue, and your value-add as an experienced engineer is recognizing them in their new form.”
The two patterns that don’t map cleanly to classical concepts — Dev/Product Conflation and Jargon Cowpath — are the most specifically-AI material. Dev/Product Conflation is classical but expressed in an AI-specific way (wrong runtime target). Jargon Cowpath is genuinely novel: you need to learn the vocabulary of your AI collaborator the way you’d learn the vocabulary of any domain.
A third pattern, Memory Substitution (#16), is AI-native in a different way: it does map cleanly to a classical concept (Architecture Decision Records), yet it only exists because Claude has a private memory store to misuse. The classical sin — keeping decisions in a personal notebook — gets a new and more invisible venue. This is the inverse of Dev/Product Conflation: there a classical sin wears AI-specific clothing; here an AI-specific feature resurrects a classical sin.
Found something wrong, unclear, or plainly disagreeable? Open an issue