# Offline Work and Reproducibility *Git's killer feature is not branching. It is that you can check out a commit from 2014 and the code still builds. Aura preserves that.* > "A distributed version control system gives me exact history, reproducible states, and `git bisect`. I am not trading those for anything." ## The Concern Any system that leans on real-time synchronization, peer-to-peer collaboration, or "the latest state is the state" is implicitly threatening reproducibility. If I need to check out a specific version of the code — the commit that shipped to production last Tuesday, the revision my auditor reviewed, the state of the repo when the incident happened — I need that to be a deterministic operation. I need to get exactly those bytes, with exactly that history, regardless of who is online and what the Mothership thinks is current. Git gives me that. A commit hash is a cryptographic commitment to a tree of content. `git checkout abc123` produces the same bytes today, tomorrow, and ten years from now as long as someone has the pack. `git bisect` walks history deterministically. Blame works across decades. None of this depends on a server being up, a peer being reachable, or a consensus protocol agreeing. If Aura is a P2P, live-sync, semantic-graph thing, the natural question is: does it preserve these properties, or does it silently erode them? ## How Aura Handles It The short answer: in the default (Git-compatible) mode, Git remains the source of truth for history and reproducibility. Aura is a semantic layer on top. You do not lose anything Git gives you. In the opt-in standalone mode (`aura init --no-git`), Aura implements its own content-addressed store with similar guarantees, plus a write-ahead log for offline work. We'll walk through both. ### Default mode: Git under the hood When Aura is initialized inside a Git repository, every operation that mutates state mirrors a Git operation: | Aura operation | Git operation executed | |---|---| | `aura save "msg"` | `git add -u && git commit -m "msg"` | | `aura push` | `git push` | | `aura pull` | `git pull` + semantic backfill | | `aura checkout ` | `git checkout ` + semantic load | | `aura merge ` | `git merge` + AST-aware conflict layer | This means: - Every state your team has ever committed is a real Git commit with a real SHA. - `git log`, `git show`, `git bisect`, `git blame`, `git reflog` all work unchanged. - `git checkout ` produces exactly the bytes that commit pointed to, independent of Aura. - If Aura is uninstalled tomorrow, your Git history is untouched and complete. Aura's semantic store (the AST graph, intent logs, impact edges) is derived data. It sits in `.aura/` alongside `.git/`. If `.aura/` is deleted, you lose the semantic state but keep all your code and all your Git history. `aura init` rebuilds `.aura/` from Git history. This is a deliberate architecture choice. Derived data is recomputable. Primary data is not. We put all primary data in Git. ### Live sync does not bypass history A natural worry: if [live sync](/live-sync-overview) broadcasts function updates between peers every five seconds, does that mean my teammate's machine has code that was never committed? And if so, is that a reproducibility hole? Answer: yes, live sync can broadcast uncommitted work — that is the point, you see what your teammate is working on before they commit. But that work lands in their working tree and **their** semantic cache, not in their Git history. When your teammate commits, the normal `git commit` path runs. The commit contains exactly the state of their working tree at commit time. Your live-sync updates are not automatically squashed into anyone's Git history. The distinction: live sync is ambient awareness. Git is the record. They operate at different levels and do not contaminate each other. ### Intent logs are first-class history Aura adds one thing that Git does not track natively: [intent logs](/intent-tracking). These are structured records of the stated purpose of each commit, attached to the commit by content-addressed hash. Intent logs are stored in `.aura/intent_log.jsonl` and committed alongside the code. They are reproducible in the same way the code is — a given commit hash always has the same intent record, because the intent is part of the commit. See [first commit with intent](/first-commit-with-intent). This means you can `git checkout` a commit from six months ago and still see exactly what the author said they intended to do. The intent log does not drift. It is pinned to the Git SHA. ### Offline work In default mode, offline work is what Git does. You commit locally. You push when you reconnect. Aura's [live sync](/live-sync-overview) queues function updates while offline and replays them on reconnect, but those updates are not the source of truth — your local Git commits are. Nothing breaks if you are offline for a week. The only thing that requires connectivity is the "ambient awareness" layer — seeing teammate activity, receiving [impact alerts](/impact-alerts) in real time. Those recover on reconnect. Your work continues uninterrupted. ### Standalone mode (opt-in) `aura init --no-git` creates a repository that does not use Git at all. Aura provides its own: - **Content-addressed object store.** Every function body, file, and tree is stored by the hash of its contents. Same guarantee as Git's object store: given a hash, you get exactly those bytes. - **Commit DAG.** Commits point to parent commits by hash. History is a Merkle DAG, same structural property as Git. - **Write-ahead log (WAL).** Every local operation is written to a durable log before being applied. If a process crashes or a peer disconnects mid-sync, the WAL is replayed on restart. This is how Aura guarantees offline work does not lose state. - **Reconcile on reconnect.** When a standalone Aura client comes back online, it syncs with the [Mothership](/mothership-overview) via a pull protocol that deterministically reconciles local commits with remote commits. Standalone mode is a complete VCS. It is not as battle-tested as Git. We recommend it only for greenfield projects or teams with a specific reason not to use Git. See [when not to use Aura](/when-not-to-use-aura). ### `aura bisect` For those coming from `git bisect`: Aura inherits it in default mode. `git bisect` walks the Git commit graph; it does not know about Aura's semantic layer, but that is fine because the commits are real Git commits. In standalone mode, `aura bisect` is available and behaves the same way: mark good and bad, Aura walks the commit DAG, produces candidate commits for you to test. The algorithm is identical. The implementation is ours. ### Determinism of builds A common worry: does Aura interfere with reproducible builds? Do I need Aura installed to build the project? No. Aura is orthogonal to your build system. Your `cargo build`, `go build`, `npm run build`, `bazel build`, `nix build` all work without Aura. The repository on disk is a normal repository — Git or otherwise — and your build tool does not know or care that Aura is watching. If your build pipeline does invoke Aura (for example, running `aura prove` in CI to verify semantic goals), that step is optional and composes with the rest of your pipeline. See [CI/CD integration](/ci-cd-integration). ## Blame Across Decades Git's `git blame` walks the history of a file line by line. It works on repos that are twenty years old. Aura preserves this in default mode because the Git history is intact. Aura adds a complementary tool: [`aura trace`](/aura-trace). It walks the history of a function by semantic identity, following renames, moves, and signature changes that line-based blame loses. If `compute_tax` was renamed to `calculate_tax` three years ago and moved to a different file, `git blame` loses the thread; `aura trace` follows it. Neither tool is strictly better. They answer different questions. Use Git blame for "who wrote this line and when." Use Aura trace for "who has modified this function over its lifetime." ## What Aura Does Not Solve **Reproducibility of binary dependencies.** If your build pulls `npm install` with a floating version, your build is not reproducible. Aura does not fix that. Use lockfiles, `nix`, Bazel, or Docker images pinned by digest. Aura is orthogonal to these concerns. **Time-travel debugging.** Checking out an old commit gives you the code, not the runtime state. Aura does not record runtime state. Tools like rr and Pernosco do that; Aura does not duplicate them. **Auditor tooling for standalone mode.** Auditors are comfortable with Git. They have scripts, tooling, and mental models for Git. If your compliance process depends on auditor-side Git tooling, do not adopt standalone mode. The Git-compatible default is what you want. See [regulated environments](/regulated-environments). **Very long-lived branches that predate Aura.** If you have a feature branch that has been open for two years on plain Git, `aura init` will backfill semantic state from Git history, but function identity on heavily-renamed code may be ambiguous. See [migration reality check](/migration-reality-check). The Git history itself is perfect; the Aura-derived semantic graph may have gaps. **Exactly reproducing a live-sync session.** Live sync is ephemeral by design. If two peers synced function drafts that never made it into commits, those drafts are not part of anyone's permanent history. This is intentional — we do not want to pollute history with every in-progress keystroke — but it means you cannot replay a live session deterministically. Commits are the permanent record; live sync is the conversation. ## The Honest Tradeoff In default mode, there is almost no tradeoff against Git for reproducibility. You keep everything Git gives you and add a semantic layer on top. The cost is disk space for `.aura/` (typically a small fraction of `.git/`) and CPU for maintaining the semantic graph (a background task, not in the hot path of commits). In standalone mode, the tradeoff is real. You are trusting a newer implementation of the core VCS invariants. Our implementation is careful and well-tested, but it has not yet survived twenty years of every codebase in the world. We are comfortable using it; we understand if you are not. The default is Git-compatible for that reason. The deeper tradeoff: any system that adds real-time features adds complexity that did not exist in plain Git. Aura tries to keep that complexity cleanly separated from the record-of-truth layer. We think we have succeeded. A skeptic who evaluates this should look at exactly where the seams are between "Git is authoritative" and "Aura is computing derived state." Those seams are where bugs live, and we audit them carefully. ## See Also - [Aura is not a Git killer](/aura-is-not-a-git-killer) — the architectural stance - [Intent tracking](/intent-tracking) — the one thing Aura adds to history - [aura trace](/aura-trace) — semantic-identity blame - [Live sync](/live-sync-overview) — the ephemeral layer - [Mothership](/mothership-overview) — the sync server in P2P mode - [Migration reality check](/migration-reality-check) — bringing legacy repos in