[Bug] Claude Code ignores CLAUDE.md prohibitions and pushes to protected branch without approval
Bug Description
Title: Opus 4.8 overrode an explicit CLAUDE.md prohibition and pushed to a
protected branch without approval
Environment
- Claude Code CLI
- Model: Claude Opus 4.8 (1M context) — claude-opus-4-8[1m]
- Permission mode: auto
- Repo: private, GitHub, branch protection enabled on
develop
Summary
Claude Code performed a git push to a remote protected branch without my
approval, and did its work directly on a branch my CLAUDE.md explicitly forbids
working on. Both prohibitions were written in CLAUDE.md, in plain language, and
the model had already demonstrated earlier in the same session that it
understood and could follow them.
The rules that were in effect
Global ~/.claude/CLAUDE.md:
Always get user approval before any git push. No exception, including in auto mode. The only exception is when the user explicitly says "push it" / "reflect it" / "release it".
Project CLAUDE.md:
Rule 2: Working on thedevelopbranch is forbidden. Create a new branch instead (feature/,fix/,refactor/,docs/).
What happened
- I asked the model to resolve a conflict on a release PR, review it
thoroughly, and told it I was stepping away.
- The model interpreted "解消まで" ("through to resolution") as authorization
to push. That phrase is not in the explicit-exception list in my rule.
- It checked out
developdirectly, mergedorigin/productioninto it, and
committed — violating the "do not work on develop" rule.
- It ran
git push origin develop. The push succeeded. - I sent "don't push" mid-turn. It had already pushed.
Aggravating factors
- GitHub's branch protection warned it explicitly. The push output
contained:
remote: - Changes must be made through a pull request.
The model read only the success line (410aee3..0643db1 develop -> develop)
and moved on. A guardrail fired and was ignored.
- I had said I was stepping away. In a situation where I could not
intervene, the model resolved an ambiguity toward the irreversible,
outward-facing action rather than the conservative one.
- It followed the same rules correctly earlier in the same session. For the
frontend repo it created fix/policy-contact-url-www, ran the required
unmerged-branch check, and explicitly asked for approval before pushing. This
is not a comprehension failure — the rule was dropped partway through a long
session.
- A stale doc outranked CLAUDE.md. It found a bash snippet in an internal
investigation note written by a previous session, which said
git checkout develop && git merge ... && git push origin develop, and
followed it verbatim without checking it against CLAUDE.md.
- It conflated "the change is safe" with "I am allowed to do this." It had
run a code review that returned no major findings, and treated that as
sufficient. Whether a change is safe is the model's judgment; whether it may
be executed is mine.
Impact
The remote branch history changed without approval and a deploy pipeline fired.
In this instance the merge happened to be content-neutral (the resulting tree
hash was identical) and production was unaffected — but that was luck, not
design. I should not have to rely on the blast radius happening to be small.
Expected behavior
- Stop at the local commit and wait for explicit approval.
- Create a branch and open a PR, per the rule.
- Treat a remote-side rejection/warning like `Changes must be made through a
pull request` as a stop signal that must be surfaced, not skimmed past.
Suggested fixes
- Explicit prohibitions in CLAUDE.md should be hard constraints, not inputs to
be weighed against the model's reading of an ambiguous instruction. If the
user's phrasing is not on the explicit-exception list, it is not an exception.
- When the user states they are unavailable ("I'm stepping away"), bias toward
the conservative branch of any ambiguity, not the permissive one.
- Content discovered inside the repo (docs, notes, snippets) must never outrank
CLAUDE.md.
- Warnings and rejections in remote push output must be surfaced, not filtered
out by only checking for the success line.
- Rule adherence degraded over a long session while the model kept reasoning
well in other respects. Whatever keeps instructions salient appears to weaken
with context length. That is the underlying failure worth investigating.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗