LearnNewsExamplesServices
Frontmatter
id10103
titleAgent OS config ownership: Tier-1 deployment defaults
stateClosed
labels
epicaiarchitecture
assigneesneo-gpt
createdAtApr 19, 2026, 5:31 PM
updatedAtJun 7, 2026, 7:19 PM
githubUrlhttps://github.com/neomjs/neo/issues/10103
authortobiu
commentsCount7
parentIssuenull
subIssues
11963 Map Agent OS config defaults into Tier-1 AiConfig
11965 Wire provider routing and native Ollama runtime paths
11964 Prove cloud provider readiness for embeddings, chat, and dream
subIssuesCompleted3
subIssuesTotal3
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtMay 26, 2026, 12:22 AM

Agent OS config ownership: Tier-1 deployment defaults

Closed v13.0.0/archive-v13-0-0-chunk-5 epicaiarchitecture
tobiu
tobiu commented on Apr 19, 2026, 5:31 PM

Current Context

#10103 is reopened as the active epic for Agent OS config ownership. The original broad intent remains valid, but several earlier ticket statements are now stale after the 2026-05-25 merge train.

This issue is intentionally kept as the existing epic instead of creating another config-substrate ticket. The current goal is to finish the remaining Tier-1 configuration substrate cleanup needed for multi-user cloud deployment, while preserving the selective boundary: deployment-wide defaults live at Tier-1; server-local knobs stay local.

Current Source Truth

Verified against dev after these merged PRs:

  • #11967 / #11969 / #11988 moved the Tier-1/provider/auth/storage config substrate forward.
  • #11966 / #11970 proved provider routing and cloud readiness paths.
  • #11989 removed the stale aiConfig.engines.neo consumers from maintenance/diagnostics scripts.

Delivered and no longer open in this epic:

  • ai/BaseConfig.mjs is now top-level and exported through Neo.setupClass(BaseConfig).
  • ai/config.template.mjs extends BaseConfig instead of carrying a separate clone/load/proxy implementation.
  • applyLegacyEnv() is gone from the shared config base and active config templates.
  • Env binding ledgers now use nested object shape, and Neo.util.Env.applyEnvBindings() rejects dotted binding keys.
  • Active ignored config overlays have been refreshed from their templates after #11988/#11989.
  • Stale graph-path consumers now use aiConfig.storagePaths.graph.

Still open after the same verification:

  • Config templates still keep defaultConfig and/or envBindings as module-scope constants, then reference them from static config. The remaining shape should move config ownership into the Neo class substrate instead of using module-level ledgers copied into the singleton.
  • backupPath is still Memory-Core-local while both Memory_DatabaseService and KB_DatabaseService default export paths to aiConfig.backupPath. That asymmetry was called out in the original #10103 comment and remains relevant.
  • The final shape must preserve the current nested-env-binding contract and the Tier-1/server-local boundary.

Contract Ledger Matrix

Target Surface Source of Authority Current State Required Behavior Evidence
Shared config base #11988 + current ai/BaseConfig.mjs Top-level Neo.ai.BaseConfig, setupClass-backed, no legacy env hook Keep as the single shared behavior base for Tier-1 and server configs Import smoke + focused config unit tests
Tier-1 config class substrate #10103 reopened current-state check Extends BaseConfig, but defaultConfig / envBindings are module-scope constants Move ownership into Neo.ai.Config class substrate while preserving defaults and env behavior Tier-1 config unit tests + template import smoke
Server config class substrate #10103 reopened current-state check Server templates extend BaseConfig, but ledgers remain module-scope constants Move server defaultConfig / envBindings ownership into each config class substrate KB/MC/GitHub/GitLab/Neural config unit tests
Env binding topology Operator clarification + #11988 Nested env-binding objects; dotted keys rejected Preserve nested binding topology; do not reintroduce dotted strings Env.spec.mjs and representative config tests
backupPath shared default #10103 comment 4283913925 + current services MC config defines backupPath; KB service defaults to aiConfig.backupPath without owning the key Promote shared backup default to Tier-1 or otherwise make MC/KB backup defaults symmetric without server-local duplication MC + KB backup/default tests or focused smoke
Tier-1 / server-local boundary Discussion #11961 + #10103 Mostly delivered by prior PRs Keep provider/auth/vector/unified-Chroma coordinates deployment-wide; keep collection names, listener ports, parser/scoring, batch knobs, and tenant-source config server-local No moved-key regression in config tests

Acceptance Criteria

  • Tier-1 ai/config.template.mjs owns its config ledgers inside the Neo.ai.Config class substrate, not as module-scope defaultConfig / envBindings constants.
  • Server config templates own their config ledgers inside their Config class substrate, not as module-scope defaultConfig / envBindings constants.
  • The nested env-binding contract remains intact and dotted env-binding keys remain rejected.
  • The backupPath default is made symmetric for Memory Core and Knowledge Base without duplicating a cross-cutting deployment default in server-local config.
  • Existing global/server-local boundaries are preserved.
  • Focused config tests and syntax/import smoke pass.

Out of Scope

  • Per-tenant provider/auth variation.
  • A monolithic all-server config catalog.
  • Reintroducing backwards-compatibility hooks for v13-unreleased config shapes.
  • Moving server-local collection names, MCP listener ports, parser/scoring knobs, batch limits, or tenant-source config to Tier-1.
  • Reworking unrelated concept ontology behavior.

Avoided Traps

  • Do not treat the previous closeout comment as authoritative after later operator V-B-A. The current source still has residual substrate work.
  • Do not file another duplicate config epic for this closure shape.
  • Do not preserve module-scope ledgers for convenience if the point of the lane is native Neo class ownership.
  • Do not regress the already-delivered nested env-binding contract.

Related

Handoff Retrieval Hint: "reopened #10103 BaseConfig setupClass module-scope defaultConfig envBindings backupPath Tier-1 Agent OS config ownership"

tobiu added the enhancement label on Apr 19, 2026, 5:31 PM
tobiu added the ai label on Apr 19, 2026, 5:31 PM
tobiu added the architecture label on Apr 19, 2026, 5:31 PM
tobiu cross-referenced by PR #10102 on Apr 19, 2026, 5:32 PM
tobiu cross-referenced by #10104 on Apr 19, 2026, 5:39 PM
tobiu referenced in commit 4df4b09 - "feat(ai): config-lift ConceptDiscoveryService tuning knobs (#10036) on Apr 19, 2026, 6:26 PM
tobiu cross-referenced by PR #10105 on Apr 19, 2026, 6:26 PM
tobiu referenced in commit a5802d7 - "feat(ai): ConceptDiscoveryService + validated flag for mined candidates (#10036) (#10105) on Apr 19, 2026, 6:30 PM
tobiu cross-referenced by #10030 on Apr 19, 2026, 7:53 PM
tobiu cross-referenced by PR #10116 on Apr 20, 2026, 1:40 AM
tobiu
tobiu Apr 20, 2026, 10:04 PM

Input from Claude Opus 4.7 (Claude Code):

❋ ## Additional migration candidate: backupPath

Surfaced during #10132 / #10133 cleanup review on 2026-04-20.

Current state:

  • ai/mcp/server/memory-core/config.mjs:205 + .../config.template.mjs:272 define backupPath: path.resolve(cwd, '.neo-ai-data/backups')
  • ai/mcp/server/knowledge-base/config.mjs + ...template.mjs — no equivalent entry

Consumers:

  • Memory_DatabaseService#exportDatabase defaults backupPath to aiConfig.backupPath (MC config — works today)
  • KB_DatabaseService#exportDatabase defaults backupPath to aiConfig.backupPath (KB config — undefined; would throw at fs.ensureDir(undefined) if called without an explicit arg)
  • buildScripts/ai/backup.mjs orchestrator — always passes backupPath explicitly (one bundle subfolder per subsystem), so the KB default path is not exercised in practice today

Why this belongs in #10103 rather than a new ticket:

  • backupPath is a canonical cross-cutting filesystem root consumed by an operator script + two peer services — fits the "cross-cutting daemon/service config" profile in this ticket's Problem section
  • Fixing it in isolation (e.g. by adding backupPath to KB config too) doubles the debt rather than resolving it — the asymmetry just moves from "MC has it, KB doesn't" to "MC has one copy, KB has an identical copy"
  • When the SDK-layer config file lands per this ticket's Fix section, backupPath should migrate alongside the other cross-cutting keys (guideGapWeightThreshold, decayFactor, autoDream, etc.) — both MC and KB services then pull from the same SDK-level default

Latent fragility note: the KB default is currently undefined — safe only because backup.mjs always passes the arg. If a future caller invokes KB_DatabaseService.manageDatabaseBackup({action:'export'}) without backupPath, it breaks at fs.ensureDir(undefined). Migration to SDK-layer config resolves this without needing a per-server patch.

Suggested addition to this ticket's Acceptance Criteria list:

  • backupPath migrated to SDK-layer config; both Memory_DatabaseService and KB_DatabaseService dispatchers read from the shared SDK-level default; MC + KB server configs drop their local backupPath entries

Origin Session ID: 5a521819-dc75-4549-888e-fcea818d0401

  • 2026-05-01T10:37:58Z @neo-opus-ada cross-referenced by #10569
  • 2026-05-01T10:42:28Z @neo-opus-ada cross-referenced by PR #10570
  • 2026-05-01T10:46:50Z @neo-opus-ada cross-referenced by #10469
  • 2026-05-01T16:01:42Z @neo-opus-ada cross-referenced by #10586
  • 2026-05-01T16:03:15Z @neo-gpt cross-referenced by #10587
  • 2026-05-01T16:09:24Z @neo-opus-ada cross-referenced by PR #10588
  • 2026-05-01T16:20:53Z @neo-gpt cross-referenced by PR #10590
  • 2026-05-01T18:02:21Z @neo-opus-ada cross-referenced by #10591
  • 2026-05-01T21:35:35Z @neo-opus-ada cross-referenced by PR #10603
  • 2026-05-03T21:47:54Z @neo-opus-ada cross-referenced by #10650
  • 2026-05-06T11:40:41Z @neo-opus-ada cross-referenced by #10815
  • 2026-05-08T19:38:19Z @neo-opus-ada cross-referenced by #10986
  • 2026-05-08T20:48:45Z @neo-opus-ada cross-referenced by #10991
  • 2026-05-08T21:02:09Z @neo-opus-ada cross-referenced by #10993
  • 2026-05-08T21:06:43Z @neo-opus-ada cross-referenced by #10994
  • 2026-05-08T21:17:50Z @neo-opus-ada cross-referenced by #10996
  • 2026-05-09T10:20:24Z @neo-gpt cross-referenced by PR #11001

@neo-gpt - 2026-05-11T18:39:02Z

Input from GPT-5.5 (Codex):

● ## Ticket Intake Gate — needs-contract-alignment

I started intake for #10103 after live lane coordination showed no collision. I am not assigning, branching, or coding yet because the Contract Completeness Gate blocks implementation.

Intake Checks Completed

  • Live issue state: open, unassigned; labels include enhancement, ai, architecture.
  • Parent/epic gate: #10030 is the stated indirect parent and is epic-labeled. Prior epic-review by @neo-gpt exists: https://github.com/neomjs/neo/issues/10030#issuecomment-4361619448
  • Duplicate sweep: exact searches for "SDK-layer config", "daemon/service-layer config", and "backupPath" "SDK-layer config" found #10103 as the only direct open target. Related M6 service-boundary tickets (#10991/#10993/#10994/#10996/#10986) are closed and orthogonal.
  • Premise spot-check: direct grep confirms the ticket's concern is still live: daemon/service-facing keys such as autoDream, autoGoldenPath, handoffFilePath, decayFactor, guideGapWeightThreshold, modelProvider, and backupPath still sit in ai/mcp/server/memory-core/config.template.mjs / config.mjs, while consumers span ai/daemons/**, ai/services/memory-core/**, ai/services/knowledge-base/DatabaseService.mjs, buildScripts/ai/**, and tests.
  • Memory/Core context: Memory summaries surface the originating #10102/#10086 service-boundary lesson (feedback_config_service_boundary.md) and the later backupPath comment. Raw-memory search did not surface a better active implementation trail. KB health is green, but the specific KB query failed with an embedding model load cancellation, so I did not rely on KB synthesis for this gate.

Blocking Gate

This ticket introduces/modifies consumed configuration surfaces:

  • a new SDK-level config module (ai/config.mjs or ai/services.config.mjs — still undecided),
  • env-var compatibility for existing operator contracts,
  • MCP server config/template boundaries,
  • daemon/service imports,
  • bootstrapWorktree.mjs config-copy behavior,
  • backup/default-path behavior shared by Memory Core and Knowledge Base.

Per learn/agentos/contract-ledger.md, that requires a Contract Ledger before implementation. The current ticket body has good prose and ACs, but no ledger matrix defining the exact contract rows.

Required Body Update Before Pickup

Please add a Contract Ledger matrix with at least these rows:

Target Surface Source of Authority Proposed Behavior Fallback / Edge Case Docs Evidence
SDK-level config module path/name #10103 + M6 SDK-boundary direction Chosen module exports default config/proxy shape for cross-cutting Agent OS config If custom config file missing/stale, define fallback and compatibility behavior JSDoc + learn/agentos/ boundary doc focused config smoke test
Env-var compatibility Existing operator env contracts Existing env var names continue to work during migration Deprecated legacy names warn or remain readable for one window where applicable config JSDoc / docs tests for representative migrated key
Memory Core MCP config boundary #10103 problem statement MC config retains MC-owned transport/storage/auth/summarization fields only Backward-compatible reads for migrated keys if needed, or explicit breaking-change note config template comments targeted unit / import tests
Cross-cutting daemon/service keys current daemon/service consumers keys like guideGapWeightThreshold, decayFactor, autoDream, autoGoldenPath, handoffFilePath, modelProvider move to SDK config define precedence if both old and new locations contain a value service JSDoc + boundary doc consumer smoke test
backupPath shared default #10103 comment 4283913925 Memory Core and Knowledge Base backup defaults read the shared SDK config caller-supplied backupPath still overrides default DatabaseService JSDoc MC + KB backup default tests or explicit scoped smoke
bootstrapWorktree.mjs handling worktree bootstrap contract copies/syncs the new local config file if it is gitignored/local no-op if tracked config path chosen; explain explicitly script JSDoc focused bootstrap test/update

Structural Pre-Flight Note

Because #10103 prescribes a new .mjs config surface, structural-pre-flight will also need to run before implementation. ArchitectureOverview.md currently lists ai/services.mjs, ai/services/<server>/, and ai/mcp/server/<server>/config, but not a root-level ai/config.mjs role. The ticket body should either pick the destination and justify it, or explicitly leave the destination open for structural pre-flight to resolve.

Intake verdict: needs-contract-alignment. The goal appears valid and high-ROI, but implementation is blocked until the contract matrix is present.

  • 2026-05-14T23:52:40Z @neo-opus-ada cross-referenced by #11383

@neo-gpt - 2026-05-25T08:16:19Z

Current-state V-B-A update — ticket shape stale, premise still live

Authored by @neo-gpt during the 2026-05-25 cloud-deployment config sweep.

I re-checked current origin/dev source and related tickets/discussions before treating this as an implementation lane. Verdict: the architectural concern is still live, but this ticket cannot be implemented as written without a current-state rewrite / Contract Ledger update.

Evidence

  • ai/config.template.mjs now exists as Tier-1 config substrate, so the original prescription to create ai/config.mjs / ai/services.config.mjs is stale.
  • ai/mcp/server/memory-core/config.template.mjs still owns cross-Agent-OS provider and storage values: modelProvider, embeddingProvider, openAiCompatible, ollama, vectorDimension, engines.chroma, backup paths, and daemon/service-facing keys.
  • ai/mcp/server/knowledge-base/config.template.mjs still owns its own Chroma host/port surface while Memory Core uses engines.chroma; unified Chroma is runtime reality but not fully represented as Tier-1 config reality.
  • ai/daemons/orchestrator/TaskDefinitions.mjs / orchestrator config only model orchestrator scheduling + MLX process supervision. Provider/storage config reaches the cloud stack through per-service env forwarding, not through a first-class top-level Agent OS config contract.
  • Cloud deployment docs and compose route the optional Ollama container via OpenAI-compatible env (NEO_MODEL_PROVIDER=openAiCompatible, NEO_OPENAI_COMPATIBLE_HOST=http://local-model:11434). Native ollama is advertised in config/health surfaces, but runtime generation/embedding/graph paths are not consistently provider-routed.
  • Current integration tests prove container health + OpenAI-compatible embedding metadata. They do not prove /v1/chat/completions or graph-processing readiness for the cloud provider path.

Related-ticket reconciliation

  • #10822 is the original broad config-substrate epic and is closed. Its body expected Tier-1 provider/storage globals, but current source still shows residual ownership split.
  • #11871 is intentionally narrow: env primitive dedup + shared MCP logger. It explicitly does not revive the broad cycle-1 “single config source” framing.
  • #10270 is narrow Chroma misconfig observability, not ownership migration.
  • #11734 delivered the optional local-model profile, but it does not solve provider config ownership or native ollama routing.

Required rewrite before pickup

This issue should be refreshed from “create SDK-layer config file” to “consolidate Agent OS provider + storage config ownership around existing Tier-1 ai/config.template.mjs while preserving per-server deployment composition.” Suggested Contract Ledger rows:

  1. Tier-1 provider config: modelProvider, embeddingProvider, openAiCompatible, ollama, vectorDimension.
  2. Unified Chroma config: shared host/port/topology plus clear boundary for per-server collection names.
  3. Runtime provider routing: decide whether native ollama is supported or explicitly retired from advertised selectors; graph services must not hardwire OpenAI-compatible if config says otherwise.
  4. Cloud deployment env parity: compose/docs should reflect the selected provider contract and avoid implying unsupported native routes.
  5. Integration evidence: mock both /v1/embeddings and /v1/chat/completions, then prove summary/dream/golden-path can use the cloud provider path.

Until that rewrite lands, implementation should stay blocked as needs-contract-alignment, not assigned straight to code.

  • 2026-05-25T09:45:42Z @neo-gpt cross-referenced by #11963
  • 2026-05-25T09:45:44Z @neo-gpt cross-referenced by #11964
  • 2026-05-25T09:45:44Z @neo-gpt cross-referenced by #11965

@neo-gpt - 2026-05-25T09:50:29Z

Epic Review by @neo-gpt

Stage 1 — Roadmap Fit: Pass

This epic fits the current v13 cloud-deployment direction. The live Discussion #11961, Memory Core mining, and duplicate sweep all point to the same shape: #10103 is the right existing target, and the cloud trial makes provider/auth/storage config ownership high-ROI now. Related older epics (#10822, #10804) are important context, but they do not make this rewrite redundant because current source still has residual provider/storage ownership split.

Stage 2 — Approach Elegance: Pass

The approach is selective Tier-1 ownership, not a central all-server config catalog. It reuses existing ai/config.template.mjs, Env parser patterns, KB/MC server config overlays, native provider classes, and cloud compose profiles. The Discussion-origin Double Diamond is present in #11961 and rejected the two main traps: per-server-only documentation and monolithic config.

Stage 2.5 — Source Discussion Mapping: Pass

#10103 now carries ## Signal Ledger, ## Unresolved Dissent, ## Unresolved Liveness, and ## Discussion Criteria Mapping. The mapping covers OQ1-OQ8 from #11961 and preserves the Google-family liveness gap rather than converting no-signal into consent.

Stage 3 — Sub-Structure Coherence: Pass

The three subissues collectively close the parent:

Parent AC Required evidence Owning sub(s) Delivered PR(s) Achieved evidence Residual state
Tier-1 config ownership ledger + KB/MC overlays L2 #11963 pending pending pending
Runtime provider routing + native Ollama chat/embedding path L2 #11965 pending pending pending
Cloud docs + embeddings/chat/dream readiness L2/L3 where CI can only mock provider endpoints #11964 pending pending pending
Preserve server-local knobs and avoid monolithic catalog L1/L2 #11963, #11964 pending pending pending

No missing phase surfaced. The split is file-group/subsystem based rather than per-file: config mapping, runtime provider routing, and cloud docs/readiness.

Stage 4 — Prescription Layer: Pass

  • #11963 is correctly scoped to Tier-1 config plus KB/MC overlay mapping.
  • #11965 is correctly scoped to runtime provider dispatch and native Ollama capability.
  • #11964 is correctly scoped to docs and readiness evidence, and it depends on not over-claiming runtime support before #11965 proves it.

The service boundaries are explicit: collection names/listener ports/parser knobs stay server-local; provider/auth/storage deployment defaults become Tier-1.

Stage 5 — Avoided Traps Completeness: Pass

The epic names the important rejected paths: monolithic config, per-server-only docs, retiring native Ollama, and treating session summarization as sufficient graph readiness. That is enough to start sub work; additional traps can be documented in the sub PR bodies if implementation exposes more.

Verdict

Greenlight. Proceed with subissue pickup. My first lane is #11963.

Session ID: current request-bound Memory Core session (Codex Desktop; session id not exposed in this harness response).

  • 2026-05-25T09:59:13Z @neo-opus-ada cross-referenced by PR #11966
  • 2026-05-25T10:00:19Z @neo-gpt cross-referenced by PR #11967
  • 2026-05-25T10:45:51Z @neo-opus-ada cross-referenced by PR #11962
  • 2026-05-25T11:43:52Z @neo-gpt cross-referenced by PR #11970
  • 2026-05-25T11:55:37Z @neo-gpt cross-referenced by PR #11969

@neo-gpt - 2026-05-25T12:41:40Z

Epic Resolution Review

Reviewer: @neo-gpt Started: 2026-05-25T12:41:40Z Completed: 2026-05-25T12:42:48Z Verdict: RECOMMEND_CLOSE_COMPLETED

Matrix

Parent AC Required evidence Owning sub(s) Delivered PR(s) Achieved evidence Residual state
Tier-1 config ownership ledger plus KB/MC overlays L1/L2 #11963 #11967, corrective #11969 #11967 maps Tier-1 provider/auth/storage defaults and KB/MC overlays; #11969 fixes runtime imports to use operator overlay ai/config.mjs. Evidence: #11967 targeted config/import suites passed, #11969 76/76 passed plus zero config.template.mjs runtime imports. none — closed
Runtime provider routing plus native Ollama chat/embedding/graph path L1/L2 #11965 #11966, corrective #11969 #11966 wires native Ollama chat, embeddings, and graph-provider dispatch with explicit unsupported-provider rejection. Evidence: 38/38 provider/unit tests. #11969 removes overlay-bypass regression for runtime config consumption. none — closed
Cloud docs plus provider readiness for embeddings, chat, and Dream/REM graph mutation L2/L3 #11964 #11970 #11970 adds Day-0 readiness docs and Dockerized provider readiness tests. Evidence verified from Actions run 26398752426: CloudProviderReadiness.integration.spec.mjs tests #13 and #14 both passed in integration-unified on the Docker-capable runner. none — closed
Preserve env compatibility and server-local knobs L1/L2 #11963, #11964, #11965 #11967, #11966, #11969, #11970 Env override surface remains final; server-local collection names, listener ports, parser/scoring/batch knobs, and tenant-source config stay local. #11969 documents and validates local overlay bootstrap behavior. none — closed
Discussion #11961 graduation mapping and liveness disposition L1 Parent #10103 plus #11963/#11965/#11964 #11967, #11966, #11969, #11970 #10103 body carries Signal Ledger, Unresolved Liveness, and Discussion Criteria Mapping. OpenAI authored, Anthropic approved, Google-family liveness remains explicitly archived as non-blocking under quorum. none — closed

Source Discussion Closeout Gate

Source Discussion criterion Epic AC(s) Owning sub(s) Delivered PR(s) Achieved evidence Residual / deferral
OQ1 auth defaults become Tier-1 deployment defaults with KB/MC overlays Tier-1 config ownership #11963 #11967, #11969 Tier-1 defaults mapped; overlay import corrected. none — delivered
OQ2 native Ollama active target plus OpenAI-compatible fallback Runtime provider routing; cloud docs #11965, #11964 #11966, #11970 Native Ollama chat/embedding/graph dispatch wired; Day-0 docs distinguish native vs OpenAI-compatible fallback. none — delivered
OQ3 vectorDimension plus unified Chroma storage invariant Tier-1 storage config; cloud readiness #11963, #11964 #11967, #11970 Tier-1 storage defaults mapped; readiness spec runs against deployed Chroma/MC fixture. none — delivered
OQ4 precedence Tier-1 template to gitignored top-level overlay to per-server mapped defaults to env Config ownership #11963 plus corrective #11968 #11967, #11969 ai/config.mjs overlay bootstrap and runtime imports are now the active path; env remains final. none — delivered
OQ5 avoid monolithic config catalog Config ownership boundary #11963 #11967 Server-local knobs kept local by design. none — delivered
OQ6 embeddings plus chat plus Dream/REM readiness Cloud readiness #11964 #11970 CI log verifies both cloud-readiness tests executed and passed under integration-unified. none — delivered
OQ7 rewrite #10103 rather than duplicate Parent epic shape #10103 issue body + epic review comment #10103 body was rewritten and reviewed before subs. none — delivered
OQ8 tenant-tier config remains data-source-only Boundary guard #11963 #11967 Tenant source config is explicitly out of the Tier-1 migration. none — delivered

Rationale

All required subs are closed and close-linked to merged PRs: #11963 -> #11967, #11965 -> #11966 and #11969, #11964 -> #11970. The operator-flagged overlay regression discovered after Sub-1/Sub-2 is also closed by #11969, so the closeout should not pretend the first-pass sub PRs alone were sufficient.

The one evidence point that needed extra verification was #11970. Its PR body honestly declared local Docker as unavailable, so I checked the GitHub Actions integration log before marking the row complete. The Docker-capable integration-unified run executed and passed both new CloudProviderReadiness tests, including the Dream/REM graph-mutator path.

No source Discussion criteria are LOST. The Google-family liveness gap is explicitly recorded in #10103 and was non-blocking under the accepted quorum; it is not a missing sub.

Required operator action

None for this epic. I am closing #10103 as completed after posting this verdict.

A2A coordination

A2A notification is currently blocked by Memory Core/Chroma degradation in this Codex session: list_messages and healthcheck report ChromaDB not accessible on localhost:8000. The heartbeat thread is the current operator-visible handoff; I will still attempt the required add_message and record the failure if it remains unavailable.

Origin Session ID: 3c3566e9-59e1-45c2-a6ae-983897a856a3

@neo-gpt - 2026-05-25T18:33:26Z

Reopening based on 2026-05-25 operator V-B-A: the original intent is still valid, but the implementation is not actually complete for the config substrate shape. This is NOT a new ticket; it is the existing Tier-1 Agent OS config ownership epic being brought back in line with current code reality.

Verified current code shape:

  • ai/mcp/server/shared/BaseConfig.mjs extends Neo.core.Base, but exports the raw class without registering the base class through Neo.setupClass(); it also still calls applyLegacyEnv() from applyEnv() and defines an override hook (BaseConfig.mjs lines 15-64).
  • ai/config.template.mjs is still a separate implementation of clone/load/proxy behavior instead of extending/reusing the shared config base (ai/config.template.mjs lines 432-499).
  • KB and MC server templates extend BaseConfig, but keep defaultConfig and envBindings in module scope and then assign defaultConfig = defaultConfig; envBindings = envBindings; inside the singleton (knowledge-base/config.template.mjs lines 18-44 and 378-398; memory-core/config.template.mjs lines 413-500).
  • Env binding paths are currently dotted strings by design in Neo.util.Env.applyEnvBindings() (src/util/Env.mjs lines 44-83). That avoids env-value-derived path injection, but it is still brittle developer-authored string topology and does not mirror the nested config object shape.
  • Generated/operator overlay files still contain legacy hooks in some server configs (rg applyLegacyEnv ai/mcp/server).

Duplicate/adjacency sweep before reopening:

  • #11871 is adjacent env/logger primitive work, but its body explicitly keeps top-level + per-server config merge contract out of scope. Folding this into #11871 would violate its negative boundary.
  • #11976 / #11981 cover test overlay determinism, not runtime config class ownership.
  • #11965 covers provider runtime dispatch, not config substrate shape.
  • #10126 covers stale aiConfig.engines.neo consumers, not BaseConfig/Tier-1 inheritance.

Required closure shape for this epic before it can be considered done:

  1. Remove applyLegacyEnv() from shared BaseConfig and remaining server template/overlay surfaces. v13 is unreleased; no compatibility hook should survive unless a ticket proves a concrete deployed consumer.
  2. Decide and implement the native Neo class shape for shared config: either BaseConfig itself is registered with Neo.setupClass() or a named, setupClass-backed shared config base replaces it. The final shape must be consistent with the ArchitectureOverview rule that Agent OS classes use the Neo class system natively.
  3. Stop ai/config.template.mjs from going rogue. Tier-1 config should share the same base config behavior as server configs, while preserving its Tier-1 ownership role.
  4. Move server defaultConfig / envBindings ownership into the class substrate instead of module-scope constants copied back onto singleton instances.
  5. Replace or strictly contain dotted-string envBinding paths. Preferred direction: nested env-binding objects or explicit path arrays that mirror the config shape; if dotted strings remain, the PR must justify why the brittle string topology is still the right canonical contract.
  6. Preserve the important boundary from #10103: global deployment defaults (auth, providers, vector dimension, unified Chroma coordinates) live at Tier-1; server-local ports, collections, parsers, scoring, batch knobs, and tenant-source config stay local.

This is cloud-deployment readiness work. The current shape still lets global config exist while orchestrator/server layers ignore or duplicate parts of it, which is exactly the invisibility failure mode this epic was supposed to close.

Retrieval Hint: "reopened #10103 BaseConfig setupClass applyLegacyEnv module-scope envBindings dotted paths Tier-1 Agent OS config ownership"

  • 2026-05-25T18:48:33Z @neo-opus-ada cross-referenced by PR #11985
  • 2026-05-25T18:57:18Z @neo-gpt cross-referenced by PR #11988
  • 2026-05-25T20:08:39Z @neo-gpt cross-referenced by PR #11991

@neo-gpt - 2026-05-25T22:22:32Z

Epic Resolution Review

Reviewer: @neo-gpt Started: 2026-05-25T22:22:00Z Completed: 2026-05-25T22:22:00Z Verdict: RECOMMEND_CLOSE_COMPLETED

Matrix

Parent AC Required evidence Owning sub(s) Delivered PR(s) Achieved evidence Residual state
Tier-1 ai/config.template.mjs owns config ledgers inside Neo.ai.Config class substrate L2 #10103 reopened residual scope #11988, #11991 origin/dev shows class Config extends BaseConfig; no module-scope const defaultConfig / const envBindings; #11991 evidence reports template import smoke + 46/46 focused config tests none — closed
Server config templates own defaultConfig / envBindings inside each Config class substrate L2 #10103 reopened residual scope #11988, #11991 origin/dev shows KB/MC/GitHub/GitLab/Neural templates no longer define module-scope ledgers; #11991 moved active template ledgers into Neo classes none — closed
Nested env-binding contract remains intact and dotted env-binding keys remain rejected L2 #10103 reopened residual scope #11988, #11991 origin/dev has no applyLegacyEnv and no module-scope ledger remnants across active config templates; #11988/#11991 focused Env.spec.mjs + config-template tests cover the hard-cut env substrate none — closed
backupPath default is symmetric for Memory Core and Knowledge Base without server-local duplication L2 #10103 comment 4283913925 + reopened residual scope #11991 origin/dev Tier-1 owns backupPath; KB and MC templates map backupPath: AiConfig.backupPath and NEO_BACKUP_PATH final override none — closed
Preserve global/server-local boundaries L2 #10103 + Discussion #11961 #11967, #11988, #11991 Tier-1 owns provider/auth/storage/backup deployment defaults; server-local collection names/listener ports/parser/scoring/batch/tenant-source knobs remain in server templates none — closed
Focused config tests and syntax/import smoke pass L2 #10103 reopened residual scope #11988, #11991 #11991 body records initServerConfigs --migrate-config, template import smoke, 46/46 focused config tests, and diff checks passing none — closed

Source Discussion Closeout Gate

Source Discussion criterion Epic AC(s) Owning sub(s) Delivered PR(s) Achieved evidence Residual / deferral
Discussion #11961 Tier-1 provider/auth/storage ownership without monolithic all-server catalog Tier-1/server-local boundary ACs #11963 plus reopened residual scope #11967, #11988, #11991 Tier-1 ownership is implemented through ai/config.template.mjs + ai/BaseConfig.mjs; server-local knobs remain local none — delivered
Native provider/cloud readiness remains compatible with config ownership Provider/runtime/doc ACs from prior closeout #11965, #11964 #11966, #11970 Prior closeout already verified runtime provider routing and Docker-capable cloud readiness; reopened residual did not add new runtime-provider criteria none — delivered
Reopened operator V-B-A on BaseConfig/setupClass/legacy env/module-scope ledgers/backupPath Reopened residual ACs #10103 residual scope #11988, #11991 origin/dev verification confirms the reopened residual list is complete none — delivered

Rationale

This epic was correctly reopened after the earlier closeout because the residual config-substrate shape was still live. The later merge train changed that: #11988 hard-cut the legacy env substrate and moved the shared base to top-level ai/BaseConfig.mjs; #11991 moved the remaining active template ledgers into the Neo config classes and promoted the shared backup default.

I verified the current origin/dev source before closing: applyLegacyEnv is absent from ai/BaseConfig.mjs, ai/config.template.mjs, and active MCP config templates; module-scope const defaultConfig / const envBindings are absent from the active templates; ai/BaseConfig.mjs exports Neo.setupClass(BaseConfig); Tier-1, KB, and MC templates extend BaseConfig; KB/MC backup defaults now point at AiConfig.backupPath with NEO_BACKUP_PATH as final override.

No source Discussion criterion is lost. The reopened residual was a concrete implementation-shape gap, not a new unresolved architectural phase. The issue can close as completed; active clones still need the already-documented post-merge overlay refresh/restart step from #11991, but that is operational rollout work, not an open substrate AC.

Required operator action

None. Closing #10103 as completed.

A2A coordination

Broadcasting closeout to AGENT:* after posting this verdict.

Origin Session ID: 3b454ac4-f2c6-4bf0-9c18-c0af6f432ffa

  • 2026-05-26T02:04:05Z @neo-opus-ada cross-referenced by PR #12010
  • 2026-05-26T23:47:32Z @neo-gpt cross-referenced by #12059
  • 2026-06-03T13:40:33Z @neo-gpt cross-referenced by #12438
  • 2026-06-08T07:58:33Z @neo-gpt cross-referenced by #12740
  • 2026-06-08T07:59:29Z @neo-gpt cross-referenced by #12741