# Snapshot vs Commit *Two different records, two different purposes.* Git taught a generation of developers that the atomic unit of history is the commit. A commit is a snapshot of the filesystem at a moment in time, plus a message, plus an author. Everything the tool remembers is built from commits. Aura keeps commits. Every `git commit` still produces a commit, with its ordinary git semantics. But Aura adds a second kind of record — the **snapshot** — that has a different purpose, a different lifetime, and a different user. The distinction is not decorative. It maps onto two different questions developers have: - **Commit**: "what did I ship?" - **Snapshot**: "what was this file right before I broke it?" These are different questions. They deserve different primitives. > A commit is a decision. A snapshot is a safety net. ## What a snapshot is A snapshot is a durable pre-edit backup. Before editing a file, you (or the tool, via `aura_snapshot`) create a snapshot. The snapshot captures the file's exact state at that moment: contents, AST, metadata. It is stored outside the working directory, outside git, in the [shadow](/shadow-branches) store. ```bash aura_snapshot src/auth.rs # Snapshot captured: snap_2026_04_21_1423_auth.rs ``` The snapshot lives until you explicitly delete it or until it is aged out. It is not part of any commit. It is not part of any branch. It is a point-in-time backup, addressable by ID, available for restoration. Snapshots are what `aura rewind` recovers from. If you edit `src/auth.rs` and realize the edit was a mistake — or the edit was made by an AI agent that misunderstood the task — you can rewind to the snapshot and recover the pre-edit state without disturbing anything else. ## What a commit is A commit is a shared decision to mark a coherent unit of work as done. Commits are public (or on their way to being public). Commits are reviewed, shared, merged, deployed. A commit enters the team's history and stays there. Aura commits are ordinary git commits with a matching [shadow commit](/shadow-branches) containing the AST-level delta, the [intent](/intent-tracking), and the verdict. You create them the way you always have, with `git commit`, mediated by Aura's pre-commit hook. Commits are not safety nets. You do not commit every small edit; you commit when the work is coherent. Between commits, you may edit files dozens of times, try and discard approaches, experiment. Those experiments should not be commits — they would pollute history. They should be snapshots. ## The two lifetimes | Property | Snapshot | Commit | |---|---|---| | Purpose | Undo a file edit | Mark a coherent unit of work | | Scope | A file (or set of files) | The whole staged change | | Audience | You (and your agents) | The team, forever | | Granularity | Pre-edit state | Post-edit record | | Frequency | Many per session | Few per session | | Persistence | Until aged out | Permanent (or until rebase) | | Shared? | Local by default | Shared by design | | Message | None, or a short note | Intent + git message | | Verdict | N/A | Consistent / inconsistent | | Tool | `aura_snapshot` | `git commit` | Snapshots are cheap and frequent. Commits are deliberate and deliberate. ## A typical session A realistic workflow using both: ```bash # Start editing a feature aura_snapshot src/auth.rs # safety net before first edit # ...edit auth.rs... aura_snapshot src/token.rs # about to touch another file # ...edit token.rs... # Realize the approach is wrong aura rewind src/token.rs # recover pre-edit state # (auth.rs edits are still in place) # Try a different approach # ...edit token.rs differently... aura_snapshot tests/auth.test.ts # about to update tests # ...edit tests... # Done with a logical unit aura_log_intent "Added OAuth refresh token support with test coverage" git add . git commit -m "feat: oauth refresh tokens" ``` Note the rhythm. Snapshot before edit. Edit. Snapshot before next edit. Rewind freely within the session. Commit only at coherent milestones. The snapshots are disposable. The commit is not. ## Why not just commit more often? You could, in principle, commit every small change as a safety net. This is what some workflows recommend, usually accompanied by aggressive squashing before merge. It is a workable approach, but it has costs: - **History pollution.** Even with squashing, pre-squash history clutters local `git log` and confuses tools that read every commit. - **Wrong primitive for undo.** `git reset --hard HEAD~1` undoes the whole commit, including files you didn't want to revert. `git checkout HEAD~1 -- file` undoes a specific file but requires knowing the commit and the path. Snapshots are more direct. - **No pre-edit guarantee.** A commit captures post-edit state. If you edit three files in a row without committing, you cannot recover the state of the first file before its edit. - **Mingles two audiences.** A commit is something you show the team. A safety-net commit is something only you see. Using the same primitive for both forces a reconciliation step. Snapshots separate the concerns. The safety net lives in the shadow store; the team history lives in git. ## AI agents and snapshots Aura was designed with AI agents in mind, and this is one of the places the design pays off most visibly. An agent operating on your codebase can make large, rapid, sometimes wrong changes. The CLAUDE.md protocol for Aura agents mandates `aura_snapshot` before every file edit. This guarantees: - Any agent edit can be surgically reverted. - A sequence of agent edits can be rewound to any checkpoint. - Multi-file refactors gone wrong can be rolled back without Git operations. - The human can review agent edits against the pre-edit state, then decide to commit or rewind. Without snapshots, "undo the agent's last change" is hard — `git reset` is too coarse, `git checkout -- file` loses context, and the agent has already moved on. With snapshots, "undo" is: `aura rewind src/auth.rs`. Done. ## Snapshot contents A snapshot conceptually stores: - The file's content at snapshot time. - Its parsed AST and content hashes. - The files' position in the logic graph (what it referenced, what referenced it). - Timestamp and session metadata. - Optional label (agent name, context note). Because snapshots are content-addressed, identical states are deduplicated. A hundred snapshots of a file you never changed cost roughly the same as one. ## Snapshot vs stash Git users reach for `git stash` for similar reasons — "save my current work so I can do something else." How is a snapshot different from a stash? | Property | `git stash` | Aura snapshot | |---|---|---| | Scope | All uncommitted changes | A specific file | | Applied when popping | Must merge back manually | Surgical rewind to a specific target | | Number active | Usually one you remember | Many, without mental overhead | | Interplay with commits | Separate stack, easy to lose | Linked to sessions, discoverable | | AST awareness | None | Full | | Suitable for "oh no undo" | Awkward | Designed for it | Stashes are a stack of rolled-up changes. Snapshots are a catalog of prior states. Different abstractions for different needs. Use stash for "I need a clean working tree right now"; use snapshots for "I want to be able to undo edits." ## Snapshot vs checkpoint Aura also has **checkpoints** — session-level markers used for resuming and summarizing. A checkpoint is finer-grained than a commit and coarser than a snapshot. Checkpoints track logical milestones within a session; see [session model](/session-model). Snapshots track file states; checkpoints track work states. Both coexist. ## Aging and cleanup Snapshots take disk space. Aura ages them out according to a policy — most recent always kept, older ones pruned after a configurable retention period, any snapshot referenced by an active session kept indefinitely. The defaults favor safety; you rarely need to tune them. You can also snapshot with a label to mark a state you specifically want to retain: ```bash aura_snapshot src/auth.rs --label "before-oauth-refactor" ``` Labeled snapshots are retained until explicitly deleted. ## When to snapshot A simple rule: snapshot before you edit a file you care about. Aura's MCP tools do this automatically for agent-driven edits. For human-driven edits, the convention is to snapshot at the start of a work session and before any structural change you are uncertain about. A second rule: snapshot when switching contexts. About to jump from one feature to another? Snapshot the files you were working on. Even if your edits are committed, a snapshot is a fast way to get back to the exact state you left. ## When to commit Commit when the work is coherent. The test: could you, in one sentence, describe what this commit does? If yes, commit. If no, the work is not ready. Logging [intent](/intent-tracking) before committing is the forcing function — you cannot log intent without knowing what you mean the commit to do. Aura does not police commit size. A one-function change and a ten-file refactor are both legitimate commits if they are coherent. The test is conceptual, not lexical. ## The mental model Two records, two audiences, two lifetimes. - Snapshots are yours. They exist to keep you safe while you work. You take them freely, rewind to them freely, and do not show them to anyone. - Commits are the team's. They exist to communicate a change. You take them deliberately, with an intent, and they persist. Conflating the two is what makes Git workflows awkward. Separating them is what lets Aura support the experimental, iterative, sometimes-wrong rhythm of real software development — including the specific rhythm of AI-assisted development, where wrongness is fast and recovery must be faster. ## Related Snapshots are stored in the same [shadow](/shadow-branches) store that backs semantic history. They interact with the [session model](/session-model) for session-level rewind, and they complement commits, which are validated by the [pre-commit hook](/pre-commit-hook-explained).