Skip to content

Trim agent instructions according to the Claude Code /doctor - #798

Draft
egpbos wants to merge 4 commits into
mainfrom
slim-agent-instructions
Draft

Trim agent instructions according to the Claude Code /doctor#798
egpbos wants to merge 4 commits into
mainfrom
slim-agent-instructions

Conversation

@egpbos

@egpbos egpbos commented Jul 30, 2026

Copy link
Copy Markdown
Member

Description

.github/copilot-instructions.md (symlinked as CLAUDE.md) is loaded in full at the start of every AI-assisted session, so its length is a recurring cost rather than a one-off. At 40,057 characters it had also crossed the threshold above which Claude Code warns about an oversized memory file.

This trims it to 24,926 characters (637 lines to 335) without dropping a single gotcha, prohibition, or piece of design rationale. Three kinds of change, one commit each so any of them can be reverted independently.

1. Removed content the repository already answers. Anything a session can reconstruct by reading the repo was paying for itself twice:

  • the developer-install script, duplicated from docs/How-to/installation.md, which the surrounding paragraph already told the reader to prefer
  • standard pytest, coverage, and ruff invocations, restated up to four times in the file; the non-guessable PR filter expression stays
  • the directory layout, config-file list, and CLI entry points, all visible from ls and proteus --help
  • the style rules ruff enforces from pyproject.toml; the two conventions it does not enforce (prefer < 92 chars, max 3 indent levels) stay
  • the code-change, new-module, and test-debugging walkthroughs
  • the Key Dependencies list, a third copy of the ecosystem module table
  • one of three copies of the coverage-ceiling values

2. Moved two subsystem-scoped blocks into .github/.claude/rules/. The SOCRATES build flags and the whole-planet oxygen accounting matter only while working on those subsystems, but were loaded on every session regardless. They now live in proteus-socrates-build.md and proteus-oxygen-accounting.md alongside the existing test and review rules, and the root file keeps a short paragraph naming when to go read them. Both new files reproduce their source material in full.

3. Stated the test-detail clauses once. Ten subsections of Testing Standards were reproduced almost verbatim in both copilot-instructions.md and proteus-tests.md, under a stated contract to keep the two in sync by hand. The root file now keeps the part a reader needs before knowing whether tests are in scope (structure rule, marker table with timeout budgets, physics-invariant tiers, anti-happy-path rules, certification markers) and a table mapping the rest to the deep-dive section that states it. proteus-tests.md now describes the split instead of claiming full sync.

The voice rule deliberately stays in the root file: it governs every commit message and pull-request body rather than only test-touching work, so it has to be present whether or not the deep-dive was read.

Two accuracy fixes found along the way: a pointer to a memory file that does not exist, and a plot-script destination given as src/tests/ rather than tests/.

Effect on a session: about 6,000 fewer always-resident tokens, measured with /context before and after rather than estimated from character counts.

Validation of changes

Test configuration: macOS 15.5 (Darwin 25.5.0), Python 3.12, conda env proteus.

  • pytest -m "unit and not skip and not slow and not integration" --ignore=tests/examples gives 34 failed, 2672 passed, 27 skipped on this branch and the same 34 failed, 2672 passed, 27 skipped on main. The failures are pre-existing in this local environment (tests/plot/test_cpl_population.py, tests/utils/test_data.py, and others) and unrelated to this change, which touches only markdown. CI is the authority on whether they also fail there.
  • bash tools/validate_test_structure.sh: passes, 0 missing directories.
  • bash tools/check_file_sizes.sh: 335 lines against the 750 limit.
  • pre-commit run --files on all four changed files: passes.
  • Every docs/, tools/, src/, and .github/ path referenced by the trimmed file resolves on disk; the two that did not are the accuracy fixes above.
  • The removed Coverage architecture anchor had two inbound references in the same file; both were repointed to proteus-tests.md section 15.

What is not verified: whether removing a clause from the always-loaded file changes agent behaviour in practice. The mechanism is sound (the deep-dive is mandatory reading before touching tests/** or src/proteus/**, and it is not auto-discovered at its path, so it loads on demand), but that is an argument, not a measurement. Group 3 is the one to push back on if you disagree with the tradeoff; it is a single revert.

Checklist

  • I have followed the contributing guidelines
  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • My changes generate no new warnings or errors
  • I have checked that the tests still pass on my computer
  • I have updated the docs, as appropriate
  • I have added tests for these changes, as appropriate (not applicable: documentation only)
  • I have checked that all dependencies have been updated, as required

egpbos added 4 commits July 30, 2026 14:35
The file is loaded in full at the start of every session, so anything a
session can reconstruct by reading the repo is a per-session cost with no
payoff. Removed:

- the developer-install script, duplicated from docs/How-to/installation.md,
  which the surrounding text already tells the reader to prefer
- standard pytest, coverage, and ruff invocations, restated up to four times
  across the file; the non-guessable PR filter expression stays
- the directory layout, config-file list, and CLI entry points, all visible
  from ls and proteus --help
- the style rules ruff enforces from pyproject.toml; the two conventions it
  does not enforce stay
- the code-change, new-module, and test-debugging walkthroughs, which restate
  rules stated once already
- the Key Dependencies list, a third copy of the ecosystem module table
- one of three copies of the coverage-ceiling values

Kept every gotcha, prohibition, and piece of design rationale: the
FWL_DATA/RAD_DIR and PETSc traps, the conda-worktree hardlink trap, the
SOCRATES build flags, the plot standards, the voice rule, and the
oxygen-accounting contract.

Also fixed a pointer to a memory file that does not exist; the canary recipe
it accompanied is stated inline and stays.

637 lines to 387; 40,057 characters to 31,707.
Both blocks matter only while working on one subsystem, but sat in a file that
loads in full on every session. They move to .github/.claude/rules/, alongside
the test and review rules, and the root file keeps a short trigger paragraph
naming when to go read them.

Nothing is lost: the portable-flags rationale, the bit-reproducibility recipe,
the four O_mode definitions, the D1A design note, and both runtime guards are
reproduced in full in the new files, with the aggregation-site list
cross-linked to proteus-code-review.md instead of restated.

387 lines to 377; 31,707 characters to 30,396. The two blocks are 4,300
characters; the trigger paragraphs and the new entries in the rule-file list
give about a quarter of that back.
Ten subsections of Testing Standards were reproduced almost verbatim in both
copilot-instructions.md and proteus-tests.md, under a stated contract to keep
the two in sync by hand. The root file loads into every session in full while
the deep-dive is read on demand, so the duplication was paid for on every
session including those that never touch a test.

The root file now keeps the part a reader needs before knowing whether tests
are in scope: the structure rule, the marker table with timeout budgets, the
physics-invariant tiers, the anti-happy-path rules and forbidden patterns, and
the certification markers. A mapping table sends the rest to the deep-dive
section that states it: float comparison, discrimination guards, mocking
discipline, importorskip, the monkeypatch trap, seeding and wall-time budgets,
per-test documentation, the review trigger, tooling, and the coverage gates.

The voice rule stays in the root file. It governs every commit message and
pull-request body rather than only test-touching work, so it has to be present
whether or not the deep-dive was read.

proteus-tests.md now describes the split instead of claiming full sync: clauses
it alone states can change there alone, clauses the root file also states
change in both.

377 lines to 335; 30,396 characters to 24,926.
The path named was src/tests/, which does not exist in this repository.
@egpbos egpbos changed the title Trim the always-loaded agent instructions to what the repo cannot answer Trim agent instructions acc Jul 30, 2026
@egpbos egpbos changed the title Trim agent instructions acc Trim agent instructions according to the Claude Code /doctor Jul 30, 2026
@codecov

codecov Bot commented Jul 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.71%. Comparing base (5d8930f) to head (fd36837).
⚠️ Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #798      +/-   ##
==========================================
- Coverage   92.63%   91.71%   -0.93%     
==========================================
  Files         111      111              
  Lines       15892    16733     +841     
  Branches     2847     3091     +244     
==========================================
+ Hits        14722    15347     +625     
- Misses       1170     1351     +181     
- Partials        0       35      +35     
Flag Coverage Δ
unit-tests 84.07% <ø> (+0.04%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@timlichtenberg

timlichtenberg commented Jul 30, 2026

Copy link
Copy Markdown
Member

Looks good, I really do hope it works as they say with the new version. All duplications in these files were hard-won lessons where Claude would ignore rules and so the rules and gotchas were duplicated high-up to actually make it in production. I presume we have to try it out to see if it works in reality; it may be we have to build it back a bit if it's now too stripped down.

@egpbos

egpbos commented Jul 30, 2026

Copy link
Copy Markdown
Member Author

Yeah, it's a bit of a gamble, for sure and we'll have to see how it works out. But the repeated instruction thing you mention is something that they also explicitly mention is no longer necessary (see the blog post here: https://claude.com/blog/the-new-rules-of-context-engineering-for-claude-5-generation-models#:~:text=Then:%20Repeat%20yourself,the%20system%20prompt.).

Btw, one other worry might be that this could make the instructions less performant on older models if people still use those, or for Copilot (I still sometimes use it for quick things inside vscode for instance; I should probably just switch there too).

Ideally, someone with a lot of experience with the existing setup would test-drive this for a week or two. I personally don't think I would be able to tell the difference right now, so maybe someone wants to volunteer?

The "robust" approach would be if we make a full PROTEUS-LLM-benchmark suite of tests, but probably overkill :)

@timlichtenberg

Copy link
Copy Markdown
Member

This reads well and the split looks right to me.

One thing I would like to add, and it belongs in the "Two conventions ruff does NOT enforce" list you kept at Code Quality rather than anywhere new: a cap on inline comment length, at most 5 lines and ideally 1 to 2.

The reason is agent-written comments specifically. Scanning src/ and tests/ turns up 294 comment blocks over 5 lines, the longest 38, and I am generating them myself: I cut an 11-line comment sitting above a single constant out of #808 this morning. It is the same class of convention as the two already in that list, something ruff has no check for and that otherwise only gets caught in review, if at all.

One line would do it, in the same shape as the others: "Inline comments: at most 5 lines, ideally 1 to 2. Longer explanation belongs in the docstring, the commit message, or the PR body."

I am raising it here rather than opening a competing PR because this is your file to shape and it would only collide. I am aware it is an addition to a change whose whole point is subtraction, so please drop it without ceremony if you would rather keep this purely subtractive; I can open it separately once this merges.

@timlichtenberg

Copy link
Copy Markdown
Member

The split is the right call, and the two new subsystem files carry their content faithfully. I checked the moved test clauses against the sections the mapping table points at, and they are there.

Two things to fix before this comes out of draft.

The branch is behind main, and the one change main has made to copilot-instructions.md since you branched lands inside the section you delete: the whole-planet oxygen block gained a carve-out for outgas.vapourise = true. Under vapourisation the main loop passes require_atm_le_planet=False, rock mass moves into M_atm without being debited from the interior, and the invariant is deliberately relaxed while M_vaps > 0. Resolving the conflict by taking your side of it drops that. Worse, proteus-oxygen-accounting.md as written tells the reader to push back on any change that weakens the guard, which is the opposite of what main now does. Please rebase and carry the vapourise paragraph into the new rules file, including its pointer to docs/Explanations/model.md.

The sync contract now says two different things. proteus-tests.md gains a preamble saying a clause that lives only there can be changed there alone, but "Testing Standards" in the root file still says the two files must be kept in sync and any change to one mirrored in the other. Whoever reads the root sentence will copy detail back up and undo the trim. Please update that sentence to the narrower rule.

One small one: the mapping table sends wall-time budgets to section 10, which has seeding and tmp_path but no budgets; those live in the marker table and section 7.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants