Parent tracker
Dependency
Problem
Managed API-key onboarding still uses connectionId: string | null. A null target means “edit the canonical-slug Connection if it exists, otherwise create it”, so callers cannot explicitly request another account for the same provider.
The Runtime Host also returns only { kind: "saved" }, while the create identity and slug are chosen too late for the onboarding ticket and durable recovery record to describe one exact entity. CLI/TUI projects at most one editable Connection per provider and cannot express add-another-account.
Desired outcome
Deepen the existing connection.onboarding.verify / connection.onboarding.save module around one explicit target:
type ConnectionOnboardingTarget =
| { kind: 'create'; providerType: ProviderType }
| { kind: 'existing'; connectionId: string };
Runtime Host and Storage own the complete identity lifecycle:
create always creates a new Connection; it never silently edits the canonical account.
existing resolves only by immutable Connection ID and never falls back by provider or slug.
- Storage allocates the final UUID and unique slug (
provider, provider-2, ...) from its authoritative catalog snapshot.
- The onboarding ticket binds the exact candidate ID, slug, provider, normalized endpoint, credential/request-header basis, and proxy basis.
- Save returns the committed Connection ID, slug, provider, and revision.
- Durable onboarding recovery replays the same ID and slug.
- Adding another account never changes an existing default target.
Scope
- Replace the nullable onboarding wire target with the explicit closed union.
- Normalize provider-specific endpoints in Storage after resolving the canonical provider.
- Persist the allocated slug in a versioned onboarding intent while continuing to recover historical v1 intents with identity-first semantics.
- Return typed
catalog_full and superseded outcomes without selecting another slug during commit.
- Update CLI/TUI setup to list every API-key-onboardable Connection plus an explicit add-account action for each provider.
- Increment
RUNTIME_HOST_COMPATIBILITY_EPOCH for the closed input/output shape change.
Acceptance criteria
- Consecutive and interleaved create requests produce distinct IDs and deterministic unique slugs.
- Editing an existing Connection preserves its ID and slug; a deleted ID returns
connection_not_found without creating a replacement.
- If a planned create slug is occupied after begin, completion fails as superseded rather than choosing another identity.
- Catalog capacity is checked both before discovery and again at commit.
- Crash recovery preserves the exact v2 ID/slug and remains compatible with identity-first v1 intents.
- Save returns the canonical committed Connection identity.
- CLI/TUI visibly disambiguates same-provider accounts and can select add-another versus edit-existing.
- OAuth/non-API-key Connections are not offered by the API-key wizard.
- A second account does not replace the default Connection.
- Protocol exact-shape and compatibility-epoch tests cover the contract change.
Non-goals
- Desktop API-key orchestration convergence
- OAuth Connection creation or multiple OAuth account cards
- User-supplied slug/name in the managed onboarding flow
- Moving custom request headers/body overlays into the onboarding transaction
- Automatic account fallback, balancing, or default-target changes
Parent tracker
Dependency
Problem
Managed API-key onboarding still uses
connectionId: string | null. A null target means “edit the canonical-slug Connection if it exists, otherwise create it”, so callers cannot explicitly request another account for the same provider.The Runtime Host also returns only
{ kind: "saved" }, while the create identity and slug are chosen too late for the onboarding ticket and durable recovery record to describe one exact entity. CLI/TUI projects at most one editable Connection per provider and cannot express add-another-account.Desired outcome
Deepen the existing
connection.onboarding.verify/connection.onboarding.savemodule around one explicit target:Runtime Host and Storage own the complete identity lifecycle:
createalways creates a new Connection; it never silently edits the canonical account.existingresolves only by immutable Connection ID and never falls back by provider or slug.provider,provider-2, ...) from its authoritative catalog snapshot.Scope
catalog_fulland superseded outcomes without selecting another slug during commit.RUNTIME_HOST_COMPATIBILITY_EPOCHfor the closed input/output shape change.Acceptance criteria
connection_not_foundwithout creating a replacement.Non-goals