v5.3.24 — One JSON to Rule All Model Defaults
Three compounding bugs turned out to share a root cause: NEXO Brain had no single source of truth for model defaults. The Python runtime, the JS installer, and the client-config sync layer each kept their own copy, and they silently drifted apart.
v5.3.24 consolidates everything into one file — src/model_defaults.json — read identically by Python and JS. Editing one line now updates new installs, offers a migration prompt to existing users, and keeps cron automation honest across updates.
The Bugs We Caught
1. Codex inheriting Claude models
A stale alias (DEFAULT_CODEX_MODEL = DEFAULT_CLAUDE_CODE_MODEL) wrote claude-opus-4-6[1m] into ~/.codex/config.toml. Codex with a ChatGPT account then rejected every session with "model not supported". Fresh installs using Codex as the primary client were dead on arrival.
2. Headless crons stalling on permission prompts
The installer wrote the MCP server into ~/.claude/settings.json but never populated permissions.allow. Interactive users had built up an allowlist click-by-click over months; fresh installs — and anyone running NEXO headlessly from cron — got a stall on every tool call because Claude Code was waiting for approval that would never come. Followup-runner, email-monitor, deep-sleep and the whole automation stack silently zombied.
3. nexo update crashing on heavy source repos
If the runtime was ever synced from a local development checkout, git status --porcelain ran against that directory on every update. On a 370MB repo with an unignored virtualenv, git hung past the 10-second timeout and the update crashed with TimeoutExpired.
The Architecture
A single JSON, read by both runtimes:
{
"schema_version": 1,
"claude_code": {
"model": "claude-opus-4-6[1m]",
"reasoning_effort": "",
"display_name": "Opus 4.6 with 1M context",
"recommendation_version": 1,
"previous_defaults": []
},
"codex": {
"model": "gpt-5.4",
"reasoning_effort": "xhigh",
"display_name": "GPT-5.4 with max reasoning",
"recommendation_version": 1,
"previous_defaults": []
}
}
When a new model ships, a maintainer edits the JSON, bumps recommendation_version, and pushes a release. On the next interactive nexo update, existing users on the prior NEXO default see a one-time prompt:
[NEXO] ⭐ Nueva recomendación de modelo para claude_code:
claude-opus-6-0 (antes: claude-opus-4-6[1m])
Opus 6.0 — recomendado por NEXO.
¿Migrar tu configuración? [y/N/later]:
Three branches:
- Customized models (not a prior NEXO default) are respected silently. No prompt, no nag. The user picked their model for a reason.
- Users already on the current recommendation are auto-acknowledged without any output. (Fresh installs never see a "migrate?" prompt for the model they just received seconds earlier.)
- Non-interactive updates (cron / headless
nexo update) log a single hint to stderr telling the user to re-run interactively, and skip any write that would require a decision.
Self-Heal on Update
Users who installed on an older version have Claude-family models wedged into their Codex profile. nexo update now scans client_runtime_profiles.codex.model, detects any claude-* / opus-* / sonnet-* / haiku-* value, and resets it to the current Codex default before client configs are re-synced. The heal runs on both the legacy sync and the packaged npm update code paths, so it fires regardless of how the user installed.
Headless-Safe Defaults
The installer now writes a minimum permissions.allow list into ~/.claude/settings.json: Bash, Read, Edit, Write, Glob, Grep, Task, Skill, NotebookEdit, WebSearch, WebFetch, mcp__*. The mcp__* wildcard covers every present and future MCP server without forcing a maintainer release every time a new one lands.
Codex gets its own defense: approval_policy = "never" and sandbox_mode = "danger-full-access" are written on install when those keys are absent. Existing user values are preserved untouched.
Update
npm update -g nexo-brain
nexo update
Fresh installs get the new defaults. Existing installs self-heal Codex profiles on first update. Users on older NEXO defaults will see the migration prompt when a new recommendation ships; users who customized their models will never be bothered.