Operating your brain · Guardrail 01
You put your brain in cloud storage so everything syncs. Then you put code in there too. One morning git says the repository is corrupt. Here is why, and the guardrail that turns it into a thirty-second problem.
What actually goes wrong, in plain words, and what "safe" looks like. No setup needed. Start here.
Six steps to install the guardrail in any repo, with a check after each one.
The one rule that makes automatic cleanup safe, and what it deliberately does not solve.
Recovery when it happens anyway, a glossary, and the wider habit this belongs to.
Wherever we name a tool we use, you will see a 🔁 Swap box with alternatives. We are showing you what worked for us, not prescribing it. This problem is identical on OneDrive, Dropbox, Box and iCloud Drive, and the fix is the same.
Almost everyone who builds a Company Brain arrives at the same arrangement, because each step is individually sensible.
Each step is fine. Together they put a database inside a file syncer, and those two disagree about what to do when the same file changes in two places at once.
Your .git folder is a database with strict internal filenames. Cloud storage resolves conflicts by renaming files. When it renames something inside that database, git can no longer find its own history.
A single space in a filename, in the one folder where a space can never legitimately appear.
It rarely announces itself as a sync problem. It shows up as git suddenly behaving as though your project has amnesia.
bad sha1 file, badRefName, or a missing object.The obvious fix is a script that deletes every oddly named file inside .git. Do not do that. Cloud storage sometimes renames the original rather than adding a copy next to it, so those "junk" files can be your only copy of a real git object. Deleting them is what actually destroys the repository. We learned this the expensive way: a cleanup like that removed 29 real objects from one of our repos, and it could no longer rebuild its own history.
The goal is not to prevent this. You cannot, short of moving the code out of cloud storage entirely. The goal is that it becomes boring: caught automatically, impossible to miss, and cheap to undo.
The remote is the source of truth. The synced folder is a replaceable view of it. Nothing irreplaceable ever lives only in that folder.
If that stays true, corruption is an inconvenience. If it stops being true, corruption is data loss. Everything in this guide exists to keep it true.
Roughly twenty minutes for the first repo, about three for every repo after that. Do them in order. Step 1 is the one people skip, and it is the one that prevents actual data loss.
~10 min · do this before touching git
If the repository ever needs to be deleted and re-cloned, anything that exists only in that folder dies with it. That is usually the real loss, not the git history. Ask what is in there that the remote has never seen:
git status --porcelain --ignored | grep '^!!' | sed 's/^!! //' \ | grep -vE '^(dist/|node_modules/|\.git/|build/|target/)' | grep -v '__pycache__'
Sort every result into one of three homes:
| What it is | Where it belongs | Why |
|---|---|---|
| Working documents, client material, invoices, exports | A sibling folder outside the repo | Still syncs, but stops living inside a folder you may have to delete |
| Real project source | Commit it | Then the remote has it, which is the entire safety net |
| Machine-local secrets and config | Leave in place, never commit | Per-machine by design. Write down which ones a new machine needs |
~2 min
Everything below treats the remote as the backup. If there is no remote, or there is work sitting unpushed, fix that first.
git remote -v && git status --short && git log --oneline origin/main..HEADYou'll know it worked when: a remote is listed and the last command prints nothing, meaning the remote has everything you have.
~3 min · copy-paste from the Starter kit below
Put clean-drive-drift.sh and repo-parity-check.sh in scripts/guardrails/, and the four hook files in .githooks/. Both scripts are plain bash and git, with no dependencies to install, so they work for any tool or person. Then activate them:
chmod +x scripts/guardrails/*.sh .githooks/* git config core.hooksPath .githooks
Hooks live in the repo rather than inside .git, which is what lets them travel to every clone and every machine.
git config core.hooksPath prints .githooks.
~4 min
The git hooks already cover everybody, because git runs hooks no matter who invoked the command. This is the extra layer, and it is the one that differs per tool:
SessionStart hook in the project's .claude/settings.json that runs the cleanup and then the parity check.AGENTS.md (Codex, Cursor and friends): they have no session-hook mechanism, so the instruction goes in the file they already read at the start. The block is in the Starter kit.make check or npm script.A repo that documents this in CLAUDE.md but not AGENTS.md is protected for one tool and silently unprotected for every other one. Put the same block in both.
~2 min · do not skip this
Do not assume the install works. Reproduce the exact failure and watch the guardrail handle it. This takes a real git object, renames it the way cloud sync would, and checks that it comes back:
OBJ="$(find .git/objects -type f ! -name '* *' ! -path '*pack*' | head -1)" mv "$OBJ" "$OBJ 2" # simulate the rename scripts/guardrails/clean-drive-drift.sh --fix # must say RESTORED, not removed [ -e "$OBJ" ] && echo "PASS: object restored" || echo "FAIL: object lost" git archive HEAD >/dev/null && echo "PASS: repo intact"
If the script removes that object instead of restoring it, you are running the naive version, and it will eventually delete something real. Stop and re-copy the script from the Starter kit.
restored -> in the output, then both PASS lines.
~2 min
An undocumented guardrail gets bypassed by the next tool, or by you in six weeks. Paste the block from the Starter kit into AGENTS.md and CLAUDE.md. It needs to say three things: run the parity check first every session, never commit a filename ending in a space and a number, and if git reports corruption then stop rather than trying to repair in place.
Four moments, four automatic checks. You never have to remember to run any of them.
You do not have to copy anything out of this page. Everything above ships as one package: the skill, the prompt, the written SOP, the three scripts, and the four hooks.
One folder. Drop it into your agent's skills directory, or just point any tool at it. Plain bash and git, nothing to install.
| Inside the download | What it is |
|---|---|
SKILL.md | The skill itself. An agent reads this and does the whole install, reporting each step. |
PROMPT.md | The same install as a fill-in-the-blanks prompt, for any tool that cannot load skills. |
SOP.md | The written procedure, to drop straight into your own Company Brain. |
scripts/ | The cleaner that restores instead of deleting, the session parity check, and the safe mount reset. |
hooks/ | pre-commit, pre-push, post-merge, post-checkout. These are what cover every tool. |
Unzip it, put the folder where your agent looks for skills, and ask for it by name from inside the repo you want to protect.
Your agent will report each step. Read two of them yourself. Step 1 lists everything in the folder your remote has never seen, which is what dies in a re-clone; decide where those go rather than letting anything move them for you. Step 5 renames a real git object and checks the guardrail puts it back. If it deletes it instead, stop, because that is the version that loses repositories.
The package works fine by hand. SKILL.md carries the same six steps with the exact commands, and SOP.md is the version to keep. It is about three minutes per repo.
.claude/skills/. Alternatively: paste PROMPT.md into Codex, Cursor, Copilot or Aider, or follow SKILL.md yourself at a terminal. The guardrail is plain bash on purpose, so nothing here depends on which tool you run.Prefer just the written procedure? Download the SOP as Markdown on its own.
Optional reading. This is the reasoning that lets a script delete things inside your git database without you watching it.
Git never puts a space in the filenames it creates inside .git. So a spaced name in there is always sync junk, never something git made. That single fact is what makes automation possible at all.
But "it is junk" does not mean "delete it", because there are two very different situations that look identical at a glance:
| What you find inside .git | What actually happened | Correct action |
|---|---|---|
4f9c2e 2 exists, 4f9c2e is missing | Sync renamed the original. This file is your only copy. | Restore it. Rename it back. |
4f9c2e 2 exists, 4f9c2e is present | Sync added a duplicate alongside an intact original. | Delete the duplicate. |
Nothing inside .git is ever deleted unless a correctly named file survives next to it. That is the difference between a working repository and a re-clone, and it is the entire reason this guide exists.
The left branch is the one a naive cleanup gets wrong, and it is the one that costs you the repository.
Corruption is the loud failure. The quiet one is worse: the folder is intact but stale, or holds commits nobody pushed, and an agent reads it and reports the contents as current. Nothing errors. You just act on the wrong information.
So before trusting the folder, the check answers four questions and refuses to shrug at any of them: is the object store readable, does this match the remote, is the working tree clean, and are there conflict copies. Exit code 0 means all four passed. Anything else prints which one failed and the command that fixes it.
Two machines editing the same file at the same time. No hook catches that. The parity check will tell each machine it has diverged, but by then the conflict already exists. The habit that prevents it is boring and effective: push before you walk away.
The root cause. The only arrangement that removes this class of problem entirely is one clone per machine on local disk, with cloud storage holding your brain and documents but not the git repository. That is more multi-machine, not less, because git itself becomes the sync layer, which is what git is for. If the parity check starts firing often, treat that as the signal that the convenience is now costing more than it saves.
One day the check will report real damage. This is the calm version of that morning.
Everything already pushed is safe. That is what makes this a chore rather than a catastrophe.
git gc, git prune and git repack turn a recoverable repository into a lost one, because they discard exactly the objects you are trying to rescue.git fsck --connectivity-only and git archive HEAD >/dev/null. Both should succeed on a healthy repo.| Term | In plain words |
|---|---|
| Repository (repo) | A project folder that git is tracking, including its full history. |
| .git folder | The hidden database inside a repo that holds every version of every file. Damage here is what this guide is about. |
| Object | One item in that database: a file version, a folder listing, or a commit. Named by its content, so a renamed object is a missing object. |
| Remote / origin | The copy of the repo on a hosting service. In this guide, the thing you can always fall back to. |
| Conflict copy | The extra file cloud storage creates when two machines change the same thing, usually named with a trailing space and a number. |
| Local mount | The folder on your computer that mirrors your cloud storage, so normal programs and agents can open the files. |
| Git hook | A script git runs automatically at a certain moment, such as before a commit or before a push. |
| fsck | Git's own integrity check. It walks the history and reports anything missing or broken. |
| Working tree | The visible files you actually edit, as opposed to the history stored in .git. |
Every guardrail in the Agentic OS follows the same shape: assume the failure will happen, make it loud, and make recovery cheap. You are not trying to build a system that never breaks. You are trying to build one where breaking costs thirty seconds and nobody loses a day.