---
id: 11049
title: 'ai/ Neo namespace bootstrap hygiene: entry-point-only Neo+core+InstanceManager imports'
state: CLOSED
labels:
  - enhancement
  - ai
  - refactoring
  - architecture
  - model-experience
assignees:
  - neo-opus-ada
createdAt: '2026-05-09T19:51:32Z'
updatedAt: '2026-06-07T17:09:17Z'
githubUrl: 'https://github.com/neomjs/neo/issues/11049'
author: neo-opus-ada
commentsCount: 1
parentIssue: null
subIssues: []
subIssuesCompleted: 0
subIssuesTotal: 0
blockedBy: []
blocking: []
closedAt: '2026-05-09T20:58:46Z'
---
# ai/ Neo namespace bootstrap hygiene: entry-point-only Neo+core+InstanceManager imports

## Context

Operator architectural clarification 2026-05-09 (post-PR-#11044 Cycle 2): `import Neo from 'src/Neo.mjs'` belongs ONLY in **process entry points** (executable files — the `node X.mjs` target), NEVER in consumed-class files. Plus all process entry points need `import InstanceManager from 'src/manager/Instance.mjs'` to enable `Neo.find` / `Neo.findFirst` / `Neo.get` aliases + consume the pre-singleton `Neo.idMap` + set `Base.instanceManagerAvailable = true`.

**Damage mechanism (multi-import beyond style-smell):**
1. **Architectural invariant violation**: per `src/Neo.mjs:52-55` doc, namespace assembly is entry-point's responsibility. Non-entry-point importing Neo violates layer-of-responsibility.
2. **Direct-load brittleness**: if a consumed-class file is loaded without going through its entry point (e.g., test bootstrap, isolated import), `globalThis.Neo` is partially populated (no Util/Compare augmentation, no InstanceManager bootstrap) and `Neo.setupClass(...)` may silently fail or work-then-break.
3. **InstanceManager-missing damage** (`src/manager/Instance.mjs:31-37`): without `import InstanceManager` in entry point, `Base.instanceManagerAvailable` stays `false`, `Neo.find`/`Neo.findFirst`/`Neo.get` aliases never bind, and `Neo.idMap` accumulates without being consumed (pre-singleton brittleness).

## Empirical Audit (ai/ folder)

### Class files that should NOT import Neo (consumed by entry points — SMELL):

| File | Why it's a class (not entry) |
|---|---|
| `ai/daemons/Orchestrator.mjs` | Consumed by `ai/scripts/orchestrator-daemon.mjs` (the `node X` target) |
| `ai/daemons/SwarmHeartbeatService.mjs` | Consumed by daemon entry points / operator scripts |
| `ai/daemons/services/SummarizationCoordinatorService.mjs` | Consumed by Orchestrator class chain |

### Entry point scripts that need Neo + core/_export + InstanceManager additions:

| File | Current state |
|---|---|
| `ai/scripts/orchestrator-daemon.mjs` | MISSING all 3; only imports Orchestrator class |
| `ai/scripts/bridge-daemon.mjs` | NEEDS VERIFICATION (audit per file) |
| `ai/scripts/*.mjs` other operator scripts | NEEDS PER-FILE AUDIT (some already have all 3 per earlier grep; others missing) |
| `ai/scripts/summarize-sessions.mjs` | Spawned-child entry point — NEEDS VERIFICATION |
| `buildScripts/ai/syncKnowledgeBase.mjs` | Spawned-child entry point — NEEDS VERIFICATION |
| `buildScripts/ai/backup.mjs` | Future BackupService spawn target — NEEDS VERIFICATION |

### Already correct (verified):

| File | Status |
|---|---|
| `ai/mcp/server/*/mcp-server.mjs` (5 files) | ✓ Import Neo + core + InstanceManager |
| `ai/mcp/server/*/Server.mjs` (consumed classes) | ✓ Do NOT import Neo |
| `ai/daemons/services/TaskStateService.mjs` | ✓ Cleaned via [PR #11044](https://github.com/neomjs/neo/pull/11044) Cycle 2 |
| `ai/daemons/services/ProcessSupervisorService.mjs` | ✓ NEW file via [PR #11044](https://github.com/neomjs/neo/pull/11044) without Neo import |
| `ai/daemons/DreamService.mjs` | ✓ No Neo import (canonical pattern precedent) |
| `ai/services.mjs` | ✓ Imports Neo + InstanceManager (SDK aggregator entry-point-shape) |
| `ai/mcp/client/mcp-cli.mjs` | ✓ Imports Neo + InstanceManager |
| `ai/demo-agents/mcp-demo-agent.mjs` | ✓ Imports Neo + InstanceManager |

## Prescription

**Two-direction cleanup with single coherent substrate concern (entry-point invariant alignment):**

### Direction 1: Remove Neo imports from class files (3 files)

```diff
- import Neo from '../../src/Neo.mjs';   // [or relative variant]
- import * as core from '../../src/core/_export.mjs';   // [if present]
```

Files:
- `ai/daemons/Orchestrator.mjs`
- `ai/daemons/SwarmHeartbeatService.mjs`
- `ai/daemons/services/SummarizationCoordinatorService.mjs`

`Neo.setupClass(...)` at file end works via `globalThis.Neo` populated by entry-point bootstrap (matches `DreamService.mjs:349` precedent).

### Direction 2: Verify and add Neo + core + InstanceManager to entry points

For each entry-point script (audit per file):

```diff
+ import Neo             from '../../src/Neo.mjs';   // [or relative variant]
+ import * as core       from '../../src/core/_export.mjs';
+ import InstanceManager from '../../src/manager/Instance.mjs';
```

Files to audit:
- `ai/scripts/orchestrator-daemon.mjs` (confirmed MISSING all 3)
- `ai/scripts/bridge-daemon.mjs`
- All `ai/scripts/*.mjs` operator scripts not already covered
- Spawned-child scripts: `ai/scripts/summarize-sessions.mjs`, `buildScripts/ai/syncKnowledgeBase.mjs`, `buildScripts/ai/backup.mjs`

## Acceptance Criteria

- [ ] AC1 — `ai/daemons/Orchestrator.mjs`, `ai/daemons/SwarmHeartbeatService.mjs`, `ai/daemons/services/SummarizationCoordinatorService.mjs` no longer import Neo or `core/_export`; class-file canonical pattern (matches DreamService.mjs precedent)
- [ ] AC2 — `ai/scripts/orchestrator-daemon.mjs` imports Neo + `core/_export` + InstanceManager; daemon process bootstrap is complete (not relying on consumed-class imports)
- [ ] AC3 — Audit + fix all `ai/scripts/*.mjs` entry points for missing Neo/core/InstanceManager imports
- [ ] AC4 — Audit + fix spawned-child entry points (`summarize-sessions.mjs`, `syncKnowledgeBase.mjs`, `backup.mjs`) — each child Node process needs own bootstrap since orchestrator spawns separate Node processes via `spawn()`
- [ ] AC5 — Audit + fix `ai/scripts/bridge-daemon.mjs` per same criterion
- [ ] AC6 — Existing tests pass (canonical Orchestrator.spec.mjs + service-level specs); new test substrate not required (refactor preserves behavior)
- [ ] AC7 — Cross-family review per `pull-request §6.1` (substrate-shaped change touching daemon entry points)

## Avoided Traps

- ❌ **Bundle with broader /tech-debt-radar systematic audit** — keep this ticket scope-restraint compliant per `feedback_substrate_scope_restraint`; broader audit can be separate Ideation Sandbox if useful
- ❌ **Forget spawned-child entry points** — orchestrator's `spawn(nodeBin, [scriptPath])` pattern means each spawned script is its own Node process needing own bootstrap; not visible from in-process import-graph
- ❌ **Manual one-by-one without audit-first** — verify each file's current state via `grep -nE "^import Neo\b" ai/scripts/*.mjs` before editing; some entry points may already have full bootstrap

## Provenance

- Operator clarification 2026-05-09: *"Neo as an import belongs ONLY into entry point files. Inside the left hemisphere e.g. worker.App or Main. A Neo import NEVER belongs into imports of entry point files themselves."*
- Operator follow-up 2026-05-09: *"i would go into the other direction: process entry points NEED import InstanceManager from ...manager/Instance.mjs => enables Neo.get(), and removes the instance maps => proper collection."*
- Operator entry-point-criterion clarification 2026-05-09: *"is there an executable file or not."* + child-process framing: orchestrator spawns child Node processes; each child = own entry point needing own bootstrap
- Empirical anchor: `src/Neo.mjs:52-55` doc note on namespace augmentation by core modules; `src/manager/Instance.mjs:31-37` Neo.find/findFirst/get aliases + Base.instanceManagerAvailable flag
- Sister precedent: `ai/daemons/DreamService.mjs:349` (canonical class-file pattern without Neo import); `ai/mcp/server/*/mcp-server.mjs` (entry-point pattern with all 3)
- PR #11044 Cycle 2 caught the smell on TaskStateService + ProcessSupervisorService; this ticket extends the cleanup to remaining ai/ surfaces

## Cross-Discussion Links

- [Discussion #11026](https://github.com/orgs/neomjs/discussions/11026) — Flat Peer-Team paradigm anchor (architectural primitive that v2 InstanceManager direction extends)
- [PR #11044](https://github.com/neomjs/neo/pull/11044) Cycle 2 — Neo-import-as-entry-point-only canonical form first established for daemon-tier services

---

**Self-Identification:** @neo-opus-ada (Claude Opus 4.7, Claude Code) — chief-architect lane, post-Round-3 quick-win cleanup. Open lane for self-selection.

## Timeline

- 2026-05-09T19:51:33Z @neo-opus-ada added the `enhancement` label
- 2026-05-09T19:51:33Z @neo-opus-ada added the `ai` label
- 2026-05-09T19:51:33Z @neo-opus-ada added the `refactoring` label
- 2026-05-09T19:51:33Z @neo-opus-ada added the `architecture` label
- 2026-05-09T19:51:34Z @neo-opus-ada added the `model-experience` label
- 2026-05-09T20:21:16Z @neo-opus-ada assigned to @neo-opus-ada
- 2026-05-09T20:24:27Z @neo-gemini-pro cross-referenced by PR #11053
### @neo-opus-ada - 2026-05-09T20:30:00Z

## Empirical findings from execution + operator scope refinement

Empirical audit on the agent/11049 branch surfaced two refinements vs. the original prescription:

### 1. SwarmHeartbeatService.mjs is a hybrid entry-point, not a pure class file

The audit-via-grep showed **no consumers** of `ai/daemons/SwarmHeartbeatService.mjs` — it's purely self-invoked under launchd / systemd via the `if (isMain)` block at lines 522-540. By the operator's "is there an executable file" criterion, this IS an entry point.

**Treatment differs:** rather than removing Neo+core (would break the self-invoke), I **added InstanceManager** so all 3 entry-point invariant imports are present. Future cleanup (deferred to follow-up): split into `ai/daemons/SwarmHeartbeatService.mjs` (class only) + `ai/scripts/swarm-heartbeat-daemon.mjs` (entry point), matching Orchestrator class+wrapper pattern.

### 2. Operator scope correction: "v13 new daemon architecture, consistent entry points"

The original ticket's AC3 mentioned "audit + fix all `ai/scripts/*.mjs` entry points." The full audit showed **wide variability** across 41 scripts (some have all 3 imports, some have 2, most have 0). Per @tobiu's clarification that the goal is *v13 new daemon architecture consistency*, this PR scopes to the v13 daemon-architecture surfaces only:

| File | Treatment |
|---|---|
| `ai/scripts/orchestrator-daemon.mjs` | ADD Neo+core+InstanceManager (was missing all 3) |
| `ai/scripts/bridge-daemon.mjs` | ADD Neo+core+InstanceManager (was missing all 3) |
| `ai/daemons/SwarmHeartbeatService.mjs` | ADD InstanceManager (hybrid entry-point) |
| `ai/scripts/summarize-sessions.mjs` | ADD Neo+core+InstanceManager (orchestrator spawn-child) |
| `buildScripts/ai/syncKnowledgeBase.mjs` | ADD InstanceManager (orchestrator spawn-child) |
| `buildScripts/ai/backup.mjs` | ADD core+InstanceManager (future BackupService spawn-child) |
| `ai/daemons/Orchestrator.mjs` | REMOVE Neo+core (consumed-class) |
| `ai/daemons/services/SummarizationCoordinatorService.mjs` | REMOVE Neo+core (consumed-class) |

**Out of scope for this PR (deferred):**
- Other operator scripts with partial bootstrap (e.g., `analyzeNlTelemetry.mjs`, `checkSunsetted.mjs`, `migrateMemoryCore.mjs`, etc.) — these are operator-runnable but not part of the v13 daemon architecture surface
- SwarmHeartbeatService class+entry-point split — bigger architectural change; follow-up ticket recommended

### 3. Test-side bootstrap pattern caught + applied

`SummarizationCoordinatorService.spec.mjs` previously relied on the class file's own Neo import. Removing that triggered `ReferenceError: Neo is not defined` in Compare.mjs:166 at module-load. Fixed by adding Neo+core bootstrap to the spec, matching the established pattern in TaskStateService.spec.mjs + ProcessSupervisorService.spec.mjs + Orchestrator.spec.mjs (all already pre-existing). The test-spec IS the entry point for test-bootstrap.

### Empirical results

- 60/60 tests passing (Orchestrator, orchestrator-daemon, SummarizationCoordinator, SwarmHeartbeat, bridge-daemon, backup, restore, swarm-heartbeat, top-level Orchestrator)
- Net diff: +59 / -14 across 8 files (mostly comment lines explaining the invariant)
- All 8 files pass `node --check` syntax validation

Opening PR shortly. Cross-family review request to @neo-gemini-3-1-pro per swarm-PR-review-routing memory (single peer for routine substrate-shape PRs).

— @neo-opus-4-7 (Claude Opus 4.7, Claude Code)


- 2026-05-09T20:31:24Z @neo-opus-ada cross-referenced by PR #11054
- 2026-05-09T20:32:49Z @neo-gemini-pro referenced in commit `1d52312` - "chore(ai): track missing CadenceEngine files for test suite (#11049)"
- 2026-05-09T20:49:32Z @neo-opus-ada cross-referenced by #11058
- 2026-05-09T20:58:47Z @tobiu closed this issue
- 2026-05-09T20:58:47Z @tobiu referenced in commit `4ec9d2e` - "refactor(ai): unify v13 daemon entry-point Neo bootstrap (#11049) (#11054)

Establishes the entry-point-only invariant for Neo + core/_export +
InstanceManager imports across the v13 new daemon architecture surfaces:

- Class files NEVER import Neo (consumed via globalThis.Neo populated
  by the entry point's bootstrap chain): Orchestrator.mjs,
  SummarizationCoordinatorService.mjs.
- Daemon entry points + spawn-child scripts ALL bootstrap consistently
  with Neo + core/_export + InstanceManager: orchestrator-daemon.mjs,
  bridge-daemon.mjs, summarize-sessions.mjs, syncKnowledgeBase.mjs,
  backup.mjs.
- SwarmHeartbeatService.mjs is treated as a hybrid entry-point (class +
  self-invoke at bottom under launchd / systemd); InstanceManager added
  to satisfy the entry-point invariant; future cleanup recommended via
  class+wrapper split matching Orchestrator pattern.

Test-spec bootstrap: SummarizationCoordinatorService.spec.mjs now imports
Neo + core/_export at the top, matching the existing pattern in
Orchestrator.spec.mjs / TaskStateService.spec.mjs /
ProcessSupervisorService.spec.mjs. Test specs ARE the entry point for
test-bootstrap.

Empirical:
- 60 tests passing (Orchestrator, orchestrator-daemon, SwarmHeartbeat,
  bridge-daemon, SummarizationCoordinator, backup, restore,
  swarm-heartbeat, top-level Orchestrator).
- Net diff: +59 / -14 across 8 source files + 1 spec.

Operator scope refinement applied: scope tightened from "all ai/scripts"
to "v13 new daemon architecture surfaces only" per @tobiu's hint that
the goal is consistent v13 daemon entry points. Other operator scripts
with partial bootstrap remain out of scope for this PR (deferrable to
follow-up if needed).

Self-Identification: @neo-opus-4-7 (Claude Opus 4.7, Claude Code)
Origin Session ID: c2912891-b459-4a03-b2af-154d5e264df1

Co-authored-by: tobiu <tobiasuhlig78@gmail.com>"
- 2026-05-09T21:00:19Z @neo-opus-ada cross-referenced by PR #11059
- 2026-05-09T21:16:07Z @neo-opus-ada cross-referenced by PR #11061
- 2026-05-09T21:33:43Z @tobiu referenced in commit `2c3f4ae` - "refactor(ai): split SwarmHeartbeatService into class + entry-point wrapper (#11058) (#11061)

Closes the entry-point-only invariant gap surfaced during PR #11054 (#11049):
SwarmHeartbeatService was a hybrid file (class + self-invoke at the bottom),
the only daemon-tier class still importing Neo directly post-#11054. This PR
applies the canonical Orchestrator class+wrapper pattern (#11041 / #11044 /
#11049 precedent):

- `ai/daemons/SwarmHeartbeatService.mjs`: class-only file. Removed Neo +
  core/_export + InstanceManager imports + self-invoke `if (isMain)` block at
  the bottom. Now matches sibling pattern (TaskStateService /
  ProcessSupervisorService / SummarizationCoordinatorService / DreamService).

- `ai/scripts/swarm-heartbeat-daemon.mjs` (NEW): entry-point wrapper. Owns Neo
  namespace bootstrap + SIGTERM / SIGINT clean-stop signal handlers +
  `SwarmHeartbeatService.start()` invocation. Mirrors orchestrator-daemon.mjs
  shape.

- `test/playwright/unit/ai/daemons/SwarmHeartbeatService.spec.mjs`: added
  `import Neo + import * as core` at top to bootstrap the Neo namespace before
  the dynamic SwarmHeartbeatService import. Matches the test-spec-as-entry-point
  pattern from sibling specs (TaskStateService.spec / ProcessSupervisorService.spec
  / SummarizationCoordinatorService.spec / Orchestrator.spec post-#11049).

- `learn/agentos/wake-substrate/PersistentProcessManagement.md`: updated
  invocation paths from `node ai/daemons/SwarmHeartbeatService.mjs` →
  `node ai/scripts/swarm-heartbeat-daemon.mjs` (lines 35, 46, 188 + descriptive
  references). The class file itself is still the daemon source (line 231).

- `learn/agentos/wake-substrate/com.neomjs.swarm-heartbeat.plist.template`:
  updated launchd ProgramArguments path + Target comment to point at the
  wrapper.

Empirical:
- 14/14 SwarmHeartbeatService.spec tests pass
- 52/52 MailboxService.spec tests pass (no collateral damage)
- node --check passes for both class file + new wrapper
- Net diff: -49 / +31 lines (net reduction; substrate accretion defense
  satisfied — the split removes redundant comment-prelude + self-invoke
  block, replacing with smaller wrapper file)

Operator action required post-merge:
- launchd / systemd installations using the old direct-class-file path will
  need to update their plist / .service file to target
  `ai/scripts/swarm-heartbeat-daemon.mjs`. The .plist.template already updated;
  re-running §3a sed substitution against the new template captures it.

Self-Identification: @neo-opus-4-7 (Claude Opus 4.7, Claude Code)
Origin Session ID: c2912891-b459-4a03-b2af-154d5e264df1

Co-authored-by: tobiu <tobiasuhlig78@gmail.com>"
- 2026-05-09T21:44:21Z @neo-opus-ada cross-referenced by #11062
- 2026-05-09T21:58:38Z @neo-opus-ada cross-referenced by #11065
- 2026-05-09T23:00:37Z @neo-opus-ada cross-referenced by PR #11069

