Context
PR #13526 surfaced a long-standing naming inconsistency for the AiConfig SSOT singleton import binding. Per @tobiu (2026-06-19): the config began as a plain proxy object bound as aiConfig (lowercase); after it was extended into a state.Provider-based SSOT (ADR 0019), the convention switched to AiConfig (uppercase — the config treated as a proper-noun SSOT singleton). The older code was never swept. #13526 re-introduced the lowercase binding because I lifted the pattern from MemoryService.mjs (the dominant existing usage).
Direction confirmed by @tobiu (2026-06-19), with the full scale in hand: normalize to uppercase AiConfig.
The Problem — V-B-A inventory (2026-06-19)
The config singleton (default export createConfigProxy(instance) from each ai/**/config.mjs) is imported under two casings:
- lowercase
aiConfig — 1,526 occurrences across 198 files: all MCP servers, the knowledge-base / github-workflow / gitlab-workflow / memory-core / neural-link services, and most specs. (The proxy-era pattern.)
- uppercase
AiConfig — 70 files: the daemons/orchestrator (the newest subsystem), the lifecycle/maintenance scripts, and the config-chain self-imports (config.mjs importing its parent/config.template.mjs as AiConfig). (The post-Provider pattern.)
The export is an instance/proxy, not a class — both casings bind the same singleton. This is purely a binding-name inconsistency; there is no contract/API change (the config export is identical), so no Contract Ledger applies.
Acceptance Criteria
Guards (must NOT be swept / care)
aiConfigDefaults — the separate TIER1 defaults module; a distinct identifier. A word-boundary \baiConfig\b rename does not match inside aiConfigDefaults, but verify.
- Already-correct compounds:
AiConfigModel, AiConfigDefaultsFixtureTest, AiConfigProviderTest, SnapshotAiConfigTest — leave.
ai/mcp/server/shared/logger.mjs uses aiConfig as a function parameter (local; receives the config object). Sub-decision: rename the params to AiConfig for full consistency (they reference the SSOT), or leave them as local camelCase. Recommend renaming for consistency; flag in the PR.
- Mechanics: word-boundary rename only; no
sed -i / bash redirection (§file_editing_tool_selection) — use the Edit tool or a sanctioned node codemod. check-aiconfig-test-mutation must stay green (this is a rename, not a mutation — verify specs still read-not-mutate).
Execution
Prefer a single mechanical word-boundary rename PR (the transformation is uniform + low-risk) with the guards verified and a cross-subsystem spot-check. If the 198-file diff proves too large to review, decompose by subsystem (memory-core · knowledge-base · github-workflow · gitlab-workflow · neural-link · shared · scripts · specs) into an epic + per-subsystem subs (1-PR-per-ticket).
Related
- Surfaced by PR #13526 (provider-login slice, the lowercase re-introduction). Aligns-with ADR 0019 (AiConfig reactive Provider SSOT).
- Sibling SSOT-hygiene: #12456 (read-then-re-implement antipatterns). Lint precedent: #13227. Flake guard: #12693. B4 isolation: #12435.
Release classification: post-release / consistency (not release-blocking) — boardless.
Origin Session ID: a200ff3b-5ea5-4fc0-b288-cd5fe2c917e0
Authored by Claude Opus 4.8 (Claude Code), @neo-opus-vega (Vega).
Context
PR #13526 surfaced a long-standing naming inconsistency for the AiConfig SSOT singleton import binding. Per @tobiu (2026-06-19): the config began as a plain proxy object bound as
aiConfig(lowercase); after it was extended into astate.Provider-based SSOT (ADR 0019), the convention switched toAiConfig(uppercase — the config treated as a proper-noun SSOT singleton). The older code was never swept. #13526 re-introduced the lowercase binding because I lifted the pattern fromMemoryService.mjs(the dominant existing usage).Direction confirmed by @tobiu (2026-06-19), with the full scale in hand: normalize to uppercase
AiConfig.The Problem — V-B-A inventory (2026-06-19)
The config singleton (default export
createConfigProxy(instance)from eachai/**/config.mjs) is imported under two casings:aiConfig— 1,526 occurrences across 198 files: all MCP servers, the knowledge-base / github-workflow / gitlab-workflow / memory-core / neural-link services, and most specs. (The proxy-era pattern.)AiConfig— 70 files: thedaemons/orchestrator(the newest subsystem), the lifecycle/maintenance scripts, and the config-chain self-imports (config.mjsimporting its parent/config.template.mjsasAiConfig). (The post-Provider pattern.)The export is an instance/proxy, not a class — both casings bind the same singleton. This is purely a binding-name inconsistency; there is no contract/API change (the config export is identical), so no Contract Ledger applies.
Acceptance Criteria
aiConfigfiles (import binding + all word-boundary usages) toAiConfig. After the sweep,grep -rwl '\baiConfig\b'overai/,src/,test/,buildScripts/returns only the explicit guard exceptions below.AiConfig") plus, ideally, a fail-build lint (precedent: #13227'saiConfig-mutation lint) that flags a lowercaseaiConfigimport of a**/config.mjsdefault export. (AC2 may split to a sub if AC1 ships first.)Guards (must NOT be swept / care)
aiConfigDefaults— the separate TIER1 defaults module; a distinct identifier. A word-boundary\baiConfig\brename does not match insideaiConfigDefaults, but verify.AiConfigModel,AiConfigDefaultsFixtureTest,AiConfigProviderTest,SnapshotAiConfigTest— leave.ai/mcp/server/shared/logger.mjsusesaiConfigas a function parameter (local; receives the config object). Sub-decision: rename the params toAiConfigfor full consistency (they reference the SSOT), or leave them as local camelCase. Recommend renaming for consistency; flag in the PR.sed -i/ bash redirection (§file_editing_tool_selection) — use the Edit tool or a sanctioned node codemod.check-aiconfig-test-mutationmust stay green (this is a rename, not a mutation — verify specs still read-not-mutate).Execution
Prefer a single mechanical word-boundary rename PR (the transformation is uniform + low-risk) with the guards verified and a cross-subsystem spot-check. If the 198-file diff proves too large to review, decompose by subsystem (memory-core · knowledge-base · github-workflow · gitlab-workflow · neural-link · shared · scripts · specs) into an epic + per-subsystem subs (1-PR-per-ticket).
Related
Release classification: post-release / consistency (not release-blocking) — boardless.
Origin Session ID: a200ff3b-5ea5-4fc0-b288-cd5fe2c917e0
Authored by Claude Opus 4.8 (Claude Code), @neo-opus-vega (Vega).