Summary
Stage 4 of Epic #12101 — consumer-side codemod migrating ai/services + ai/mcp off the non-getter aiConfig anti-patterns (Discussion #12100 sub-classes A / B / D-prod / E) onto the canonical Proxy-routed read + the no-hidden-default contract. Behaviour-preserving.
Deltas
- A (12):
aiConfig.data.X → aiConfig.X (drop the Proxy bypass) — DreamService, ConceptDiscoveryService, GapInferenceEngine, DatabaseService, SessionService, GraphService.
- D-prod (8): bootstrap
aiConfig.data.debug = true → aiConfig.debug = true (proxy set-trap → setData) — the 6 mcp-servers + run-bridge + mcp-cli. (No aiConfig.set() method exists — Discussion #12100 hypothesized one; the proxy assignment is the write path.)
- B (3):
ProviderReadinessHelper default-params config = aiConfig.data → config = aiConfig.
- E (scalar + tenant): removed config-backed redundant
?? <literal> fallbacks — guideGapWeightThreshold/minSourceLength/prScanLimit, mcpSyncMaxChunks (×2), defaultTenantId/defaultRepoSlug (DocumentService/QueryService/SearchService). The config leaf provides each value verbatim; behaviour-identical.
Test Evidence
963 ai/services unit specs pass. The 8 failing memory-core specs are pre-existing env-flaky (need live ollama/models/MC) — confirmed failing identically on stashed-clean dev (git stash → same 8 fail → pop). node --check clean on all 19 files.
Evidence: every removed E default is config-backed — verified the owning leaf(...) in the templates (guideGapWeightThreshold: leaf(0.8), mcpSyncMaxChunks: leaf(50), defaultTenantId: leaf('neo-shared'), …). The tenant filters now read aiConfig.defaultTenantId verbatim (= 'neo-shared' for any current config), so the fail-closed isolation is unchanged.
Post-Merge Validation
None for the bulk — behaviour-preserving.
⚠️ Open sub-decision (deliberately NOT in this PR): the 9 KB Source ?? '<path>' fallbacks are #11660's deliberate byte-equivalence-for-stale-configs shims. The sourcePaths leaf defines all 9 verbatim, so the no-hidden-default contract says remove them — but removal breaks KB ingestion for operator overlays predating #11660's sourcePaths block. Surfaced as a config-SSOT-vs-backward-compat call before removal.
FAIR-band: n/a — operator-directed epic lane (#12101 Stage 4).
Refs #12106.
Authored by Claude Opus 4.8 (Claude Code, 1M context).
Summary
Stage 4 of Epic #12101 — consumer-side codemod migrating
ai/services+ai/mcpoff the non-getteraiConfiganti-patterns (Discussion #12100 sub-classes A / B / D-prod / E) onto the canonical Proxy-routed read + the no-hidden-default contract. Behaviour-preserving.Deltas
aiConfig.data.X→aiConfig.X(drop the Proxy bypass) — DreamService, ConceptDiscoveryService, GapInferenceEngine, DatabaseService, SessionService, GraphService.aiConfig.data.debug = true→aiConfig.debug = true(proxy set-trap →setData) — the 6 mcp-servers + run-bridge + mcp-cli. (NoaiConfig.set()method exists — Discussion #12100 hypothesized one; the proxy assignment is the write path.)ProviderReadinessHelperdefault-paramsconfig = aiConfig.data→config = aiConfig.?? <literal>fallbacks —guideGapWeightThreshold/minSourceLength/prScanLimit,mcpSyncMaxChunks(×2),defaultTenantId/defaultRepoSlug(DocumentService/QueryService/SearchService). The config leaf provides each value verbatim; behaviour-identical.Test Evidence
963
ai/servicesunit specs pass. The 8 failing memory-core specs are pre-existing env-flaky (need live ollama/models/MC) — confirmed failing identically on stashed-clean dev (git stash→ same 8 fail →pop).node --checkclean on all 19 files.Evidence: every removed E default is config-backed — verified the owning
leaf(...)in the templates (guideGapWeightThreshold: leaf(0.8),mcpSyncMaxChunks: leaf(50),defaultTenantId: leaf('neo-shared'), …). The tenant filters now readaiConfig.defaultTenantIdverbatim (='neo-shared'for any current config), so the fail-closed isolation is unchanged.Post-Merge Validation
None for the bulk — behaviour-preserving.
⚠️ Open sub-decision (deliberately NOT in this PR): the 9 KB
Source?? '<path>'fallbacks are #11660's deliberate byte-equivalence-for-stale-configs shims. ThesourcePathsleaf defines all 9 verbatim, so the no-hidden-default contract says remove them — but removal breaks KB ingestion for operator overlays predating #11660'ssourcePathsblock. Surfaced as a config-SSOT-vs-backward-compat call before removal.FAIR-band: n/a — operator-directed epic lane (#12101 Stage 4).
Refs #12106.
Authored by Claude Opus 4.8 (Claude Code, 1M context).