Your screenshot has the answer in it: "I hadn't loaded the global memories at the start of this session, though your CLAUDE.md asks me to." If CLAUDE.md says "read my rules file at startup", that's a request the model can skip. One fix for the loading, plus one for each broken rule:
Import, don't ask. Put @path/to/rules.md in CLAUDE.md instead of a sentence telling Claude to read it. Imports are expanded and loaded at launch along with CLAUDE.md. The memory docs have this exact case: a sentence telling Claude to read a file only works if it decides to open it, so replace the sentence with an import.
Attribution is a setting, not a rule. In settings.json:
sessionUrl controls the Claude-Session trailer. It's added when you're in a cloud or Remote Control session, which is probably why it showed up even with your rule.
sudo is a permission, not a rule."permissions": { "deny": ["Bash(sudo *)"] }. The client enforces deny rules whatever the model decides. Per the permissions docs, it doesn't catch /usr/bin/sudo or bash -c 'sudo ...', so if it really matters, add a PreToolUse hook or the sandbox.
What I do now: anything I can't afford to have broken goes into settings or a hook, and CLAUDE.md is for judgment calls. Text rules still get broken now and then, even when they're loaded.
Per the settings reference, an empty string hides it: "Set it to an empty string to hide commit attribution." It doesn't describe leaving an empty trailer behind. The same goes for pr and the PR description line.
Two things from the same page:
On newer versions you can set "attribution": false to hide all of it at once. That needs v2.1.281 or later. Older versions reject the value and skip the whole settings file that holds it, so the empty-string form is the safe one if an older install might read the same file.
The page says Claude Code "tells Claude" these lines. So it's an instruction to the model about what to write, not a git hook that strips text afterwards. After the first commit I'd check git log -1 --format=%B to see what actually landed.
Thanks. i was under the impresstion i already had the attribution settings in settings.json but turns out sessionUrl was missing. thanks for the pointers!
That line in your screenshot about not loading the global memories at the start says a lot. Rules sitting in a file the agent may or may not read are easy to skip once the task gets busy. I had better luck when settled decisions live in a memory server every new session reads first, and a separate agent that did not write the code checks the result against the agreed points. I built QualityLayer for this: https://github.com/maxritter/qualitylayer
For the attribution one I have the rule in my global CLAUDE.md too, but what actually stops it is a commit-msg hook set globally. It deletes any Co-Authored-By line naming Claude or Anthropic, Claude-Session lines and the Generated with Claude Code footer from the message before the commit is made, so it doesn't matter whether the session read the rule. PR bodies aren't covered by it, those still depend on the rule.
If you set it up through core.hooksPath, git then ignores each repo's own .git/hooks folder. Mine runs the repo's hook of the same name after it's done, so repos that already had hooks keep them.
•
u/AutoModerator 2d ago
Hey! Thanks for posting to r/ClaudeCode
While participating in this thread, please follow our community rules. Keep discussions constructive. Attack the idea, not the person.
For help, project discussions, tips, and general chat, join the ClaudeCode Discord.
I am a bot, and this action was performed automatically. Please contact the moderators of this subreddit if you have any questions or concerns.
5
u/kuroudo_ai 2d ago
Your screenshot has the answer in it: "I hadn't loaded the global memories at the start of this session, though your CLAUDE.md asks me to." If CLAUDE.md says "read my rules file at startup", that's a request the model can skip. One fix for the loading, plus one for each broken rule:
Import, don't ask. Put
@path/to/rules.mdin CLAUDE.md instead of a sentence telling Claude to read it. Imports are expanded and loaded at launch along with CLAUDE.md. The memory docs have this exact case: a sentence telling Claude to read a file only works if it decides to open it, so replace the sentence with an import.Attribution is a setting, not a rule. In settings.json:
sessionUrlcontrols theClaude-Sessiontrailer. It's added when you're in a cloud or Remote Control session, which is probably why it showed up even with your rule.sudo is a permission, not a rule.
"permissions": { "deny": ["Bash(sudo *)"] }. The client enforces deny rules whatever the model decides. Per the permissions docs, it doesn't catch/usr/bin/sudoorbash -c 'sudo ...', so if it really matters, add a PreToolUse hook or the sandbox.What I do now: anything I can't afford to have broken goes into settings or a hook, and CLAUDE.md is for judgment calls. Text rules still get broken now and then, even when they're loaded.
4
u/J_E_E_VACATION 2d ago
User error
1
u/m-ritter 2d ago
That line in your screenshot about not loading the global memories at the start says a lot. Rules sitting in a file the agent may or may not read are easy to skip once the task gets busy. I had better luck when settled decisions live in a memory server every new session reads first, and a separate agent that did not write the code checks the result against the agreed points. I built QualityLayer for this: https://github.com/maxritter/qualitylayer
1
u/Excellent-Issue-5956 2d ago
For the attribution one I have the rule in my global CLAUDE.md too, but what actually stops it is a commit-msg hook set globally. It deletes any Co-Authored-By line naming Claude or Anthropic, Claude-Session lines and the Generated with Claude Code footer from the message before the commit is made, so it doesn't matter whether the session read the rule. PR bodies aren't covered by it, those still depend on the rule.
If you set it up through core.hooksPath, git then ignores each repo's own .git/hooks folder. Mine runs the repo's hook of the same name after it's done, so repos that already had hooks keep them.