LearnNewsExamplesServices
Frontmatter
id14953
titleRoute KB config consumers without breaking standalone migrations
stateOpen
labels
enhancementairefactoringtesting
assignees[]
createdAt8:24 AM
updatedAt8:24 AM
githubUrlhttps://github.com/neomjs/neo/issues/14953
authorneo-gpt
commentsCount0
parentIssue12456
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]

Route KB config consumers without breaking standalone migrations

Open Backlog/active-chunk-5 enhancementairefactoringtesting
neo-gpt
neo-gpt commented on 8:24 AM

Context

PR #14935 is the first new Knowledge Base domain slice under parent epic #12456. It correctly targets two ADR-0019 cleanup classes: the Knowledge Base OpenAPI path is re-derived in toolService.mjs, and two one-shot migration CLIs re-derive Chroma host/port defaults.

Exact-head review at f9ee826134d41e716bc2012efcfef3bd33881d7f found that the intended SSOT refactor has no coherent leaf close-target and regresses both actual standalone commands before argument parsing:

node ai/scripts/migrations/backfillChromaSharedUserId.mjs --help
node ai/scripts/migrations/renameAgentIdentities.mjs --help

Both exit 1 with ReferenceError: Neo is not defined at src/core/Compare.mjs:166. The 65 migration specs and 42 KB/list-tools specs pass because their Playwright process has already loaded setup.mjs, src/Neo.mjs, and src/core/_export.mjs; that is not fresh-process CLI evidence.

Live latest-open sweep: checked the latest 20 open issues at 2026-07-10T06:24:12.785Z; no equivalent ticket found. Recent A2A claim sweep: checked the latest 30 messages across read states; no competing claim found. Knowledge Base and local issue/discussion sweeps found historical no-Neo-bootstrap constraints in #12434 / #12518, but no ticket for this exact KB SSOT + current-head CLI-bootstrap delivery leaf.

The Problem

The change needs to satisfy both sides of one coherent boundary:

  1. ADR 0019 requires config defaults and env bindings to be owned by the Provider SSOT and read at the use site.
  2. The two migration files are real Node entrypoints. Importing ai/mcp/server/knowledge-base/config.mjs pulls in ConfigProvider and core modules, so the CLI must establish the same Neo/core bootstrap ordering used by other genuine Agent OS entrypoints before resolving kbConfig.

Import-only unit coverage masks this boundary. A green in-process suite therefore currently coexists with two broken user-facing commands, including --help, which should require neither Chroma nor SQLite.

The template change adds another runtime contract: active clones load the gitignored ai/mcp/server/knowledge-base/config.mjs, not the tracked template. A new openApiPath leaf requires overlay migration and restart coordination or the boot-time freshness guard intentionally rejects the stale clone.

The Architectural Reality

  • ADR 0019 §2/§5 makes AiConfig plus child providers the reactive SSOT. Genuine entrypoints may import and read it at the use site; hidden env/default cascades are forbidden.
  • ai/mcp/server/knowledge-base/mcp-server.mjs demonstrates the established bootstrap order: src/Neo.mjs + src/core/_export.mjs, then server config and services.
  • ai/scripts/migrations/backfillChromaSharedUserId.mjs and renameAgentIdentities.mjs are executable entrypoints, not Playwright-only helper modules.
  • test/playwright/unit/ai/scripts/migrations/renameAgentIdentities.spec.mjs imports setup.mjs, Neo, and core before importing the migration module, so it cannot falsify a fresh Node-process bootstrap failure.
  • ai/scripts/setup/initServerConfigs.mjs#assertConfigFresh deliberately fails stale active overlays and names npm run prepare -- --migrate-config plus restart as the recovery path.
  • Structure-map ownership is unchanged: config shape stays in ai/mcp/server/knowledge-base/; migration execution stays in ai/scripts/migrations/. No new file or service boundary is needed.

The Fix

Converge the existing PR in place:

  1. Add openApiPath to the KB config template and consume kbConfig.openApiPath directly in toolService.mjs.
  2. Consume kbConfig.host / kbConfig.port as the migration defaults while retaining explicit --host / --port precedence.
  3. Repair both standalone entrypoints with the established Neo/core bootstrap before the KB config dependency is evaluated.
  4. Add fresh-process regression coverage for both --help commands. The test must spawn Node without Playwright's preloaded Neo globals and assert exit 0 plus usage output.
  5. Document the openApiPath active-overlay rollout: run npm run prepare -- --migrate-config in each active clone, restart the KB MCP server/harness, and notify active peers because live MCP behavior changes.

Contract Ledger

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
kbConfig.openApiPath ADR 0019; KB config.template.mjs Default to the server's shipped openapi.yaml; allow NEO_AI_MCP_KB_OPENAPI_PATH as the test-isolation override; consumer reads the resolved leaf Stale active overlay fails fast with the existing config-freshness instruction Leaf JSDoc + PR rollout note Config/template spec, KB list-tools smoke, active-overlay migration probe
Migration default Chroma endpoint ADR 0019; kbConfig.host / kbConfig.port Canonical NEO_CHROMA_HOST / NEO_CHROMA_PORT resolution comes from the Provider; explicit CLI flags still win Provider defaults remain localhost:8000; undocumented NEO_KB_CHROMA_* aliases are intentionally retired Script usage + PR named behavior change Focused parse/CLI probes
backfillChromaSharedUserId.mjs --help Script CLI contract Fresh Node process exits 0 and prints usage before external-infrastructure access None; bootstrap failure is fatal Existing usage block Spawn-equivalent regression
renameAgentIdentities.mjs --help Script CLI contract Fresh Node process exits 0 and prints usage before external-infrastructure access None; bootstrap failure is fatal Existing usage block Spawn-equivalent regression
Active KB config overlay Config-template change guide; assertConfigFresh Every active clone understands openApiPath before KB restart npm run prepare -- --migrate-config, then restart PR Post-Merge Validation + A2A notification One stale-overlay detection/migration receipt

Decision Record impact

aligned-with ADR 0019 — this leaf applies the existing SSOT and entrypoint-boundary rules; it does not amend or supersede the ADR.

Acceptance Criteria

  • PR #14935 uses this leaf as its newline-isolated Resolves target; parent epic #12456 remains a non-closing related node.
  • toolService.mjs reads kbConfig.openApiPath without its own env/default/path derivation.
  • Both migration CLIs read their default host/port from the KB config Provider, retain explicit --host / --port precedence, and document the intentional retirement of NEO_KB_CHROMA_HOST / NEO_KB_CHROMA_PORT.
  • Both direct --help commands exit 0 in fresh Node processes and print their usage text without touching ChromaDB or SQLite.
  • Fresh-process regression coverage would fail on head f9ee826134d41e716bc2012efcfef3bd33881d7f with the reproduced Neo is not defined error and pass after the bootstrap repair.
  • The PR body names openApiPath, the active-clone overlay migration command, restart requirement, and peer notification.
  • The focused migration and KB/list-tools suites remain green.

Out of Scope

  • Other ADR-0019 census batches under #12456.
  • Broad changes to Chroma lifecycle, migration data semantics, or shared identity constants.
  • Reintroducing undocumented NEO_KB_CHROMA_* aliases.
  • Committing any gitignored config.mjs overlay.

Avoided Traps

  • Treating Playwright import success as standalone CLI proof.
  • Reading the Provider before Neo/core bootstrap exists.
  • Re-deriving env/default values in each script to avoid bootstrap.
  • Closing the epic from a single batch.
  • Shipping a tracked template key without coordinating the active gitignored overlays.

Related

Parent: #12456

Implementation: #14935

Related prevention work: #14500

Historical lightweight-runner context: #12434, #12518

Origin Session ID

be72c069-8cdc-46f6-8624-54f041a43f24

Handoff Retrieval Hints

  • query_raw_memories("PR 14935 AiConfig migration CLI bootstrap crash")
  • Exact head: f9ee826134d41e716bc2012efcfef3bd33881d7f
  • Falsifiers: the two direct node ... --help commands above.