Skip to content

v3.38.6 β€” Codex stdin fix, intelligence cache staleness fix, daemon config restore fix

Choose a tag to compare

@ruvnet ruvnet released this 12 Aug 20:49
· 5 commits to main since this release

Fixes

#2947 β€” DualModeOrchestrator left every Codex worker's stdin open, causing codex exec to hang waiting for EOF. Both Claude and Codex workers receive their prompt positionally/via a flag β€” never over stdin β€” but the pipe was never written to or closed. claude -p ignores the unused pipe, but codex exec blocks in resolve_root_prompt waiting for stdin EOF that never arrives, hanging every real Codex worker until the orchestrator's own multi-minute timeout kills it. Now closes stdin immediately after spawn for both platforms.

#2920 β€” Editing a MEMORY.md section's body (same ID, same entry count) served stale cached content instead of refreshing it. Two related bugs in the intelligence helper's graph/store caching, both keyed on entry count instead of content: init()'s graph-cache-hit gate compared only node count, so a same-ID content edit was invisible to it and ranked-context.json never refreshed; consolidate()'s persist gate only fired on insight creation or a dedup-driven shrink, so an in-memory content change (e.g. assigning an id to a previously id-less entry) was silently never written back to disk. Added a storeFingerprint() helper folding every entry's content into one aggregate value, used to gate the cache hit and to make consolidate() always persist.

#2935 β€” .claude-flow/config.json resourceThresholds overrides were silently lost to a stale daemon-state.json. The daemon's stale-state restoration guard only checked the constructor arg (originalConfig), not a value set via config.json β€” so an explicit override (e.g. minFreeMemoryPercent: 0, a workaround for Darwin's os.freemem() undercounting reclaimable memory) kept losing to whatever a daemon-state.json from before the override existed had persisted, on every restart. Same bug class as #2661 (aiWorkersEnabled), fixed the same way, per-field. Also fixed a secondary diagnostic bug: readDaemonConfigFromFile() logged "Daemon config loaded from ..." from inside the constructor before this.config existed, so the log call threw inside its own try/catch and never reached daemon.log β€” made "is the config file even being read?" impossible to answer from the log. Does not address this issue's primary Darwin os.freemem() memory-gate report β€” that needs vm_stat/memory_pressure-based measurement, left for a follow-up.

CI infrastructure

Fixed a recurring sharp/libvips "socket hang up" / 503 flake in npm ci across CI workflows (confirmed on 8+ unrelated PRs this session) by adding a retry-with-backoff composite action and wiring it into every npm ci call site, including the two OS-conditional fallback blocks initially missed.

Links