CLAUDE LABJP
2.1.269 — Prompt suggestions were being dropped for Japanese, Chinese, Thai and other languages written without spaces between words. That is now fixedKB5124008 — After September's cumulative update, Windows 11 users report Cowork failing to mount any host folder at all. The VM still starts, which makes the cause hard to pin downPUSH — Some cloud and Cowork sessions have git push rejected by the proxy before it reaches GitHub. Cloning still works, so it reads like a token permission problem when it is notNEW — Adding more material made Projects answer thinner. Three questions we now use to decide which knowledge files stayTOKENS — You cannot price a PDF before sending it: CountTokens does not accept document input. That leaves estimating from page count or extracting the text and counting thatCLEANUP — Before asking an agent to tidy up, separate the work that only needs reading from the work that needs writing. The order you hand over folders cannot be reconsidered afterwards2.1.269 — Prompt suggestions were being dropped for Japanese, Chinese, Thai and other languages written without spaces between words. That is now fixedKB5124008 — After September's cumulative update, Windows 11 users report Cowork failing to mount any host folder at all. The VM still starts, which makes the cause hard to pin downPUSH — Some cloud and Cowork sessions have git push rejected by the proxy before it reaches GitHub. Cloning still works, so it reads like a token permission problem when it is notNEW — Adding more material made Projects answer thinner. Three questions we now use to decide which knowledge files stayTOKENS — You cannot price a PDF before sending it: CountTokens does not accept document input. That leaves estimating from page count or extracting the text and counting thatCLEANUP — Before asking an agent to tidy up, separate the work that only needs reading from the work that needs writing. The order you hand over folders cannot be reconsidered afterwards
Articles/Claude.ai
Claude.ai/2026-09-15Intermediate

Where to Put an Instruction That Keeps Coming Back: Chat, Style, Settings File, or Hook

No comments, please. Do not translate the product name. When an instruction drifts back a few turns later, the fix is usually the location, not the wording. I compared the same sentence across four layers and settled on a rule for which instruction belongs where.

instructionsclaude-code132hooks19settings9workflow39

I was midway through a client site refresh when I noticed I had typed the same line three times. "Please don't add explanatory comments to the code." It worked the first time. It worked the second time. Four exchanges later, once we had moved to a different component, a line came back that simply restated the code it sat above.

For a while I assumed the wording was too soft. I added emphasis, then a reason, then both. That went nowhere. The instruction wasn't weak — it was sitting somewhere that never gets read again.

There are layers to where an instruction can live, and each layer is re-read at a completely different rate. Preferences belong near the top; rules you can't afford to lose belong further down. Since I started sorting instructions that way, the days of typing the same sentence three times have mostly gone.

An instruction drifts because its location is never re-read

There are roughly four places you can put an instruction. The higher ones are cheap to write; the lower ones survive repetition.

LayerWhere it livesWhen it gets re-read
1. ChatA message in the conversationThe next few turns only. Summaries and topic shifts dilute it
2. Style / custom instructionsCustom styles, project custom instructions, Claude Code output stylesAcross conversations, though it fades as the subject drifts
3. Project settings fileCLAUDE.md, project-level settingsAt the start of every session — if the path and key names are right
4. Runtime guardrailHooks, verification scriptsEvery time a tool runs, for instructions you can actually test

The same frustration has been piling up in a Claude Code issue thread. What's being argued there is phrasing — how to say it so it sticks. I couldn't find anyone comparing the layers side by side, so I ran the comparison on my own machine.

I put the same sentence in all four places and watched ten exchanges

The setup was deliberately boring. One instruction: don't add explanatory comments to the code. One task: ten small UI fixes on the client site, one after another. Each round, I opened a file, asked for the edit, and noted the exchange where a comment line reappeared.

LayerDrifted back atHow it broke
1. Said once at the start of the chatExchange 3–4Right after we switched files
2. Written into a styleExchange 7 onwardSurvives new conversations, thins out inside a long implementation
3. Written into the settings fileDidn't driftBut I had no way to confirm that from inside the session
4. Enforced by a hookDidn't driftOnly accepts instructions you can evaluate mechanically

Layer 3 surprised me, and not in the direction I expected. It held — but I had no way to verify that it was holding, and that gap is the real difference between 3 and 4. A settings file with one mistyped key is ignored in total silence. I wrote about that particular silence in A One-Letter Typo in settings.json Is Ignored Without a Single Warning.

Preferences up, rules down

I sort instructions with two questions. Does breaking it cause real cleanup? And can a machine tell whether it was broken?

  • Preferences — tone, paragraph length, emoji, how much explanation — live comfortably in layers 1 and 2. If they drift, you restate them, and nobody is measuring them precisely anyway.
  • Rules — files that must not be touched, whether commits are allowed, naming conventions, proper nouns that must not be translated — move down to layers 3 and 4. When a rule breaks, someone has to undo the damage, and restating it doesn't get you there.

As an indie developer I hit the same wall while expanding the store listings for my wallpaper apps into more languages. "Don't translate the app name or the feature names" holds in chat for a while, and then somewhere around the third or fourth language it quietly stops holding. Now the do-not-translate terms live in a file that gets read every run, and a final check confirms the proper nouns survived intact. It isn't that I stopped asking in chat — it's that I started asking the right layer.

If a rule must not break, stop explaining it and start blocking it

Here's the layer-4 version. It runs right after an edit and looks only at the file that was just written. This goes in settings.json:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/no-echo-comments.sh"
          }
        ]
      }
    ]
  }
}

And the script it calls. The hook receives JSON on stdin, which is where the edited file path comes from:

#!/usr/bin/env bash
# PostToolUse hook: look at exactly one file, the one just edited
INPUT=$(cat)
FILE=$(printf '%s' "$INPUT" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("tool_input",{}).get("file_path",""))')
 
# Narrow the scope first. Scanning config files and Markdown invites false positives
case "$FILE" in
  *.ts|*.tsx|*.js|*.jsx) ;;
  *) exit 0 ;;
esac
 
# Catch comments that only restate the line below them
HITS=$(grep -nE '^[[:space:]]*//[[:space:]]*(updates?|sets?|returns?|gets?|initializes?) the .+$' "$FILE")
 
# Silence on success
[ -z "$HITS" ] && exit 0
 
{
  echo "Comments that only restate the code are still here. Remove them before moving on:"
  echo "$HITS"
} >&2
exit 2

What you should see:

$ # immediately after Claude runs an Edit
Comments that only restate the code are still here. Remove them before moving on:
42:  // updates the state

Three things matter in that script. First, exit 2 is the signal to try again, and whatever you write to stderr goes back to Claude as the reason. Second, narrow the file types before you scan anything; a hook that inspects every file will stall on comments in config files that were never the problem. Third, say nothing when the check passes — I've written about what a chatty-on-success hook costs you in Don't let your verification script's full output flow back through a hook.

If you're not writing code and hooks aren't part of your setup, stopping at layer 3 is fine. Just make the sentence you put there testable. "Be concise" can't be checked by anyone, including you. "Keep sentences under 25 words" can.

Three things to check when it still drifts

  1. Confirm the file is actually being read. Plenty of instructions aren't losing an argument; they're never arriving. Check for evidence that the file loaded before you rewrite its contents.
  2. Ask whether the instruction is testable. "Be thoughtful" won't survive at any layer, because nothing can confirm it held. Trade it for something countable.
  3. Look for two rules in the same layer pulling opposite ways. Settings files grow, and a line from six months ago can quietly contradict today's. On the related question of how context thins out over a long conversation, I wrote Picking Up Where You Left Off: When to Lean on Claude's Memory and When to Ask It to Search.

One thing to try today: pick a single instruction you've now restated three times in chat, and move it down exactly one layer. The fact that you typed it three times is the signal that it's sitting in the wrong place.

I still get this wrong in the other direction — pushing something down to layer 4 that layer 2 handled fine, then spending an afternoon on false positives. Finding the layer where an instruction settles seems to be part of the work rather than a detour from it.

Share

Thank You for Reading

Claude Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $15 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

Claude.ai2026-03-12
Using Claude Code's /loop and Cron Scheduling as a Background Worker — What I Learned
A hands-on record of folding Claude Code's /loop command and cron-style scheduling into everyday personal-project tasks. Covers the basic syntax, the gotchas I only found by using it — tasks that vanish after 3 days, tasks that fire only when idle — and how to decide what belongs on a real cron instead.
Claude Code2026-05-21
Claude Code Hook `command timed out`: Timeout Settings and Split-Execution Patterns That Actually Work
Fix Claude Code's `command timed out` hook failure without just bumping the timeout. Includes practical split-execution, detached background jobs, and a settings.json layout that keeps your session fast.
Claude Code2026-04-27
Using Claude Code in a pnpm Monorepo — Combining --filter with dlx
Running Claude Code in a pnpm monorepo? It often touches files in packages you didn't ask about. Here's how to scope work properly with --filter, when dlx is dangerous, and what to put in .claude/settings.json so confirmation dialogs stop interrupting you.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links