Claude Code changed files without asking: what git diff can't show you
6m read time

Claude Code changed files without asking: what git diff can't show you

Since auto mode became the default, an agent that asks before it edits is the exception by design. The final diff shows where the session ended up. It cannot show which changes were put to you, which ran in a subagent, or which work was done and undone before you looked.

Five prompts, two minutes, one small checkout module. At the end, git diff looks like this:

text
 src/cart.ts     | 8 ++++++--
 src/checkout.ts | 3 +++
 2 files changed, 9 insertions(+), 2 deletions(-)

Nine lines. An email check, a discount code. You could review that over a coffee.

It is also a fraction of what happened. Claude Code made eight changes in that session. Not one of them was put to me as a decision.

Two were made by a subagent whose edits never appeared in my conversation, only its summary did. And three changes were written, then overwritten or reverted, before the session ended, so the diff has no trace of them at all.

This is a staged session, built for this post in a throwaway repository. Everything that follows is what a normal session already does.

Five prompts on a timeline: eight edits to two files, three undone, two by a subagent, ending in a +9 -2 diff

The case for not being asked ​

Auto mode is the built-in starting permission mode for interactive sessions since Claude Code 2.1.283. A second model, the classifier, reviews actions instead of you. Before that, plenty of people ran acceptEdits all day, because a prompt on every edit trains you to press Enter without reading.

That trade is a good one. Being asked forty times an hour makes the asking worthless, and the classifier still stops the actions that can do real damage. I run auto mode and have no plans to go back.

What the trade costs is less obvious. The permission prompt was also your record. Every edit you approved was an edit you had, at least in principle, seen. Remove the prompt and that record goes with it, and the final diff becomes the only account of the session you will ever read.

Three ways a change reaches your tree ​

Every file change Claude Code makes through its editing tools arrives by one of three routes:

  • Decided: the prompt it came from was submitted in a mode where Claude Code stops and asks first, Manual (still default in config) or plan.
  • Auto: submitted under acceptEdits, auto or bypassPermissions. Applied without asking.
  • Subagent: applied inside a subagent. The subagent works in its own context and, as the subagent docs put it, "returns only the summary". The diff stays in its own transcript.

The subagent route has a second edge. The checkpointing docs say Claude Code "usually doesn't capture those edits in your session's checkpoints". Rewinding restores the files Claude had already edited in your own conversation, and a subagent's edits to anything else stay where they are.

Git sees all three routes as one thing: lines that changed.

What disappears between prompts ​

The final diff is a snapshot. It shows the last state of each file and nothing about how the file got there. That is fine for code you wrote, because you remember the detours. It is a problem for a session you did not watch, because the detours are where the surprises live.

In the staged session, prompt 1 asked for email validation and got a strict check. Prompt 4 asked for a looser one, and the strict version was overwritten. Prompt 3 added a receipt mail, prompt 5 asked for it to be undone, and the edit was reverted. All of that was requested, so here it is harmless.

Now picture the same shape when nobody asked. A fix applied at 19:02 is overwritten at 19:41 by a later turn working on something else. The bug comes back, the diff looks clean, and the one artefact that knows what happened is a JSONL file in ~/.claude/projects that nobody opens.

Minos: reading the session instead of the tree ​

Minos is a tool I built for this question. It reads the Claude Code transcripts that are already on your disk and rebuilds what a session changed, by which route, and what did not survive. It records nothing of its own while you work, because the transcript already holds everything, so it also answers for sessions that happened before you installed it, for as long as Claude Code keeps their transcripts.

For the staged session, minos report prints this (trimmed):

text
CHANGED  2 files, 8 changes, +25 / -18

  decided       0 changes  +   0  -   0   you were asked before it was applied
  auto          6 changes  +  15  -  12   acceptEdits or auto, no prompt
  subagent      2 changes  +  10  -   6   applied inside a subagent, never rendered

UNDONE  3 changes did not survive the session

  src/checkout.ts   overwritten  22:50  prompt 1  to 22:51  prompt 4
  src/checkout.ts   reverted     22:51  prompt 3  to 22:52  prompt 5
  src/checkout.ts   overwritten  22:51  prompt 3  to 22:52  prompt 5

The diff said nine lines in two files. The session says eight changes, of which the discount code in src/cart.ts came from a subagent. That is the part I would read first, because it is the part I never saw. It throws on an unknown code, and that is a checkout behaviour nobody decided on.

minos file src/checkout.ts lists every operation on one file in order, with the prompt behind each. minos undone gives you the lost changes on their own. minos sessions --all puts every project on the machine in one table, for a date window you choose.

Minos is pre-release and installs from its repository or the plugin marketplace. Inside Claude Code, /minos:report prints the report for the session you are in, and /minos opens a pane beside the chat that keeps the same account up to date as you work.

What it cannot see ​

A tool that implies it knows more than it does is worse than none, so the limits are part of the design.

  • decided is read off the permission mode, not off an approval. Nothing on your machine records that you read a prompt. A standing allow rule can mean a default turn put nothing on screen at all, and Minos says so under its own figures.
  • Only Edit, Write and NotebookEdit are counted. A file rewritten by sed -i, a redirect or an MCP server leaves no edit to read. Minos counts shell commands that look like writes as a separate, loose heuristic and keeps them out of the three classes.
  • Undone detection works on the text of the changes. Treat a finding as a strong indication and check it in the file.
  • History is finite. Claude Code deletes transcripts after cleanupPeriodDays, 30 days by default.

What to do with it ​

The routes are worth handling differently, because they fail differently.

  • Read the subagent changes separately. They are the ones that never reached your conversation and that a rewind may leave behind. When a subagent's job is to write code, a fork can be pointed at its own git worktree with isolation: "worktree", so its edits arrive as a branch you review instead of changes in your checkout.
  • Check what was undone before you commit. An overwritten fix is the cheapest bug you will ever catch, as long as you catch it before the session's transcript is the only place it exists.
  • Keep reviewing the diff. Minos tells you where to look. Whether the code is right is still decided by reviewing what an agent wrote, and that stays your job.

The nine-line diff from the top was accurate about where the session ended up. What the session did on the way to get there is in the transcript.