- Rewrote
mcodexas a Node bin (scripts/mcodex.js); the old bash script shipped as a Windows bin died withHCS_E_SERVICE_NOT_AVAILABLEwhen a WSL stub shadowed git-bash. Zero bash dependency on the default path;tmux/watchinvoked as argv arrays; graceful degrade when absent. - Canonicalized the direct-run gate (realpath) so the launcher runs through an npm-created symlink bin.
- Relayed
SIGTERM/SIGINTto the spawned child so it is never orphaned.
- Isolated OAuth concurrent-login state in per-call closures instead of the shared
http.Serverinstance, so parallel logins can't cross-bind callbackcode/state. - Serialized the local-client-token store's read-modify-write through its write queue and widened the rename retry set to
EBUSY/EPERM/EAGAIN/ENOTEMPTY/EACCES; debouncedlastUsedAtwrites on the bearer-verify hot path.
- Closed the
routingMutex="enabled"selection race: selection and cursor commit now run in one reentrant mutex acquisition. Legacy mode unchanged. - Bucketed a model-less
/codex/responsesrequest into the codex family (CURRENT_CODEX_MODEL) instead of the generalgpt-5.5family, keeping rotation/cooldown/budget accounting correct. - Stripped inbound
cookie/proxy-authorizationon both egress paths; short-circuited per-request storage re-reads on unchanged mtime/size; check auth before path/method (401 before 404).
- Fixed a storage-transaction deadlock: flagged-storage recovery (backup restore + legacy-file migration) inside a held lock re-acquired the global mutex and wedged all later saves. Lock ownership is now tracked so recovery persists without re-locking.
- Preserved
pinnedAccountIndex/affinityGenerationthrough the combined transaction clone so a doctor restore no longer erases the manual pin. - Serialized the env-path config save under a cross-process file lock (owner token + compare-before-unlink) plus retried
statand mtime compare-and-swap. - Created secret directories
0o700; floored fractional indices and coercedNaNinclampIndex.
gpt-5.5is now the default live/quota probe model, legacy fallback chain (gpt-5.4→gpt-5.3-codex→gpt-5.2-codex→gpt-5-codex) preserved in one sharedQUOTA_PROBE_MODEL_CHAIN.- Codex-unavailable accounts are labeled "signed in" not "working"; live check gained
Codex available/signed in only/need re-logincounters (!instead of✓).
- Classified the normalized "model not currently available for this ChatGPT account" wording as an entitlement block across the probe/forecast/report/check surfaces.
- Excluded policy-blocked and token-exhausted accounts from forecast recommendations.
- Fixed status-tone precedence so a failed live check carrying a quota percentage renders red, not green.
- Hardened
--modelparsing on every parser (best, forecast, report, fix, integrations, models): a flag-like or whitespace-only value after--model/-m/--model=is rejected, not consumed. - Rejected non-integer
workspace/switchindices instead of truncating; rejected a flag-likebudget checkkey. - Shipped
.codex-plugin/plugin.jsonin the package, enforced by the pack-budget check via an exact-file requirement. - Read the capability matrix under the entitlement key (matching the write path); clamped out-of-range quota percentages; made capability-policy eviction LRU.