Summary
ao update (git / source installs) only rebuilds when git fetch advances the local commit. If the compiled output (dist/) is out of sync with src/ at the same commit, the script prints Already on latest version and skips the rebuild — so the running binary keeps executing stale compiled code.
How it happens
The rebuild is gated purely on the SHA advancing:
if [ "$local_sha" = "$remote_sha" ]; then
printf 'Already on latest version.\n' # ← skips pnpm install + build
else
git pull ... && pnpm install && pnpm build ...
fi
So dist/ can be stale at HEAD via:
- a manual
git pull before ao update (HEAD already matches remote → no rebuild)
- a branch switch
- an interrupted previous build (SHA advanced but the build never finished; re-running sees a matching SHA → no rebuild)
- a manual
pnpm clean
Impact
Source / npm link installs (install method git) end up running whatever was last compiled. Seen in practice: a fix that exists in src/ throws at runtime because dist/ predates it (e.g. a session-restore change still throwing the pre-fix error). Registry installs (npm / pnpm / bun-global) are unaffected — they ship prebuilt dist/.
Proposed fix
Gate the rebuild on whether dist/ is in sync with HEAD, not on the SHA advancing:
- record the built commit in a gitignored marker (
node_modules/.ao-build-sha), written only after a fully successful build + launcher refresh
- rebuild when the marker ≠ HEAD, the build output is missing, or
--force-rebuild is passed
- add
ao update --force-rebuild as an explicit escape hatch
Mirror the change in the PowerShell port and wire --force-rebuild through update.ts.
Summary
ao update(git / source installs) only rebuilds whengit fetchadvances the local commit. If the compiled output (dist/) is out of sync withsrc/at the same commit, the script printsAlready on latest versionand skips the rebuild — so the running binary keeps executing stale compiled code.How it happens
The rebuild is gated purely on the SHA advancing:
So
dist/can be stale at HEAD via:git pullbeforeao update(HEAD already matches remote → no rebuild)pnpm cleanImpact
Source /
npm linkinstalls (install methodgit) end up running whatever was last compiled. Seen in practice: a fix that exists insrc/throws at runtime becausedist/predates it (e.g. a session-restore change still throwing the pre-fix error). Registry installs (npm / pnpm / bun-global) are unaffected — they ship prebuiltdist/.Proposed fix
Gate the rebuild on whether
dist/is in sync with HEAD, not on the SHA advancing:node_modules/.ao-build-sha), written only after a fully successful build + launcher refresh--force-rebuildis passedao update --force-rebuildas an explicit escape hatchMirror the change in the PowerShell port and wire
--force-rebuildthroughupdate.ts.