Skip to content

chore: audit and trim always-loaded Claude config (post-Opus-5 ablation) #252

Open

Description

@joshukraine

Premise

Boris Cherny (Anthropic) reports cutting 80% of Claude Code's system prompt for Opus 5, and recommends users periodically delete their CLAUDE.md, skills, and hooks to see what the model no longer needs. Talk: https://youtu.be/qyPCVqFUyDo · Writeup: https://www.xda-developers.com/your-claude-md-is-probably-wrong-how-anthropics-engineers-structure/

The advice applies to one category only: prompt text that corrects model behavior. It does not apply to context the model cannot derive (project conventions, domain facts, deliberate style rulings, safety constraints).

Sorted by that distinction, the audit finding is lopsided: the project CLAUDE.md files are mostly the good kind; the global file is where the cruft lives.

Always-loaded budget today: global 1,675w + project 900–1,800w + MEMORY.md ~1,314w + 618w of skill descriptions ≈ 6–7k tokens/session. On a 1M window that is not a budget problem. The cost is dilution — ~40 generic instructions make the ~6 load-bearing ones harder to weight. That is the case for cutting; token economy is not.

Phases

  • Phase 0 — Ledger + guardrails. This issue, the attic, the stumble log.

  • Phase 1 — Global CLAUDE.md trim. 1,675w → 1,015w (39%) in one pass. Highest leverage (loads everywhere), lowest risk (nothing safety-critical in it). Merged in chore(claude): trim the global CLAUDE.md and set up the ablation guardrails #253. Observation window opens here.

  • [~] Phase 2 — Observation window. Now closes 2026-10-16 (end of day). Extended twice: on 2026-08-12 to 09-26, because travel 08-04 → 09-09 left ~3 days of representative work; and on 2026-09-29 to 10-16, because use stayed light after the return. Log every stumble; no re-adds during the window. → Observation window

  • Phase 3 — Re-add pass. Re-add only what appears in the stumble log more than once, at the narrowest scope that fixes it. Unblocks 2026-10-17.

  • Phase 4 — Responsive-QA → skill. Decide whether the extracted doc becomes a skill with a trigger description. Deferred out of Phase 1 on purpose (see D5). Actionable now (the freeze ended 2026-09-09); not tied to the observation window.

  • Phase 5 — resolve-issue trim. 649w → 386w, then 560w (14%) after the fix below. Six narrated steps down to seven non-derivable rules. Merged in chore(claude): trim resolve-issue from six narrated steps to seven rules #254 (2026-08-12). Pulled forward ahead of Phase 2 completion on purpose: Joshua had a real ComixDistro issue about to start, and using it beats reasoning about it. That paid off immediately — see the first stumble below, and D7.

  • Phase 6 — Project CLAUDE.md trims. ofreport's hard-wrapped Development Workflow: done (merged in ofreport.com#219). ComixDistro's 3× repeated CI-ordering rationale: done — kept once, in the sign-off step; 1,796w → 1,757w (merged in euroteamoutreach/comix_distro#1096, 2026-10-06).

  • Phase 7 — Retire tutorial mode. Policy decided (Q2, answered 2026-08-01). Applied in three PRs, all merged 2026-08-12:

    Confirmed by grep that no tutorial-mode language exists anywhere in dotfiles, including the PRD starter template, so nothing propagates to future projects. ComixDistro never had any. Both project PRs were branched off main rather than committed onto the in-flight branches those repos were sitting on (chore/markdownlint-config-standardization, feat/gh-15-footer); both original branches were restored afterward.

Guardrails (must stay in place for the whole initiative)

Guardrail Location
Attic — quarantined text, never hard-deleted claude/.claude/docs/attic-2026-08.md
Stumble log — the only evidence admissible in Phase 3 claude/.claude/docs/stumble-log.md
Ledger — phase state, decisions, open questions this issue

Decisions

  • D1 — Cut in one pass, not incrementally. You cannot predict which line mattered; you can only observe. Incremental trimming never generates signal because nothing changes enough to notice.

  • D2 — Quarantine, never hard-delete, for the duration. Git already covers recovery; the attic makes "bring it back line by line" a two-second edit instead of an archaeology session.

  • D3 — Re-add at the narrowest scope: skill > project file > global. A line that only matters in one repo must never land in the global file.

  • D4 — Safety-critical project content is exempt from ablation entirely. Not experiments: ETO's memorial page + Fallen Defender/IRS earmarking language, ComixDistro's post-launch QA gate, URL-preservation/no-404s, the MailChimp RSS re-blast warning. A regression there has real-world cost, not just an annoying correction.

  • D5 — Responsive-QA body moves to a doc, with a 3-line trigger left in the global file. It is not cut outright. Rationale: that failure mode is silent — resize_window returns success while innerWidth stays wrong, so the overflow check then passes trivially. Ablating it would produce no stumble-log signal, which breaks the entire method. Cost drops ~440w → ~40w with the trigger preserved.

  • D6 — Large orchestration skills are out of scope. autopilot-batch (4,325w), autopilot (3,299w), qa-triage-batch etc. are specifications with safety invariants (worktree isolation, model gating, merge tiers), not behavioral correction, and they are just-in-time loaded — zero cost when unused. Gutting them would be the wrong lesson from the talk.

  • D7 — A command correction is not a behavioral correction, and is out of ablation scope. Surfaced by the first stumble (see below). Ablation removes instructions that correct model behavior — "be thorough", "read carefully", "don't forget X" — because current models don't need them. It does not cover a skill that hands over a command which is incomplete for the job it describes: there the instruction introduces the gap rather than merely failing to prevent one, and no amount of model capability closes it, because the model is doing exactly what it was told. Test to tell them apart: if the model followed this line perfectly, would it still get the wrong result? If yes, it is a command bug — fix it, don't trim it.

First stumble — logged and corrected 2026-08-01

The trimmed /resolve-issue ran live on comix_distro #512 and surfaced a real regression on its first outing.

The trim cut Step 1's "extract title, description, labels, and comments" as GENERIC, leaving only gh issue view N — which prints the body but not the comment thread. On #512 the three comments held roughly a third of the actual scope, plus one that superseded an acceptance criterion still written in the body. Following the skill literally would have shipped incomplete work while ticking every AC — a silent, confident miss. That session read the comments anyway, out of habit, which is not something to rely on across sessions or model versions.

Verified against the live CLI before fixing:

Command Behavior
gh issue view N body only — no comment content. Header does carry a comments: N count, but in a metadata block that is easy to skim past.
gh issue view N --comments comments only — omits title and body, so it is not a drop-in replacement

Fixed in #254: the fetch step now runs both calls unconditionally, with the rationale inline (the body is the oldest artifact on an issue; comments carry scope added later and decisions that supersede it). Also switched the acceptance-criteria write-back from --body "$var" to a file round-trip with --body-file, which keeps issue bodies containing backticks out of shell parsing — the same reasoning that survived the Q1 test.

Note on the original: it was already self-contradictory — an incomplete command paired with an instruction to extract something that command does not return. The trim did not create the flaw, but it removed the one word that prompted a human or agent to go around it. Recorded honestly in the stumble log as the initiative's first entry.

Open questions — both ANSWERED 2026-08-01

Q1 — Is the Git Commit Protocol still necessary? → Right conclusion, wrong reason.

Tested rather than reasoned about: four --allow-empty commits on a throwaway branch, with Bash(git commit:*) allow-listed and defaultMode: auto.

Message form Prompted? What landed
double quotes, plain text no correct (baseline)
double quotes, backticked phrase no phrase silently deleted
double quotes, $(echo INJECTED) no substitution ran and was inlined
single quotes, same content no exactly correct, both literal

Zero prompts across all four. The stated rationale is dead — the permission system does not pre-flag substitution ahead of the allow-list.

But the conclusion survives for a better reason, so the section was rewritten, not cut: the shell still performs the substitution, and neither form aborts the commit. That is worse than a permission prompt — a prompt is visible and stops you; a mangled message just ships. The rewrite also documents a newly verified light path (single quotes preserve both literally, for a one-liner with no apostrophe).

Neither predicted outcome ("still needed" / "collapses to one line") was correct. Recorded in the attic under a new FALSIFIED code — the method argument for testing over guessing.

Q2 — Per-project autonomy / tutorial mode → Retire tutorial mode, keep the understanding.

Joshua's ruling: the "explain Hugo concepts" framing that started on ofreport is out of date, and tutorial-mode leanings should go generally. What stays is clarity, transparency, and understanding of the code we write — he wants to follow the logic, not be hand-held as a junior developer, and not be given something so terse the reasoning is hard to follow. He expects this calibration to evolve.

Implemented as "Understanding transfer, not tutoring" in the global file, naming both failure modes rather than one. Rules out: concept tutorials for tech he already ships in production, narrating what the code plainly says, and pausing to offer a choice when one option is clearly right. Explicitly warns against over-correcting into terseness. Discriminator: explain the decision, not the syntax.

Note this is not the same as flipping projects to /autopilot by default — that remains a per-run opt-in. Q2 settled the explanation register, not the supervision boundary.

Confirmed redundancies (Phase 1 evidence)

Now near-verbatim in Claude Code's own system prompt:

Global CLAUDE.md line Superseded by
"Finish the job" "Finish the whole task, not just easy parts — report completion only when fully done."
"Bias toward action" (head) "make routine judgment calls yourself, and check in only when different readings would lead to materially different work"
"Flag it honestly rather than glossing over it" "Report outcomes faithfully: if tests fail, say so with the output"
"Prefer established patterns over clever abstractions" "Write code that reads like the surrounding code: match its comment density, naming, and idiom."
"Use Context7 (MCP) before implementing…" the Context7 server's own instructions: "Use even when you think you know the answer — your training data may not reflect recent changes."

Activity

  1. added a commit that references this issue on Aug 1, 2026
    ea6a5b3
  2. joshukraine commented on Aug 12, 2026

    @joshukraine
    OwnerAuthor

    Reopened — and why it closed

    This issue auto-closed on 2026-08-01 at 16:41, two minutes before #254 was opened. Nothing was actually complete.

    The cause: the squash-merge of #253 concatenated its constituent commit subjects into the squash message, one of which read

    * chore(claude): resolve #252 Q1 and Q2 — rewrite the commit protocol, retire tutorial mode
    

    resolve #252 is a GitHub closing keyword, and closing keywords fire from commit messages landing on the default branch. #253's PR body said explicitly "Does not close it — #252 stays open through Phases 2–7." The body was right; the commit subject silently overrode it.

    Worth recording precisely because it is not an ablation stumble: "Never reference issue numbers in a commit message" survived the Phase 1 trim and is still in the global file. This was a violation of a rule that is on the books, not evidence that a cut line should come back. It does not go in the stumble log.

    Phase 2 extended to 2026-09-26

    The window opened 2026-08-01 and was set to close 08-15. Joshua left on 2026-08-04 for a trip to the States and returns 2026-09-09, with work volume in between a fraction of normal. So the original window rests on roughly three days of representative work — and the single logged entry came from day one.

    Less volume is only half of it. Travel work is a different shape: short sessions and cold re-entry into projects untouched for a week make some stumble classes more likely, while the watch-list items that need long implementation sessions to surface at all — doc drift, large unreviewed diffs — cannot fire. The sample skews in both directions at once, which is worse than merely being small.

    New close date allows ~2.5 weeks of normal-volume work after the return. Travel-period entries still count and are still logged; they are now tagged as atypical so Phase 3 can weigh them accordingly.

    Two rules added to the stumble log alongside the extension:

    • Command bugs get fixed on the spot, not logged and endured. D7 already established that an incomplete command is not a behavioral correction; a six-week window makes the distinction load-bearing rather than academic. Still logged, so the method keeps its record.
    • Tag rows from atypical work stretches.

    Frozen until 2026-09-09: Phase 4 (responsive-QA → skill) and the remaining Phase 6 item (ComixDistro CI-ordering de-dup). Both change live config, and config surgery on a single travelling machine is a bad trade against signal this weak.

    Merged today

    PR Repo Phase
    #254 dotfiles 5 — resolve-issue trim, 649 → 560w
    joshukraine/ofreport.com#219 ofreport 7 — tutorial mode
    euroteamoutreach/euroteamoutreach.org#20 ETO 7 — tutorial mode

    Phases 5 and 7 are now complete. One thing #254's merge fixed that was not on anyone's list: because ~/.claude/skills/resolve-issue is a stow symlink into the working tree, the live skill had been serving the unmerged branch version. master still carried the 649-word original with the comment-fetch bug, so any git checkout master — or a fresh dotfiles setup on another machine during the trip — would have silently reverted to the version that ships incomplete work while ticking every AC. Merging before six weeks of travel closed that gap.

  3. added a commit that references this issue on Sep 10, 2026
    4c4e240
  4. joshukraine commented on Sep 21, 2026

    @joshukraine
    OwnerAuthor

    Status check 2026-09-21 — plus a new style ruling (not a re-add)

    Where the initiative stands, 5 days before the window closes:

    • Phases 0, 1, 5, 7 merged. Phase 2 closes 2026-09-26; Phase 3 unblocks then.
    • Stumble log holds one entry — the day-one /resolve-issue comment-fetch bug, a D7 command bug, fixed in chore(claude): trim resolve-issue from six narrated steps to seven rules #254 and closed out 2026-08-02. Zero behavioral stumbles in the whole window. Nothing on the watch list (doc drift, commented-out code, mock boundaries, large diffs) ever fired.
    • Phases 4 and 6 were frozen until 2026-09-09. That thaw passed 12 days ago and both are actionable now: Phase 4 (responsive-QA → skill) and Phase 6 (ComixDistro's 3× CI-ordering rationale).

    On current evidence Phase 3's answer is re-add nothing.

    New ruling — response register (committed today, bce9545)

    Joshua reported weeks-long friction that is not an ablation regression: replies long enough to be hard to digest live, and jargon/idiom standing in for named things — concretely, a Hermes-agent session where "the tripwire we worried about never materialized" referred back to a problem never re-named.

    Checked the attic first: nothing about concision was ever cut. The suspected cause is a line Phase 7 added on 2026-08-01 — "Don't over-correct into terseness either — when the reasoning is load-bearing, spell it out" — paired with a "give him the why" instruction carrying no length budget. Together they read as standing permission to expand.

    Applied: the anti-terseness clause is out; three bullets replace it —

    1. Default to the short version — answer first, then a tight list; depth on request.
    2. Name things plainly — no metaphor standing in for something that has a name; gloss jargon once, in a few words.
    3. Put the long version where it lasts — Claude memory, the Obsidian vault, GitHub issues. The transcript is the executive summary, not the record.

    Why this does not violate the no-changes-during-the-window rule: it is a deliberate style ruling from Joshua, the category this issue's own premise exempts from ablation — not a re-add of quarantined text, and not evidence-driven from the log. Net +104 words on a 1,015-word file.

    Quarantined the removed clause in the attic under a new SUPERSEDED code (replaced by a later, deliberate ruling — the line was doing its job, the job changed), and logged the friction in the stumble log. Phase 3 should confirm this, not reopen it.

  5. joshukraine commented on Sep 29, 2026

    @joshukraine
    OwnerAuthor

    Phase 2 extended again, now through 2026-10-16

    The 9/26 close assumed the ~2.5 weeks after the 9/09 return would be normal-volume work. They weren't: use stayed light. So the zero-stumble result mostly means the trimmed config went largely unexercised, not that it held up. It is not a basis for closing Phase 3.

    • New close: end of day 2026-10-16. That is the last working day before the 10/17 departure for the Hugo project, after which there will be a couple of weeks with no serious development.
    • Why now: heavy development on a web project starts today (9/29), so this window should finally reflect normal daily use. It covers about 2.5 weeks.
    • Existing rows (8/01 command bug, 9/21 style ruling) stand as logged. Treat them as light-use evidence.
    • Unchanged: Phases 4 and 6 are not evidence-driven and remain actionable independently of the window.

    Stumble log updated accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    choreMaintenance, refactoring, dependencies

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions