There’s a commit on main you didn’t sign off on. Before you rush to revert, here’s how to see exactly what the agent ran, and whether you ever actually approved it.
A push happened. The question is whether it was authorised.
“Never push to main without asking” is one of the most common rules people put in CLAUDE.md — and one of the easiest for an agent to step over when it’s trying to be helpful at the end of a task.
The record of what was actually run, and what you said before it, is in the session transcript. You don’t have to reconstruct it from memory or from git reflog alone.
Find the push, then read backwards for your approval.
Open the session file — Claude Code stores it as one JSON object per line:
~/.claude/projects/<your-project-path>/<session-id>.jsonl
Project folder = your working directory with each / replaced by -; the newest .jsonl is the last session.
git push inside "name":"Bash" tool calls — that’s the exact command the agent ran, and its origin main target."role":"user" messages just before it. Did you say “push,” “ship it,” “go ahead” — or nothing about pushing at all?The catch: in a long session the push and the last relevant instruction can be hundreds of lines apart, and “was this approved?” is a judgement you have to make by re-reading. That’s the part the tool automates.
It finds the push and checks whether anything in the session approved it.
RuleReceipt reads the transcript locally and, for an approval-style rule, looks for the action and for approval ahead of it in the conversation. If the action ran with nothing approving it, that’s a not followed — with the command quoted:
$ npx rulereceipt@latest check RuleReceipt · 51 rules checked ──────────────────────────────────────── Not followed (1) ✕ FAIL Rule 1 — Never push to `main` evidence: a git command actually targeted the "main" branch: git push origin main
Sample output. The verdict points at the real command; you decide if it was a step too far.
The check above is after the fact — it reports, it doesn’t undo. For this specific rule there’s also an optional guard: rulereceipt protect --git installs a local pre-push hook that blocks a push to a protected branch before it leaves your machine.
That guard covers a narrow, specific set of file and branch actions — branch pushes like this one, and a few file edits. It is not general enforcement, and it does not make the model comply; it’s a targeted backstop for exactly the case where “don’t push to main” keeps getting crossed.
RuleReceipt is a free, source-available CLI that checks Claude Code sessions. Run npx rulereceipt@latest check to audit the last session — locally, no account, no upload.