Skip to content

Instantly share code, notes, and snippets.

@robertDouglass
Last active August 26, 2026 15:05
Show Gist options
  • Select an option

  • Save robertDouglass/f732bb1d1fa0f7692a564f151b272391 to your computer and use it in GitHub Desktop.

Select an option

Save robertDouglass/f732bb1d1fa0f7692a564f151b272391 to your computer and use it in GitHub Desktop.
Zeitgeist: safe uninstall runbook for Claude Code / Codex / OpenCode (companion to the install runbook)

Uninstalling Zeitgeist safely (Claude Code / Codex / OpenCode)

Companion to the Zeitgeist install runbook, for pulling it back off a machine. Give this document to Claude Code, Codex, or OpenCode and say:

Execute this runbook on my machine. Keep working until every check in "Definition of Done" passes. Do not just summarize the steps.

The three safety principles, in order of importance:

  1. Inventory before you change anything. Only remove what a grep finds, and only the exact Zeitgeist additions.
  2. Back up every file before touching it. Backups are the rollback.
  3. Edit, never rewrite. Delete the exact entry; never regenerate a whole config file from scratch. Validate that every touched file still parses before calling it done.

What the installer actually touches

  1. ~/.config/zeitgeist/token — credential file
  2. ~/.local/share/priivacy-zeitgeist — git checkout that hooks execute
  3. Claude Code ~/.claude/settings.json — hook entries (rumors.py on SessionStart/UserPromptSubmit, beacon.py on PostToolUse) and a statusLine block
  4. Codex ~/.codex/config.toml — a [mcp_servers.zeitgeist] block, and a notify line wrapping the original notify chain in notify-wrap.py (the original is saved in ~/.codex/zeitgeist-notify-chain.json)
  5. OpenCode — mcp.zeitgeist entry in ~/.config/opencode/opencode.json and the plugin file ~/.config/opencode/plugin/zeitgeist.js
  6. Possibly (case-by-case): a marker-delimited Zeitgeist block in project CLAUDE.md / AGENTS.md, a managed block in /etc/hosts, and ~/.config/fly-wireguard/* if the server tunnel was also set up

Step 0 — inventory (read-only, do ALL of this before changing anything)

grep -rn -i zeitgeist \
  ~/.claude/settings.json ~/.claude/settings.local.json \
  ~/.codex/config.toml ~/.codex/hooks.json \
  ~/.config/opencode/opencode.json ~/.config/opencode/AGENTS.md \
  ~/.claude/CLAUDE.md ~/.codex/AGENTS.md
ls -d ~/.local/share/priivacy-zeitgeist ~/.config/zeitgeist 2>/dev/null
ls ~/.config/opencode/plugin/ 2>/dev/null
grep -n "^notify" ~/.codex/config.toml
grep -n "priivacy-zeitgeist" /etc/hosts

Rules:

  • Only remove what this grep finds. A hook that does not contain zeitgeist is someone else's — leave it alone.
  • Default to the surgical manual edits in Step 2, not the bundled uninstaller. install.py <harness> --uninstall (run from the checkout before deleting it) exact-matches the commands it wrote. If any hook is wrapped in a local guard script, edited, or otherwise not byte-identical, it matches nothing and silently leaves the wrapper behind — and it regenerates config files, which is how unrelated custom blocks (permissions, theme, other hooks) get eaten. Only use it when you can confirm BOTH: (a) every Zeitgeist hook in the config is exactly the installer's command, and (b) the config file carries no custom blocks you need kept. If you do run it, re-run the Step-0 grep and the Step-3 parse check afterwards and diff against your Step-1 backup to catch collateral damage. If the checkout is already gone, there is nothing to run — the hooks are dead references and trivially identifiable.
  • If a config file looks hand-modified around a Zeitgeist block (stray commas, mixed syntax, unfamiliar edits), stop for that file, work from the Step-1 backup, and proceed extra carefully.

Step 1 — back up everything you will touch

mkdir -p ~/.zeitgeist-removal-backups
ts=$(date +%Y%m%d%H%M%S)
for f in ~/.claude/settings.json ~/.codex/config.toml \
         ~/.config/opencode/opencode.json \
         ~/.codex/zeitgeist-notify-chain.json /etc/hosts; do
  [ -f "$f" ] && cp "$f" ~/.zeitgeist-removal-backups/$(basename "$f").$ts
done

Keep these for at least a week. They are the rollback.

Step 2 — remove each artifact

The deletions below are safe: every path is Zeitgeist-specific and nothing else references it.

rm -rf ~/.config/zeitgeist
rm -rf ~/.local/share/priivacy-zeitgeist
rm ~/.config/opencode/plugin/zeitgeist.js

Then edit (do not rewrite) the three config files.

~/.claude/settings.json

  • Delete every hooks entry whose command contains ZEITGEIST_URL or priivacy-zeitgeist.
  • If a hook array ({"hooks":[...]}) becomes empty, delete the whole array element — and fix the trailing comma.
  • If statusLine.command contains priivacy-zeitgeist: check the backups for an older statusLine value. If one existed, restore it. If none ever did, delete the whole "statusLine" key — this is the common case, because the installer overwrote the default, not a custom one.
  • Do not touch other hooks (e.g. context-mode, codegraph) in the same arrays.

~/.codex/config.toml

  • Delete the entire [mcp_servers.zeitgeist] block: from the section header to the line before the next [ section. It contains the plaintext token.
  • Fix notify. The installer replaced it with a 4-element array ending in --previous-notify "...". Read ~/.codex/zeitgeist-notify-chain.json — it holds the exact original args (usually ["<original binary>", "turn-ended"]) — and set notify to that. Then delete the json file. If it is missing, restore notify from the Step-1 backup's pre-install value, or delete the notify line (Codex works without it; you lose turn notifications only).

~/.config/opencode/opencode.json

  • Delete the "zeitgeist": { ... } object inside "mcp". It contains the plaintext token. Watch for a dangling comma left behind.

Text files (only if Step 0 found them)

  • Project CLAUDE.md / AGENTS.md: delete only the marker-delimited Zeitgeist block, start marker to matching end marker.

  • /etc/hosts: delete the block between # BEGIN priivacy-zeitgeist (managed) and # END priivacy-zeitgeist (managed). Needs sudo. Inert unless the wireguard tunnel is up:

    sudo sh -c "awk '/^# BEGIN priivacy-zeitgeist \(managed\)$/{skip=1} !skip{print} /^# END priivacy-zeitgeist \(managed\)$/{skip=0}' /etc/hosts > /tmp/h && mv /tmp/h /etc/hosts"
  • ~/.config/fly-wireguard/: contains a WireGuard private key for the server deployment. Delete only if you no longer need admin access to it.

Step 3 — validate (do not skip)

python3 - <<'EOF'
import json, os, tomllib
for f in ("~/.claude/settings.json", "~/.config/opencode/opencode.json"):
    json.load(open(os.path.expanduser(f)))
tomllib.load(open(os.path.expanduser("~/.codex/config.toml"), "rb"))
print("all configs parse OK")
EOF

grep -rn -i zeitgeist ~/.claude/settings.json ~/.claude/settings.local.json \
  ~/.codex/config.toml ~/.config/opencode/opencode.json \
  ~/.config/opencode/plugin/ /etc/hosts 2>/dev/null   # must be empty

pgrep -fl -i zeitgeist   # must print nothing
  • If a config fails to parse, restore it from ~/.zeitgeist-removal-backups/ and redo that one file carefully. Do not keep patching a broken file.
  • If the grep finds leftovers, go back and remove them.

Step 4 — restart and tell the human

  • Restart every running Claude Code / Codex / OpenCode session. Hooks and MCP registrations are read at session start, so live sessions keep the old (now dead) hooks until restarted.
  • Tell the human the shared credential is compromised: it is hardcoded in a public gist and was stored in plaintext in local config files. Anyone holding it can read all presence data and publish under any name. The token must be rotated for the whole team — notify the deployment owner rather than hoping no one noticed.

Definition of Done

  • ~/.config/zeitgeist and ~/.local/share/priivacy-zeitgeist are gone.
  • No zeitgeist-bearing hooks or statusLine remain in ~/.claude/settings.json; other hooks untouched.
  • ~/.codex/config.toml has no [mcp_servers.zeitgeist]; notify matches the pre-install chain (or is absent).
  • ~/.config/opencode/opencode.json has no mcp.zeitgeist entry; plugin/zeitgeist.js is deleted.
  • No Zeitgeist block in CLAUDE.md / AGENTS.md / /etc/hosts (if present).
  • All touched files parse; the validation grep is empty; no zeitgeist processes run.
  • Backups exist in ~/.zeitgeist-removal-backups/.
  • The human restarted their sessions and was told about the token rotation.

If anything cannot pass, report BLOCKED with the exact file and line — not DONE.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment