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
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.mjsno 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:44:49Z @neo-gpt removed the enhancement label
  • 2026-05-25T09:44:49Z @neo-gpt changed title from [enhancement] SDK-layer config file — migrate daemon/service-layer keys out of memory-core/config.template.mjs to Agent OS config ownership: Tier-1 deployment defaults
  • 2026-05-25T09:44:49Z @neo-gpt added the epic label
  • 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
  • 2026-05-25T09:46:10Z @neo-gpt added sub-issue #11965
  • 2026-05-25T09:46:10Z @neo-gpt added sub-issue #11963
  • 2026-05-25T09:46:11Z @neo-gpt added sub-issue #11964

@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
tobiu referenced in commit 58d352b - "feat(memory-core): native Ollama runtime dispatch + provider.embed() method (#11965 Sub-2) (#11966) on May 25, 2026, 1:21 PM
tobiu referenced in commit a838ff8 - "feat(ai): hard-cut config env substrate (#10103) (#11988) on May 25, 2026, 9:26 PM
tobiu referenced in commit 592c0a6 - "feat(ai): move config ledgers into class substrate (#10103) (#11991) on May 25, 2026, 11:22 PM