Playbook: Update
Runs on /update, when the boot check finds a newer version, or when the principal asks to update. The mechanics live in brain/integrations/updates.md; this playbook is the interaction.
Check
- Read the local
VERSION; fetch the latest publishedVERSION(brain/integrations/updates.md). If the host can't fetch / there's no network, say so and give the manual path (README) — don't guess. - Already current → say so and stop.
- Newer available → report the new version and the
CHANGELOG.mdhighlights, and confirm before applying. (For/update check, stop here — report only.)
Apply (only on an explicit OK)
Follow brain/integrations/updates.md → "Applying an update": download the latest release, replace everything it ships (brain/, the boot files, .claude/'s shipped contents) in this folder. Never touch memory/ or .claude/settings.local.json — the principal's data and local settings carry over untouched. This is an irreversible file operation on the install folder, so confirm first.
After
- Confirm
VERSIONbumped; report the what's-new highlights. - Don't migrate memory in this session — it's now stale (still on the pre-upgrade brain). Any memory migration (the
CHANGELOG.mdmigration notes, orphaned-override reconciliation, an optional/lintconvergence) runs automatically at the first fresh session, driven by the new brain — seebrain/integrations/updates.md→ "Applying memory migrations". If the span has migration notes, tell the principal a one-liner that their next fresh session will apply them; their memory is untouched until then. - Enter stale-session mode (see
CHIEFOFSTAFF.md→ SESSION FRESHNESS): the swap changed the files on disk, but this session is still running the brain it loaded at boot, so from now on prefix every reply with the stale-session banner until the principal opens a new chat, and this session is now frozen from writing memory. Tell them plainly that the new version — and the migration — take effect only in a fresh session; this one keeps working, on the old version. - Don't write the ledger here — the freeze forbids it, and this session's brain is the old one. The first fresh session's migration pass records the upgrade (and any migration) in
memory/ledger.mdwhen it advancesonboarded_against(brain/integrations/updates.md→ "Applying memory migrations").
Create the neutral skills directory (existing installs)
Run at boot by the migration pass (brain/integrations/updates.md → "Applying memory migrations") when onboarded_against < VERSION and the changelog carries path:agents-dir — or on explicit ask. Idempotent: an install where every .claude/commands/<name>.md already has a matching .agents/skills/<name>/SKILL.md is skipped, so a re-run is a no-op.
- Check whether every
.claude/commands/<name>.mdalready has a matching.agents/skills/<name>/SKILL.md. Yes → do nothing and say nothing. - Copy, don't compose. For each
.claude/commands/<name>.mdlacking a matching.agents/skills/<name>/SKILL.md, create it with the same body, and frontmatter carryingname: <name>plus that file's existingdescription:(andargument-hint:where it has one). Use the host's file operations; writing them out as generated text is the expensive way to do this. - No execution surface, or
.claude/commands/is missing → skip silently. The next update delivers the directory anyway. - Report nothing to the principal. This changes none of their content.