Uninstalling tuhdoo

How a machine — or a whole team — walks away from tuhdoo. The companion to joining.md: joining is four steps, and leaving is a handful of ordinary git commands, because nothing tuhdoo does touches your code history — the ledger is an orphan branch, there are no git hooks, and your worktree is never written to. This doc is self-contained; you do not need to read anything else first.

Two layers, deliberately separate:

  • Per machine — safe and reversible: remove every trace of tuhdoo from one clone. As long as the team's ledger still exists on the remote, tuhdoo init rejoins with full history at any time.
  • For the team — irreversible, and usually unnecessary: retiring the shared ledger itself.

There is intentionally no tuhdoo uninstall command. Leaving via ordinary git commands is the point — you can read exactly what each step removes — and the one destructive team-level step must never be automated.

What tuhdoo leaves on a machine

The complete footprint, verified against the code:

  • Three refs. refs/heads/tuhdoo — the local copy of the data branch; refs/remotes/origin/tuhdoo — an ordinary remote-tracking ref (full clones only; --single-branch clones never have one); and refs/tuhdoo/remote — the daemon's own tracking ref, where its fetches of the remote data branch land.
  • The runtime directory .git/tuhdoo/daemon.json, daemon.lock, daemon.log, daemon.sock, machine-id.
  • One git config key, tuhdoo.principal — repo-local, or --global if you set it there. Only present if you overrode the default identity.
  • The MCP entry in your agent harness's config (the snippet tuhdoo init printed), if you added one.
  • The binary.

Nothing else. No hooks, no writes to your worktree, no commits on your code branches — after the steps below, the repository looks exactly as if tuhdoo had never run.

Per machine: walk away clean

Run everything below from the repository root. (In a linked worktree, the runtime dir lives under $(git rev-parse --git-dir)/tuhdoo rather than .git/tuhdoo — substitute accordingly.)

1. Stop the daemon

The daemon's pid is in .git/tuhdoo/daemon.json. Send it SIGTERM and wait for it to actually exit — shutdown flushes and publishes any last events, so killing harder than TERM can strand your final writes locally:

if [ -f .git/tuhdoo/daemon.json ]; then
  pid="$(sed -n 's/.*"pid":[[:space:]]*\([0-9][0-9]*\).*/\1/p' .git/tuhdoo/daemon.json)"
  kill -TERM "$pid"
  for _ in $(seq 1 50); do kill -0 "$pid" 2>/dev/null || break; sleep 0.1; done
fi

No daemon.json means no daemon is running — the block above skips itself and you move on.

2. Remove the runtime directory

A clean shutdown already removed the socket and daemon.json; this clears the lock, log, and machine-id too:

rm -rf .git/tuhdoo

3. Delete the three refs

Depending on clone shape and history, any of the three may be absent (a --single-branch clone has no remote-tracking ref; a repo that never synced has no refs/tuhdoo/remote). This deletes exactly the ones that exist, silently skipping the rest:

git for-each-ref --format='delete %(refname)' \
  refs/heads/tuhdoo refs/remotes/origin/tuhdoo refs/tuhdoo/ \
  | git update-ref --stdin

This only touches your machine's refs — the team's ledger on the remote is unaffected, and other machines never notice.

4. Unset your principal

git config --unset tuhdoo.principal || true
git config --global --unset tuhdoo.principal || true

(|| true because most machines never set the key at all — git config --unset exits non-zero when there is nothing to unset.)

5. Remove the harness MCP entry and the binary

Both are environment-specific, so no single command fits. Delete the "tuhdoo" entry from your agent harness's MCP config — it is the snippet tuhdoo init printed, under "mcpServers". Then remove the binary however it arrived:

npm uninstall -D tuhdoo      # if installed via npm
rm "$(command -v tuhdoo)"    # if installed from a release archive or `go install`

Verify: zero trace

Every check below succeeds only when nothing is left; the last line prints only if all of them pass:

test -z "$(git for-each-ref refs/heads/tuhdoo refs/remotes/origin/tuhdoo refs/tuhdoo/)" \
  && ! git config --get tuhdoo.principal \
  && ! test -e .git/tuhdoo \
  && echo "clean: no trace of tuhdoo on this machine"

And git status looks exactly as it did before you started: tuhdoo never writes to your worktree, so there is nothing there to clean up.

Maintainers: the fenced blocks above marked with <!-- uninstall-test: run --> comments are executed verbatim by TestUninstallDocStepsLeaveZeroTrace (cmd/tuhdoo/uninstall_doc_test.go) against a temp repo with a running daemon. The doc is the single source of truth — edit a step here and the test re-proves the walk-away claim.

For the team: retiring the ledger

First: you probably don't need to. A dormant tuhdoo branch costs nothing — a small stretch of orphan history that never touches your code branches, never appears in --single-branch clones, and (configured per joining.md) never triggers CI. It is also the team's decision record: every task, note, escalation, and answer. The recommended way to stop using tuhdoo is simply to stop: each machine runs the per-machine steps above, and the branch sits untouched on the remote, rejoinable later.

Want the branch name gone but the history kept? Archive it first, from any machine that still has the local branch:

git push origin refs/heads/tuhdoo:refs/tags/tuhdoo-archive

then delete the branch as below — the history stays reachable through the tag.

Deleting the remote branch

This is the one irreversible step in this document. It destroys the whole ledger for every peer at once, and there is no undo beyond a surviving local copy on some machine. Two things must happen first:

  1. Every machine stops (or fully uninstalls) its daemon. A live daemon on any peer will faithfully republish the branch on its next sync — from its point of view the remote merely lost history that it still has. Coordinate: per-machine steps everywhere, then delete.
  2. Lift any host protection on the data branch. If your host restricts branch deletion (rulesets, protected branches, or whatever your host calls them), the tuhdoo branch must be released from that rule before it can be deleted.

Then, typed by a human, on purpose:

git push origin --delete tuhdoo

If you regret it: any machine that has not yet run the per-machine cleanup still holds the full ledger in refs/heads/tuhdoo, and a plain git push origin tuhdoo from there restores everything.