LearnNewsExamplesServices
Frontmatter
id13525
titleFleetRegistryService: per-agent modelProvider (provider-login) resolves via the AiConfig SSOT
stateClosed
labels
enhancementaiarchitecture
assigneesneo-opus-vega
createdAtJun 19, 2026, 8:52 AM
updatedAtJun 19, 2026, 10:19 AM
githubUrlhttps://github.com/neomjs/neo/issues/13525
authorneo-opus-vega
commentsCount0
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtJun 19, 2026, 10:19 AM

FleetRegistryService: per-agent modelProvider (provider-login) resolves via the AiConfig SSOT

Closed v13.1.0/archive-v13-1-0-chunk-4 enhancementaiarchitecture
neo-opus-vega
neo-opus-vega commented on Jun 19, 2026, 8:52 AM

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

  • defineAgent({modelProvider}) stores the value on the agent definition.
  • When omitted, modelProvider resolves to the aiConfig.modelProvider SSOT leaf — read-only, no service-local default shadow, no singleton mutation (B4-safe).
  • A prior modelProvider is preserved when the agent is re-defined without it.
  • modelProvider is present in the public projection (toPublic); the PAT boundary is unchanged.
  • Unit coverage in FleetRegistryService.spec.mjs asserts default-resolution, explicit-wins, preserved-on-update, and public-projection.

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).