<!-- Reference: running a session under a second Anthropic account (account roots + alt profiles).
     Hand-authored against tools/claude-spt/src/alt.rs + the [profiles.alt.*] manifest overlay;
     the decision behind it is docs/adr/0010. [doc->REQ-ALT-ACCOUNT-ROOTS] [doc->REQ-DOCS-SITE] -->
# Alt accounts

Run a session under a **different Anthropic account** without logging out of the first — so when one
account runs out of tokens, an endpoint can keep going on another.

Claude Code holds exactly one account per config root: `/login` **replaces** the credentials in the
active root, and `claude auth` offers only login/logout/status. So a second account means a second
config root, selected by `CLAUDE_CONFIG_DIR`. `claude-spt` owns those roots and calls them **account
roots**; an **alt profile** is an adapter profile whose only job is to point a session at one.

## The layout

```text
~/.claude-spt/
  shared/                     one node-wide continuity tree
    projects/ todos/ file-history/ shell-snapshots/ session-env/
  accounts/<account>/         = CLAUDE_CONFIG_DIR for one alt profile
    .credentials.json         real file — one login, shared by every endpoint on this account
    .claude.json              real file — identity + trust
    projects/ …               junctions into ../../shared/…
    skills/ agents/ commands/ plugins/
                              junctions into your primary root's
    settings.json             a copy of your primary root's, taken at init
```

Two properties are load-bearing:

- **Continuity is shared.** `projects/` and friends are directory junctions into one node-wide tree,
  so a session started on one account can be **resumed on another** — spt's resume passes
  `--resume <session_id>`, and Claude Code reads that transcript out of whichever root is active.
- **Nothing account-bound is shared.** Credentials and `.claude.json` are real files in each root.
  `.claude.json` is rewritten with a new file identity every 15-25 seconds while a session is live,
  so a link there would stop tracking on the first rewrite and the two stores would diverge
  silently — a refreshed token landing in one while the other rots.

`history.jsonl` is a file, so it cannot join the shared tree: **prompt history does not follow an
account switch.** That is the one accepted loss.

Your **plugins** ride along too: the plugin store — marketplaces, installs, caches — is junctioned
from your primary root, so a plugin installed once is present under every account. Which plugins are
*enabled* stays per-account, because `settings.json` is a copy. Without the shared store, the copied
settings would enable plugins the account root does not hold, and the session would come up with its
hooks and skills silently missing.

## One account, many endpoints

An account root holds a login, not a session — every endpoint on that account shares the one login.
Per-endpoint memory and identity are spt's job at the mind layer, so endpoints do **not** need a root
apiece (and a root apiece would cost a login apiece, which defeats the failover).

An endpoint **keeps its id** across profiles. The profile selects which account pays, never who is
speaking.

## Setup

There is none. The **first launch** of an endpoint on an alt profile notices the account root does
not exist yet and builds it right there: it creates the root and the shared tree, junctions the
continuity set and the authoring surface, copies `settings.json`, and seeds the trust map from your
current root (trust is per-config-root, and an unseeded root does not fail — it **hangs** on the
trust dialog). Every launch after the first finds the root in place and pays nothing: per-launch
maintenance is exactly the cost this design removes.

So the whole flow is: launch an endpoint on the profile and **log in at Claude Code's own prompt**.
A launch against a root with no credentials proceeds deliberately — Claude Code does the login, and
the credentials land in that root for every later endpoint on the account.

The same one-shot setup also exists as a command, for building a root ahead of its first launch or
repairing one (it is idempotent — re-running it fixes the missing piece and touches nothing else):

```sh
claude-spt alt init [account]    # account defaults to "alt", the shipped profile's
```

## Using it

The adapter ships one example profile, `claude-spt:alt`, bound to an account literally named `alt`:

```sh
spt endpoint run --adapter claude-spt:alt --id <id>
```

Every spawned role follows the profile — the session, its resume, the Psyche, and the end-of-session
summarizer — because a failover that leaves the Psyche drawing on the exhausted account is not a
failover.

## Your own accounts

Add your own without waiting for an adapter release, using spt-core's own profile machinery:

```sh
spt adapter create-profile claude-spt work     # then point its commands at --account work
```

The first launch on the new profile builds its account root, exactly as with the shipped one. A
created profile is node-local and survives re-registration and adapter updates. Profiles are
**static**: spt has no runtime profile parameterization and no `{account}` fill key, so each profile
names its account literally — one profile per account.

## What this is not

It does not swap providers or backends. The `claude-spt:ccs` profile (model/billing multiplexing
through `ccs`) is untouched and keeps its own roles.
