# Upgrade Guide — vNEXT

<!-- assembled-by: assemble-next-md -->
<!-- bump: patch -->

## What Changed

Delivers the §5 livetest battery as testable orchestration — the structural gate for the dry-run→live promotion decision, so "is this safe to turn on?" is a runnable, verified procedure rather than a memory.

- **`CredentialRepointingLivetest`** (src/core/CredentialRepointingLivetest.ts) — drives the automatable battery items against injected deps (wired to the real CredentialSwapExecutor + identity oracle only at enablement):
  - **(a)** enrolled-home swap round-trip and **(b)** default-home slot round-trip — each verified by the identity oracle (NOT `claude auth status`, disqualified in E4a): after the swap the two slots' identities must have EXCHANGED; after the swap-back they must be RESTORED. The harness ALWAYS attempts the restoring swap, even when the forward verify fails, and reports any residual state honestly.
  - **Manual items surfaced, never auto-passed** — (c) post-swap refresher correctness, (d) the §0.c at-expiry residual (a deliberately-minted disposable grant), and the E4 liveness observation are listed as required operator steps; `promotable` stays `false` while any remain outstanding.
- **Armed guard** — `run()` performs ZERO swaps unless explicitly armed. The arm is set only at enablement, behind an operator flag + the feature's own enable check — never in CI, never as a dark-build step. So importing or testing the module can never move a real credential.

Closes the Migration Parity + Agent Awareness gap for live credential re-pointing: existing agents (not just fresh installs) learn the `/credentials/*` manual levers and the zero-touch default-account flip on their next update, and the dark config defaults are proven to install in place.

- **CLAUDE.md awareness (new + existing agents)** — `generateClaudeMd()` (new agents) and `migrateClaudeMd()` (existing agents, content-sniffed + idempotent) both gain a "Live Credential Re-pointing" section documenting the levers (`GET /credentials/locations`, `POST /credentials/swap`, `POST /credentials/set-default`, `POST /credentials/restore-enrollment`, `GET /credentials/rebalancer`) and the two proactive triggers: "flip my default account" → `set-default`; "which account is this slot on?" → `GET /credentials/locations` (read the ledger, never infer from `claude auth status`).
- **Config-defaults parity (proven)** — the dark `subscriptionPool.credentialRepointing` block (`enabled:false`, `dryRun:true`, `manualLeversEnabled:true`) already rides the generic `ConfigDefaults` → `getMigrationDefaults` → `applyDefaults` add-missing path onto existing agents. This step adds the parity test that proves it installs on a config lacking it AND never overwrites an operator who explicitly set `enabled:true`.
- **Dark** — every lever still 503s/no-ops behind the existing `subscriptionPool.credentialRepointing.enabled` flag. This step adds zero runtime behavior; it only makes the (still-off) feature discoverable and its dark defaults durable across the install base.

## What to Tell Your User

Nothing changes for you yet — this is off-by-default validation tooling. What it adds: before the credential-moving feature is ever turned on, there's now a runnable, verified "is this actually safe to switch on?" check. It performs a real account-swap and swap-back and confirms — using the trustworthy identity check, not the misleading one — that the move landed on the right account and then cleanly undid itself, always leaving things exactly as they were. Two parts of that check are inherently hands-on (they involve waiting out a token refresh and deliberately stressing a throwaway login), so the tool lists those as steps you and I do together. Crucially, the whole battery refuses to run unless explicitly armed at turn-on time — it can never move a real credential just by existing or being tested. Turning the feature on, and running this gate, stays your decision.

Nothing changes for you yet — the underlying feature is still switched off. What this does is make me *aware* of it so that, once it's turned on after a review window, you can just say "flip my default account to X" or "which account is this session on?" and I'll know exactly which lever to use instead of guessing. It also makes sure that awareness reaches agents that were set up before this feature existed, not only brand-new ones — so the capability isn't silently missing on an older install.

## Summary of New Capabilities

No new runtime capability — this is the dry-run→live promotion gate for live credential re-pointing, shipped unwired (it runs only when the operator arms it at enablement). New internal class `CredentialRepointingLivetest`: drives the automatable swap round-trip battery (identity-verified exchange-then-restore, always restoring), surfaces the manual items (refresher correctness, the at-expiry residual via a disposable grant, liveness) without ever auto-passing them, and refuses every swap unless explicitly armed. Not wired into any runtime path; no route, no config flag, no credential write path.

No new runtime capability — this is the Migration Parity + Agent Awareness step. New + existing agents' CLAUDE.md now documents the live-credential-re-pointing levers and the "flip my default account" / "which account is this slot on?" proactive triggers, and the feature's dark config defaults are proven to install on existing agents without clobbering an operator's explicit settings. The feature itself remains dark behind `subscriptionPool.credentialRepointing.enabled`.

## Evidence

- `tests/unit/credential-repointing-livetest.test.ts` (8) — armed guard (refuses + zero swaps when unarmed); armed happy path (both round-trips exchange-then-restore, world left exactly as found, 4 swaps); not-promotable while manual items remain; fail-closed when the oracle can't resolve a slot; refusal when both slots already report one account; fail-AND-still-restore when the forward swap doesn't actuate; residual-state report when the restoring swap fails; the manual items (c)/(d)/E4 are surfaced. tsc + full lint clean; feature-delivery-completeness 97/97.

- `tests/unit/PostUpdateMigrator-credentialRepointing.test.ts` (8) — migrateClaudeMd adds the section when absent (with both proactive triggers + the dark-posture line + the `claude auth status` honesty caveat present), is idempotent (no duplicate on re-run, byte-identical), preserves prior content, and gracefully skips a missing CLAUDE.md; the generateClaudeMd template emits the same section (source parity); and migrateConfig installs the DARK credentialRepointing block on a config lacking it, NEVER clobbers an operator's explicit `enabled:true` (fills only the missing sibling default), and is idempotent.
- tsc clean; full `npm run lint` clean (dark-gate unchanged — no ConfigDefaults edit; the defaults already existed from Steps 1/7).
