# Shadow Branches *Parallel semantic history that mirrors git without polluting it.* Aura is not a replacement for Git. It runs alongside Git. Your `main` branch is still a git branch; your `feat/auth` is still a git branch; `git log`, `git push`, `git pull` still work the way they always did. Every tool and CI script that understands Git continues to function unchanged. What Aura adds is a second layer of history kept in a *shadow branch* — a parallel record that mirrors your git branches, one-for-one, but records changes at the semantic level. The git branch records commits as snapshots of the filesystem. The shadow branch records commits as operations on the AST. > Your git history is what you shipped. Your shadow history is what it meant. ## Why a shadow, not a replacement Replacing Git is not a realistic proposition. Git is the interchange format for software in 2026. GitHub, GitLab, CI, deploy tooling, package registries — all of them speak Git. Any new tool that refuses to play nicely with Git is a tool that never gets adopted. A shadow layer is the right shape. It gives up nothing: every git operation still works. And it adds what Git cannot: semantic identity, intent, rename-proofing, AST merge, surgical rewind. The shadow is the place where those things live. ## Location and shape Aura's shadow state is stored in `.aura/shadow/` at the root of your repository. It is tracked separately from git, by design — you do not commit shadow data to git, and git does not know about it. It is synchronized by Aura's own mechanisms (including [live sync](/intent-tracking) for teams on the mothership). The contents, at a conceptual level: - A set of shadow branches, one per git branch, with matching names. - For each shadow branch, a log of semantic commits — each linked to a git commit by SHA. - For each semantic commit: the AST delta, the intent, the verdict, the session metadata, the author, the timestamp. - A store of [content-addressed logic nodes](/content-addressed-logic) — the actual function bodies and related AST fragments, addressed by hash. - Snapshots, session records, impact alerts, and other ancillary state. Each git commit has a matching shadow commit. When you run `git commit`, Aura's hook writes a shadow commit. When you merge or rebase in git, the shadow mirrors the operation at the AST level. The two histories stay in lockstep. ## How shadow commits differ from git commits A git commit is a snapshot of files. It says: "at this point in time, these files contained these bytes." A shadow commit is a set of operations. It says: "at this point in time, the program changed in the following structural ways." Then it references the relevant content hashes. ```json { "shadow_id": "s_9f42a1", "git_sha": "7c9f21ab...", "intent": "Refactored retry_logic to use exponential backoff", "operations": [ { "op": "modify", "node": "fn:retry_logic@v3", "prev": "fn:retry_logic@v2" }, { "op": "add", "node": "fn:exponential_interval@v1" } ], "verdict": "consistent", "author": "ashiq", "session": "sess_2026_04_20_1837" } ``` The shadow is a log of meaning, not a log of bytes. It can be read backward to answer questions a git log cannot: "when was this function last changed?" regardless of renames; "who wrote the current version of this function?" across file moves; "what was the intent of every change to this module?" ## One-to-one with git branches Every git branch has a shadow counterpart. Create `feat/auth` in git, and Aura creates a `feat/auth` shadow. Delete a git branch, and its shadow is archived. Rename a git branch, and its shadow follows. This mirroring is deliberate. The shadow is never ahead of or behind git in terms of *which branches exist*. It differs only in the kind of history it records for each branch. | Git | Shadow | |---|---| | Branch is a pointer to a commit | Shadow branch is a pointer to a semantic commit | | Commit is a tree of blobs | Shadow commit is a set of AST operations | | Merge is a text-level merge | Shadow merge is an [AST merge](/ast-merge) | | Rebase rewrites commit chain | Shadow rebase rewrites operations | | Cherry-pick picks a commit | Shadow cherry-pick replays operations | | `git log` shows commit messages | Shadow log shows intents + diffs | ## How the shadow stays in sync When you run a git operation, Aura's hooks and tooling keep the shadow coherent. The hook points: - **pre-commit** — stages a shadow commit, computes the AST diff, runs the [intent check](/pre-commit-hook-explained). - **post-commit** — finalizes the shadow commit, linking it to the new git SHA. - **post-merge** — records the shadow merge, running an AST merge to populate operations. - **post-rewrite** (rebase, amend) — updates shadow history to match the rewritten git history, preserving semantic continuity. - **post-checkout** — points the shadow HEAD at the matching shadow branch. When the hooks are installed correctly, the shadow is transparent. When they are not, `aura doctor` notices the drift and offers to repair. ## Why not just put it in git? The natural question: if shadow data is so valuable, why not just commit it to git? Store `.aura/shadow/` in the tree? Several reasons: - **It would bloat every repo.** Shadow data for a large codebase is substantial. Putting it in git history means every clone carries every version of every AST node. - **It would merge conflict constantly.** Shadow data is machine-generated; two developers working in parallel produce divergent shadow states. Merging them as text is a disaster. Merging them semantically is what Aura does — but that requires Aura to own the storage, not git. - **It would couple tool upgrades to history rewrites.** If the shadow format changes (and it will), you would have to rewrite git history to update. With the shadow outside git, you upgrade the shadow in place, without touching git at all. - **It would force every collaborator to use Aura.** Some teammates may not. They can still use git normally; the shadow is maintained by whoever runs Aura. The team gets the benefit wherever it is installed, without a mandate everywhere. The shadow is *derived* state. It is computed from the code and the intents; in principle, it can always be recomputed. Treating it as derived, not source-of-truth, is what makes it durable. ## Shadow sharing and team sync On solo projects, the shadow lives in `.aura/shadow/` and is not synchronized. On team projects, Aura offers synchronization through the mothership: your shadow is pushed to a shared service, teammates pull the pieces they need, and the team gets a coherent view of semantic history. Team sync is what makes cross-branch impact alerts possible — your teammate on `feat/payments` modifies a function you depend on, and Aura tells you because the shadow knows the function identity across branches. This is discussed under live sync; the foundation is the shadow. ## Shadow rewind Because the shadow records operations, not snapshots, rewinding is an operation on operations. `aura rewind fn:retry_logic` finds the last state of `retry_logic` before the current commit and applies the inverse operation — restoring the function without touching anything else. Git has no equivalent: `git revert` undoes whole commits, `git checkout -- path` undoes whole files, and neither targets a function. The shadow is what makes surgical rewind possible. It is also what makes [session-level rewind](/session-model) possible: the session references its shadow commits, and the session can be rewound as a coherent unit. ## Corruption and repair Because the shadow is derived, it can always be rebuilt. `aura doctor` detects shadow inconsistencies — missing commits, orphaned nodes, stale references — and offers to rebuild from git history. The rebuild reparses the relevant files, recomputes hashes, and replays the semantic diffs. This is a guarantee worth naming. If the shadow is ever corrupted, you lose nothing that git did not already have. Intent history and verdicts are the one thing that cannot be rebuilt — they are stored durably and backed up to the mothership when enabled. ## The mental model Think of your repository as having two parallel histories: - The **git history** — what files existed at each point in time. Byte-accurate, universal, understood by every tool. - The **shadow history** — what the program meant at each point in time. Structurally accurate, understood by Aura and by any tool that speaks Aura's API. When you run a Git command, you see the first. When you run an Aura command, you see the second. They reference the same commits, the same branches, the same changes — but through different lenses. Neither is the "real" history; both are views of the same underlying work. The shadow is where Aura's power lives. Every other concept — [semantic diff](/semantic-diff), [intent tracking](/intent-tracking), [rename-proof identity](/rename-proof-identity), [session rewind](/session-model) — either writes to the shadow or reads from it. Without the shadow, Aura would be a set of diagnostic tools. With the shadow, it is a version control system in its own right. ## Related The shadow stores commits as semantic operations; the operations themselves are defined by [semantic diff](/semantic-diff). Shadow nodes are addressed by their [content hash](/content-addressed-logic). Shadow merges are [AST merges](/ast-merge).