Refuse to start unless this install reached the current version through a
sanctioned path (setup / update / migrate). A raw `git pull` that skips
migrations now fails loudly with a self-healing message instead of
silently breaking.
- src/upgrade-state.ts: marker at data/upgrade-state.json, getCodeVersion,
isUpgradeCurrent, enforceUpgradeTripwire (fails closed on missing /
corrupt / mismatched marker)
- src/index.ts: gate wired in at startup step 0.5, before DB init
- scripts/upgrade-state.ts: get/set CLI (also the override / recovery cmd)
- setup/service.ts, /update-nanoclaw, /migrate-nanoclaw: stamp on success;
update/migrate also self-update their own skill first
- CHANGELOG [BREAKING] entry bridges existing installs via the skills'
breaking-change check
- docs/upgrade-recovery.md: clearing the tripwire
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>