LearnNewsExamplesServices
Frontmatter
id11009
titleMove Orchestrator logic into Neo daemon class
stateClosed
labels
enhancementairefactoringarchitecturemodel-experience
assigneesneo-gpt
createdAtMay 9, 2026, 1:34 PM
updatedAtMay 12, 2026, 4:09 AM
githubUrlhttps://github.com/neomjs/neo/issues/11009
authorneo-gpt
commentsCount4
parentIssue9999
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[x] 11017 Orchestrator task: primary-checkout `dev` auto-sync + KB cascade
closedAtMay 9, 2026, 4:34 PM

Move Orchestrator logic into Neo daemon class

Closedenhancementairefactoringarchitecturemodel-experience
neo-gpt
neo-gpt commented on May 9, 2026, 1:34 PM

Context

This follow-up exists because PR #11008 merged the #11006 Orchestrator MVP in a shape that conflicts with the v13 architecture path the PR itself referenced.

PR #11008 added ai/scripts/orchestrator-daemon.mjs as a 455-line runtime owner for task definitions, singleton enforcement, state files, child-process adoption, scheduling intervals, sunset-handover polling, and summary / KB-sync task dispatch. That got the immediate MVP behavior out of bridge-daemon.mjs, but it also moved the real Orchestrator logic into ai/scripts/.

learn/agentos/v13-path.md defines a stricter M3 structure:

ai/scripts/orchestrator-daemon.mjs   # Thin Node-process boot wrapper (PID file, lifecycle, error-isolation)
ai/daemons/Orchestrator.mjs          # Neo class: schedules + runs tasks; per-task try/catch
ai/daemons/services/
  ├── SummarizationCoordinatorService.mjs   # NEW: Piece C
  ├── DreamService.mjs (existing)            # consumed by Orchestrator
  ├── SwarmHeartbeatService.mjs (existing)   # consumed by Orchestrator
  └── ... (existing decomposed services from #10013)

Operator feedback after the merge: the new script item conflicts with that path and turns the MVP into new technical debt. This ticket captures the repair instead of letting future Agent OS maintenance tasks accrete inside the script wrapper.

The Problem

The MVP preserved bridge-daemon focus, but the Orchestrator boundary is now inverted:

  • ai/scripts/orchestrator-daemon.mjs owns scheduling and task orchestration instead of only booting a Neo daemon class.
  • ai/daemons/Orchestrator.mjs does not exist yet, so M3's class boundary is not represented in code.
  • SummarizationCoordinatorService.mjs does not exist yet, so Piece C remains child-process dispatch around summarize-sessions.mjs rather than a daemon service boundary.
  • Failure isolation is local to child-process callbacks and a broad runMaintenanceCycle() try/catch, not the v13 path's per-task try/catch with a task-health envelope. HealthService.recordTaskOutcome(...) does not exist yet; the nearest precedent is HealthService.recordStartupSummarization(status, details=null) in ai/services/memory-core/HealthService.mjs.
  • The longer the script wrapper owns this logic, the more likely DreamService, SwarmHeartbeatService, graph maintenance, and concept ingestion get appended to ai/scripts/ instead of being scheduled by a real daemon class.

This is not a request to roll back #11008. It is the corrective M3 completion ticket: keep the useful MVP behavior, move its load-bearing logic to the proper substrate.

The Architectural Reality

  • learn/agentos/v13-path.md lines 93-104 define ai/scripts/orchestrator-daemon.mjs as the thin boot wrapper and ai/daemons/Orchestrator.mjs as the scheduler / task runner.
  • learn/agentos/v13-path.md lines 147-152 name M3 as Orchestrator.mjs plus the boot wrapper, with #11006 only as the MVP split.
  • PR #11008 merged ai/scripts/orchestrator-daemon.mjs with 455 lines of orchestration logic and added npm run ai:orchestrator as the external operator entrypoint.
  • #11006 and #10813 are closed. They explain the MVP lineage, but neither should be reopened for this structural repair.
  • #10449 tracks the prevention layer (structural-pre-flight). This ticket is the repair layer for the concrete #11008 debt.
  • Discussion #10447 is the earlier archaeological source for the same class of issue: daemon-shaped runtime logic accumulating under ai/scripts/ because directory-choice discipline fired too late.

The Fix

Reshape #11008's MVP into the v13 M3 architecture without changing the operator-facing command:

  1. Add ai/daemons/Orchestrator.mjs as a Neo class that owns task registration, cadence calculation, per-task execution, state updates, and task-failure isolation.
  2. Add ai/daemons/services/SummarizationCoordinatorService.mjs for the Piece C summary trigger path, so summarization logic is no longer just a child-process branch inside the script wrapper.
  3. Reduce ai/scripts/orchestrator-daemon.mjs to a thin Node-process boot wrapper: process-level lifecycle, PID file, error isolation, environment setup, and class instantiation.
  4. Preserve npm run ai:orchestrator and the #11008 env contracts: NEO_ORCHESTRATOR_POLL_INTERVAL_MS, NEO_ORCHESTRATOR_SUMMARY_SWEEP_INTERVAL_MS, NEO_ORCHESTRATOR_KB_SYNC_INTERVAL_MS, and the compatibility alias NEO_SUMMARIZATION_SWEEP_INTERVAL_MS.
  5. Introduce the smallest daemon-task health surface needed for per-task outcomes. A HealthService.recordTaskOutcome(taskName, status, details=null)-style method is in scope and should mirror the existing recordStartupSummarization(status, details=null) envelope rather than inventing a separate reporting shape.
  6. Rewrite the #11006 MVP note in learn/agentos/v13-path.md from "future full class remains" to the new landed state once this ticket merges.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
npm run ai:orchestrator / ai:scripts operator entrypoint #11006, PR #11008, package.json Still starts the Orchestrator daemon; external command and env contracts remain compatible Manual npm run ai:summarize-sessions and npm run ai:sync-kb remain operator escape hatches learn/agentos/v13-path.md, operator notes if present Node syntax checks + wrapper unit tests
ai/scripts/orchestrator-daemon.mjs learn/agentos/v13-path.md D3 structure Thin boot wrapper only: PID, lifecycle, process error isolation, class startup If daemon class fails to instantiate, log and exit non-zero without touching bridge-daemon behavior v13-path.md M3 section Static grep verifies no task scheduling logic remains in script
ai/daemons/Orchestrator.mjs learn/agentos/v13-path.md D3 / M3 Neo class owns task scheduling, per-task try/catch, state, and health outcomes Individual task failure records an error and leaves other tasks eligible to run JSDoc / @summary on class and methods Unit tests for summary failure not blocking KB sync or later tasks
Orchestrator task health envelope HealthService.recordStartupSummarization(status, details=null) precedent Add recordTaskOutcome(taskName, status, details=null) or the smallest equivalent daemon-health method with the same status + details envelope If health substrate cannot be extended cleanly in this PR, document the blocker and keep per-task state file evidence JSDoc / @summary on new health method Unit tests assert success/failure outcomes are recorded per task
SummarizationCoordinatorService.mjs #10813 Piece C, v13-path.md D3 structure Owns summary sweep / sunset-handover trigger coordination consumed by Orchestrator Manual summarization script stays available JSDoc / @summary Unit tests for sunset handover and interval sweep trigger shape

Acceptance Criteria

  • ai/daemons/Orchestrator.mjs exists as a Neo class with JSDoc / @summary coverage for the class and its load-bearing methods.
  • ai/daemons/services/SummarizationCoordinatorService.mjs exists and owns the summary-trigger coordination currently embedded in the script wrapper.
  • ai/scripts/orchestrator-daemon.mjs is reduced to a thin boot wrapper and no longer owns task definitions, cadence decisions, or task dispatch logic.
  • npm run ai:orchestrator still works and preserves all #11008 env var contracts and aliases.
  • Per-task failure isolation is explicit: one task failure records an outcome and does not stop unrelated due tasks from running.
  • Health observability records success/failure per orchestrated task. Introducing HealthService.recordTaskOutcome(taskName, status, details=null) is in scope and should mirror the existing recordStartupSummarization(status, details=null) envelope in ai/services/memory-core/HealthService.mjs.
  • Unit tests cover Orchestrator scheduling, disabled intervals, per-task failure isolation, wrapper startup behavior, and preservation of the existing bridge-daemon separation.
  • learn/agentos/v13-path.md is updated so the M3 section no longer describes #11008's script-heavy MVP as the standing target once the class split lands.
  • No new Agent OS scheduled-maintenance task logic is added directly to ai/scripts/ as part of this repair; verify with rg "setInterval|scheduleTask|runMaintenanceCycle|buildTaskDefinitions" ai/scripts/orchestrator-daemon.mjs returning no matches after the wrapper split.

Out of Scope

  • Moving wake delivery into the Orchestrator. bridge-daemon.mjs remains specialized for wake-event delivery.
  • Completing M4 DreamService / Sandman / Golden Path scheduling. This ticket can add extension points, but it should not pull the full M4 migration into the repair PR.
  • M2 common base MCP server work.
  • M5 NEO_MC_PRIMARY retirement.
  • Broad directory reshaping such as moving bridge-daemon.mjs out of ai/scripts/; that remains tied to the structural-pre-flight / daemon-isolation lineage.

Avoided Traps

  • Do not treat #11006 closure as M3 completion. It was an MVP split that moved work out of bridge-daemon.mjs; it did not land the class structure promised by v13-path.
  • Do not append more tasks to the script wrapper. That compounds the debt this ticket exists to remove.
  • Do not reopen #10813 or #11006 for this. Both are closed lineage tickets; this repair needs its own review surface.
  • Do not over-expand into all future daemon services. The repair should create the Orchestrator class boundary and migrate the existing #11008 summary / KB sync behavior first.
  • Do not file a narrower companion MX ticket for this same prevention layer. #10449 already owns the broad structural-pre-flight skill work; PR #11008 / #11009 should feed that epic as a second empirical anchor instead of splitting the graph into an ai/scripts/-only review rule.

Related

  • Parent v13 epic: #9999
  • Closed MVP ticket: #11006
  • Merged MVP PR: #11008
  • Closed summarization lineage: #10813
  • Archaeological source: Discussion #10447
  • Architectural source of authority: learn/agentos/v13-path.md
  • Prevention layer: #10449 — existing structural-pre-flight epic graduated from Discussion #10447. PR #11008 / #11009 is a second empirical anchor for that broader skill, after the original bridge-daemon.mjs placement issue.

Origin Session ID: 20a824b0-29d1-4082-ae12-87705ec69c3f

Retrieval Hint: query_raw_memories(query="PR #11008 orchestrator-daemon script wrapper v13-path ai/daemons Orchestrator SummarizationCoordinatorService technical debt follow-up")

tobiu referenced in commit 9c228ae - "feat(skill): structural-pre-flight discipline gate (#10449 sub-1) (#11010) on May 9, 2026, 2:28 PM
tobiu referenced in commit 45bab37 - "refactor(ai): move orchestrator logic into daemon class (#11009) (#11016) on May 9, 2026, 4:34 PM
tobiu closed this issue on May 9, 2026, 4:34 PM
tobiu referenced in commit ab4f97c - "feat(skill): session-sunset primary-checkout staleness probe (#11013) (#11015) on May 9, 2026, 4:34 PM
tobiu referenced in commit 576f663 - "feat(docs): v13-path.md update post-Round-2 substrate (#11019) (#11043) on May 9, 2026, 9:57 PM