# Sessions and accounts

Inspect account status and usage, continue a conversation, switch providers, and handle interrupted work without duplicating it.

## Check the account before starting work

Use these commands on an existing, initialized machine whose rollout prerequisites are satisfied. Each named profile isolates its managed provider configuration. Select the provider explicitly when checking sign-in state.

```text
hra account list
hra account show personal --provider codex
hra account usage personal --refresh
```

Codex usage reports observed limits and resets; `hra account usage-history personal --limit 50 --json` reads its retained local history. Claude exposes sign-in status, not account quotas or usage history. HRA does not pool subscription limits or automatically move a failed turn to another account.

A pending Codex login can be checked with `hra account show personal --provider codex` and canceled with `hra account login-cancel personal --provider codex`. A lost one-time URL cannot be recovered by starting another login over the pending attempt. Claude recovery instead requires the exact acknowledged command reported by status, after you have confirmed the original login child exited.

## Continue the same conversation

```text
hra session list
hra session status <session-id> --json
hra session send <session-id> -- "Review the latest changes."
hra session stop <session-id>
```

Use the returned session ID in scripts. A session name is convenient for people, but can change. For live observation, read `data.eventStream.cursor` from status and pass that exact cursor to `hra session watch <session-id> --cursor <status-cursor> --jsonl` so the status snapshot and subsequent events join without a gap.

Queue a message for later with `hra session queue <session-id> -- <message>`. Use `hra session steer <session-id> -- <message>` for the current turn. The [attachment contract](https://github.com/hraness/hra/blob/main/docs/attachments.md) lists accepted files and limits.

## Change the provider for the next turn

When the session is idle and the target provider is signed in, switch it explicitly. Claude Code requires a Linux execution machine.

```text
hra session switch <session-id> --provider claude --preset fable-max
hra session export <session-id> --format json
```

The new provider receives the retained tail of HRA's conversation record. Its native thread, hidden state, and cached context do not transfer. HRA states a retention gap when older recorded history was pruned; it does not invent history from before a session was adopted.

Switching providers within the same account profile preserves the session's working memory. A session with working-memory authority cannot switch to another account profile; start a new session for that account. Presets control future turns and do not reinterpret an already-bound historical model until you select a preset.

## Inspect an interrupted operation before retrying

A lost connection is not proof that a command failed before taking effect. Keep the command ID and reuse the exact recovery command or idempotency key HRA reports. An ambiguous result needs inspection, not a new send.

```text
hra status --json
hra session status <session-id> --json
hra remote command <uuidv7>
hra sync status
```

A recovery-required session stays fenced while HRA cannot prove who owns the provider process. Do not delete state or launch a second writer to clear it. `hra session abandon <session-id>` ends HRA's local session with provider state still unknown; use it only when you accept that consequence.

## First account

> **Conditional walkthrough.** Current daemon and hosted command-writer rollout remains blocked on capacity. Do not initialize, start, or autostart a current daemon until the hosted operator records protected two-pass zero-debt capacity evidence and its exact .activated readback receipt. Artifact availability and the live sync service do not clear this gate. After activation, complete the update runbook's daemon and target marker-2 proofs before globally enabling hosted writers.

```text
hra account add personal
hra account login personal --provider codex --device-code
hra account usage personal --refresh
hra account usage-history personal --limit 50 --json
```

Account login is always a dedicated one-shot invocation, including while the persistent shell is running. For Codex, use `hra account login personal --provider codex --device-code` in a foreground TTY for app-server's device-code path. That terminal displays the code and verification URL directly. An opted-in registered machine can also receive a versioned web request that always selects device-code mode; HRA accepts only the pinned Codex device URL and a separate closed code, encrypts them to the account key, and lets only the requesting browser read the handoff once before its five-minute hosted expiry. HRA keeps the resulting provider state inside that profile's isolated `CODEX_HOME` without copying `auth.json`.

On Linux, `hra account login personal --provider claude` launches a realpath-resolved Claude Code executable only after its exact self-reported version matches HRA's pin, in the foreground inside that profile's isolated `CLAUDE_CONFIG_DIR`. Claude owns its prompts and browser handoff. HRA gives it the terminal, joins the exact child, and reports only whether Claude says it is signed in; HRA never opens or copies a Claude credential. Claude exposes no HRA device-code, handoff-file, or web-linking protocol. New Claude effects are refused on macOS pending authenticated isolated-Keychain and detached-read acceptance.

For a Codex login, JSON and noninteractive callers must create an empty mode-0600 file under a canonical current-user-owned mode-0700 directory, then pass its absolute canonical path:

```text
hra account login personal --device-code --handoff-file /absolute/private/login.json --json
```

HRA opens and holds the parent and file, resolves the account selector to one exact local account ID, and dispatches login only for that authority. It validates the returned account, state, cancellation command, URL, and device-code shape, writes one versioned login document through the held descriptor, verifies it with fsync and readback, and closes both descriptors before returning only the path and cleanup disposition on stdout. The caller reads the file through its protected boundary and removes it after login. A same-key replay never claims or rewrites a handoff. While login is pending it reports that one-time instructions are unavailable; after completion or cancellation it reports the terminal account state.

If the first pending-login handoff is lost or the daemon restarts before completion, `hra account show personal --provider codex` reports the pending attempt. Then run `hra account login-cancel personal --provider codex`. A caller that retained the idempotency key may retry it without redispatching. A still-pending local replay cannot recover the one-time code or URL; a completed or canceled replay returns terminal signed-in or signed-out evidence instead of stale pending state. HRA cancels only that profile's exact current-generation provider login before allowing a fresh login. Verification URLs and user codes never enter local durable HRA state, logs, or ordinary command output. A protected handoff file may retain them for its local caller; the web path instead retains only an account-key-encrypted, one-read hosted result until consumption or five-minute expiry.

If a Claude foreground parent or daemon fails after launch, `hra account show personal --provider claude` retains the one-child fence even if Claude reports signed in. After confirming that original child has exited, use the exact attempt, generation, and idempotency key in the reported acknowledged `hra account login-cancel` command to release only the local fence. That recovery does not stop Claude or read, change, or delete a credential.

`hra account usage` is Codex-only and keeps the latest snapshot and 1-, 5-, and 15-minute observed token velocity. `hra account usage-history <profile>` reads the retained 24-hour local ledger in durable source order. Use UTC RFC3339 `--from` and `--through` bounds plus the returned opaque cursor for later pages; a cursor freezes that account and range and expires after five minutes. History rows contain only derived token observations or closed poll-failure codes; raw provider payloads are never returned.

HRA automatically spends one available earned Codex rate-limit reset when a fresh read shows the exact seven-day Codex window at 99 percent used or higher. It records a private idempotency key before dispatch, retries only that key after an uncertain response, and rereads limits after every closed outcome. A successful redemption is latched to that weekly window, so a stale usage snapshot cannot spend another credit. Rate-limit notifications wake a coalesced authoritative read; the staggered 50-to-70-second poll remains the fallback. `hra account usage` reports the most recent local reset attempt with its source weekly-window boundary and suppresses a prior identity's snapshot after an account change. Credit IDs, descriptions, private keys, and account fingerprints never enter that reset status or its cloud projection.

HRA cloud identity is separate from every Codex or Claude Code account. Use the email-code flow below only after a hosted or self-managed Convex deployment has been configured.

## First session

> **Conditional walkthrough.** Current daemon and hosted command-writer rollout remains blocked on capacity. Do not initialize, start, or autostart a current daemon until the hosted operator records protected two-pass zero-debt capacity evidence and its exact .activated readback receipt. Artifact availability and the live sync service do not clear this gate. After activation, complete the update runbook's daemon and target marker-2 proofs before globally enabling hosted writers.

Only after the rollout prerequisite is satisfied, complete initialization and the first provider login before this walkthrough. Account login remains a dedicated one-shot command, and the session-start command returns the new session ID.

### Human terminal

Create an idle session, open the persistent shell, select the account and exact returned session ID, then type a request as an ordinary line. HRA sends that line to the selected session and shows safe live updates. `/exit` leaves the daemon running.

```text
hra session start personal --provider codex
hra
/account personal
/session <session-id>
Review this project and summarize its current state.
```

### Agent caller

Read `data.session.id` from the start response. Before sending, call status and read `data.eventStream.cursor` from its version-2 result. Start watch from that exact cursor so the atomic local snapshot and subsequent event stream are contiguous. Keep watch as a long-running subprocess, consume its two output streams independently, and use the exact ID instead of a mutable title in automation.

```text
hra session start personal --provider codex --json
hra session status <session-id> --json
hra session send <session-id> -- "Review this project and summarize its current state."
hra session watch <session-id> --cursor <status-cursor> --jsonl
hra session interactions <session-id> --pending --json
```

If the event stream reports a blocking interaction, read its exact ID and revision, inspect the live authority through the protected path, and resolve only the interaction kind you received. Keep following while a separate one-shot invocation handles the approval, question, permission grant, or supported MCP form. The protected interaction commands and input documents are defined below.

Devin support has been removed because its supported CLI integration cannot provide verified remaining account quota and reset times. Existing Devin history is read-only and provider-owned credentials are preserved. [Retired-provider compatibility and local login-fence cleanup](https://github.com/hraness/hra/blob/main/docs/providers/devin.md) remain documented; no new Devin login or session can start.

### Claude Code and provider switching

Start directly with Claude Code by selecting its provider and reviewed preset, or move an idle session between providers. A switch seeds a fresh provider-native runtime from the latest retained tail of HRA's provider-neutral conversation record; it does not move a provider-native thread. From the point the v0.6 daemon begins recording a session, that record covers accepted direct, queued, Work and scheduled automation, autorespond, and provider-switch handoff messages with actor provenance. It does not backfill provider history from before a personal-home session was admitted or user turns from before a v0.5 installation was upgraded, and those origin gaps do not set the current retention-gap field. Attachments are represented only by byte-free manifests containing bounded names, media types, sizes, and digests. Retention is capped at 50,000 events, 64 MiB, and seven days; when pruning has occurred, switch seeds and exports state the retention reason and leave the unavailable older count unknown. A switch refuses an active turn, an unsettled provider effect, an unsigned target profile, or a preset that belongs to another provider. If a Claude controller is no longer available, HRA can recover the exact conversation with `--resume` only after prior-process exit or an already-completed exact process release is proven. Ambiguous custody stays fenced in recovery without launching another process.

```text
hra session start personal --provider claude --preset fable-max --json
hra session switch <session-id> --provider claude --preset fable-max
hra session export <session-id> --format json
```

### Scheduled work in the same conversation

Attach a recurring whole-minute interval to an existing session with `hra session task`. Each run returns to that exact HRA conversation. A task cannot independently retarget its account, provider, project, model, or execution environment; later explicit changes to the session apply to future runs. Missed intervals coalesce into one queued turn. Use the returned task ID and revision for later edits or deletion; HRA never creates a replacement provider conversation or writes a provider's private automation registry.

```text
hra session task create <session-id> --name daily-review --every-minutes 1440 -- "Review the release queue."
hra session task list <session-id>
hra session task show <session-id> <task-id>
hra session task edit <session-id> <task-id> --revision <revision> --pause
hra session task edit <session-id> <task-id> --revision <revision> --resume
hra session task delete <session-id> <task-id> --revision <revision>
```

## Presets and permissions

> **Conditional walkthrough.** Current daemon and hosted command-writer rollout remains blocked on capacity. Do not initialize, start, or autostart a current daemon until the hosted operator records protected two-pass zero-debt capacity evidence and its exact .activated readback receipt. Artifact availability and the live sync service do not clear this gate. After activation, complete the update runbook's daemon and target marker-2 proofs before globally enabling hosted writers.

HRA reviews the bound provider's exact runtime profile immediately before each new provider-native session or turn. For Codex, that refresh includes model, reasoning effort, Fast service tier, permission profile, computer-use capability, and accessible apps. For Claude, HRA admits only the pinned Fable profile and reviewed host-tool boundary. An unavailable requirement fails before the provider effect. Every successful start records that exact account generation and effective profile; `hra session show` displays the bound provider's history and recorded public profile. Read the provider-neutral HRA record with `hra session export` or the transcript endpoint. Codex profiles include the requested model, reasoning effort, service tier, permission profile, computer-use capability, and accessible apps; an empty enabled-app list is reported as empty. Claude Code public profiles include the pinned CLI, model, reasoning effort, default permission mode, and stream formats. HRA privately reviews the exact config-home authority for every Claude effect but omits that custody identity and legacy isolation marker from `session show`; managed and adopted personal-home sessions therefore share one non-identifying public shape. Each provider remains authoritative for its native permissions, tools, and hidden runtime state.

- `low`: Codex Luna Max, currently `gpt-5.6-luna` with `max` reasoning.
- `high`: Codex Sol Max, currently `gpt-5.6-sol` with `max` reasoning.
- `ultra`: Codex Sol Ultra, currently `gpt-5.6-sol` with `ultra` reasoning.
- `fable-max`: Claude Code Fable, currently `claude-fable-5-1` with `max` reasoning.
- `fast on|off`: a Codex-only, explicit per-turn Fast or Standard overlay. Claude Code refuses Fast instead of ignoring it. A prior Fast value cannot leak into the next turn.

New HRA-created Codex sessions that use `high` or `ultra`, and explicit selections of either preset, use the Sol mapping above. The `low` and `fable-max` bindings are unchanged. Codex sessions already bound to historical contract 2 keep their exact Astra model and effort until a preset is explicitly selected; unrelated metadata edits, restart recovery, and queued work do not reinterpret an established session.

`hra init` reports the required confirmation without changing local state; `hra init --yes` creates your Documents directory when it is absent, verifies that it is a readable, writable, and traversable canonical directory, and accepts it as the default project. Initialization is a one-shot maintenance command: run it before opening the persistent shell. The shell rejects `/init` because its running daemon already owns local state. Codex turns use Codex's `auto_review` path, the exact advertised `:workspace` permission profile, and the selected project as the runtime workspace root. Codex remains authoritative for the profile's effective sandbox, network policy, computer use, plugins, and protected turn inspection. Claude Code runs in its default interactive permission mode under the selected project and maps supported tool-use requests into HRA interactions; it does not expose Codex's permission-profile, app, plugin, or protected turn-inspection surfaces.

## Desktop account switching

`hra account switch <profile>` is experimental and macOS-only in the first beta. The current compatibility gate accepts only the signed OpenAI ChatGPT application at `/Applications/ChatGPT.app` with reviewed version, build, CDHash, and isolated-profile launch hooks. Unsupported or changed bundles fail before quit.

A switch requires a signed-in target with a verified provider email, takes one machine-global lock, rejects multiple exact app processes, and refuses an unsettled earlier switch. It journals the target generation, gracefully quits the exact process, waits for exit, relaunches once with the target's isolated Codex and desktop-data roots, and binds read-only account verification to that launched PID, executable, CDHash, and environment.

HRA never copies `auth.json`, swaps one token, changes Keychain blindly, rotates accounts to evade a provider limit, or retries an uncertain switch. An uncertain quit, transition, or relaunch becomes `recovery_required` and preserves both profiles. Run `hra account switch-recover` to reconcile only the current attempt. Recovery performs bounded read-only bundle, process, environment, and account observations; it never quits or launches the app. It releases the switch authority only when those observations prove the target account is active or prove that no target instance remains.

## Next

- [Complete command reference](/docs/reference/)
- [Update and recovery runbook](/docs/status/#install-and-update)
