Parent tracker
Problem
A Session and AgentRun currently persist only llmConnectionSlug + model. A slug is a human-readable catalog locator, not immutable entity identity. If connection A is deleted and connection B later reuses A's slug, execution can resolve B and read B's credential for an old Session.
The Runtime Host already resolves a canonical ConnectionCatalogEntry while creating or explicitly reconfiguring a Session, but discards its connectionId before persistence.
Desired outcome
Establish the durable identity foundation for #3852 without changing the Runtime Host wire contract in this slice:
- New and explicitly reconfigured Sessions persist
llmConnectionId + llmConnectionSlug + model in one metadata commit.
- New AgentRuns snapshot the Session's ID, slug, and model.
- Branches, revisions, conversation copies, inherited subagents, recovery runs, and continuations preserve the identity when present.
- Execution with a bound identity looks up by ID, verifies the stored slug, and never falls back to a same-named replacement.
- OAuth execution reconciliation uses the bound Connection identity instead of resolving only by slug.
- Legacy slug-only Session and AgentRun records remain decodable.
Module interface
Deepen the existing Runtime Policy execution resolver instead of adding a parallel readiness path:
type ExecutionConnectionRef =
| {
readonly kind: 'bound';
readonly connectionId: string;
readonly connectionSlug: string;
}
| {
readonly kind: 'catalog_slug';
readonly connectionSlug: string;
};
resolveExecutionConnection(ref: ExecutionConnectionRef)
Invariants:
bound locates by ID and then validates slug.
- Missing ID returns a not-found/deleted outcome.
- ID/slug disagreement fails closed as identity mismatch.
- Neither case retries by slug.
catalog_slug remains available only where the caller is selecting from current catalog state rather than resuming a durable entity binding.
Legacy migration
A legacy Session has no stored ID. A lazy adoption path may bind the currently matching slug to an ID only under Session admission using metadata revision/CAS, followed by ID-based revalidation before execution.
The catalog has no deletion tombstone or historical identity evidence. If a slug was already deleted and reused before upgrade, the original identity cannot be reconstructed. The implementation and PR description must state this limitation rather than claim historical certainty.
Acceptance criteria
- Session decode accepts a legacy record without
llmConnectionId.
- AgentRun exact decode accepts a legacy record without
llmConnectionId.
- New Session creation and explicit configuration update persist canonical ID, slug, and model atomically.
- A configuration no-op comparison includes Connection ID.
- New AgentRuns copy the Session Connection ID.
- Branch, revision, conversation-copy, inherited-child, recovery, and continuation paths preserve an existing ID.
- Deleting A and creating B with A's slug causes a bound Session for A to fail without reading B's API key or OAuth token.
- An existing ID with a different stored slug fails closed.
- OAuth uncertain-commit reconciliation cannot cross to a same-slug replacement Connection.
- Legacy migration uses revision/CAS and revalidates the resulting bound identity before execution.
- Focused core, storage, runtime, and runtime-host tests cover persistence, propagation, resolution, and races.
Non-goals
- Adding
connectionId to Runtime Host wire model targets or Session catalog projections
- Updating CLI/TUI or Desktop pickers
- Showing the final “original account deleted” UI state
- Multi-account onboarding
- Changing the Runtime Host compatibility epoch
- Weighted routing, automatic failover, or silent rebinding
The wire target, identity-health projection, explicit-selection TOCTOU closure, and compatibility epoch change are tracked as the next independently reviewable slice under #3852.
Parent tracker
Problem
A Session and AgentRun currently persist only
llmConnectionSlug + model. A slug is a human-readable catalog locator, not immutable entity identity. If connection A is deleted and connection B later reuses A's slug, execution can resolve B and read B's credential for an old Session.The Runtime Host already resolves a canonical
ConnectionCatalogEntrywhile creating or explicitly reconfiguring a Session, but discards itsconnectionIdbefore persistence.Desired outcome
Establish the durable identity foundation for #3852 without changing the Runtime Host wire contract in this slice:
llmConnectionId + llmConnectionSlug + modelin one metadata commit.Module interface
Deepen the existing Runtime Policy execution resolver instead of adding a parallel readiness path:
Invariants:
boundlocates by ID and then validates slug.catalog_slugremains available only where the caller is selecting from current catalog state rather than resuming a durable entity binding.Legacy migration
A legacy Session has no stored ID. A lazy adoption path may bind the currently matching slug to an ID only under Session admission using metadata revision/CAS, followed by ID-based revalidation before execution.
The catalog has no deletion tombstone or historical identity evidence. If a slug was already deleted and reused before upgrade, the original identity cannot be reconstructed. The implementation and PR description must state this limitation rather than claim historical certainty.
Acceptance criteria
llmConnectionId.llmConnectionId.Non-goals
connectionIdto Runtime Host wire model targets or Session catalog projectionsThe wire target, identity-health projection, explicit-selection TOCTOU closure, and compatibility epoch change are tracked as the next independently reviewable slice under #3852.