NEXO 7.2.0 — Guardian active by default: G1 enforcer + G3 SSH wrapper + persist hard + F0.6 hardening + adaptive empirical
Published 2026-04-22. Minor release over v7.1.10.
v7.2.0 consolidates three parallel workstreams into a single Guardian-active-by-default train. Every non-ephemeral install gets Guardian in hard mode automatically on the next nexo update — no env vars, no manual activation, no per-install script. The three batches landed via stacked PRs (#261 F0.6 hardening, #258+#259+#260 B8/B9/B10/B11 small fixes + path-constants lazy, #262 G1/G3/G5/persist) and all passed CI end-to-end.
Block K — Guardian roadmap closure
- G1 enforcer active: new PostToolUse gate (
src/hooks/g1_enforcer.py) nudges when the latestnexo_task_openreturnedmode ∈ {defer, ask, verify}and the operator has not executed the pairednext_action(nexo_confidence_checkwith populatedevidence_refsfor verify,nexo_cortex_decidefor defer/ask, or a user turn). Grace window (NEXO_G1_GRACE_SECONDS=120) and rate limit (NEXO_G1_RATE_LIMIT_SECONDS=180). Shadow writes a warn-severity debt row; hard emits a system-reminder nudge. - G3 SSH remote-write detector:
_classify_ssh_remote_writecatchesssh host "cat > ...",ssh host "tee ...",ssh host "sed -i ...",scp upload,rsync upload,sftp -b batchand 10+ other patterns the local destructive gate never saw. Sameshadow/hard/offcontract as G3 local (NEXO_G3_SSH_ENFORCE_REMOTE_WRITE). - Guardian runtime config resolver: new
src/guardian_runtime_config.pyunifies all four gate modes (G1 + G3-destructive + G3-SSH + G4). Priorityenv > ~/.nexo/personal/config/guardian-runtime-overrides.json > default. Env vars remain the ad-hoc debug override; the JSON file is the operator-persistent default. - Persist hard by default:
_persist_guardian_hard_defaultsruns during everynexo update, writing the override JSON with all four gates inhard. Never overwrites operator customization (a key already atshadoworoffstays that way). Operator opt-out withNEXO_GUARDIAN_PERSIST_HARD=off. Skips ephemeral runtimes. Reversible. - G5 adaptive empirical promotion:
adaptive_mode.pyflips from "14-day calendar wait" to "14 days OR (≥200 samples AND ≥2 days)". A new_maybe_promote_adaptive_weights_empiricallyruns duringnexo updateand auto-promotes shadow→learned when the install already has mature data. Mature installs feel the Cortex calibration immediately post-update instead of waiting for the next learner cron.
F0.6 hardening
nexo rollback f06CLI: two-stage safe swap. Renames the current~/.nexoto a dated~/.nexo-rollback-backup-<stamp>before restoring the snapshot, so an interrupted rollback never destroys state. Boots outcom.nexo.*LaunchAgents before the swap and reloads them after (--keep-agents-runningskips).--dry-run,--yes,--jsonsupported. Non-interactive runs without--yesrefuse.docs/f06-layout-contract.md: 240-line authoritative contract for the post-F0.6 runtime layout. Canonical paths, compatibility-symlink retention windows (v7.x → v8.0.0),core-dev/developer opt-in, Dashboard standalone vs Desktop-managed modes, residual/cleanup windows, and the eight doctor expectations that enforce the contract.- Three new doctor boot-tier checks:
check_core_dev_packaged_installwarns when a packaged install shipscore-dev/content.check_dashboard_desktop_contractflags the two contradictory states between Desktop product surface and thecom.nexo.dashboardLaunchAgent.check_f06_migration_consistencydetects half-migrated installs in both directions (F0.6 marker with legacy residue, orcore/populated without the marker). scripts/nexo-migrate-nora.sh+scripts/f0-safe-apply-remote.sh: 8-phase idempotent SSH workflow for migrating a remote NEXO install from F0.0/F0.5-safe to F0.6. Snapshot, F0.5-safe pass, junk cleanup, calibration rename,nexo update, classifier install auto, LaunchAgent reload, doctor report. Dry-run by default;--applyfor mutation. Ships withscripts/README-migrate-nora.mdas the runbook.- Promoted
src/scripts/prune_runtime_backups.pyto core: retention policy separates TECHNICAL rollback snapshots (rotated automatically) from BUSINESS/HOURLY_DB/ROOT_DB operational artifacts (never touched). - F0.6 hardening tests:
test_v6_to_f06_full_migration_rollback_restores_snapshot, LaunchAgent rewriter shape preservation (dict + array shapes + no-op), half-migration detector coverage. The CHANGELOG v7.0.0 rollback recipe was also fixed — the old recipe silently clobbered operator state; the new recipe mandates backup-rename before restore.
B10 — module-level path constants lazy-evaluated
Four files migrated so monkeypatch.setenv(NEXO_HOME) works mid-run instead of snapshotting at import: src/public_contribution.py, src/tools_sessions.py, src/plugins/recover.py, src/plugins/update.py. PEP 562 __getattr__ keeps legacy attribute access working; the three runtime_root: Path = NEXO_HOME default-argument bugs in update.py are fixed explicitly (the default becomes None + resolve in body). Followup NF-B10-UPDATE-PY-LAZY-CALLSITES-COSMETIC tracks the 77 cosmetic callsites for v7.3.
Small fixes
- R34 bool fix:
bool("unknown")==Trueforce-inject corrected insrc/r34_identity_coherence.py. classify_scripts_dirdedup by realpath so transition-era symlinks and duplicate entries don't double-count.- B8 rules DB dedup: rules #212 and #224 merged; rule #156 Cloudflare/wrangler gains
applies_to_domainto stop cross-project false positives. Data-only change,change_log#356-359. - Schedule override audit log:
runtime/logs/core-schedule-overrides.loggets one JSON line per change (ts / name / action / previous / current / warning / actor). No-op calls stay out of the log. - Watchdog hash registry: now folds entries from the pre-F0.6 legacy path (
~/.nexo/scripts/.watchdog-hashes) into the canonical F0.6 file and removes the legacy artifact, with a symlink-alias guard so installs where the legacy path is a symlink to the canonical dir are not touched twice. - Watchdog manifest fallback gains a second slot (
$NEXO_HOME/crons/manifest.json) for half-migrated installs that would otherwise lose all core monitors.
Release discipline
scripts/pre-release-verify.sh: single-command sanity pack combiningverify_release_readiness.py --ci,verify_tool_map.py,check_no_personal_data.sh, and a minimal pre-release smoke. Paired withdocs/release-discipline.mddocumenting the exact order + who owns each step.- Pre-commit hook for
tool-enforcement-map.json: blocks commits when the tool map drifts from the actualsrc/plugins/MCP tool inventory. Enforces every developer runsverify_tool_map.pybefore push. - B9 privacy guard hardened:
check_no_personal_data.shgains aCHECK_ROOTconfigurable root and extends its shape-match layer; six new test cases cover regex detection beyond fixed-string tokens.
Pending
francisco_emailsshim retirada blocked until Nora (Maria's Mac) completes F0.6 migration via the new scripts. FollowupNF-B1B6-RETIRAR-FRANCISCO-EMAILS-POST-MARIAtarget2026-05-10.- Four B9 hooks runtime (NF-DS-552323BE post-audit followup, NF-DS-E41FBD45 re-consulta opt-out, NF-DS-67F8DCF5 continuity checklist, NF-DS-9B9B4E63 mid-session restriction-lift) deferred to
NF-B9-HOOKS-POST-RELEASE-2026-04-22— scope-risk runtime hooks, better handled with an observation window post-release. - B10 cosmetic callsites (77 remaining in
plugins/update.py) tracked inNF-B10-UPDATE-PY-LAZY-CALLSITES-COSMETICtarget2026-05-15. - Cortex calibration re-review at day 14 tracked in reminder
R-CORTEX-CALIBRATION-REVIEW-14Dtarget2026-05-06. - G6 mid-session pressure, G10 somatic markers scoped for v7.3 (need 14+ days of observation data after G1 lands).
Migration
Run nexo update. Everything else happens automatically:
~/.nexo/personal/config/guardian-runtime-overrides.jsonwritten withharddefaults for G1/G3/G3-SSH/G4.- Adaptive weights auto-promoted if the install already has ≥200 shadow samples + ≥2 days.
- F0.6 hardening doctor checks activate on the next
nexo doctor --tier boot. - Rollback path:
nexo rollback f06if anything goes wrong. - Operator opt-outs:
NEXO_GUARDIAN_PERSIST_HARD=off,NEXO_ADAPTIVE_EMPIRICAL_PROMOTION=off, or per-gate env vars (NEXO_G4_ENFORCE_GUARD_CHECK=shadow, etc.).
Desktop
NEXO Desktop v0.22.6 remains compatible with Brain v7.2.0 and is not bumped in this release — the MCP external contract did not change. Desktop bumps when its own D-block lands in a future release.
Verification
Full Brain pytest suite green on main post-merge. scripts/verify_release_readiness.py --ci green. scripts/verify_client_parity.py 179 tests + docs + parity passed. All five PRs (#261, #258, #259, #260, #262) passed their own CI end-to-end before squash-merge.