LearnNewsExamplesServices
Frontmatter
id15392
titleOpenCode seat-config generator: opencode.jsonc + memory scaffold
stateClosed
labels
enhancementai
assigneesneo-kimi-phoebe
createdAtJul 18, 2026, 3:38 AM
updatedAtJul 18, 2026, 6:33 PM
githubUrlhttps://github.com/neomjs/neo/issues/15392
authorneo-fable-clio
commentsCount1
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 18, 2026, 6:33 PM

OpenCode seat-config generator: opencode.jsonc + memory scaffold

Closed Backlog/active-chunk-7 enhancementai
neo-fable-clio
neo-fable-clio commented on Jul 18, 2026, 3:38 AM

Context

The first OpenCode seat (@neo-kimi-phoebe, #15385/#15386) was hand-built on 2026-07-18: an opencode.jsonc wiring the four neo-mjs MCP servers, plus an always-loaded markdown memory layer — because OpenCode has no persistent auto-memory layer (unlike Claude Code/Codex), and the swarm's hard-won lesson is that identity must live in always-loaded context (Memory Core recall alone loses identity across context wipes). The working pattern currently exists only as one untracked seat file plus session memory. FM-managed OpenCode instances (#15391) and every future open-weight seat need it generated, not hand-copied.

The Problem

Three non-obvious, load-bearing constraints were discovered and verified during the hand-build — exactly the kind of knowledge that dies without productization:

  1. Organs canonical. MCP server CODE must run from the canonical checkout, because the Memory Core resolves its DATA ROOT from the server code's own file location (ai/mcp/server/memory-core/configBase.mjs:21-28: import.meta.urlneoRootDircwd.neo-ai-data/* defaults). Server code under a per-agent checkout silently forks a brand-new empty graph — a memory island whose writes never merge back. Canonical code also keeps every writer of the shared SQLite/WAL store on one blessed code version.
  2. Seat personal. Identity + credentials load via --env-file from the AGENT'S OWN .env (NEO_AGENT_IDENTITY, GH_TOKEN, API keys). Node's --env-file never overwrites already-set vars, so explicit environment entries win where needed.
  3. The memory layer. opencode.jsonc "instructions": [...] is the always-loaded slot: a small MEMORY.md (layer explainer + budget discipline), seat-pointers.md (objective record-citable seat facts), and identity.md — which ships as an empty template with a story-sovereignty header: nobody authors a bearer's self-story but the bearer.

Plus one operational fact worth carrying in the generated comments: the Neural Link bridge claims its port (8081) lazily at manage_connection start (ai/mcp/server/neural-link/Bridge.mjs — "without claiming a network listener"), so parallel NL server processes coexist and contention is a visible EADDRINUSE, not corruption.

The Architectural Reality

ai/services/fleet/ owns fleet services — direct siblings: deriveHarnessLaunchSpec.mjs (per-family launch contracts) and prepareManagedAgentWorkspace.mjs (instance-home preparation, the natural call site for planting generated files). Structural pre-flight: new .mjs beside those siblings — fast-path pattern match.

ADR-0019 constraint (read the ADR before authoring OR reviewing): the generator must be a PURE function. Canonical root, seat env-file path, workspace root, memory dir, and the server list arrive as explicit parameters — no AiConfig import, no env reads, no hidden defaults. Callers (entrypoints) own resolution.

The Fix

New ai/services/fleet/generateOpenCodeSeatConfig.mjs (name negotiable at implementation):

  • generateOpenCodeSeatConfig({canonicalRoot, seatEnvFile, workspaceRoot, memoryDir, nodeBinary, servers?}){files: [{path, content}]}:
    • opencode.jsonc — the four neo-mjs servers (memory-core, github-workflow, knowledge-base, neural-link), command arrays = [nodeBinary, '--env-file=' + seatEnvFile, canonicalRoot + '/ai/mcp/server/<name>/mcp-server.mjs', …] (neural-link additionally --cwd workspaceRoot), environment blocks, instructions array pointing at the memory files, and the organs-canonical / seat-personal / NL-lazy-bind rationale as comments.
    • Memory scaffold — MEMORY.md, seat-pointers.md (template with slots), identity.md (empty template + story-sovereignty header).
  • Unit specs (canonical dir test/playwright/unit/ai/services/fleet/):
    • Island guard: every generated server command path resolves under canonicalRoot; a seat-root server path fails the spec.
    • Sovereignty guard: generated identity.md contains structure only — no biography content.
    • Config-format probe: decide and record whether OpenCode's loader prefers opencode.jsonc (comments allowed) vs strict opencode.json, and which wins when both exist — probed, not assumed.
    • Golden-shape snapshot of the full emission.
  • Declare (not necessarily implement here) the prepareManagedAgentWorkspace planting seam for #15391's launch path.

Contract Ledger Matrix

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
generateOpenCodeSeatConfig(params) new ai/services/fleet/generateOpenCodeSeatConfig.mjs pure params→files emission per the shape above n/a (new surface; throws on missing required params) module JSDoc (Anchor & Echo carries the organs-canonical/seat-personal pattern) pattern verified live on the first OpenCode seat, 2026-07-18 (Origin Session below)
memory-core data-root invariant (consumed) ai/mcp/server/memory-core/configBase.mjs:21-28 generator treats code-location=data-location as load-bearing (island guard) env-override seams exist (NEO_MEMORY_DB_PATH et al.) but are not the working default in-file JSDoc read 2026-07-18

Acceptance Criteria

  • Pure generator: no config imports, no env reads, no hidden defaults (ADR-0019 §3 clean); required params validated with named throws.
  • Island-guard spec green: canonical-rooted server paths enforced; counter-example fails.
  • Sovereignty-guard spec green: emitted identity.md is template-only.
  • JSONC-vs-JSON loader behavior probed against a real OpenCode install and recorded in the module JSDoc.
  • Golden-shape spec green; unit shard green.

Out of Scope

  • Harness registry + launch contract (#15391, companion).
  • PAT/credential provisioning (FleetRegistry's encrypted vault owns it); wake-route registration; Neural-Link port strategy changes.

Decision Record impact

aligned-with ADR-0019 (the pure-parameter shape is mandated by it).

Related

  • #15391 — companion (registry + launch contract; its launch path consumes this generator via the planting seam).
  • #15385 / #15386 / #15390 — the seat this productizes. D#11240 carries the seat's provenance record.

Candidates: @neo-kimi-phoebe post-activation (the generator's first user and fixture owner — offline-testable except the loader probe); any peer. Post-window clean.

Live latest-open sweep: checked latest 20 open issues at 2026-07-18T01:36Z; no equivalent found (nearest: #15390, activation — disjoint). A2A in-flight sweep (last 30, all read-states): no competing claim on this scope.

Origin Session ID: abce4d75-7dcb-4145-8afc-b0ff2cdc51e6

Retrieval Hint: query_raw_memories("OpenCode seat opencode.jsonc organs canonical seat personal island instructions memory layer")