Local first.
Honest limits.
Your code and your save points stay on your computer. Secret values from config files like .env are never stored, only key names and a fingerprint. Nothing is pushed, merged or deployed. And where our protection stops, we say so.
Time Machinerecovery receipt · Marigold Tips
$ tm recover cp-0003
Nothing was pushed, merged or deployed. Your folder and branch were not touched.
Branch
tm/recover/cp-0003
Not restored
Secret values in .env: PORT, STRIPE_SECRET_KEY
Databases, deployed versions and external services are not captured
Manual steps
Set PORT in .env in the recovery copy.
Set STRIPE_SECRET_KEY in .env in the recovery copy.
Key names only for .env values.
From a real tm demo run. The keys are fake.
Six rules the engine keeps.
These are built and tested today, on macOS and Linux CI. They apply to the CLI, the hooks and the MCP server, which all call the same engine.
Local first
The tm tool has no account and no server. Save points, logs, reports and the audit log live on your machine. We cannot see them.
No .env values stored
For config files like .env, only key names and a keyed fingerprint. Files that look like they hold a secret are skipped. Check logs are scrubbed of current secret values.
Signed save points
Each save point and each verdict is signed with a key on your machine. A changed save point gives ERROR, never PASS.
A separate copy
Checks run in a separate Git worktree with a clean environment and a time limit. The network is off when a sandbox can enforce it.
Never pushes, merges or deploys
Recover makes a new branch and a recovery copy. It never switches your folder. Switching is up to you.
Everything is logged
Every action goes in an append-only audit log in the store. Read it with tm log.
Outside your project.
On your machine.
If an agent runs rm -rf on your project, the save points are somewhere else.
~/.timemachine/ or $TM_HOME ├── key signs every save point └── projects/ └── 9f2c41d07a3be815/ hash of the path ├── objects/ files, stored once ├── checkpoints/ signed manifests ├── bundles/ Git bundles ├── logs/ check logs ├── reports/ recovery reports ├── audit.jsonl append only └── project.json
- One folder per project, named by a hash of the project path. A store inside the project is refused.
- Code survives the folder. Each save point is a Git commit pinned at
refs/tm/<id>, and also written as a Git bundle into the store. Deleting your project does not delete its save points. - Files are stored once by content and compressed, so repeats cost nothing. Check disk use with
du -sh ~/.timemachine. - Keep the key.
~/.timemachine/keysigns every save point, so edits by other tools are caught. Save points are not encrypted: anyone who can read your disk can read them.
Key names only.
Never .env values.
After a recovery, you set secret values again by hand. The report lists each one, so nothing is a surprise.
- For files like
.env, Time Machine saves the key names and a keyed fingerprint. The fingerprint shows a value changed, intm diff, without storing it. - Secret files are never saved. Names like
.envfiles (except examples),.npmrc,*.pemand*.keyare skipped, and so is any file whose content matches a secret pattern. Each one is listed. - A tracked file that now holds a secret keeps its last committed version in the save point.
- Check logs are scrubbed of current secret values. The hooks never store prompt text that looks like a secret, holds a current secret value from your config files, or has a URL with a password in it.
- Plain values are opt in. Only keys you list in
config.plainkeep their value, and not even then if the value looks like a secret.
PORT=••••
STRIPE_SECRET_KEY=••••••••
PORT · name only
STRIPE_SECRET_KEY · name only
The values on the left never leave your project folder.
A changed save point fails.
Each save point has one manifest: a JSON file that lists everything it holds. Manifests and verdicts are signed with the key in ~/.timemachine.
A verdict is bound to the exact manifest it was made for, so an old PASS can never stick to a new save point. If a save point was changed after it was saved, its integrity check fails and the verdict is ERROR, not PASS. Save point numbers come from a counter and are never reused.
What the signature does not do
It catches accidental edits, and edits by tools that do not read the key. It does not stop someone who can read ~/.timemachine/key. We do not call it tamper proof.
Network off,
or no check at all.
If you ask for the network to be off and we cannot enforce it, the check does not run. It never quietly runs online instead.
verify, open and find-good work in a separate Git worktree. Your folder and current branch are never touched.
The check gets a clean environment: PATH, HOME, locale, proxy and certificate settings, package manager settings, your config.plain values and CI=1. Nothing else.
With network: deny, the check runs inside a sandbox: sandbox-exec on macOS, bwrap or unshare on Linux. If none is available, the verdict is BLOCKED and tells you how to fix it.
The setup step, like npm ci, always has the network so it can install dependencies. Only the check itself runs offline.
Today this is host mode: a separate copy on your machine, running as you. That is weaker than a container, and every verdict says which mode and network rule it ran with. Container isolation is Planned
network: denysandbox found
$ tm verify cp-0003
PASS cp-0003 works
host mode, network off
The check ran in the sandbox.
network: denyno sandbox
$ tm verify cp-0003
BLOCKED exit 3
The check did not run.
Install bubblewrap, or set allow.
network: allowno sandbox needed
$ tm verify cp-0003
PASS cp-0003 works
host mode, network on, 1.4 s
The verdict says network on.
Flip the switches. A simulation of the rule. It runs nothing.
Never pushes.
Never merges.
Never deploys.
- Your state is saved first. Before a recovery, Time Machine saves where you are now as a new save point, so you can always come back to it.
- A new branch, not your branch. Recover makes
tm/recover/<id>and a recovery copy next to your project. - You decide when to switch. It does not change your folder or your current branch. The report gives you the commands.
- Paths stay inside. Restores never write through a symbolic link, and saved paths must stay inside the project.
Your email and a few facts.
Never your IP address.
The waitlist is the only thing on this site that stores personal data. Here is all of it.
| What we store | Your email, that you ticked the consent box, the page you joined from, the time, your own referral code, and the referral code that brought you, if any. |
|---|---|
| Rate limits | A one-way code made from your IP address, never the IP itself. Codes older than one hour are removed during later requests. |
| What we do not | No IP address, no browser details, no cookies. |
| Where | Its own schema in Supabase, written by one function hosted on Vercel. |
| Who can read it | Row level security is on. The public key can only call three fixed functions and cannot read any table. |
| Logs | The function never logs or echoes your email. |
| No fake success | The form says you are on the list only when the row was saved. If saving fails, it asks you to email us. |
| Deleting it | Email preston@unvibe.site and we delete your row. |
More in the privacy policy, which is a draft pending lawyer review.
Found something?
Tell me first.
Email preston@unvibe.site with Security in the subject. Include what you found, how to reproduce it, and what it affects.
Please do not access other people's data, and give me a fair chance to fix it before you share it publicly. I read every report myself, and every fix starts with a test that shows the bug. There is no bug bounty yet.
What this does not protect.
A safety tool that oversells is worse than none. If you find a limit that is not on this list, tell us.
- Only captured project state. Databases, deployed versions, emails, payments and anything outside your project folder are not captured.
- Host mode is weaker than a container. A check runs as you, on your machine, in a separate copy. Container isolation is Planned.
- The signature is not tamper proof against someone who can read
~/.timemachine/key. - Save points are not encrypted. Anyone who can read your disk can read them.
- Secret detection uses names and patterns. A secret that matches none of them, or one already committed to Git, is saved like any code.
- Setup has the network, even with
network: deny. Only the check runs offline. - A PASS proves your check passed. It does not prove your app is correct. The verdict is only as good as the check.
- Not a disk backup. Keep one.
- No outside security review yet. One is part of why we are raising. Until then, this page is our own account.
- Early software. Not on npm yet. The web app runs from a source install with
tm ui.
Build with
a way back.
We write to the list when the CLI is on npm. Nothing else.