NEXO 7.3.0 — Guardian wire hotfix: PreToolUse properly registered, post-sync runs the fresh tree, tool-enforcement-map.json now shipped via npm

Published 2026-04-22. Hotfix minor release over v7.2.0.

v7.3.0 is a same-day follow-up to v7.2.0 correcting three critical bugs that surfaced right after the Guardian-active-by-default train went live. Two of them (B11 Guardian wire and B10 post-sync ordering) were discovered while verifying the v7.2.0 rollout on Francisco's machine and would have silently disabled every Guardian gate on every fresh install. The third (B12) is a distribution gap that had existed quietly since tool-enforcement-map.json was born: nothing in the npm bundle, nothing in the Desktop DMG, nothing in ~/.nexo was shipping it, so Desktop could never discover it on a new machine. All three fixes ship here, together with the PE1 rapid items that were planned for this milestone.

B11 — PreToolUse hook actually wired

B10 — post-sync hooks run from the freshly-copied tree

The first time nexo update introduces a new post-install hook, the hook dispatch runs inside the pre-upgrade module that is already loaded in memory. That module does not yet know about the new hook. Result: the hook silently no-op's on the upgrade that was supposed to introduce it. This bit us on v7.2.0 when _persist_guardian_hard_defaults and _maybe_promote_adaptive_weights_empirically failed to write guardian-runtime-overrides.json on the first nexo update that brought them into existence.

v7.3.0 introduces a whitelist _POST_INSTALL_FRESH_HOOKS and a helper _run_post_install_hooks_fresh(dest, env) that invokes each whitelisted hook in a clean subprocess with sys.path pointed at the newly copied tree (dest/core when packaged, dest when running from the repo). Each hook emits its verdict as JSON; the parent parses per-hook results and logs outcomes individually. 5 integration tests in tests/test_post_install_hooks_fresh.py cover the happy path (marker files written), missing function graceful skip, no-core fallback, broken import error surfacing, and per-hook exception isolation.

B12 — tool-enforcement-map.json is shipped via npm

Before v7.3.0, the Brain package.json whitelist did not include tool-enforcement-map.json, so npm publish never shipped it. Desktop's findEnforcementMap had a candidate pointing at /opt/homebrew/lib/node_modules/nexo-brain/ but the file was never there. Combined with the 23a4529 Desktop commit that removed the ~/Documents/_PhpstormProjects/nexo/ dev fallback, fresh installs silently loaded a null map and the session-end diary+stop policy never fired on close.

Brain v7.3.0 adds tool-enforcement-map.json to the files whitelist so every npm install -g nexo-brain gets the map. Desktop v0.23.0 (shipping alongside) copies the same file into the DMG's brain-bundle via extraResources, preflights it into ~/.nexo/core/ at app startup, and surfaces a visible warning if the map cannot be located after all candidates are exhausted — no more silent degradation.

PE1 rapid items — 0.4 preset entities + 0.25 guardian-metrics cron

Desktop v0.23.0 — renderer-side of B12 + the Parar/queue recovery loop

Desktop v0.23.0 ships in lockstep. It picks up the server side of B12 (discovery order, bootstrap preflight, visible warning) plus two UX bugs Francisco hit on v0.22.10: B13 (clicking “Send queue” after a Stop did nothing when turnBusy stayed pinned because the previous turn's result/close events never reached the renderer) and B14 (no synthetic claude-exit floor, so a wedged Claude process froze the UI until force-quit). Both are now covered by unit tests and shape-match contracts so a future refactor cannot silently regress them.

What to do after updating

nexo update picks up the fix automatically. On the first update to v7.3.0 the post-install hooks will write guardian-runtime-overrides.json with G3-destructive, G3-SSH, and G4-guard_check in hard. Verify with cat ~/.nexo/personal/config/guardian-runtime-overrides.json after the update. Guardian is now actually enforcing. Installing Desktop v0.23.0 (separate DMG) adds the renderer-side map discovery and the “Send queue” recovery.

Related: full v7.3.0 changelog · v7.2.0 release notes · source on GitHub