Core Philosophy
"Find the smallest set of high-signal tokens that maximizes the likelihood of the desired outcome." — Anthropic
The goal is for instructions to be correctly loaded, found, and executed in actual tasks. Information efficiency, readability, and maintainability serve this outcome; file size, review counts, and green script checks cannot substitute for behavioral evidence.
This skill keeps decision-making and execution entry points in the main text, while verification commands and historical materials are read on trigger. Official length recommendations are used to discover splittable content, not as pass/fail thresholds; what the user needs is correct behavior, not reaching a certain line count.
Execution Boundaries and Acceptance
- First fix the current target file, the host that consumes it, the authorized scope, the user-visible outcome, and the stopping condition. Diagnostic/audit requests are read-only; when optimization or repair is explicitly requested, perform local reversible modifications within scope and necessary verification. Publishing, irreversible operations, and scope expansion are handled according to the current user's authorization; do not repeatedly confirm the same matter that has already been answered.
- "Zero Information Loss" ConstraintContracts that are still valid and migration as-is, it does not require old errors to remain permanently in the current specification. Label each change first as: retain/move as-is, deduplicate from the same source, correct based on current authority, or retirement/boundary change pending user adjudication. If a clear ruling already exists, execute according to it; "optimization" cannot be used as permission to revoke an unauthorized contract.
- The proposal or acceptance body provides:current original text → candidate text/accurate diff → basis → behavioral consequence → unverified points. Produce a reviewable local result first, then request the still-missing decisions; do not just paste the revised version or make the user dig through files to assemble the differences.
- Bases are divided into current host/official contracts, original research, long-term user contracts, tested examples, and hypotheses pending verification. Mark the research's model, task, sample, and limitations; do not rewrite old model results, company practices, or a single success into a universal threshold for all GPT/Claude models.
- First fix conflicts, invalid rules, permission ambiguities, false pointers, or real truncation that would change the current task decision. Only when the problem is truly a persistent burden should the order of burden reduction be arranged by measuring contribution; do not modify a file first just because it is the largest, and do not create new hooks, monitoring, or Skills just to shrink instructions.
- Acceptance is: changes within the authorized scope are complete and correct, the real host loading path is correct, and representative tasks meet expectations. Stop after completing the necessary checks; expand verification only due to new changes, failures, or unresolved doubts. Ordinary small modifications do not automatically add an independent review; complex modifications lacking a mechanical judge undergo one bounded review according to the current collaboration contract.
Current bases and applicable boundaries are in references/progressive_disclosure_principles.md at the beginning; read when verifying external mechanisms or research conclusions, and historical cases do not override the current contracts here. When the user asks "what are the best practices" or requests reference to external practices, first read that evidence table and answer; whether re-research is needed is determined by the refresh rules under the table.
Iron Rule: Line count is forbidden as a KPI, but allowed as a diagnostic symptom
Forbidden as an optimization goal / success metric(cannot be weakened—the defense line for cases 7/8/9 is this):
- Fewer lines do not mean better, and more lines do not mean worse
- The criterion is:single source of information(the same information is not maintained in multiple places),cognitive relevance(information not needed for the current task does not distract attention),maintenance consistency(changing one place does not require syncing another)—not line count
- It is forbidden to present "streamlined from X lines to Y lines" or "reduced by Z%" as an outcome in an optimization plan / summary
- It is forbidden to use "reducing line count" as a reason to move / delete something
- A long file with clear structure and no duplicated information is better than a short file that cuts key information
Can serve as a diagnostic symptom(official basis: Claude Code documentation "files too long → rules get drowned out → Claude does not follow them"):
- It is allowed to treat "abnormally large line count + Claude repeatedly not following a certain rule" as asignal that triggers investigation, not a conclusion
- The investigation action is still signal triage (Step 2.1) + layering,not "cutting down to N lines"
- To distinguish in one sentence: line count can make youstart to suspect, but it cannot become youroptimization goalorreported outcome
Trigger means reframe (when the user says "too big / too long / streamline / trim down"—this is where it is easiest to go off track)
The instinct triggered by these words is "cut line count."Reframe first, then act: ① confirm the actual symptom the user wants to improve and the existing authorization; ② perform the relevant measurement according to Step 2.0, then proceed to Step 2.1 signal triage, and use "does this section duplicate a canonical source / is it a counter-signal" to decide whether to keep it,notuse "how long the file is"; ③ treat "is it too big" asthe starting point of investigation, notpermission to cut. The same applies when the user repeatedly asks "is it still too big"—the response is "do another round of triage to find duplication / counter-signals"; if triage comes up empty, honestly say "what remains is all high-frequency core, and cutting further would lose signal,"notkeep cutting content that has information. (Field example: turning "is it too big" into a line-reduction task, reporting "saved 39%" as the outcome all along, and being dragged by repeated follow-up questions into cutting more and more → Cases 15 and 16.)
Two-layer architecture
The figure below is an example of a project-level layout, not a template that every file must complete. The global layer keeps only cross-project decision constraints; commands, code, diagnostics, and directory navigation are allocated according to actual task frequency and reliable retrieval paths.
Level 1 (CLAUDE.md) - 每次对话都加载
├── 信息记录原则 ← 防止未来膨胀的自我约束
├── Reference 索引(开头) ← 入口1:遇到问题查这里
├── 核心命令表
├── 铁律/禁令(含代码示例)
├── 常见错误诊断(症状→原因→修复)
├── 代码模式(可直接复制)
├── 目录映射(功能→文件)
├── 修改代码前必读 ← 入口2:改代码前查这里
└── Reference 触发索引(末尾) ← 入口3:长对话后复述
Level 2 (references/) - 按需即时加载
├── 详细 SOP 流程
├── 边缘情况处理
├── 完整配置示例
└── 历史决策记录
But "two layers" is only the file layer—choose the carrier first, then choose the layer
Progressive disclosure is not something inside a single file; it happens inmultiple layersat the same time: MCP lazy-loaded tools, RAG retrieving knowledge on demand, Skills descriptions resident while the body is on demand, and Claude Code's dynamic tool selection (progressive disclosure at the tool index layer). Moving L1↔L2 only within CLAUDE.md is equivalent to treatingthe four carriers in the table belowtwo of them (resident L1 / reference) as the whole.
Ask about the carrier first, then about the layer. The criterion is whether the model can find this rule before making a decision, and whether the existing mechanism can cover the required conditions. The table below is a candidate routing, not proof that the mechanism already exists, nor authorization to install a new mechanism.
| violation recoverable | violation unrecoverable | |
|---|---|---|
| self-report on trigger(I know I'm about to do X) | Skill / reference with trigger conditions | When mechanically decidable, consider existing interception mechanisms; retain necessary authorization rules |
| Trigger not self-reported, but the "moment" is observable as a tool event | Reference on demand; evaluate injection when advance reminder is needed | Evaluate hook reminders and minimal always-on constraints; semantic judgment still requires model or user |
| Trigger not self-reported, and no observable moment | Decide whether to keep always-on based on error cost and task frequency | Necessary always-on L1 constraints |
Definitions of the two axes:
- Trigger self-reported = at the moment before acting, the command/filename/keyword already says "I'm about to do this thing" —
aliyun ..., write.tf, run a build. Skill description matching can catch this type. - The "moment" is observable ≠ trigger self-reported.This is the entire reason the third row exists:
"I'm fixing the test" doesn't self-report "I'm about to delete a feature", but
Writea.pyfileis a tool event, the hook can fire at that moment.The semantic rule can't be judged by the hook, but the moment it can see — so the hook is only responsible for reporting the moment and shoving the rule in your face; the judgment still belongs to the model. - Even if hookable events exist, the principles of cross-project authorization and user decision-making may still require always-on. You cannot conclude it can be moved away just because it's "hookable".
Two forms of Hook: an interceptor only rejects operations on events the host supports blocking and under decidable conditions; an injector returns context reminders on supported events. Triggering, successful execution, reminder visibility, and model compliance are four separate things and cannot vouch for each other. A loaded reminder still occupies context; having a hook registered does not equal zero cost, full coverage, or always alive.
For irreversible rules that can only be judged semantically, retain the necessary always-on authorization sentence; existing injection mechanisms can remind but do not replace authorization or blocking. The rule body retains a single current source, and historical records are clearly marked as historical.
Host differences: Claude's @import is expand-load,.claude/rules/ unconditional rules are also always-on;paths: rules depend on the matched file being read and cannot be treated as triggers for all tool events. Codex's AGENTS hierarchy, override/fallback, and load budget need separate verification. Use current official documentation and real host read-back to adjudicate; do not extrapolate one host's behavior to another, and do not automatically enable memory.
When verifying alternative mechanisms: first read the real registration and implementation, then bidirectionally calibrate with side-effect-free healthy inputs and dangerous-form samples, recording events/matchers, results, and coverage boundaries. Periodic mechanisms must also verify the most recent success time. For detailed payloads, shell traps, and probe templates, see references/verification-recipes.md 's "Alternative Mechanism Probes"; until empirical verification is complete, do not reduce it to "already covered by X".
Multi-entry principle (important!)
The same Level 2 resource can havemultiple entries, serving different lookup paths:
| Entry | Location | Trigger scenario | User mindset |
|---|---|---|---|
| Reference index | Beginning | Encountering an error/problem | "Something's buggy — which document do I check?" |
| Must-read before changing code | Middle | Preparing to change code | "I want to change X — what should I watch out for?" |
| Reference-triggered index | End | Long-conversation lookup | "Which document was that one just mentioned?" |
This isn't duplication — it's multiple entry points. Just like a book has a table of contents (by chapter), an index (by keyword), and a quick reference card (by task).
Boundary (the tension with SSOT, which must be upheld): multiple entry points holdonly if— each entry point is keyed differently (error index / task index / end-of-conversation restatement), and all of them onlypoint tothe same Level 2 resource,without copying its body text. If you copy the same rule text into 3 places, that's duplication that violates SSOT (each copy will drift), not multiple entry points. One-sentence criterion: an entry point stores a "signpost + trigger condition," not a "content copy."
Workflow optimization
Step 1: Pin the original baseline (before writing)
The read-only audit reads first, and does not change the target environment by "backing up first." Before starting authorized modifications, record the exact source path and the resolved real target; back up the complete file and the references involved, saving the path, byte hash, and time. Use a unique backup name and do not overwrite older backups. Step 5b later uses the paths explicitly recorded this time; do not guess the baseline from the earliest/latest filenames in a directory.
When the target is in Git, you can retrieve the original text using the immutable ref from before this work and the repository-root-relative path; first confirm whether the current state, including uncommitted content, also needs to be saved. Personal global files need not be in Git; standalone backups apply equally. A backup protects the bytes that were saved; it does not automatically prove that other files are recoverable.
Step 2: Content classification
Three stages: measure by current symptoms, triage by authority, and layer by trigger. A whole-machine inventory unrelated to diagnosis is not part of this step; you cannot mechanically move low-signal content into a reference dumping ground.
2.0 Hotspot measurement (before any proposal — the first lesson of performance optimization)
First determine whether what the user wants fixed is non-compliance, conflict, loading errors, or context burden, then measure the relevant signal. The large file in Case 19 was once a measured hotspot, but that does not mean all tasks should be sorted by bytes.scripts/profile_claude_md.py It only describes the inside of a single file; it does not measure rule compliance or overall startup latency. When doing load/size diagnostics, then inventory the following startup surface.
-
The host's actual injection surface: Claude uses
/contextto see category proportions,/memoryto see the memory/instruction files actually loaded; when continuous observation of loading events is needed, use the officialInstructionsLoadedhook. Codex uses its own authoritative renderer; do not guess from configuration:codex debug prompt-input 'startup-instruction-audit' | jq -r '.[] | [.role, ([.content[]? | select(.type == "input_text") | .text] | join("") | utf8bytelength)] | @tsv'Also read the beginning of each developer message to distinguish global instructions, project instructions, Skill catalog, and hook/plugin injections;A single CLAUDE.md will miss always-on Skill descriptions and hook text。
Claude's
/contextcounts auto memory'sMEMORY.mdtogether with CLAUDE.md as Memory files. The official memory documentation states that it loads the first 200 lines or 25KB (whichever comes first) before each session; the toggle is the settingautoMemoryEnabledor the environment variableCLAUDE_CODE_DISABLE_AUTO_MEMORY=1. It is written by the model itself and often duplicates or contradicts user-written instructions (for example, the user specifies that experience should be documented, yet auto memory remains enabled); handle it as a conflict. Migrating memory entries into documentation is the responsibility of another Skill, routed viaclaude-code-ops-routertoclaude-migrate-memory-to-doc; this Skill is only responsible for listing it as a loading surface and a source of conflict. -
Per-section byte table: count bytes/lines by heading; a parent section includes its child sections, compare only at the same level, and do not add them together as a total. Size is used for locating, not for directly determining the order of changes; priority is still determined by the current failure, the cost of error, task relevance, and verifiable benefit.
-
Line-length distribution: a giant line >1KB is the signature of "a rule and its battle example welded into one bullet" (real-world: 4.4% of lines carry 35.6% of the bytes)
-
Loading semantics and limits: measure each host empirically; do not treat a historical version's default value as a current invariant. Current Codex's
project_doc_max_bytesisthe cumulative budget for project-level documents; global user instructions may take another loading path, and this value cannot be used to infer whether they are truncated. First check~/.codex/config.toml, then use the actual bytes ofcodex debug prompt-inputin the same cwd as the ruling. Historically, there was indeed an incident where a 96 KiB configuration combined with old loading behavior caused the last 41% of a 164KB file to be invisible, but it only proves that "you must measure empirically"; it does not prove that today it is still truncated at 32 KiB or via the same path. After confirming actual truncation, within the current authorization choose the smallest fix that can restore the visibility of the required content; modifying the budget, reorganizing the file, and adding monitoring are different actions and are not automatically bundled together. -
Always-on trigger audit:Skill frontmatter
descriptionwill enter the always-on catalog; if generic corrective sentences, ordinary quality words, or maintenance actions are written as trigger words, they will cause the Skill and the Stop hook to self-activate. Check item by item whether the description declares onlyexplicit task intent, and check whether the hook will temporarily create a new obligation at the final-answer stage that did not exist before work started. Keep descriptions at ≤1024 characters per the official limit; do not list the complete methodology.
On the Claude side, if some instruction files are permanently irrelevant to the current project, you can use the official claudeMdExcludes to explicitly exclude them; it is a scope configuration, not using @import to pretend to save context. Path-related rules should preferably go in .claude/rules/ 's paths: conditional carrier.
⚠️ Two pitfalls of the measuring instrument itself (both have been encountered in practice; the script has built-in avoidance; first calibrate on samples with known answers, see cases 17/19):
- The heading regex must be aware of code fences—the
# 注释inside a fence will be treated as a heading, creating a nonexistent large section out of thin air (in practice it created a fake 45.9KB section, and the entire hotspot ranking was distorted) - Do not treat bytes/chars as tokens. Historical sample ratios for CJK cannot be generalized to all files and models; omit estimates without a current tokenizer or host measurement. When explicitly providing an empirical ratio, mark it
est., and record the ratio's source and applicable sample.
2.1 Signal triage (necessity gate, prerequisite)
For each section, first ask Anthropic's official litmus:"If this item is deleted, will Claude make a mistake?"
- Will make a mistake → it is a signal; proceed to 2.2 tiering
- Will not make a mistake, and it belongs to any of the following → it is acounter-signal, add it to the "candidate deletion" list:
- Inferable from code / project structure / file names (e.g., "this project uses TypeScript")
- Standard conventions of the language / framework (e.g., "follow PEP 8")
- Self-evident common sense (e.g., "write clean code", "test before committing")
- Already covered by an independent canonical source (note where the source is)
- Outdated one-off fixes (will not recur)
- Checks that need to be deterministically executed(e.g., lint before committing) → verify whether existing hooks/CI/workflows cover them. Give candidate carriers, trigger timing, coverage and gaps; do not presuppose a hook just because "determinism is needed", and do not treat Skill description matching as a determinism guarantee. This audit does not automatically authorize implementing a new mechanism.
Safety rail: Candidate deletion does not equal authorization obtained. For each item, give the original text, the basis, and the behavior change; trade-offs not decided by the current user instruction, existing rulings, or currently authoritative decisions are left to the user. Do not re-ask about clear existing rulings; keep the necessity uncertain as unknown when unsure, and do not treat "the model should know" as evidence.
Boundary with Cases 8/9: 8/9 is compressingtrue signals(debug hints, code patterns) when moving them = always wrong; this step is removingconfirmed counter-signals(inferable / self-evident) = correct. The difference lies in "whether what is deleted is a signal", not in "whether to delete". See
references/progressive_disclosure_principles.mdCase 10.
2.2 Layered classification
Forsignals that pass triage, classify:
| Question | Yes | No |
|---|---|---|
| High-frequency use? | Level 1 | ↓ |
| Severe consequences if violated? | Level 1 | ↓ |
| Code patterns needed every round of a task and hard to retrieve reliably? | Level 1 keep minimal pattern | ↓ |
| Clear trigger conditions? | Level 2 + trigger conditions | ↓ |
| Historical/reference material? | Level 2 | Consider deletion |
Step 3: Create Reference files
Only execute when the current task has already authorized modification.profile_claude_md.py is read-only;sink_sections.py writes backups, references and source files as soon as it runs, with no dry-run. First read its --help and exact spec, then check all targets and recovery boundaries; the shared fence parser scripts/markdown_headings.py is an internal implementation with no independent CLI. The script's OK only proves that the listed mechanical checks pass.
Naming:docs/references/{主题}-sop.md
Iron rule: move as-is, no compression allowed
When moving content to Level 2, you mustfully preserve the original content. Do not "trim it down along the way" while moving.
✅ 正确:把 100 行原封不动搬到 Level 2(100 行 → Level 2 100 行)
❌ 错误:把 100 行"精简"到 60 行搬到 Level 2(100 行 → Level 2 60 行,40 行消失)
Scope: This step only does as-is migration, so it does not covertly change semantics during the transfer. Deduplication, factual correction and authorized retirement are declared and verified separately; preserving a valid contract is not the same as continuing to label an invalid rule as a current specification.
How to do it:
- Copy exactly the paragraphs to be moved from the original CLAUDE.md
- Paste as-is into the Level 2 file
- You may add structure (headings, separators) in Level 2, butdo not delete, rewrite, or mergethe original content
- If there is indeed redundancy (the same passage appears multiple times in the source text), keep one complete copy in Level 2, with a comment noting the deduplication
Mechanical process for batch demoting an entire section (script it when there are ≥3 sections; manual moving is forbidden)
Manually moving multiple sections easily causes line number drift or omissions. Use scripts/sink_sections.py(spec-driven; in real use passed 10 sections / 119KB in one go, with whole-string verification 10/10 and zero loss):Extract the source text by delimiting on exact heading lines (fence-aware) → append verbatim to the target reference (with a dated provenance header, and an intro for new files) → replace the L1 compressed version bottom-up so line numbers do not become invalid → verify each section as a whole-string substring (grep treats multiple source lines as line-by-line OR, so it will let a half-lost move pass; you must use python in for whole-string checking) → if verification fails, restore the source file and keep the reference append for inspection. It is not a cross-file transaction; after an I/O failure midway, first check the source backup and each target, and do not blindly rerun to avoid duplicate appends. Two hard rules:
- Refuse to write to a symlink target (including parent directories): if any component of the target path is a symlink (the file itself, ora parent directory—file-level
islinkchecks are silently bypassed by directory-level symlinks; independent review measured an actual bypass), "local append" is actually modifying the repo that the link points to (triggering its version bump / commit obligations, and that repo may be public). The script decides byrealpath ≠ abspathand aborts; for intentional cross-link cases (such as macOS/tmp) use--allow-symlinked-targetto explicitly allow; the correct action is to create a local sibling file + provenance noting "to be merged later with the symlink source" - Extract all first, then replace in a unified pass: extraction is done once using the original line numbers, and replacement is bottom-up—interleaving the two steps will cause the line numbers of unprocessed sections to drift. The compressed-version snippet must retain exactly one complete start_heading line outside the code fence(check before writing and re-verify after writing; body substrings do not count as headings); the heading used as the delimiter must be unique in the source file (abort on duplicate names)
Step 4: Update Level 1
- Keep the currently valid cross-task constraints, and update the existing entry points actually affected by this change.
- After migrating details, state clearly when to read it, where to read it, and what can be obtained from it.
- Place code patterns, diagnostics, and directory navigation according to the task frequency and retrieval reliability from Step 2.2.
- Use a question index, task table, or inline links when there is a real lookup need; do not repeat the head and tail indexes just to fill out a template.
- Only add the minimal information-recording principle when the target truly lacks it and the current scope requires it; do not automatically inject a whole governance charter.
⚠️ Hard gate before writing pointers (in-flight verification, easiest to skip, biggest pitfall this time): before writing each pointer of the form "→ some reference / see X for details,"confirm on the spot that the target file really contains this content。
⚠️ The verification method depends on what you want to verify(the criteria pitfall table in verification-recipes.md has been tested in practice): if you only verify "is this passage present" → sample 3–5distinctive stringsand use grep -F to check;
if you want to verify that "the entire passage was moved over completely」→ you cannot use grep — when the original sentence has multiple lines, grep -F is OR by line,and a half-lost passage will still be reported as a hit,
must use python3 whole-string substring check. Three outcomes: ① target already has the complete content → write the pointer; ② target lacks it / uncertain whether it is complete → first verbatim cut the original text to the target (return to Step 3), then write the pointer; ③ never write a false pointer that "points to a file that does not actually contain that content". A false pointer is more insidious than losing content—it lets 5a "file exists" pass, yet the reader only discovers it is empty when clicking in. Why: 5a/5b areafter-the-factverification; the false pointer has already been written to the file at that moment; only an in-process gate can block it at the source. (Real-world: wrote "see anti-patterns" but there were 0 hits for the Stripe endpoint → Case 15.)
Step 5: Verify structure, loading, and task results
5.0–5a. Calibrate criteria and check references
First calibrate the criteria to be used on known healthy and failing samples, distinguishing no-hit, instrument error, and undecidable; after resolving the real path, verify the link target'sactual content. A title or file existing only proves the entry point can be found, not that the entire content is complete. For verbatim migration, match the whole string using the original bytes; checking only keywords cannot prove nothing was lost.
When performing link checks, cross-shell calibration, or integrity verification, read the "Verifier calibration and reference checks" in references/verification-recipes.md . The shell commands therein are auxiliary screening: any skipped items must be explained one by one; printing success or exit 0 does not replace the judgments not covered.
5b. Content integrity (most critical)
For each section moved out of the original CLAUDE.md, check one by one:
-
Use the exact original backup path and hash already recorded in Step 1; do not sort by filename to guess the earliest version. The Git comparison must predate this work, with paths relative to the repo root; do not use a HEAD that already includes this commit to self-certify. A global personal file may use an independent backup; there is no need to assume it belongs to a Git repository.
-
Section-by-section comparison: for each
##section of the original file, confirm that its content exists completely in one of the following locations:- in the new CLAUDE.md (kept at Level 1)
- in some Level 2 reference file (fully moved)
📖 For a helper script that quickly exposes whole-section omissions, see
references/progressive_disclosure_principles.mdAppendix C: triggering scenario—the first screening before doing the section-by-section comparison below (the script does not replace manual section-by-section comparison; it only checks whether section titles exist). -
Explain differences item by item: verbatim moves should preserve bytes completely; same-source deduplication must have a reachable authoritative source; factual corrections or authorized retirements must cite the current basis and authorization, and explain the behavior change. A missing item that cannot be attributed to these categories is a regression; restore it and then verify.
Do not use after-the-fact "intentional deletion" to cover up omissions, nor add old rules that have already been overturned by the user or current authority back into the current specification. Historical original text may be retained via backups, Git history, or clearly annotated incident materials.
Fidelity audit of compressed restatements (mandatory when L1 keeps a compressed version): what compression most easily loses is not whole sections—it isqualifiers. Hands-on (Case 19): The original sentence "public + 0 stars/forks and the user explicitly authorizes" was compressed into "0 stars and explicit authorization", 6 characters disappeared, and the condition of one gate was literally relaxed by half; the same audit also caught a declaration mismatch where it claimed to omit only battle cases but actually also omitted 4 executable criteria. Two audit actions: ① For each compressed restatement, take theoperational clause(conditions / values / enumerations / hook names / negations) and do a word-by-word diff against the original sentence—a whole-segment loss can be caught by 5b, but a single "/forks" can only be caught by a clause-level diff; ② Run an expected-hunks-only check over the full text—with difflib comparing against the baseline, every non-equal hunk must be attributed to a declared change; anything that cannot be attributed is an unplanned difference.
Independent review is triggered according to the current collaboration contract: for ordinary small changes where mechanical checks are sufficient to adjudicate, no reviewer is automatically dispatched; for complex, high-risk changes that lack independent mechanical criteria, freeze the original baseline and the final candidate, perform one bounded fresh-context review, and prohibit forks and nested dispatch. When section-by-section fidelity review is needed, use the template in references/progressive_disclosure_principles.md Appendix D.
A finding is a hypothesis to be verified; first adjudicate it using the original bytes, an accurate diff, linked content, or a real task. Stop after completing the relevant fixes and checks; expand the review only when a newly added high-risk semantic issue cannot be mechanically adjudicated or the user explicitly requests it. Record the methods executed, finding dispositions, and unverified items; follow the existing private knowledge repository/project SSOT recording conventions, and do not create another governance project for ordinary small instruction changes.
5c. Line counts do not enter the verification criteria
Verificationdoes not use line counts as a pass condition, and does not calculate "original X lines vs new Y lines = reduction of Z%"—this kind of reconciliation will pull you back into KPI thinking.
Necessary structural checks:
- Every original content item has an explicit disposition: retained, migrated, deduplicated, corrected, or authorized for retirement
- No signal loss (anti-signals confirmed and deleted do not count as loss)
- Level 2 references all have trigger conditions
Then check the real results: in the same host/cwd, verify the actual loaded content and source before and after the change, and check overrides, imports, symlinks, and budgets. Test behavior with representative tasks corresponding to this issue, preserving both the contrasts that should be followed and those that should not be triggered; report the model, host, sample size, and execution limitations. One success, merely initializing without running the model, or a tool success receipt cannot prove a stable improvement in adherence rate. If the model is not executed due to quota/network limitations, write "unverified" and do not change the measurement name to pass it off as success.
(Note: During the diagnostic phase, looking at line counts as a suspicion signal is allowed, see the "Iron Rules" at the beginning; butduring the verification phaseline counts are not any criterion—these two phases have different attitudes toward line counts, do not mix them up.)
Level 1 Content Classification
🔴 Always-on candidates: first see whether the current task requires them
| Content type | Reason |
|---|---|
| Core commands | Retain when they are high-frequency in the current scope and cannot be reliably discovered from existing entry points |
| Authorization / key prohibitions | Retain the applicable scope, conditions, and stopping points that must be visible before decision-making |
| Code patterns | Retain the minimal example when it is high-frequency and re-derivation has reproducible risk; otherwise route by task |
| Error diagnosis | Retain the entry point and key pitfalls; the full SOP can be loaded by symptom |
| Directory mapping | Keep only navigation that cannot be reliably inferred from the file structure |
| Trigger index | Set according to actual lookup needs; do not force a fixed location or table |
🟡 Keep summary + trigger conditions
| Content type | Level 1 | Level 2 |
|---|---|---|
| SOP process | Trigger conditions + key pitfalls | Complete steps |
| Configuration examples | The 1-2 most commonly used | Complete configuration |
| API documentation | Common method signatures | Complete parameter descriptions |
🟢 Can be moved away entirely
| Content type | Reason |
|---|---|
| Historical decision records | Low-frequency access |
| Performance data | Reference nature |
| Technical debt list | View on demand |
| Edge cases | Load only when there are clear trigger conditions |
Reference formats (four types)
The four reference formats each serve different scenarios; for the standard "trigger conditions" wording, see below 原则 2(includes copyable examples).
| Format | Purpose | Trigger scenario |
|---|---|---|
| Detailed format | Important references in the body text | A single reference needs to explain when to read it |
| Problem trigger table | Reference index at the beginning/end | Look up by "error/problem" |
| Task trigger table | "Must read before modifying code" | Look up by "what to change" |
| Inline format | Brief reference | Mentioned briefly in a sentence in the body text |
📖 For complete copyable templates of the four formats, see references/progressive_disclosure_principles.md Appendix B: Trigger scenarios—when producing a Reference index / task table / inline / detailed reference.
Format selection: Use the simplest format that lets readers reliably find the content; do not mix formats for the sake of "variety".
⚠️ @import does not save context (technical correctness, easiest to get wrong)
@path import isfully expanded and loaded at startup—splitting into @import only improves organization,does not reduce any context(official memory documentation wording). "I split the content into @import so it's optimized" is fake optimization.
Common ways to reduce load include the following three; you can also evaluate paths rules or explicit scope exclusions according to current host support, and do not treat this list as an exhaustive enumeration:
- Move non-general contentto the project-level CLAUDE.md(the global file will be loaded by unrelated projects)
- Keepa plain-text pointer("Read when needed
references/xxx.md",not@), letting the model pull on demand - Convert to skill(description always present, body text on demand)
References produced by this skill always use backtick paths,do not use @import to unload. See references/progressive_disclosure_principles.md Case 11.
Core Principles
Principle 0: Update existing information attribution rules
First check whether the target already specifies where the information is placed. Only add the triggers, attribution, and maintenance sources that are missing and needed for this instance; do not mechanically add an entire chapter.references/progressive_disclosure_principles.md Appendix A is a customizable template, to be used when attribution rules genuinely need to be completed.
Principle 1: Index placement follows retrieval needs
By default, keep one clear entry point. Add multiple entry points only when there are different lookup paths or observed missed reads; each entry point points only to the same authoritative main text. The Lost in the Middle research cannot directly prove that all modern models need the index duplicated at the beginning and end of an instruction file, nor can it provide a universal optimal position. Case 4 retains one layout experience; when using it, validate it against the current task.
Principle 2: References must have trigger conditions
Incorrect:详见 native-modules-sop.md
Correct:
**📖 何时读 `native-modules-sop.md`**:
- 遇到 `ERR_DLOPEN_FAILED` 错误
- 需要添加新的原生模块
> 包含:ABI 机制、懒加载模式、手动修复命令
Reason: Without a trigger condition, the LLM does not know when it should read it.
Principle 3: Preserve the code patterns the task actually needs
In tasks where it has been confirmed that this pattern needs to be resident, writing only "use the lazy loading pattern" while dropping the complete implementation is incorrect; the copyable example below should be retained.
Correct: Level 1 retains the complete copyable code:
// ✅ 正确:懒加载,只在需要时加载
let _Database = null;
function getDatabase() {
if (!_Database) {
_Database = require("better-sqlite3");
}
return _Database;
}
Applicability conditions: This example stays resident only when this code pattern is high-frequency and provides reliability benefits. If it applies only to a certain component or occasional task, keep the trigger entry point and place it in full in the corresponding reference; do not copy all project code examples into the global layer.
Principle 4: Use three-state priority, not "marking everything as ironclad law"
Marking all rules as the highest priority obscures the actual boundaries. First eliminate rules that give opposite actions in the same scenario, then clarify must, prohibited, optional, and their respective trigger and stop conditions; labels or positions cannot override the instruction priority of the actual host.
Stacking emphasis words (bold,CRITICAL、MUST, "ironclad law", "absolutely prohibited", punitive threats) belongs to the same problem. Anthropic's official guidance suggests noting that new models will over-trigger because of this; when rewriting, switch to an ordinary tone, clearly state the applicable conditions and reasons, and keep the rule's boundaries and stopping point unchanged.
✅/⚠️/🚫 can be used as display styles, not as the best structure proven by controlled experiments. There is not enough evidence to set "150–200 rules" or "keep only 5–7 high-risk rules" as universal upper limits for modern GPT/Claude. For the applicable scope of the research on quantity and position, see the evidence table at the beginning of reference; decide based on actual behavior on the current host.
Principle 5: Add reasons only when they help decision-making
Brief reasons are useful when they help clarify applicable boundaries; the advice in engineering articles does not constitute experimental proof that "all rules must include a one-line Why".
For non-intuitive restrictions, add specific consequences; rules that are already clear should not be explained again, and incident processes should not be copied or history fabricated.
Incorrect:🚫 禁止 fallback 默认值
Correct:必需凭据缺失时显式报错;不要回退到内置密钥,以免误连其他环境。
⚠️ Hard boundary when restating rules: If the original sentence is embedded in a mixed case study paragraph, Principles 4/5 must not directly rewrite the original sentence—see Anti-pattern 6 (first move the entire paragraph verbatim to L2, Case 14).
Anti-pattern warnings
⚠️ Anti-pattern 1: Over-compression aimed at line count
Case: To "reduce line count", code patterns, diagnostic flows, and directory mappings were removed
Result:
- Code patterns were lost, and the LLM re-derived them every time
- Lost diagnostic procedures: when an error occurs, you don't know where to look
- Lost directory mapping: finding files is inefficient
Correct: Retain all frequently used content. The criterion for optimization is whether information is redundantly maintained and whether it is irrelevant to the current task, not "the file is too long."
⚠️ Anti-pattern 2: References without trigger conditions
Case:详见 xxx.md
Problem: The LLM doesn't know when to load it, so it either ignores it or reads it every time.
Correct: Trigger condition + content summary.
⚠️ Anti-pattern 3: Moving away code patterns
Case: Move commonly used code examples to Level 2
Problem: The LLM must read Level 2 every time it writes code, increasing latency and token consumption.
Correct: Keep frequently used code patterns in Level 1.
⚠️ Anti-pattern 4: Deleting instead of moving
Case: Delete "unimportant" sections
Problem: Information is lost, and there is nowhere to look it up when needed in the future.
Correct: Effectively move low-frequency content in full to Level 2 and retain triggers; outdated rules are corrected or retired based on clear grounds and authorization, not disguised as migration as-is.
⚠️ Anti-pattern 5: Using line count as a KPI
Case: The optimization plan says "streamlined from 2000 lines to 500 lines, a 75% reduction"
Problem: Treating line count as a success metric drives wrong decisions—cutting useful information just to hit a number.
Correct: Evaluate optimization effectiveness by information quality—is information duplicated? Is the maintenance burden reduced? Can the LLM find the information it needs faster?
⚠️ Anti-pattern 6: Compressing while moving (deletion in disguise)
Rule: Moving is moving, streamlining is streamlining. These are two independent operations,do not perform them at the same time。
- When moving content to Level 2, you mustcopy it verbatim, without changing a single word
- Deduplication, correction, or retirement must be separately declared and verified, executed under this and existing authorization; leave to the user only the substantive choices that are still missing
- "Since we're already editing, let's streamline it along the way" is the most hidden form of deletion—it wears the cloak of "optimization" while doing the work of "deletion"
- Mixed paragraphs: In as-is migration mode, first preserve the original paragraph in full, then generate the L1 retrieval entry; verify conditions, values, negations, and stopping points item by item. Label historical original text and current rules separately; outdated original text and new decisions must not both masquerade as authoritative at the same time. Authorized corrections/retirements are not bound by "old rules may never be rewritten," but must have an independent baseline and an accurate diff.
⚠️ Do not verify this criterion with grep(measured in row 4 of the Step 5.0 table): when the original sentence spans multiple lines,
grep -Fsplits it into multiple patterns OR'd by line, losing half the passage still reports a match — it issues a certificate of innocence for a lossy transfer. Use whole-string substring checking: store the original sentence in a temporary file and usePath("orig").read_bytes() in Path("target").read_bytes()to check for a contiguous complete byte match; first import frompathlibimportPath. Principles 4/5 govern how L1 is presented, and do not authorize destroying the original signal sentence
For a complete case analysis, see
references/progressive_disclosure_principles.mdCase 8, Case 14
⚠️ Anti-pattern 7: Using "deliberate deletion" to cover up information loss
Rule: For every deletion or behavior change, state the basis and authorization before modifying; you cannot make up reasons only after noticing something is missing.
- Deduplication from the same source means pointing out the existing authoritative source and reachable entry point.
- Correction or authorized retirement points out the newer authoritative fact/user ruling; invalid content does not need to continue being kept as a runtime rule.
- Loss without the above basis is a regression; restore and verify it; it cannot be covered up with "low risk".
For the complete case analysis, see
references/progressive_disclosure_principles.mdCase 9
⚠️ Anti-pattern 8: Purely negative rules (no replacement given)
Case:🚫 不要用 X — it did not say what to use instead.
Problem: Lacking a necessary alternative path may leave the executor unsure of the next step; this is a verifiable executability problem, not that all negative sentences cause model failure.
Correct: When a known and authorized alternative path exists, state it clearly; an effective stop/prohibition rule does not become invalid just because there is no alternative.
🚫 不要用全局 mutable 单例存请求状态
✅ 改用显式参数传递或 request-scoped context
When encountering a prohibition, first preserve its true boundary; add replacement actions only when current evidence supports it, do not fabricate a fallback, and do not delete a necessary prohibition on that basis.
⚠️ But if the original prohibition sentence is embedded in a mixed case study paragraph, first move the entire paragraph verbatim to L2 per Anti-pattern 6, then derive a restatement at L1 — the original sentence must not be rewritten (Case 14).
⚠️ Anti-pattern 9: Fake pointer (pointing to nonexistent content)
Case: After moving a section of content, it says "see X.mdfor details", but X.md does not contain this section at all — the pointer points to nothing.
Problem: More covert than directly losing content.5a"The file exists" will pass (X.md does indeed exist), but the content is not there; the reader only discovers this after clicking in, and by then there is no way to know what the original text was. In essence, it is a combination of Anti-pattern 6 (compression during moving) + Anti-pattern 7 (covering up loss): the content is cut + covered up with a seemingly compliant pointer.
Correct: Before writing a pointer, verify on the spot that the target really has that content (Step 4 hard gate;to verify "whether it is there", use grep -F to sample a distinctive string; to verify "the whole passage is complete", you must use a python3 substring check — grep will give false positives, see the criteria trap table in verification-recipes.md). A pointer pointing to the wrong file (the content is in A, but it says "see B") is the same kind of problem; correct it according to where the content actually is, not by deleting the pointer.
For the complete case analysis, see
references/progressive_disclosure_principles.mdCase 15
Information sufficiency check
✅ Correct information sufficiency
| Check item | Pass criterion |
|---|---|
| Daily tasks | The required commands can be discovered and completed according to existing project conventions |
| Common errors | A credible diagnostic procedure can be found based on symptoms |
| Code writing | Required non-default patterns can be reliably obtained |
| Specific problems | Know when to read which Level 2 |
| Trigger index | The entry point is reachable and does not copy the authoritative body text; position/format is not a hard gate |
❌ Insufficient signals
- The LLM repeatedly asks the same question
- The LLM re-derives the code pattern every time
- The user needs to repeatedly remind it of the rules
❌ Too many signals
- A large low-frequency detailed process at Level 1
- Completely identical contentin multiple places (note: multiple entry points pointing to the same resource ≠ duplication)
- Edge cases and common cases mixed together
Project-level vs user-level
| Dimension | User-level | Project-level |
|---|---|---|
| Location | ~/.claude/CLAUDE.md |
项目/CLAUDE.md |
| References | ~/.claude/references/ |
docs/references/ |
| Information scope | Personal preferences, global rules | Project architecture, team conventions |
Hard check: scope misplacement (adjudicated by the official hierarchy documentation)
User-level ~/.claude/CLAUDE.md will beall projectsloaded,and can only contain universally applicablethings. During optimization, perform a scope check on each section:
| Content characteristics | Belongs to | Consequence of not doing so |
|---|---|---|
| Project name / deployment target / per-project paths / project credentials | Project-level, never global | Unrelated projects get polluted; no one maintains it per project → paths/status rot (typical staleness) |
| Personal preferences, cross-project behavior rules | User-level | — |
| Team conventions, project architecture | Project-level (committed to VCS) | — |
Step 2.1 First determine the content's responsibility: specific project status/implementation details go into that project's SSOT; cross-project navigation may retain pointers with trigger conditions. Discovering a project name does not automatically authorize relocation or deletion, nor should a global routing pointer be misjudged as a project fact. See references/progressive_disclosure_principles.md Case 13.
Canary detection method (only as a diagnostic candidate)
A single harmless naming instruction can only probe whether that instruction is visible/executed in that sample; it cannot prove that the entire file is "within the compliance threshold," nor can it prove that a failure originates from the file being too long. Use it in an isolated sample only when the user needs this kind of diagnosis; do not automatically inject irrelevant rules into the global contract. Prioritize verifying the behaviors that should be followed and should not be triggered in real tasks.
Quick checklist
- The user's goal, authorization scope, exact original text/candidate diff, basis, and unverified items are clear; no already-authorized request is repeated.
- Moving as-is preserves bytes; corrections, deduplication, and retirement each have a basis, and expired rules are not restored under the guise of "zero loss."
- Every referenced target content actually exists, and its trigger, scope, and authoritative source are clear; there are no false pointers or dual-current rules.
- The criteria used have been calibrated with healthy/failing samples, and tool errors and uncovered items are not disguised as success.
- The actual load surface of the current host has been checked; representative tasks have verified this behavior, and untested models/branches are truthfully labeled.
- The necessary independent review is performed according to the current collaboration contract; after fixes, the relevant scope is checked, and once the stopping condition is reached, it is wrapped up.
- Bytes, line counts, reviewer counts, naming canaries, or script OK are not treated as business results.
- The global file carries only cross-project responsibilities; no template sections, memory, hooks, Skills, or monitoring are automatically added.