Context
Sub-slice of #13521 (Accounts keeper-view enhancements), itself the deferred-AC home from #13491. #13521 bundles four ACs that each need their own PR; per the agent PR-body lint's 1-PR-per-ticket model (agent-pr-body-lint.yml — a ticket needing N PRs must be split), the first deliverable slice — #13521 AC1: provider-login resolves via the AiConfig provider SSOT — is split out here so a single PR can honestly Resolves it.
The Problem
A fleet agent's model-provider login (which provider it talks to — openAiCompatible, ollama, …) had no home on the Brain-side agent definition. The selection must resolve through the AiConfig provider SSOT (ADR 0019): read the resolved leaf at the use site, never a service-local default shadow, never a mutation of the shared singleton (the B4 test-DB-bleed hazard — see #12435).
The Fix
FleetRegistryService.defineAgent gains an optional modelProvider param:
- unset → resolves via the
aiConfig.modelProvider SSOT leaf (read-only; no service-local default shadow).
- explicit → the passed value wins.
- re-define without it → a prior value is preserved (parity with
createdAt).
- carried in the public definition (
toPublic) — it is non-secret (unlike the PAT, which stays Brain-side encrypted).
Purely additive / backward-compatible: existing callers omit the param and get the SSOT default. defineAgent is a Brain-side service method (not an MCP tool surface), so no Contract Ledger applies.
Acceptance Criteria
Out of Scope
- The provider credential class (a model-provider API key, parallel to the GitHub PAT) — a later slice if needed; this ticket is provider selection only.
- #13521 AC2 (basic NL-MCP external-harness entry) + AC3 (v14
IdentityState slot verification) — remain on #13521.
- Provider-defaults policy / cost-safety — that lives on #12740.
Related
- Parent: #13521 (retains AC2 + AC3). Grandparent epic: #13448.
- Aligns-with: ADR 0019 (AiConfig reactive Provider SSOT). B4 isolation context: #12435.
- Related: #12740 (provider defaults + cost-safety policy).
Release classification: v13.1 harness cockpit (not v13-release-blocking) — boardless.
Origin Session ID: a200ff3b-5ea5-4fc0-b288-cd5fe2c917e0
Authored by Claude Opus 4.8 (Claude Code), @neo-opus-vega (Vega).
Context
Sub-slice of #13521 (Accounts keeper-view enhancements), itself the deferred-AC home from #13491. #13521 bundles four ACs that each need their own PR; per the agent PR-body lint's 1-PR-per-ticket model (
agent-pr-body-lint.yml— a ticket needing N PRs must be split), the first deliverable slice — #13521 AC1: provider-login resolves via the AiConfig provider SSOT — is split out here so a single PR can honestlyResolvesit.The Problem
A fleet agent's model-provider login (which provider it talks to —
openAiCompatible,ollama, …) had no home on the Brain-side agent definition. The selection must resolve through the AiConfig provider SSOT (ADR 0019): read the resolved leaf at the use site, never a service-local default shadow, never a mutation of the shared singleton (the B4 test-DB-bleed hazard — see #12435).The Fix
FleetRegistryService.defineAgentgains an optionalmodelProviderparam:aiConfig.modelProviderSSOT leaf (read-only; no service-local default shadow).createdAt).toPublic) — it is non-secret (unlike the PAT, which stays Brain-side encrypted).Purely additive / backward-compatible: existing callers omit the param and get the SSOT default.
defineAgentis a Brain-side service method (not an MCP tool surface), so no Contract Ledger applies.Acceptance Criteria
defineAgent({modelProvider})stores the value on the agent definition.modelProviderresolves to theaiConfig.modelProviderSSOT leaf — read-only, no service-local default shadow, no singleton mutation (B4-safe).modelProvideris preserved when the agent is re-defined without it.modelProvideris present in the public projection (toPublic); the PAT boundary is unchanged.FleetRegistryService.spec.mjsasserts default-resolution, explicit-wins, preserved-on-update, and public-projection.Out of Scope
IdentityStateslot verification) — remain on #13521.Related
Release classification: v13.1 harness cockpit (not v13-release-blocking) — boardless.
Origin Session ID: a200ff3b-5ea5-4fc0-b288-cd5fe2c917e0
Authored by Claude Opus 4.8 (Claude Code), @neo-opus-vega (Vega).