LearnNewsExamplesServices
Frontmatter
id14159
titleOrchestrator log grows unbounded — no daily rotation (the one daemon missing it)
stateClosed
labels
bugaimodel-experience
assigneesneo-opus-ada
createdAtJun 27, 2026, 12:42 AM
updatedAtJun 27, 2026, 8:48 AM
githubUrlhttps://github.com/neomjs/neo/issues/14159
authorneo-opus-ada
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJun 27, 2026, 8:48 AM

Orchestrator log grows unbounded — no daily rotation (the one daemon missing it)

Closed v13.1.0/archive-v13-1-0-chunk-7 bugaimodel-experience
neo-opus-ada
neo-opus-ada commented on Jun 27, 2026, 12:42 AM

Context (operator question, V-B-A'd 2026-06-26)

"How big should orchestrator.log grow? What is the cap?" → There is no cap and no rotation. Both writers append forever:

  • Orchestrator.writeLog (Orchestrator.mjs:569) — fs.appendFileSync(this.logFile, ...), the high-volume per-poll writer.
  • daemon.mjs:58fs.appendFileSync(LOG_FILE, ...), both targeting the same .neo-ai-data/orchestrator-daemon/orchestrator.log.

The live file was 33MB in ~10h and would keep growing indefinitely across days/restarts.

Inconsistency: the sibling daemons ALL rotate daily + prune:

  • embed/daemon.mjs:70 rotateLogIfNewDay() + pruneOldLogs() (30-day retention).
  • message/daemon.mjs:43 rotateLogIfNewDay().
  • wake/daemon.mjs daily .YYYY-MM-DD rotation.

The orchestrator — the highest-volume logger — is the only daemon without it.

The fix (match the proven sibling pattern)

Add daily rotation + retention prune to Orchestrator.writeLog: before the append, rotateLogFileIfNewDay(this.logFile) (rename to orchestrator.log.YYYY-MM-DD when the file's mtime is a prior calendar day); at startup, pruneOldDailyLogs() (delete orchestrator.log.* archives older than the retention window). Best-effort (log integrity must not gate daemon liveness — same contract as the siblings). The orchestrator polls every ~3s, so its writeLog reliably triggers the daily rotation; daemon.mjs's low-volume lines are carried by the same file's rotation.

Retention: 30 days, matching the embed daemon (LOG_RETENTION_DAYS).

Acceptance criteria

  • On a new calendar day, the active orchestrator.log is renamed to orchestrator.log.<prior-day> and a fresh active file is started.
  • Archives older than the retention window are pruned at startup.
  • Rotation/prune failures are swallowed (daemon liveness not gated).
  • Unit coverage: a log file with a prior-day mtime → rotated; a recent file → not; old archives → pruned, recent kept.

This bounds the size; the rate fixes (#14147 / #14149 / #14156) cut what fills each day. Refs #14039 (epic). Self-assign @neo-opus-ada. Authored by Ada (Claude Opus 4.8, Claude Code).

tobiu referenced in commit 8fa34cf - "fix(ai): daily-rotate the orchestrator log (was unbounded; the one daemon missing it) (#14159) (#14160) on Jun 27, 2026, 8:48 AM
tobiu closed this issue on Jun 27, 2026, 8:48 AM