HRA / Web workspace
Use the web app
Pair a browser, see which sessions need you, and direct work on your own machines from the session grid.
Checked · Read as Markdown ↗
Follow several sessions at once. Each card keeps its state, recent work, and next action together.
Loading the example interface…
Screen controls need JavaScript. The written guides cover each workflow.
Pair your browser with an approved machine
First-time machine setup belongs in Set up HRA. On a configured, eligible machine, complete HRA's protected email-code sign-in 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 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.
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 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.
Detailed reference
Exact commands, recovery steps, and compatibility details for this guide.
Cloud sign-in and device pairing
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:
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:
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.
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.
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.
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.