I let an agent edit a private vault in bulk, and a bulk pass fails as a whole. When the pass is wrong, I need the state the vault had before it ran, not a repair in place. My privacy rule forbids that vault’s history from reaching any server, which rules out the obvious answer: a repository hosted elsewhere.
TL;DR
A private vault keeps its own record, on the machine. One local repository per vault, one automatic snapshot committer on a fixed interval and no other, so it only moves forward. No remote is ever configured, and the job alerts if one is. Rollback restores files rather than rewriting commits, and the snapshot after a restore is what turns it into recoverable history.
The constraint: an undo that cannot leave the machine
A bulk edit is one pass across dozens of files. An agent does not mistype a line; it applies a rule to a whole vault, and reversing that is not like fixing a sentence.
What confines that work is the container the agent runs in, not the instruction it was given (the boundary that holds it, and the doors it leaves open).
The privacy rule is what makes this hard. That vault’s history may not reach any server, so a hosted repository, the ordinary way to keep a versioned record, puts the recovery I need exactly where the rule forbids it. Either the undo stays on the machine, or I do not have one.
The decision: one local repository, one committer
Each private vault holds one local git repository, and one automatic snapshot committer writes to it on a fixed interval, and nothing else does. Every 10 minutes it records the tree when it changed: no agent commits there, and I do not either.
The single-committer rule is the whole design. Because that one writer only ever adds, the history moves forward and cannot be rewritten, so an undo can never be confused with a rewrite of what already happened. That is what makes a rollback safe to hand to an agent.
The interval is a frequency, not a schedule, and the job is one more unattended run (automation that runs without being watched).
The guardrail keeps the rule. In a private vault I never run git reset, git checkout <sha>, git rebase, git commit --amend, git revert, or git commit.
Rollback changes files, never the commit graph
Undo in this vault is plain git that changes files only.
- One file restores from a previous state, one path at a time.
- One snapshot reverses the diff it introduced across the whole tree.
Neither writes a commit, so a rollback cannot rewrite a graph later commits already describe.
A restore enters history only once a snapshot records it, and the next snapshot turns the restored files into a new commit. Run the job right after reversing a change: that is what makes a bad restore itself recoverable, because the state you just left is committed like any other.
No remote, ever
A private vault’s local repository carries no remote. Ever. Nothing about the undo adds a place where that vault’s data lives: the repository sits on the machine, the history stays there, and the trust boundary does not move.
Its only off-machine copy is the one the backup already carries, the bundle that goes to Proton Drive. A git remote would have been a second copy in a second trust domain, and that is what the rule prevents.
If a remote is ever configured, the job raises an alert. The failure mode here is quiet: it breaks nothing, it exports the history, and nothing looks wrong until someone checks.
The change check skips the repository, so the undo ships nothing
Committing creates no backup copy. The content hash that decides whether a job writes skips the repository’s own directory, so a snapshot commit on its own ships nothing off the machine, and a job writes only when the content changed.
That is the cost line, and it is zero. The history grows on the machine without adding a copy anywhere else, which keeps the undo cheap enough to run unattended (why a backup set holds a recipe rather than the bytes).
The history starts fresh
The local history was given back on late October. It starts on that date and is deliberately not grafted onto what came before; the older record survives only in the final backup bundles, so the new repository cannot be built on it.
The break is deliberate, not an accident of recovery. The commits after the date of commissioning describe the vault as it now stands, which is what the undo needs.
What broke
Nothing broke in this loop, and I will not turn a clean design into an incident. The four records behind this piece report the same thing: the snapshot arrangement is the design, not a repair.
The friction sits one step back, in a vault that had lost its local record and needed one given back. The two guards answer the two failure modes found there: a commit that rewrites the past, and a remote that exports it. A third, a snapshot job that ships everything by committing, is closed by the change check.
A quiet job is not proof the pattern is exercised, though. An unattended run stays trustworthy only through the discipline around it (daily automation that does not silently break).
What this does not solve
- It is a local undo, not a backup. A repository on the machine cannot survive that machine. It restores a file or a snapshot; it does not put the vault’s content anywhere that outlives the hardware. That is the backup’s job, and a separate pattern (test your backups or they don’t exist).
- It does nothing about the machine itself being lost. The history begins on the machine and ends there, and no part of this pattern changes that.
What it buys is narrow, and worth stating exactly: the undo a bulk agent pass needs, on the machine where the data already lives, with no server in the path (de-risking your digital life).
One qualifier travels with every claim above. The records behind this piece are partial: they narrate the arrangement from my own wiki page, not the code, so what I describe is the design and its rules, not a measured behavior.
If a bulk edit in your own vault has ever left you without an undo, let’s talk about that constraint. Who I am, and how the rest of this stack is built, is on the about page.