Premise
6 consumer sites hardcode aiConfig.openAiCompatible.contextLimitTokens / safeProcessingLimitTokens. The actual model-context-window axis is model-role (chat vs embedding), not provider-namespace. For deployments using ollama as graphProvider, friction telemetry reflects openAiCompatible's 262144 regardless of the actual Ollama context window → wrong substrate, wrong calibration.
Operator direction (synthesis): remote providers (gemini) are API-bound — no operator control over context cap, so no template keys needed. Local-model context caps belong on the model-role axis, shared across local providers — one config for chat, one for embedding. Provider-namespace duplication is over-the-top.
Substrate shape (cross-family V-B-A converged with @neo-gpt)
- Remote providers (
gemini, future API-only): no contextLimitTokens in template
- Local-model-role-keyed:
localModels.chat.{context,safe}LimitTokens + localModels.embedding.{context,safe}LimitTokens
- Namespace boundary (
localModels.*) states the actual constraint: locally controlled context caps; top-level chat/embedding would be too close to provider-selector primitive
Surface enumeration (V-B-A 2026-05-27)
| Site |
Role |
Current state |
SemanticGraphExtractor.mjs:125-126 |
chat |
pre-existing local vars (cascade fix point) |
TopologyInferenceEngine.mjs:83-84 |
chat |
added in PR #12113 (consistent with pre-existing pattern) |
SessionService.mjs:612-613 |
chat |
pre-existing + hidden default fallback || 32768 (violates §no_hidden_default_fallbacks) |
mcp/server/memory-core/config.template.mjs:186,197 |
derivation |
config-resolved doc-baseline |
Template current state: aiConfig.openAiCompatible.contextLimitTokens=262144 + safeProcessingLimitTokens=200000. aiConfig.ollama namespace has NO context-limit keys.
Contract Ledger
| Surface |
Before |
After |
Consumer |
| Chat context limits |
aiConfig.openAiCompatible.contextLimitTokens=262144 + safeProcessingLimitTokens=200000 |
aiConfig.localModels.chat.contextLimitTokens=262144 + safeProcessingLimitTokens=200000 (preserve current values per AC1) |
SemanticGraphExtractor + TopologyInferenceEngine + SessionService chat-path consumers |
| Embedding context limits |
NOT present in template |
aiConfig.localModels.embedding.{context,safe}LimitTokens (concrete value per AC6 V-B-A) |
Future TextEmbeddingService consumer (pre-positions for #11393/#11395 retry-on-unload telemetry) |
| Hidden default fallback |
SessionService.mjs:612 || 32768 |
Loud-fail on missing config |
(eliminates §no_hidden_default_fallbacks contract violation) |
Acceptance Criteria
Timing + scope
Recommendation (lean B-with-escape-hatch per @neo-gpt): fold into Epic #12101 Stage 1+ rewrite to avoid double migration. Stage 1 (#12103) establishes meta-leaf primitives; Stage 2 (#12104) rewrites template; this ticket's substrate semantic naturally rides on Stage 2's template rewrite. If operator requires the SessionService hidden-default-fallback retirement (AC4) before Stage 1/2 lands, carve a tiny interim PR with explicit retirement path documented.
Empirical anchor
PR #12113 (just-shipped) preserved the existing aiConfig.openAiCompatible.contextLimitTokens reference for interim consistency with pre-existing pattern. Operator surfaced the substrate-shape issue during cycle-1 V-B-A: "client wants to use ollama". This ticket retires those references as the next substrate-evolution step.
Related
- Parent: Epic #12101 (greenfield aiConfig substrate redesign — graduated from Discussion #12100)
- Sibling: #12104 (Stage 2 template rewrite — this ticket's substrate semantic rides on Stage 2)
- Sibling: #12090 (provider multi-model coexistence; orthogonal but adjacent)
- Sibling: #11976 (graphProvider routing — the consumer-side discriminator)
- PR #12113 (interim consistency baseline; this ticket retires the deferred reference)
Discipline anchor
@neo-gpt's V-B-A surfaced: chat default = preserve current 262144/200000 (already live after #12064). Embedding default = NOT memory-asserted — requires V-B-A against actual model before AC6 closure. SessionService.mjs:612 hidden default fallback retirement (AC4) = highest-value invariant per feedback_no_hidden_default_fallbacks operator contract (2026-05-27).
Premise
6 consumer sites hardcode
aiConfig.openAiCompatible.contextLimitTokens/safeProcessingLimitTokens. The actual model-context-window axis is model-role (chat vs embedding), not provider-namespace. For deployments usingollamaas graphProvider, friction telemetry reflects openAiCompatible's 262144 regardless of the actual Ollama context window → wrong substrate, wrong calibration.Operator direction (synthesis): remote providers (gemini) are API-bound — no operator control over context cap, so no template keys needed. Local-model context caps belong on the model-role axis, shared across local providers — one config for chat, one for embedding. Provider-namespace duplication is over-the-top.
Substrate shape (cross-family V-B-A converged with @neo-gpt)
gemini, future API-only): nocontextLimitTokensin templatelocalModels.chat.{context,safe}LimitTokens+localModels.embedding.{context,safe}LimitTokenslocalModels.*) states the actual constraint: locally controlled context caps; top-levelchat/embeddingwould be too close to provider-selector primitiveSurface enumeration (V-B-A 2026-05-27)
SemanticGraphExtractor.mjs:125-126TopologyInferenceEngine.mjs:83-84SessionService.mjs:612-613|| 32768(violates §no_hidden_default_fallbacks)mcp/server/memory-core/config.template.mjs:186,197Template current state:
aiConfig.openAiCompatible.contextLimitTokens=262144+safeProcessingLimitTokens=200000.aiConfig.ollamanamespace has NO context-limit keys.Contract Ledger
aiConfig.openAiCompatible.contextLimitTokens=262144+safeProcessingLimitTokens=200000aiConfig.localModels.chat.contextLimitTokens=262144+safeProcessingLimitTokens=200000(preserve current values per AC1)aiConfig.localModels.embedding.{context,safe}LimitTokens(concrete value per AC6 V-B-A)SessionService.mjs:612|| 32768Acceptance Criteria
localModels.chat.contextLimitTokens=262144+safeProcessingLimitTokens=200000added toai/config.template.mjs(preserves current shipped defaults per @neo-gpt V-B-A)localModels.embedding.{context,safe}LimitTokensadded toai/config.template.mjswith concrete defaults — value requires V-B-A per AC6aiConfig.openAiCompatible.{context,safe}*toaiConfig.localModels.{chat,embedding}.*based on consumer roleSessionService.mjs:612hidden default fallback (|| 32768) deleted; loud-fail on missing config (matchesfeedback_no_hidden_default_fallbacksoperator contract)SemanticGraphExtractor.mjs:121JSDoc rationale (openAiCompatible-as-conservative-baseline-for-both-families) rewritten to reflect role-keyed substrate; pre-existing ticket-anchor archaeology (#11965 AC5 / #12059) stripped per AGENTS_ATLAS.md §15.6aiConfig.openAiCompatible.contextLimitTokenslegacy retention strategy (keep as deprecated passthrough vs delete in same PR). Operator/Stage-1 sequencing call.Timing + scope
Recommendation (lean B-with-escape-hatch per @neo-gpt): fold into Epic #12101 Stage 1+ rewrite to avoid double migration. Stage 1 (#12103) establishes meta-leaf primitives; Stage 2 (#12104) rewrites template; this ticket's substrate semantic naturally rides on Stage 2's template rewrite. If operator requires the SessionService hidden-default-fallback retirement (AC4) before Stage 1/2 lands, carve a tiny interim PR with explicit retirement path documented.
Empirical anchor
PR #12113 (just-shipped) preserved the existing
aiConfig.openAiCompatible.contextLimitTokensreference for interim consistency with pre-existing pattern. Operator surfaced the substrate-shape issue during cycle-1 V-B-A: "client wants to use ollama". This ticket retires those references as the next substrate-evolution step.Related
Discipline anchor
@neo-gpt's V-B-A surfaced: chat default = preserve current 262144/200000 (already live after #12064). Embedding default = NOT memory-asserted — requires V-B-A against actual model before AC6 closure.
SessionService.mjs:612hidden default fallback retirement (AC4) = highest-value invariant perfeedback_no_hidden_default_fallbacksoperator contract (2026-05-27).