# Rollback Runbook — LLM-first router overhaul

**Anchor commit/tag:** `brain-pre-llm-bootstrap` → `9d4a30c3` (origin/main on 2026-05-25, before any Phase 1 destruction).

**When to use this:** any time the LLM-first overhaul (Phase 1/2/3) needs to be reverted in full. Partial rollback is via runtime flags (`~/.claude/runtime/*-mode.json`), not this runbook.

**Time to revert:** ~5 min (mechanical) + dependency reinstall.

## What this rollback restores

| Layer | Source of truth | Restore mechanism |
|---|---|---|
| Git-tracked files | tag `brain-pre-llm-bootstrap` | `git checkout brain-pre-llm-bootstrap -- .` |
| User settings (`~/.claude/settings.json`) | `settings-snapshot/user-settings.json.pre-overhaul` | `tools/test-rollback.mjs --execute` |
| User hooks (`~/.claude/hooks/*`) | `user-hooks/` (14 files snapshot) | `tools/test-rollback.mjs --execute` (full directory restore: wipes new hooks, restores snapshot) |
| Runtime flags (`~/.claude/runtime/*-mode.json`) | `runtime-flags-snapshot/` (only `router-gate-mode.json` at snapshot time) | `tools/test-rollback.mjs --execute` (strategy `restore-snapshot-delete-new`: deletes flags absent in snapshot, copies snapshot files back) |
| Node deps | `package-lock.json` from tag | `npm install` |

## What this rollback does NOT touch (intentional)

- `docs/observer/episodes-*.jsonl` — preserved (G6). Evidence accumulated during the experiment stays. Schema v4 episodes remain readable after rollback because the parser is forward-compatible (graceful skip of unknown schema versions — Task 15 / G5).
- `docs/observer/notes/*` — preserved.
- Database / production state — out of scope. This overhaul does not touch the portal's runtime.

## Procedure

### Step 1 — Verify rollback is ready (dry-run)

```bash
cd <repo root>
node tools/test-rollback.mjs --dry-run
```

Expected: `[dry-run] OK — rollback ready` and exit 0. If `MISSING ...` lines appear — **STOP**, fix the missing artefact first.

### Step 2 — Restore user-level state + runtime flags

```bash
node tools/test-rollback.mjs --execute
```

Expected output:

- `[execute] restored ~/.claude/settings.json`
- `[execute] restored ~/.claude/hooks/ (14 files)`
- `[execute] runtime flags: deleted N new, restored 1 from snapshot`
- `[execute] user-level + flags restored. Now run: git checkout brain-pre-llm-bootstrap -- . && npm install`

### Step 3 — Restore git-tracked state

```bash
git fetch origin
git reset --hard brain-pre-llm-bootstrap
git status
```

`git reset --hard <tag>` does both jobs in one shot: tracked files that EXISTED in the tag are restored to their tag content, and tracked files that were ADDED during the overhaul (e.g. `tools/test-rollback.mjs`, `tools/router-config.mjs`, `docs/archive/llm-bootstrap-2026-05/*`) are removed from the working tree.

**Why not `git checkout brain-pre-llm-bootstrap -- .`** (the naive command): `checkout -- <pathspec>` only restores files present in the target ref. Files committed during the overhaul but absent in the tag are left on disk and remain staged — the end-to-end smoke during Task 1 caught this. Use `reset --hard` instead.

Untracked files (never committed) survive `reset --hard`:

- `docs/observer/episodes-*.jsonl` — preserved by design (G6).
- `docs/observer/notes/*` — preserved.
- Any local scratch files — preserved.

If you want a fully hermetic revert that also wipes untracked files, follow with (use with care — also kills .gitignore'd local-only artefacts):

```bash
git clean -fd --exclude=docs/observer/episodes-*.jsonl --exclude='docs/observer/notes/*' --exclude=.env --exclude=node_modules
```

### Step 4 — Reinstall dependencies

```bash
npm install
```

Reverts `node_modules/` to the pre-overhaul tree (`@xenova/transformers` etc. removed; `package-lock.json` already restored by Step 3).

### Step 5 — Smoke verification

```bash
npx vitest run tools/                                 # all GREEN, no test-rollback or new modules
ls ~/.claude/hooks/ | sort                            # contains skill-marker.py + skill-check.py
cat ~/.claude/runtime/router-gate-mode.json           # warn-only
git log --oneline -1                                  # brain-pre-llm-bootstrap (9d4a30c3)
```

Re-start Claude Code session to pick up restored user hooks.

## Snapshot manifest (from → to during execute)

| From (in archive) | To (live) |
|---|---|
| `settings-snapshot/user-settings.json.pre-overhaul` | `~/.claude/settings.json` |
| `user-hooks/*` | `~/.claude/hooks/*` (full replace) |
| `runtime-flags-snapshot/*.json` | `~/.claude/runtime/*.json` (new flags deleted) |
| `nodes-yaml-archive/nodes.yaml.pre-overhaul` | `docs/registry/nodes.yaml` (via `git checkout` in Step 3) |
| `settings-snapshot/project-settings.json.pre-overhaul` | `.claude/settings.json` (via `git checkout` in Step 3) |

## Failure modes

- **Tag missing**: `MISSING git tag: brain-pre-llm-bootstrap`. Recreate from the commit it pointed to (`git tag brain-pre-llm-bootstrap 9d4a30c3`).
- **Snapshot file missing**: same `--dry-run` will name it. Snapshots are also reachable via `git show brain-pre-llm-bootstrap:docs/archive/llm-bootstrap-2026-05/...` after Task 1 commit — never lose them.
- **User hooks partial restore**: `--execute` wipes the live hooks dir before restoring. If the snapshot is corrupted, Claude Code will start without hooks (graceful degrade) — restore from `git show`.

## Verification log

End-to-end smoke proof of this rollback was executed BEFORE any destructive Phase 1/2/3 work — see Task 1 Step 9 in `docs/superpowers/plans/2026-05-25-llm-first-router-overhaul.md` and the test-rollback commit message.
