# Use the web app

Pair a browser, see which sessions need you, and direct work on your own machines from the session grid.

## Pair your browser with an approved machine

> **Before you start a daemon.** The v0.7.1 CLI artifact is admitted for installation. Initialization, daemon startup, and hosted command writers remain blocked on capacity. Complete the [rollout and update prerequisites](/docs/status/#install-and-update) before the steps below. Installing the CLI or opening the app does not clear that gate.

First-time machine setup belongs in [Set up HRA](/docs/start/). On a configured, eligible machine, complete HRA's [protected email-code sign-in](/docs/web/#cloud-sign-in-and-device-pairing) with `hra auth login --input-stdin`. Each invocation reads one protected JSON document; the linked instructions show how to request and verify a code. Complete machine sign-in before enrolling the browser. Your provider sign-in is separate.

Open [app.hra.sh](https://app.hra.sh/) and sign in with your HRA email and one-time code. Use the same identity as your execution machine. A browser cannot be the first device on an account or approve another device.

- Choose Enroll this browser. HRA generates this browser's device keys and shows a fingerprint.
- On an already approved machine, list devices and compare the browser fingerprint before approving its exact device ID.
- Return to the waiting browser and choose Check again. Once approved and unlocked, it can decrypt your synchronized sessions.

```text
hra device list
hra device approve <pending-device-id-or-prefix> --fingerprint <value>
```

Email access alone cannot recover encrypted history. Keep an approved device with the account key. The browser drops its unwrapped account key when locked; `Ctrl+L` also locks the app.

## See what needs you

The grid shows your conversations as cards with their latest activity and a named state: Working, Needs an answer, Needs approval, or Done. Sessions needing attention come first. Open a card to read the conversation; drag cards to keep your preferred arrangement.

With no session selected, the composer starts a new conversation on the account and project you choose. With a session selected, it sends to that conversation. Only registered targets with the necessary local permissions appear. Claude targets require a Linux execution machine.

The execution machine must be running and eligible before it can apply a command. An offline command can remain pending until its deadline; opening this page does not move the session to your browser. [Current rollout status](/docs/status/) determines whether new commands are available.

## Read, answer, and send the next instruction

Inside a session, follow the transcript and send your next message. HRA lets the execution machine decide whether to begin a turn or steer the active one. Stop is available while a turn is running. The session menu offers model presets, Codex Fast mode, approval settings, and eligible provider changes.

Attach supported images or text files by picking, pasting, or dropping them into an existing conversation. A new session starts with text only. Other devices see attachment names and metadata, not a copy of the original file or image.

A supported, non-secret multiple-choice question can be answered here. Command, file-change, and permission requests can be declined remotely; accepting them, granting permission, typing a free-text or Other answer, and completing MCP forms stay on the execution machine. Follow the interaction's local instruction when the browser cannot act.

## Find machines, accounts, and history in Settings

- Machines show published defaults and projects. Changes travel as commands to that machine, so wait for the confirmed result.
- Accounts show provider sign-in status. Codex can offer Link here after the machine enables `hra remote allow account-linking`. Claude sign-in stays in a foreground terminal on Linux.
- Memory and peer activity show read-only summaries, coverage, and recent activity. The browser does not edit memory pages.
- Archived sessions remain readable and can be restored to the grid. Scheduled tasks are read-only here; create or edit them with the CLI.
- Devices show enrollment state. Approve or revoke a device from an active machine, not from this browser.

## Cloud sign-in and device pairing

> **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.

The hosted endpoint is live as an open beta. An unset `HRA_CONVEX_URL` selects HRA's hosted deployment. Set it to an explicit empty value before the first daemon starts to disable cloud transport. A nonempty HTTPS value selects a self-managed Convex deployment. The first valid selection permanently binds that local state root; a later mismatch fails closed instead of moving credentials or recovery state. After deliberately disabling a bound state root, `hra sync status` and `hra doctor` report its exact restart prerequisite: unset `HRA_CONVEX_URL` for the hosted deployment, or restore the bound URL for a self-managed deployment. HRA accepts cloud credentials only as protected JSON on standard input or a nonterminal file descriptor. It rejects email addresses, identity invites, and verification codes on the command line:

```text
hra auth login --input-stdin
hra auth login --input-fd <fd>
hra device pair
hra device key-loss --acknowledge-no-key-holders
hra sync status
```

Each login reads exactly one JSON document. Request a code for an existing identity with `{"email":"you@example.com"}`, create a new identity with `{"email":"you@example.com","invite":"<identity-invite>"}`, or verify a requested code with `{"email":"you@example.com","code":"12345678"}`. No other keys or combinations are accepted. A TTY prompt hides the document; agents should pass a private descriptor with `--input-fd <fd>`. The document is never an argument.

The CLI stores HRA's revocable device credential, workspace encryption key, and local signing authority as immutable generations below its private state root. Custody directories are current-user-owned mode-0700 directories, values are single-link mode-0600 files, and reads use bounded no-follow descriptors. The detached Bun daemon never opens a Keychain prompt. HRA forces both pinned Codex credential stores to file mode and verifies their effective settings. Managed Codex accounts keep credentials in each profile's isolated `CODEX_HOME`. Claude Code receives that profile's isolated `CLAUDE_CONFIG_DIR`; HRA treats the whole directory as Claude's authentication boundary and never reads, copies, or forwards its credentials. Explicitly adopted Codex and Claude Code personal sessions use credentials already owned by the user's personal provider home without copying or parsing them. Provider-managed credential storage remains owned by the provider runtime.

After successful email verification, the daemon automatically registers the current installation before it reads cloud data. The first registered device becomes active and creates the client-side encryption key. A later verified installation is registered as pending and may report presence, but it has no synchronized data, execution, or key authority.

On an already active machine, list devices and approve the pending device by its exact ID or unique prefix. The listing shows each device's class, daemon or browser, and the fingerprint of its two public keys. Approval requires that exact fingerprint, so the machine you approve is the one whose fingerprint you read:

```text
hra device list
hra device approve <pending-device-id-or-prefix> --fingerprint <value> [--idempotency-key <current-uuidv7>]
```

After approval, run `hra device pair` on the new machine to retrieve and unwrap its encryption-key envelope. Use `hra device revoke <device-id-or-prefix>` from a different active machine to revoke a device.

`hra auth status` and `hra sync status` expose the account key as a closed status. `ready` includes the usable key version. `pairing_required` says recovery requires an existing account-key holder and that no remaining holder makes the encrypted content unrecoverable.

Only after this authenticated, registered, active installation reports `pairing_required` and the operator has confirmed that no account-key holder remains, run `hra device key-loss --acknowledge-no-key-holders`. The command records that explicit observation in the current HRA cloud identity's isolated local custody, but only when the current auth token generation, identity, auth epoch, registered device, and pairing observation agree exactly. It performs no network, provider, or cloud mutation and does not mint, replace, or delete a key or ciphertext. Signed-out, unregistered, stale-identity, missing-observation, and already-ready states fail with a bounded next command. Pairing the real account key later supersedes the observation.

> **Unrecoverable encrypted cloud content.** After that acknowledgement, account-key status is unrecoverable on this installation. Local provider profiles, sessions, credentials, and execution are unaffected, but existing encrypted cloud content cannot be decrypted without the real account key. Search again for an existing holder and run hra device pair if one is rediscovered; the real key restores ready status and supersedes the acknowledgement. Only after that renewed holder search is exhausted may the operator explicitly choose erasing and reinitializing the HRA cloud account as a fallback. Reinitialization creates a new account boundary; it does not regenerate the lost account key or recover old ciphertext.

Approve and revoke create one current UUIDv7 before daemon transport. If the response is lost after dispatch, HRA prints the exact same-key replay command. Reusing that command recovers the original operation; changing the device or operation under the same key is rejected.

Device credentials are bearer credentials, not hardware-bound proofs. Connection and generation fencing blocks a copied credential from creating a second concurrent connection or surviving revocation, but an uncontested, unrevoked copy can impersonate that device until it is detected and revoked.

Cloud-account erasure is an explicit and irreversible fallback, not the default response to a key-loss acknowledgement. After a renewed holder search is exhausted, run `hra auth delete --acknowledge-erasure` to disable every cloud effect before bounded server-side removal begins. `hra auth status` recovers capability-only progress after authentication records disappear. Erasure does not delete local provider profiles, local sessions, or local encryption custody.

## Sessions across machines

The machine that created a provider session remains its only executor in v1. It must be online with its HRA daemon running and must hold the current execution lease before a remote command can affect Codex or Claude Code. Other paired machines never execute that provider session through one of their own local provider profiles.

Paired machines can read the encrypted projection and submit bounded send, queue, steer, stop, preset, provider-switch, and Codex Fast commands. The origin daemon claims each command by lease generation and idempotency key. Commands remain pending within their deadline while the origin machine is offline; another machine cannot take over or become a second provider writer.

`hra remote show` includes interaction events with a public interaction ID, kind, state, revision, blocking status, bounded safe summary, and a nested version 2 remote policy. That policy is the only remote action authority. Provider request IDs, exact commands, permission values, affected paths, MCP fields, protected answers, and response digests remain local. Another device may decline a pending command, permission, or file-change request with `hra remote resolve <cloud-session> --interaction <id> --revision <n> --decision decline`. The web app may answer only a complete non-secret closed-choice user question set whose provider adapter proves exact response translation. Every command, permission, or file-change acceptance or grant, cancel, session scope, free-text or Other response, and every MCP answer stays on the execution machine. A missing policy, nested policy version 1, or unknown policy version exposes no control. The execution daemon rechecks the session, revision, pending state, deadline, requesting device, and exact action membership before using the ordinary local resolution path. `hra remote send --or-steer` lets the execution device decide whether a message steers the active turn or starts a new one, because a remote view of turn state is always slightly stale.

```text
hra remote list
hra remote show <cloud-session>
hra remote command <uuidv7>
hra remote send <cloud-session> <message>
hra remote queue|steer <cloud-session> <message>
hra remote stop <cloud-session>
hra remote preset <cloud-session> <low|high|ultra|fable-max>
hra remote provider <cloud-session> <codex|claude> [--preset <low|high|ultra|fable-max>]
hra remote fast <cloud-session> <on|off>
hra remote allow|deny <device-commands|account-linking>
hra remote policy
```

A cloud-session selector accepts an exact public ID, a unique public-ID prefix, or an exact synced name. HRA resolves that selector to the session's exact execution device before enqueueing. Remote mutations accept `--idempotency-key <current-uuidv7>` for explicit lost-response recovery; otherwise the CLI creates one and durably recovers an unsettled encrypted outbox entry before accepting a different command. Every enqueue returns its command ID. Use `hra remote command <uuidv7>` to read its bounded current or terminal state and result code, including a failed or ambiguous outcome.

Transcript upload is bound to a durable local stream ledger and the exact remote head and tail. Missing or mismatched evidence pauses upload for only that session. Remote reads, commands, and usage continue, while `hra sync status` keeps the recovery condition visible. HRA never resets, aliases, overwrites, or destructively reseeds encrypted history.

```text
hra sync projection recover <local-session> --acknowledge-gap [--idempotency-key <uuidv7>] [--json]
```

Projection recovery is an explicit append-only operation. Running it without `--acknowledge-gap` performs no daemon call and returns `INTERACTION_REQUIRED` with the exact safe next command. JSON mode never prompts. The acknowledged operation preserves all older encrypted cloud history and changes no provider or app state. It opens the next compact stream epoch at sequence `H+1`, where `H` is the exact remote compact head, and baselines only completed turns currently visible in the bounded local projection. Any possibly unsynced interval remains visible to remote readers as a recovery gap.

The CLI creates a current UUIDv7 before daemon transport. Success reports the phase, local session, old and new epochs, boundary head, persistent gap, and an exact same-key replay command. A prepared recovery inside the seven-day server window renews its execution lease and keeps the same exact key. Changed-key retry remains closed while that recovery is unsettled. After the window, exact-key replay first reconciles an already committed effect from immutable lineage. If no effect began, it discards local staging, settles the old attempt as rejected, and clears its authority. Run `hra sync status --json`, then start a fresh recovery without `--idempotency-key` if recovery is still required.

Session names and notes sync as encrypted metadata, but v1 does not execute remote rename or note commands. Project directories are local-only and are neither synced nor remotely changed.

## Next

- [Session and account operations](/docs/sessions/)
- [Privacy and encryption](/privacy/)
