Make the agent provider a first-class, operator-chosen property instead of a
Claude-only assumption. Trunk gains the seams; the actual non-default payloads
(Codex first) install from the `providers` branch.
Setup
- A provider registry feeds a hard-wired setup picker (Claude | Codex). Picking
a non-default provider installs its payload (setup/add-codex.sh, channel-style),
runs a vault-only auth walkthrough (--step provider-auth), and records the pick
on the first agent before its first spawn.
- Picking Claude changes nothing — default installs are byte-for-byte unaffected.
Provider as a DB property
- Provider lives on container_configs.provider (materialized to container.json,
read by resolveProviderName). Creation stays provider-agnostic; the picked
provider is applied via the picked-provider seam. The deprecated
agent_groups.agent_provider path is not used.
Switching + memory
- Switch a live group with `ncl groups config update --provider` + restart.
- Memory never migrates at runtime — each provider keeps its own store. The
/migrate-memory skill carries a group's memory across a switch in either
direction (flat CLAUDE.local.md <-> memory/ scaffold). group-init seeds an
imported-agent-memory note for non-default providers; the runner's memory
definition reads it first turn. See docs/provider-migration.md.
No install-wide default, no runtime provider guard — switching is operator-by-
convention, consistent with the no-install-gating posture.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>