Release classification: boardless post-merge architecture follow-up; #13868 was approved and merged as shippable without this cleanup.
PR #13868 merged the native Ollama serve lifecycle slice for #13867. The approving review explicitly chose approve-and-follow-up: the PR adds value, but leaves roughly 200 LOC of configured child-process/provider task composition in Orchestrator, which is supposed to remain a small coordinator and should not know this much about delegated child processes.
Live evidence:
#13868 merged at 2026-06-22T20:38:39Z on head 7c2aec4278028ff0a603b6b55b7992411b2a75fe; merge commit c5c4055ac5bd9151b18483865ddcf1cb0545d82c.
Current ai/daemons/orchestrator/Orchestrator.mjs is 735 LOC.
Orchestrator.mjs:359-564 builds configured task definitions and inlines GraphLog, MLX, LMS, and Ollama task composition/liveness/preload closures.
ai/daemons/orchestrator/taskDefinitions.mjs is 335 LOC and remains the pure descriptor/default task table layer.
ai/services/memory-core/lifecycle/InferenceLifecycleService.mjs is 141 LOC and currently says Memory Core assumes MLX/Ollama are managed by AgentOrchestrator; it is adjacent prior art, not a direct relocation target by name alone.
Current ai/deploy/docker-compose.yml includes the cloud profile local-lane disables and Memory Core WAL in-process drain settings (NEO_MEMORY_WAL_IN_PROCESS_DRAIN=true, NEO_MEMORY_WAL_DIR=/app/.neo-ai-data/sqlite/memory-wal). The extraction must preserve current cloud deployment behavior, not just older discussion assumptions.
Live latest-open sweep: checked the latest 20 open issues at 2026-06-22T20:53:07Z. Closest related tickets were #13874, #13860, #13852, #13851, #13755, and #13624; no equivalent "extract configured task composition from Orchestrator" ticket was open. A2A in-flight sweep: checked latest 30 messages immediately before create; no competing claim found. Label sweep confirmed enhancement, ai, architecture, refactoring, and model-experience exist.
The Problem
Orchestrator.mjs keeps absorbing task-specific composition when new lifecycle lanes land. #13868 was not wrong to ship value, but it repeated the long-running failure mode: child-process/provider mechanics get added to the central coordinator because that is the nearest place with AiConfig and task-state access.
This is not only an Ollama issue. MLX/LMS composition and GraphLog flags already sit in the same configured task composition block. The follow-up should audit the whole configured-task composition surface rather than blaming only the last merge.
Prior art:
Discussion #11857 is the last explicit separation-of-concerns/decomposition discussion, but live GraphQL verification on 2026-06-22 showed it is still open and awaiting re-graduation. It is cited as prior art, not binding authority.
Memory Core raw memory bc86a77a-98de-4237-ab4a-60a0390a1e07 records the prior GPT review of #11857: single collector with typed metadata, no policy body in the collector, and profile/deployment metadata matters.
Memory Core raw memory 8237984d-23da-480b-ba36-6e91425c5559 records the #12096 trap: adding +174 LOC of REM mechanics to Orchestrator.mjs was blocked; the gate was that Orchestrator should stay limited to cadence/backpressure/readiness/delegation/task-health mapping.
ADR 0014 landed after the older SoC discussion and must constrain any extraction: local-only/cloud-deployable/shared primitive task taxonomy and cloud negative-behavior guarantees must remain intact.
The Architectural Reality
ai/daemons/orchestrator/Orchestrator.mjs should coordinate boot, scheduling/poll, and collaborator wiring, not own provider-specific child-process mechanics.
ADR 0014 classifies orchestrator lanes by deployment profile. Extraction must preserve local-only/cloud-deployable/shared-primitive gates; it must not make cloud start local wake/harness, MLX, local checkout sync, Chroma local supervision, or other local-only lanes.
The current cloud compose profile is now part of the live constraint set. mc-server owns its in-process WAL drain loop in the single-process container shape, and orchestrator runs with cloud-safe lane disables. Refactoring configured task composition must not move those responsibilities across profile boundaries.
ADR 0019 says AiConfig is the reactive Provider SSOT. The exact use-site boundary needs conscious treatment here: either the extracted composition module reads AiConfig directly because it is the correct use site, or Orchestrator passes a narrow named bootstrap object. The broad ad-hoc pass-through shape must not return.
ai/daemons/orchestrator/services/ already contains collaborator boundaries such as ProcessSupervisorService, MaintenanceBackpressureService, and TaskStateService. A configured-task composition service/builder likely belongs there if a new module is introduced, but implementation must run and document structural pre-flight.
ai/services/memory-core/lifecycle/InferenceLifecycleService.mjs is conceptually adjacent but currently a Memory Core shim that explicitly does not manage MLX/Ollama; do not blindly move Orchestrator code into it.
Structural pre-flight at ticket creation: considered ai/daemons/orchestrator/services/, ai/daemons/orchestrator/taskDefinitions.mjs, and ai/services/memory-core/lifecycle/. Fast-path candidate is ai/daemons/orchestrator/services/ because sibling orchestrator collaborators already live there; exact file name remains implementation-owned. Map maintenance is likely not needed if the PR adds another orchestrator service under the existing directory role, but implementation must re-check.
Substantive rationale for citing ungraduated Discussion #11857
Discussion #11857 is cited descriptively because it mapped the last SoC attempt. It is not treated as a graduation source.
Shape
Verdict
Rationale
Extract configured task composition under the current ADR 0014 taxonomy
Recommended
Solves the immediate post-#13868 bloat while preserving current local/cloud lane gates and cloud WAL-drain/container constraints.
Reopen #11857 as the only authority before filing
Rejected
#13868 has already merged and the review created a concrete follow-up. Waiting for re-graduation would leave active debt untracked.
Refactor only the new Ollama code
Rejected
The same block already includes MLX/LMS and GraphLog composition; an Ollama-only cleanup would preserve the accretion pattern.
If #11857 later graduates with a stricter topology, this ticket's target boundary, ACs, and ADR-impact note may need refresh before implementation.
The Fix
Extract the configured-task composition block out of Orchestrator.mjs while preserving behavior.
Expected implementation shape:
Move provider/child-process composition for MLX, LMS, Ollama, and adjacent configured task flags out of the Orchestrator class body.
Preserve taskDefinitions.mjs as the pure descriptor/defaults layer unless the implementation explicitly justifies changing that contract.
Preserve ADR 0014 deployment-profile behavior: local-only tasks remain local-only, cloud-deployable tasks remain cloud-safe, and shared primitives are not silently reclassified.
Preserve the live cloud compose constraints: Memory Core WAL drain ownership remains with the MC container/runtime path, and cloud orchestrator profile disables remain effective.
Resolve the ADR 0019 use-site question explicitly in code/docs/PR body.
Add focused tests proving the same tasks are composed/gated for local and cloud profiles before and after extraction.
Contract Ledger Matrix
Target Surface
Source of Authority
Proposed Behavior
Fallback
Docs
Evidence
Orchestrator.mjs configured task composition
#13868 review, current Orchestrator.mjs:359-564, v13 path, #11857 prior art
Orchestrator delegates configured task composition to a named collaborator/builder and remains a coordinator
If extraction splits into multiple collaborators, keep each boundary role-named and testable
JSDoc on new collaborator plus PR body boundary note
ADR 0014, current ai/deploy/docker-compose.yml cloud profile
Local-only/cloud-deployable/shared primitive classification is preserved through extraction
Failing profile parity test blocks merge
ADR citation plus test names
Local/cloud profile tests
Cloud WAL-drain ownership
Current ai/deploy/docker-compose.yml MC container env and WAL comments
MC container/runtime path owns the in-process WAL drain loop; configured task extraction does not move this into generic Orchestrator composition
If a future profile uses an embed daemon instead, it must be explicitly profile-gated
PR body deployment-profile note
Compose/config invariant or focused unit fixture
AiConfig read boundary
ADR 0019 plus #13868 review note
Chosen module reads resolved config at its true use site or receives a narrow named bootstrap object; no broad ad-hoc pass-through
If ADR 0019 wording conflicts, document whether this aligns with or amends/challenges ADR 0019
PR body Decision Record impact
Focused tests and lint; no defensive optional config subtree reads
InferenceLifecycleService adjacency
Source read of ai/services/memory-core/lifecycle/InferenceLifecycleService.mjs
Either leave it alone, retire/clarify it, or deliberately integrate after boundary proof
Do not move code there by name similarity alone
JSDoc/comment if touched
Tests only if touched
Decision Record impact
Aligned with ADR 0014 and ADR 0019. This may produce a small ADR 0019 clarification if the chosen "child module can import AiConfig" use-site boundary contradicts current wording. No ADR amendment is required merely to extract code.
Acceptance Criteria
Orchestrator.mjs no longer contains the MLX/LMS/Ollama provider-specific task descriptor, liveness, and preload construction block.
The extraction audits the whole configured-task composition block around Orchestrator.mjs:359-564, not only the new Ollama code.
Local/default task composition remains behaviorally equivalent for MLX, LMS, Ollama, GraphLog compaction, and continuous supervision.
Cloud/deployment-profile tests prove ADR 0014 local-only/cloud-deployable/shared primitive gates still hold after extraction.
Cloud compose/profile constraints remain intact: local-only lanes stay disabled in cloud, chroma is not reintroduced as an Orchestrator-supervised child in cloud, and Memory Core WAL drain ownership is not moved into generic Orchestrator composition.
The PR body states the resolved ADR 0019 config-read boundary and whether any ADR wording needs amendment.
If a new .mjs module is introduced, the PR documents the structural-pre-flight result and chosen directory.
Focused unit/invariant coverage runs for the affected orchestrator/task-definition/config-profile surfaces.
Out of Scope
Reopening or resolving all of Discussion #11857.
Changing the functional behavior delivered by #13868 / #13867.
Context
Release classification: boardless post-merge architecture follow-up;
#13868was approved and merged as shippable without this cleanup.PR
#13868merged the native Ollama serve lifecycle slice for#13867. The approving review explicitly chose approve-and-follow-up: the PR adds value, but leaves roughly 200 LOC of configured child-process/provider task composition inOrchestrator, which is supposed to remain a small coordinator and should not know this much about delegated child processes.Live evidence:
#13868merged at 2026-06-22T20:38:39Z on head7c2aec4278028ff0a603b6b55b7992411b2a75fe; merge commitc5c4055ac5bd9151b18483865ddcf1cb0545d82c.ai/daemons/orchestrator/Orchestrator.mjsis 735 LOC.Orchestrator.mjs:359-564builds configured task definitions and inlines GraphLog, MLX, LMS, and Ollama task composition/liveness/preload closures.ai/daemons/orchestrator/taskDefinitions.mjsis 335 LOC and remains the pure descriptor/default task table layer.ai/services/memory-core/lifecycle/InferenceLifecycleService.mjsis 141 LOC and currently says Memory Core assumes MLX/Ollama are managed by AgentOrchestrator; it is adjacent prior art, not a direct relocation target by name alone.ai/deploy/docker-compose.ymlincludes the cloud profile local-lane disables and Memory Core WAL in-process drain settings (NEO_MEMORY_WAL_IN_PROCESS_DRAIN=true,NEO_MEMORY_WAL_DIR=/app/.neo-ai-data/sqlite/memory-wal). The extraction must preserve current cloud deployment behavior, not just older discussion assumptions.Live latest-open sweep: checked the latest 20 open issues at 2026-06-22T20:53:07Z. Closest related tickets were
#13874,#13860,#13852,#13851,#13755, and#13624; no equivalent "extract configured task composition from Orchestrator" ticket was open. A2A in-flight sweep: checked latest 30 messages immediately before create; no competing claim found. Label sweep confirmedenhancement,ai,architecture,refactoring, andmodel-experienceexist.The Problem
Orchestrator.mjskeeps absorbing task-specific composition when new lifecycle lanes land.#13868was not wrong to ship value, but it repeated the long-running failure mode: child-process/provider mechanics get added to the central coordinator because that is the nearest place withAiConfigand task-state access.This is not only an Ollama issue. MLX/LMS composition and GraphLog flags already sit in the same configured task composition block. The follow-up should audit the whole configured-task composition surface rather than blaming only the last merge.
Prior art:
bc86a77a-98de-4237-ab4a-60a0390a1e07records the prior GPT review of#11857: single collector with typed metadata, no policy body in the collector, and profile/deployment metadata matters.8237984d-23da-480b-ba36-6e91425c5559records the#12096trap: adding +174 LOC of REM mechanics toOrchestrator.mjswas blocked; the gate was that Orchestrator should stay limited to cadence/backpressure/readiness/delegation/task-health mapping.The Architectural Reality
ai/daemons/orchestrator/Orchestrator.mjsshould coordinate boot, scheduling/poll, and collaborator wiring, not own provider-specific child-process mechanics.mc-serverowns its in-process WAL drain loop in the single-process container shape, andorchestratorruns with cloud-safe lane disables. Refactoring configured task composition must not move those responsibilities across profile boundaries.AiConfigis the reactive Provider SSOT. The exact use-site boundary needs conscious treatment here: either the extracted composition module readsAiConfigdirectly because it is the correct use site, orOrchestratorpasses a narrow named bootstrap object. The broad ad-hoc pass-through shape must not return.ai/daemons/orchestrator/services/already contains collaborator boundaries such asProcessSupervisorService,MaintenanceBackpressureService, andTaskStateService. A configured-task composition service/builder likely belongs there if a new module is introduced, but implementation must run and document structural pre-flight.ai/services/memory-core/lifecycle/InferenceLifecycleService.mjsis conceptually adjacent but currently a Memory Core shim that explicitly does not manage MLX/Ollama; do not blindly move Orchestrator code into it.Structural pre-flight at ticket creation: considered
ai/daemons/orchestrator/services/,ai/daemons/orchestrator/taskDefinitions.mjs, andai/services/memory-core/lifecycle/. Fast-path candidate isai/daemons/orchestrator/services/because sibling orchestrator collaborators already live there; exact file name remains implementation-owned. Map maintenance is likely not needed if the PR adds another orchestrator service under the existing directory role, but implementation must re-check.Substantive rationale for citing ungraduated Discussion #11857
Discussion
#11857is cited descriptively because it mapped the last SoC attempt. It is not treated as a graduation source.#13868bloat while preserving current local/cloud lane gates and cloud WAL-drain/container constraints.#11857as the only authority before filing#13868has already merged and the review created a concrete follow-up. Waiting for re-graduation would leave active debt untracked.If
#11857later graduates with a stricter topology, this ticket's target boundary, ACs, and ADR-impact note may need refresh before implementation.The Fix
Extract the configured-task composition block out of
Orchestrator.mjswhile preserving behavior.Expected implementation shape:
Orchestratorclass body.taskDefinitions.mjsas the pure descriptor/defaults layer unless the implementation explicitly justifies changing that contract.orchestratorprofile disables remain effective.Contract Ledger Matrix
Orchestrator.mjsconfigured task composition#13868review, currentOrchestrator.mjs:359-564, v13 path,#11857prior artai/deploy/docker-compose.ymlcloud profileai/deploy/docker-compose.ymlMC container env and WAL commentsAiConfigread boundary#13868review noteInferenceLifecycleServiceadjacencyai/services/memory-core/lifecycle/InferenceLifecycleService.mjsDecision Record impact
Aligned with ADR 0014 and ADR 0019. This may produce a small ADR 0019 clarification if the chosen "child module can import
AiConfig" use-site boundary contradicts current wording. No ADR amendment is required merely to extract code.Acceptance Criteria
Orchestrator.mjsno longer contains the MLX/LMS/Ollama provider-specific task descriptor, liveness, and preload construction block.Orchestrator.mjs:359-564, not only the new Ollama code.chromais not reintroduced as an Orchestrator-supervised child in cloud, and Memory Core WAL drain ownership is not moved into generic Orchestrator composition..mjsmodule is introduced, the PR documents the structural-pre-flight result and chosen directory.Out of Scope
#11857.#13868/#13867.#13624.Avoided Traps
AiConfigvalue pass-through that#13868's review rejected.InferenceLifecycleServiceas a dumping ground just because the name sounds adjacent.#11857's older topology notes; re-check current compose/profile/WAL-drain constraints during implementation.Related
Parent: #13624. Related: #13868, #13867, #13852, #11734. Prior-art: Discussion #11857, Discussion #11025, Memory Core raw memories
bc86a77a-98de-4237-ab4a-60a0390a1e07and8237984d-23da-480b-ba36-6e91425c5559.Origin Session ID: db5b2ecf-db91-4b7d-9498-ccef00426a1c
Handoff Retrieval Hints:
query_raw_memories("Orchestrator Round-2 decomposition Discussion #11857 thin coordinator task portfolio deployment profile");query_raw_memories("thin orchestrator local inference lifecycle composition Orchestrator bloat MLX LMS Ollama follow-up"); commitc5c4055ac5bd9151b18483865ddcf1cb0545d82c.