LearnNewsExamplesServices
Frontmatter
id11039
titleExtract TaskStateService to isolate state-mutation API
stateClosed
labels
enhancementai
assigneesneo-gemini-3-1-pro
createdAtMay 9, 2026, 8:21 PM
updatedAtMay 9, 2026, 8:54 PM
githubUrlhttps://github.com/neomjs/neo/issues/11039
authorneo-gemini-3-1-pro
commentsCount0
parentIssue11022
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 9, 2026, 8:54 PM

Extract TaskStateService to isolate state-mutation API

Closedenhancementai
neo-gemini-3-1-pro
neo-gemini-3-1-pro commented on May 9, 2026, 8:21 PM

Resolves Sub-1 of Epic #11022.

Problem Statement

The Orchestrator daemon currently suffers from the fat-class problem, mutating raw task state directly. Before we extract the ProcessSupervisorService, we must invert the dependency order: we must first extract TaskStateService to lock the state-mutation boundary. If we extract the supervisor first against raw mutable state, the new service will inherit the exact anti-pattern we are trying to eliminate.

Proposed Prescription

Extract TaskStateService into ai/daemons/services/TaskStateService.mjs.

This new service will own:

  • Mutation API: markStarted, markSkipped, markCompleted, markFailed, adoptRunning, clearRecovered, getLastRunAt
  • On-disk Persistence: readState, writeState, createInitialTaskState

The Orchestrator will consume this service via the taskState_ reactive collaborator. No downstream service will mutate raw state directly; they will consume the TaskStateService API.

Substrate

  • Location: ai/daemons/services/TaskStateService.mjs
  • Consumer: Orchestrator, ProcessSupervisorService (future extraction)

Acceptance Criteria

  • AC1: TaskStateService Neo class is created at ai/daemons/services/TaskStateService.mjs.
  • AC2: The mutation API and on-disk persistence logic is successfully migrated from Orchestrator to TaskStateService.
  • AC3: Orchestrator is updated to inject and consume TaskStateService via the taskState_ reactive config.
  • AC4: Orchestrator no longer mutates raw task state directly.
  • AC5: All existing Orchestrator tests continue to pass (no behavior regression), and new service-level unit specs are added for TaskStateService.

Avoided Traps

  • Extract ProcessSupervisor first — this would bake in raw-state-mutation responsibility we're trying to remove. TaskStateService must extract first.
  • Change behavior — this is a pure refactor/extraction. The on-disk state schema and task behavior must remain identical.
tobiu referenced in commit c938d36 - "refactor(orchestrator): extract TaskStateService from Orchestrator (#11041) on May 9, 2026, 8:54 PM
tobiu closed this issue on May 9, 2026, 8:54 PM