---
name: alexandria-update
description: Update this brain to the latest Alexandria by its real update channel — a zip-installed brain (`.alexandria/app/` present) ingests a new Alexandria.zip via `alexandria update --from-zip` (verify newer → survivable software swap → Core re-render → doctor); a git-checkout install (runner vaults included) pulls the checkout and re-renders. The old CI update workflow is retired — this skill also cleans up its leftovers. Core only — the owner's Config and notes are never touched. Use when the owner says "update my brain", "update alexandria", "upgrade my vault", "get the latest version", "is there a new version", or hands over a downloaded Alexandria.zip. NOT for first-time setup (that's alexandria-install).
served: false
---

# Update Alexandria

This refreshes the vault's **Core** — the operating manual (`AGENTS.md`), the skills, the
prompts and config-derived docs — and, on zip installs, the software itself. The owner's
**Config** and **notes are never touched**: that is the bucket model's guarantee, enforced
by the renderer, not by care.

**Pick the lane by what's on disk** — exactly one applies:

| On disk | Lane |
|---|---|
| `.alexandria/app/` exists | **A — zip-installed folder brain** (the zip is the update channel) |
| `.github/workflows/alexandria-update.yml` exists | **B — retired CI lane** (delete the leftover; update via **C**) |
| neither | **C — terminal path** (a git-checkout / kit install: pull the checkout yourself, then `update` re-renders) |

## Lane A — zip-installed brain (the folder IS the brain)

`ALEX=".alexandria/app/.venv/bin/alexandria"` — the shipped CLI. Everything runs at the
vault root.

1. **Commit any in-flight work first, as its own commit.** `git status --porcelain`; if
   the tree is dirty, commit the owner's work separately (`git add -A && git commit -m
   "vault: work in flight, committed before core update"`) so the update lands as one
   clean, reviewable commit and there is an exact point to return to.
2. **Get the new zip and verify its checksum.** If the owner already downloaded one,
   use its path directly (a `.zip` or its unzipped folder both work). Otherwise fetch
   the latest — say that this step is networked — and check it against the published
   sha256:
   ```sh
   mkdir -p .alexandria/tmp
   curl -fsSL --proto '=https' https://keystone.computer/Alexandria.zip -o .alexandria/tmp/Alexandria.zip
   curl -fsSL --proto '=https' https://keystone.computer/Alexandria.zip.sha256 -o .alexandria/tmp/Alexandria.zip.sha256 \
     && (cd .alexandria/tmp && shasum -a 256 -c Alexandria.zip.sha256)
   curl -fsSL --proto '=https' https://keystone.computer/Alexandria.zip.sig -o .alexandria/tmp/Alexandria.zip.sig
   ```
   `OK` → continue. A checksum mismatch means a corrupted or tampered download: **stop**,
   delete the files, re-fetch once; if it mismatches again, report it and do not update.
   Fetch the `.sig` (release signature) into the same folder — step 3 verifies it. (A 404
   on the `.sha256` or `.sig` sidecar just means an older deploy — note it and continue.)
3. **One command does the whole update:**
   ```sh
   "$ALEX" update --from-zip .alexandria/tmp/Alexandria.zip --vault .
   ```
   It **verifies the release signature** first (the `.sig` beside the zip, against the key
   the software pins — an unsigned, wrong-key, or tampered release is refused; a genuine
   emergency can add `--allow-unsigned`, which warns loudly), then checks the zip is a real
   release **newer** than the installed version (same version → Core re-render only, no
   swap; older → refused), moves the running
   software aside to `.alexandria/app.prev` (never deleted first), installs the new
   snapshot, rebuilds its venv (the other networked step — pip), re-renders Core
   **through the new code**, runs `doctor`, refreshes `CLAUDE.md`/`README.md` from the
   zip, and only then cleans up. Any failure before the render rolls the software back
   automatically; any failure after it keeps `.alexandria/app.prev` and tells you. On
   success the **previous software stays at `.alexandria/app.prev`** until the next
   update — a one-version rollback is always on disk. One update runs at a time (an
   `update.lock` under `.alexandria/`); "another update is already running" means wait,
   not retry. An update that was interrupted mid-swap self-heals on the next run.
4. **Commit and report.** The update never commits for you:
   ```sh
   rm -f .alexandria/tmp/Alexandria.zip
   git add -A && git commit -m "alexandria: core update <old> → <new>"
   ```
   (`git add -A` is safe *because* step 1 guaranteed a clean pre-update tree — only the
   update's own output is unstaged.) Then tell the owner, plainly: the version jump, how
   many Core files changed (`.state/last-update.md` has the list), any **hand-edited Core
   that was overwritten** (drift — those edits belonged in Config), any **new skills or
   modules** this version ships, and — if `Agent/Standing Context.md` changed — that
   they'll need to re-paste it wherever they embed it.

**If it fails:** read the error — it says what state you're in. `.alexandria/app.prev`
present means the previous software is intact on disk; the vault's git history has the
pre-update state of every rendered file. Report honestly and fix forward; never
hand-render Core or hand-edit anything under `.alexandria/`.

**If `$ALEX` itself won't start** (an update died during the environment build, so no
installed CLI runs), use the no-venv recovery entry point — plain system python, run the
copy at the live app path (it carries this entry point and is the newest one on disk):
```sh
python3 .alexandria/app/scripts/zipupdate.py heal .
```
(If `.alexandria/app` is gone entirely, use `.alexandria/app.swap` or `.alexandria/app.prev`
in its place.) It takes the update lock, restores a runnable copy, and tells you to re-run
the update to finish. Never edit anything under `.alexandria/` by hand to recover.

**Rolling back** ("undo the update", "go back to the previous version"): commit any
in-flight work first, then
```sh
"$ALEX" update --rollback --vault .
```
— the kept previous software swaps back into place, Core re-renders with it, doctor
gates it, and the newer copy is set aside at `.alexandria/app.next` (the next successful
update removes it). Then commit (`alexandria: roll back core update`) and tell the owner
what version they're on. This is the one sanctioned downgrade; `--from-zip` refuses them.

## Lane B — retired (the CI update workflow)

The old CI lane — a `.state/update-request` trigger commit → the **Alexandria Update**
GitHub Action → a review PR — **no longer exists**: updates run where the software
actually lives (the zip channel on folder brains — Lane A; the terminal path on
checkout installs — Lane C). If this vault still carries
`.github/workflows/alexandria-update.yml` (and/or a `.state/update-request` file),
those are leftovers of the retired lane: delete them in your next commit here —
nothing reads them anymore.

The old **`ALEXANDRIA_REPO_DIST_PAT` secret is fully retired too** — current renders
vendor the engine wheel into the vault at `.github/engine/` and the workflows install
it from the checkout. If the repo still carries that secret, delete it; nothing reads it.

## Lane C — terminal path (git checkout / kit)

`alexandria update` is **render-only** — it refreshes Core from whatever software is
installed and never fetches any itself. On a checkout install, get new software first,
then render:

```sh
git -C <software-checkout> pull --ff-only   # skip if the checkout is already current
alexandria update --vault <path>            # re-render Core from the installed software
```

Review with `git diff` in the vault, then commit + push.
