Context
This ticket exists to give a narrow close target to a small, already-verified slice of the broader B3 cleanup tracked by #12461. The broader ticket still has known residuals, so using it as the PR close target would falsely close work that remains open.
Duplicate sweep evidence:
- Knowledge Base semantic search was attempted for the B3 cleanup context but the KB collection was unavailable in this session.
- Local issue/discussion sweep over
resources/content/issues and resources/content/discussions found historical swarmHeartbeat.targetSource and AiConfig context but no duplicate for this exact three-file existing-leaf slice.
- Live GitHub REST search returned
total_count: 0 for existing-leaf B3 Orchestrator ChromaManager SessionService.
The Problem
ADR 0019 made AiConfig the reactive Provider SSOT. Production AI consumers should read resolved leaves directly. Existing-leaf B3 fallbacks such as ?? null, || 2000, || '<unset>', and provider-name substitutes hide missing or malformed config by silently inventing local defaults at the consumer.
The currently verified removable slice is narrow:
ai/daemons/orchestrator/Orchestrator.mjs reads AiConfig.orchestrator.swarmHeartbeat.targetSource.
ai/services/memory-core/managers/ChromaManager.mjs reads aiConfig.summarizationBatchLimit in both count methods.
ai/services/memory-core/SessionService.mjs reads provider model leaves and aiConfig.summarizationBatchLimit directly for logging/guardrail metadata.
The Architectural Reality
These are production consumers of existing imported config leaves. They do not introduce a new config key, tool contract, or public API surface. The correct substrate is a direct-read cleanup in the consuming services, not a config-template or schema expansion.
Current line anchors on the implementation branch:
ai/daemons/orchestrator/Orchestrator.mjs:511
ai/services/memory-core/managers/ChromaManager.mjs:309
ai/services/memory-core/managers/ChromaManager.mjs:348
ai/services/memory-core/SessionService.mjs:253
ai/services/memory-core/SessionService.mjs:577
ai/services/memory-core/SessionService.mjs:592
The Fix
Remove only the existing-leaf B3 defensive fallbacks in the three files above:
- Replace
AiConfig.orchestrator.swarmHeartbeat.targetSource ?? null with the direct leaf.
- Replace
aiConfig.summarizationBatchLimit || 2000 with the direct leaf in ChromaManager.
- Replace
SessionService provider-model fallbacks and summarizationBatchLimit || 'unset' with direct leaf reads.
Contract Ledger Matrix
Not applicable. This ticket changes no consumed public/config/tool surface and adds no new config leaf. It only removes consumer-side hidden defaults for leaves that already exist in the imported AiConfig authority.
Decision Record Impact
Aligned with ADR 0019, the AiConfig reactive Provider SSOT. This ticket does not amend, supersede, or challenge the ADR.
Acceptance Criteria
Out of Scope
memorySharing B3 residuals in SummaryService / MemoryService; those are blocked by red PR #12532 and should be cleaned after that lane resolves or folded into it.
HealthService residuals touched by open self PR #12562.
PullRequestSyncer pullFilenamePrefix || 'pr-'; the imported config lacks that leaf, so that belongs to a ledgered missing-leaf follow-up rather than a bare-strip cleanup.
- Normalized plain-object fallbacks in
KnowledgeBaseIngestionService and generic local config helpers that are not direct AiConfig SSOT reads.
Avoided Traps
- Do not close broad
#12461 from this narrow PR; it still contains verified residual work.
- Do not add missing config leaves in the same PR. Existing-leaf cleanup and config-contract expansion are different substrates.
- Do not mutate ignored local overlays to make tests pass; local
ai/config.mjs contamination must not become tracked PR scope.
Related
Related: #12461
Related: #12456
Blocked-adjacent: #12532
Conflict-adjacent: #12562
Handoff Retrieval Hints
Retrieval Hint: query_summaries("AiConfig SSOT B3 existing-leaf residuals Orchestrator ChromaManager SessionService #12461")
Retrieval Hint: commit range HEAD~1..HEAD on branch codex/12461-b3-existing-leaves.
Context
This ticket exists to give a narrow close target to a small, already-verified slice of the broader B3 cleanup tracked by
#12461. The broader ticket still has known residuals, so using it as the PR close target would falsely close work that remains open.Duplicate sweep evidence:
resources/content/issuesandresources/content/discussionsfound historicalswarmHeartbeat.targetSourceand AiConfig context but no duplicate for this exact three-file existing-leaf slice.total_count: 0forexisting-leaf B3 Orchestrator ChromaManager SessionService.The Problem
ADR 0019 made
AiConfigthe reactive Provider SSOT. Production AI consumers should read resolved leaves directly. Existing-leaf B3 fallbacks such as?? null,|| 2000,|| '<unset>', and provider-name substitutes hide missing or malformed config by silently inventing local defaults at the consumer.The currently verified removable slice is narrow:
ai/daemons/orchestrator/Orchestrator.mjsreadsAiConfig.orchestrator.swarmHeartbeat.targetSource.ai/services/memory-core/managers/ChromaManager.mjsreadsaiConfig.summarizationBatchLimitin both count methods.ai/services/memory-core/SessionService.mjsreads provider model leaves andaiConfig.summarizationBatchLimitdirectly for logging/guardrail metadata.The Architectural Reality
These are production consumers of existing imported config leaves. They do not introduce a new config key, tool contract, or public API surface. The correct substrate is a direct-read cleanup in the consuming services, not a config-template or schema expansion.
Current line anchors on the implementation branch:
ai/daemons/orchestrator/Orchestrator.mjs:511ai/services/memory-core/managers/ChromaManager.mjs:309ai/services/memory-core/managers/ChromaManager.mjs:348ai/services/memory-core/SessionService.mjs:253ai/services/memory-core/SessionService.mjs:577ai/services/memory-core/SessionService.mjs:592The Fix
Remove only the existing-leaf B3 defensive fallbacks in the three files above:
AiConfig.orchestrator.swarmHeartbeat.targetSource ?? nullwith the direct leaf.aiConfig.summarizationBatchLimit || 2000with the direct leaf inChromaManager.SessionServiceprovider-model fallbacks andsummarizationBatchLimit || 'unset'with direct leaf reads.Contract Ledger Matrix
Not applicable. This ticket changes no consumed public/config/tool surface and adds no new config leaf. It only removes consumer-side hidden defaults for leaves that already exist in the imported AiConfig authority.
Decision Record Impact
Aligned with ADR 0019, the AiConfig reactive Provider SSOT. This ticket does not amend, supersede, or challenge the ADR.
Acceptance Criteria
OrchestratorassignsswarmHeartbeatService.targetSourcefromAiConfig.orchestrator.swarmHeartbeat.targetSourcewithout?? nullor another local default.ChromaManagercount methods readaiConfig.summarizationBatchLimitdirectly without|| 2000.SessionServicelogging and guardrail metadata read provider model leaves andsummarizationBatchLimitdirectly without local substitutes.#12461residuals remain open and are not closed by this ticket.Out of Scope
memorySharingB3 residuals inSummaryService/MemoryService; those are blocked by red PR#12532and should be cleaned after that lane resolves or folded into it.HealthServiceresiduals touched by open self PR#12562.PullRequestSyncerpullFilenamePrefix || 'pr-'; the imported config lacks that leaf, so that belongs to a ledgered missing-leaf follow-up rather than a bare-strip cleanup.KnowledgeBaseIngestionServiceand generic local config helpers that are not directAiConfigSSOT reads.Avoided Traps
#12461from this narrow PR; it still contains verified residual work.ai/config.mjscontamination must not become tracked PR scope.Related
Related: #12461 Related: #12456 Blocked-adjacent: #12532 Conflict-adjacent: #12562
Handoff Retrieval Hints
Retrieval Hint:
query_summaries("AiConfig SSOT B3 existing-leaf residuals Orchestrator ChromaManager SessionService #12461")Retrieval Hint: commit rangeHEAD~1..HEADon branchcodex/12461-b3-existing-leaves.