# Availability and release status

What is released, what each provider supports, and which runtime rollout prerequisites still apply to HRA.

## v0.7.1 artifacts are admitted. Daemon rollout remains blocked.

The v0.7.1 CLI passed immutable GitHub and npm artifact admission. For its exact installation instructions, use the [immutable README](https://github.com/hraness/hra/tree/v0.7.1#get-started) to install and run `hra doctor --offline`. The public website, browser app, and open-beta sync service are available; their availability does not authorize starting the current daemon or sending new hosted commands.

The v0.7.1 release adds read-only exact Codex default-profile observation. The display remains unavailable until the intended daemon publishes a matching fresh companion after its rollout gates pass. This does not change Ultra defaults, admit models, choose a route, or authorize a command.

> **Current runtime hold.** 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 operator must complete protected capacity activation, then prove the current daemon and every intended target before enabling writers. Installing a release, signing in, or loading a fresh browser tab does not substitute for those proofs. [Release record](https://github.com/hraness/hra/blob/main/docs/beta-release.md) · [Hosted rollout procedure](https://github.com/hraness/hra/blob/main/docs/hosted-sync.md#converge-command-lifecycle-capacity-before-writer-rollout)

## Provider support

- Codex: macOS and Linux, through pinned Codex 0.153.2. Managed device-code sign-in, account usage and reset observations, and opt-in browser linking are implemented.
- Claude Code: Linux for managed sign-in and execution, using an installed executable that reports the exact 2.1.260 compatibility pin. HRA reports signed-in status only; quota, usage history, Fast mode, and browser linking are unavailable.
- macOS Claude: new managed effects remain disabled pending authenticated isolated-Keychain and detached-daemon acceptance. A discovered executable is not acceptance evidence.
- Devin: retired. Historical records remain read-only; HRA does not start new Devin logins or sessions.

Providers own their accounts, billing, tools, and native execution. HRA's automated tests do not imply that every live provider and device flow has been qualified. [Claude compatibility details](https://github.com/hraness/hra/blob/main/docs/providers/claude.md) record the remaining live checks.

## Before upgrading an existing machine

Use the ordered update runbook below. Preserve recovery evidence, obtain a successful daemon-stop authority release, and back up the complete private state as one unit before the upgrade boundary. Never launch an older daemon against state after a newer daemon has begun migrating it.

An interrupted installer belongs to its exact originating release. Do not remove the durable intent or retry with a different release. The runbook names the safe inspection and recovery path; local installation recovery does not authorize changing a release workflow.

## Install and update

HRA requires Bun 1.3.14 plus curl with HTTPS and TLS 1.2 support. The CLI and local daemon support macOS and Linux. Codex effects run on both platforms; Claude Code effects run on Linux only. HRA refuses new Claude Code effects on macOS pending authenticated isolated-Keychain and detached-read acceptance. Supported ChatGPT desktop account switching is macOS-only. Native protected-input control loads only when a terminal prompt needs it and supports the standard macOS, glibc, and x64 or arm64 musl library names. Install the admitted release's reviewed immutable tag, then verify the binary before initialization:

```text
bun --version
test "$(unset BUN_OPTIONS NODE_OPTIONS LD_AUDIT LD_LIBRARY_PATH LD_ORIGIN_PATH LD_PRELOAD DYLD_FALLBACK_FRAMEWORK_PATH DYLD_FALLBACK_LIBRARY_PATH DYLD_FRAMEWORK_PATH DYLD_IMAGE_SUFFIX DYLD_INSERT_LIBRARIES DYLD_LIBRARY_PATH DYLD_ROOT_PATH DYLD_VERSIONED_FRAMEWORK_PATH DYLD_VERSIONED_LIBRARY_PATH && curl -fsSL --connect-timeout 10 --max-time 60 --max-filesize 524288 --retry 3 --retry-delay 1 --retry-max-time 60 --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/hraness/hra/v0.7.1/src/install-preflight-runtime.ts | command bun --no-env-file --config=/dev/null -e 'const n=["BUN_OPTIONS","NODE_OPTIONS","LD_AUDIT","LD_LIBRARY_PATH","LD_ORIGIN_PATH","LD_PRELOAD","DYLD_FALLBACK_FRAMEWORK_PATH","DYLD_FALLBACK_LIBRARY_PATH","DYLD_FRAMEWORK_PATH","DYLD_IMAGE_SUFFIX","DYLD_INSERT_LIBRARIES","DYLD_LIBRARY_PATH","DYLD_ROOT_PATH","DYLD_VERSIONED_FRAMEWORK_PATH","DYLD_VERSIONED_LIBRARY_PATH"],x=process.execArgv;const c=x.filter(v=>v==="-c"||v.startsWith("--config"));if(n.some(k=>process.env[k]!==undefined)||x.filter(v=>v==="--no-env-file").length!==1||c.length!==1||c[0]!=="--config=/dev/null"||x.some(v=>v.startsWith("-r")||v==="--preload"||v.startsWith("--preload=")||v==="--require"||v.startsWith("--require=")||v==="--import"||v.startsWith("--import=")||v==="--env-file"||v.startsWith("--env-file=")))throw new Error("The tagged HRA preflight requires a neutral Bun stage zero.");const[a,h]=process.argv.slice(1);const r=Bun.stdin.stream().getReader(),q=[];let z=0;try{for(;;){const o=await r.read();if(o.done)break;z+=o.value.byteLength;if(z>524288)throw new Error("The tagged HRA preflight exceeds its byte limit.");q.push(o.value)}}finally{r.releaseLock()}const b=new Uint8Array(z);let p=0;for(const v of q){b.set(v,p);p+=v.byteLength}const d=new Bun.CryptoHasher("sha256").update(b).digest("hex");if(d!==h)throw new Error("The tagged HRA preflight digest is invalid.");const j=new Bun.Transpiler({loader:"ts",target:"bun"}).transformSync(b);const u=URL.createObjectURL(new Blob([j],{type:"text/javascript"}));try{const m=await import(u);await m.installHraRelease(a);process.stdout.write(`${m.HRA_INSTALL_SUCCESS}\n`);}finally{URL.revokeObjectURL(u)}' -- https://github.com/hraness/hra/releases/download/v0.7.1/hraness-hra-0.7.1.tgz ed407bd0f0cb04fbca6c4f8ff90aab6643f1c43c16073de1193585dd54fb24f6)" = hra-install-safe
hra --version
hra doctor --offline
```

The single install command removes ambient Bun, Node, and native-library injection variables before either download or Bun startup, disables Bun dotenv loading, and selects /dev/null as the only Bun configuration. Curl and the loader independently cap the streamed preflight at 512 KiB, and the loader refuses an overrun before transpilation or installation. It then verifies and executes the exact v0.7.1 preflight from HRA's protected source tag and passes it the exact release archive URL. The preflight requires GitHub repository ID 1343008607, a published immutable v0.7.1 release, and one uploaded archive whose byte length and SHA-256 match GitHub's immutable release metadata. It creates a fresh random private staging root, downloads the archive into a private file there, and gives Bun only a verified in-memory snapshot of those exact bytes. The reviewed normalizer verifies the private archive again, derives its bounded package-file manifest, and compares every extracted HRA package path and SHA-256 while measuring the completion receipt. Local archives and official archives use separate full-digest version namespaces, so a local package cannot populate or replace the official cache entry. HRA then verifies the tagged preflight and normalizer, exact package identity, zero-lifecycle manifest, CLI SHA-256, and complete staged tree under protected descriptor and ACL custody. Bun 1.3.14 resolves the package's exact dependency versions from the configured package registry trust boundary with lifecycle scripts disabled; the release archive does not claim to contain that dependency closure. The detached staging worker and its Bun package-install child repeat the runtime neutralization while retaining the configured registry, proxy, and certificate trust inputs needed for dependency resolution. The prior verified command remains active throughout staging. Publication atomically replaces only the $BUN_INSTALL/bin/hra symlink after every check succeeds and fsyncs its directory. If installation is interrupted, the next invocation of that exact release's installer recovers or removes only the proven private stage; another release's installer refuses the durable intent. The invoking shell, PATH-selected pinned Bun binary, configured package registry and transport trust, operating system, and same-UID account remain trust boundaries. Existing trustedDependencies remain unchanged.

### Update runbook

Use this sequence to replace an installed release. Resolve every uncertain local mutation that depends on old alias or prepared authority before starting the current daemon, and preserve remote-command evidence for the fail-closed reconciliation below. Replace the tagged preflight URL, release archive URL, expected preflight digest, and expected version together with one exact reviewed immutable tag. Never install a moving branch on a release machine, and never run an older daemon against this state root after the current daemon has started.

1. Settle any durable installer intent left by an interrupted installation. An installer refuses `$BUN_INSTALL/install/hra/install-intent.json` when the intent is invalid or belongs to another release. Do not edit or delete that file or its staging or version directories. Rerun the exact immutable install command from the originating release's trusted README or release notes and require the exact `hra-install-safe` success output. If that installer refuses the intent, stop installation and use bounded read-only diagnosis while preserving the intent and its directories; after exact recovery succeeds, restart this runbook with the current release. Establish the originating tag independently from trusted release evidence; never execute a URL or command copied only from the intent. An uncertain tag blocks execution, not diagnosis. Ask the owner only when the evidence cannot resolve a required decision or authority is missing. This recovers only local installer state. It is not authorization to retry, rerun, or mutate that release's GitHub Actions workflow, tag, GitHub Release, or npm publication.

2. Resolve keyed local mutations under the installed release. For a Codex High or Ultra `session start`, or a source-sensitive provider switch that explicitly or implicitly selects either alias, replay the exact idempotency key using the originating release's own syntax and source evidence. Resolve an affected Work mutation by replaying its exact request document. A v42 attachment-bearing send or steer should likewise be replayed under v42 before updating whenever that release remains usable; retain the exact original message, attachment path and basename, and explicit key if migration has already occurred and the narrow v43 bridge below is required. Continue only when exact replay under the originating release, or that release's documented kind-specific recovery, reaches a terminal settlement. Otherwise the update remains blocked. If that release has no explicit source-contract flag, use only its exact syntax; do not invent an unsupported option or infer an old alias meaning from the new release.

3. Resolve any uncertain `session preset` under the installed release. This command has no idempotency key, so repeat it if necessary and inspect the session before updating.

4. Block the update on any remaining prepared or indeterminate local mutation. HRA exposes no general command to cancel a prepared session start or provider switch, and `session abandon` applies only to an existing recovery-required session. Retain the originating release and state root until exact replay or its documented recovery reaches a terminal settlement. Do not generate a fresh key or edit SQLite as a workaround.

5. Reconcile every uncertain CLI session-command enqueue by repeating the exact remote request with its exact idempotency key. Let HRA's durable local outbox reconcile the response, retain every returned session-command ID, and inspect each one with `hra remote command <uuidv7>`. For a browser or device command, retain the current tab's returned command handle and public ID, then inspect it through the app or the corresponding hosted query. The app does not expose its internal idempotency key and must not synthesize a resend. Never edit or delete the local command journal, local outbox, tab state, or hosted row to force progress.

6. Stop the daemon and prove that it released authority:

   ```text
   hra daemon stop --json
   hra daemon status --json
   ```

   Require the stop command itself to exit zero; its recovery path is the authority-release proof. Treat a status response containing `data.running: false` only as a secondary no-listener confirmation. Status alone does not prove authority release. Stop on any stop or recovery error.

7. Install the admitted v0.7.1 exact release, then verify the installed version and offline health:

   ```text
   test "$(unset BUN_OPTIONS NODE_OPTIONS LD_AUDIT LD_LIBRARY_PATH LD_ORIGIN_PATH LD_PRELOAD DYLD_FALLBACK_FRAMEWORK_PATH DYLD_FALLBACK_LIBRARY_PATH DYLD_FRAMEWORK_PATH DYLD_IMAGE_SUFFIX DYLD_INSERT_LIBRARIES DYLD_LIBRARY_PATH DYLD_ROOT_PATH DYLD_VERSIONED_FRAMEWORK_PATH DYLD_VERSIONED_LIBRARY_PATH && curl -fsSL --connect-timeout 10 --max-time 60 --max-filesize 524288 --retry 3 --retry-delay 1 --retry-max-time 60 --proto '=https' --tlsv1.2 https://raw.githubusercontent.com/hraness/hra/v0.7.1/src/install-preflight-runtime.ts | command bun --no-env-file --config=/dev/null -e 'const n=["BUN_OPTIONS","NODE_OPTIONS","LD_AUDIT","LD_LIBRARY_PATH","LD_ORIGIN_PATH","LD_PRELOAD","DYLD_FALLBACK_FRAMEWORK_PATH","DYLD_FALLBACK_LIBRARY_PATH","DYLD_FRAMEWORK_PATH","DYLD_IMAGE_SUFFIX","DYLD_INSERT_LIBRARIES","DYLD_LIBRARY_PATH","DYLD_ROOT_PATH","DYLD_VERSIONED_FRAMEWORK_PATH","DYLD_VERSIONED_LIBRARY_PATH"],x=process.execArgv;const c=x.filter(v=>v==="-c"||v.startsWith("--config"));if(n.some(k=>process.env[k]!==undefined)||x.filter(v=>v==="--no-env-file").length!==1||c.length!==1||c[0]!=="--config=/dev/null"||x.some(v=>v.startsWith("-r")||v==="--preload"||v.startsWith("--preload=")||v==="--require"||v.startsWith("--require=")||v==="--import"||v.startsWith("--import=")||v==="--env-file"||v.startsWith("--env-file=")))throw new Error("The tagged HRA preflight requires a neutral Bun stage zero.");const[a,h]=process.argv.slice(1);const r=Bun.stdin.stream().getReader(),q=[];let z=0;try{for(;;){const o=await r.read();if(o.done)break;z+=o.value.byteLength;if(z>524288)throw new Error("The tagged HRA preflight exceeds its byte limit.");q.push(o.value)}}finally{r.releaseLock()}const b=new Uint8Array(z);let p=0;for(const v of q){b.set(v,p);p+=v.byteLength}const d=new Bun.CryptoHasher("sha256").update(b).digest("hex");if(d!==h)throw new Error("The tagged HRA preflight digest is invalid.");const j=new Bun.Transpiler({loader:"ts",target:"bun"}).transformSync(b);const u=URL.createObjectURL(new Blob([j],{type:"text/javascript"}));try{const m=await import(u);await m.installHraRelease(a);process.stdout.write(`${m.HRA_INSTALL_SUCCESS}\n`);}finally{URL.revokeObjectURL(u)}' -- https://github.com/hraness/hra/releases/download/v0.7.1/hraness-hra-0.7.1.tgz ed407bd0f0cb04fbca6c4f8ff90aab6643f1c43c16073de1193585dd54fb24f6)" = hra-install-safe
   hra --version
   hra doctor --offline
   ```

   Require the exact expected version. Before the first current-daemon start, doctor must either succeed or report only the exact pending state-schema migration that names the old and current schema versions. Any other diagnostic stops the update.

8. Before starting any current daemon, require the hosted operator to deploy the additive candidate from this release's exact reviewed source, then run the source- and runtime-bound command-capacity status and repair workflow in `docs/hosted-sync.md`. Accept only its protected two-pass zero-debt capacity evidence together with the exact .activated receipt produced after hosted activation and readback for that candidate and numeric target. The capacity evidence alone is not readiness. The hosted activation tuple opens the exact-runtime gate; the later local .activated publication proves the readback and is required before declaring writers ready, but does not itself open that gate. A hard-full legacy owner, partial capacity set, unreserved command debt, unsafe cleanup shape, interrupted intent, candidate swap, concurrent debt, missing activation, or failed readback blocks the update. The Vercel app may auto-deploy earlier, but that UI is not command readiness or effect authority and its commands should receive expected pre-insertion refusals while the runtime gate is closed.

9. Start the current daemon. This is the no-downgrade boundary: after this command begins, never launch an older daemon against the same state root. Prove post-migration health before syncing, then inspect every retained CLI session-command ID:

   ```text
   hra daemon start
   hra doctor --offline
   hra sync now --json
   hra sync status
   hra remote command <uuidv7>
   ```

   Require the post-start doctor command to succeed before sync. If migration retained a v42 send or steer that stopped after preparation but before its attachment manifest or provider effect, replay it now with the same command kind, session, message, original attachment path and basename, and explicit idempotency key. The current CLI admits an earlier-policy-only basename only on this keyed local replay, and the daemon requires the original durable request digest before resolving the blob or contacting a provider. Any missing or changed field fails without a new mutation; fresh sends, steers, queued messages, and hosted payloads remain on the current name rule. For every intended target, require the sync-now response to contain `data.online: true` and `data.errorCount: 0`, and `data.commandRequestVersion: 2`; a pending device identity or failed registry publication leaves the last field null, and the command exits zero even when its bounded diagnostics report a registry-publication failure. There is no per-target writer switch. Finish all intended target proofs before deploying marker-emitting writer clients globally, or accept and monitor the expected pre-insertion refusals on ungated or mismatched targets. Old clients and targets whose markers are both absent remain compatible. Sync status reports projection recovery, not the command outbox. Use retained CLI session-command IDs for remote-command inspection; inspect browser and device commands through the app or corresponding hosted query.

10. Classify legacy remote commitments from both the local journal and hosted row before retrying. The current daemon never executes a legacy request commitment. An already-hosted terminal row takes precedence: it confirms the hosted result and permits local retirement without replaying a local outcome. Otherwise, if the hosted row remains nonterminal and either side records `effect_started`, close it result-less as `ambiguous`. A legacy local terminal outcome over any hosted nonterminal row is unauthenticated evidence: discard that outcome and close result-less as `LOCAL_EFFECT_RECOVERY_REQUIRED` ambiguous. A fresh or local-prepared legacy request over hosted `pending` or `prepared` row closes as `failed` with `LEGACY_REQUEST_COMMITMENT_BEFORE_EFFECT`. Retry only a failed-before-effect request, only after its initiating client is also current, and use a fresh idempotency key. Retain the new command ID. Never automatically retry an ambiguous command. Each daemon privately publishes its command-request version before processing commands. A fresh request is inserted only when its marker exactly matches the target's last stored registry marker and the hosted runtime's capacity activation tuple exactly matches its compiled release attestation. A marker or activation mismatch is rejected before the command, quota charge, or security event is written. A stale matching target marker can exist during an upgrade or downgrade window, but a candidate redeploy invalidates the hosted activation, and the executor checks stop a mismatched binary before prepare or provider effect while recovery paths classify retained rows conservatively. Exact same-key replay remains available across a later target or runtime change, but changing versions under one key conflicts. A registry-publication failure skips both command queues for that cycle, and every marker-2 command also requires current target and hosted activation markers before a new prepare or effect start. The hosted tuple, not the local receipt publication, opens the runtime gate. Accept the protected capacity evidence and its .activated readback receipt from the prerequisite above before declaring writers ready. Require one `hra sync now --json` result with `data.online: true` and `data.errorCount: 0`, and `data.commandRequestVersion: 2`, before treating marker-emitting writers as globally available. The Vercel app can auto-deploy from main earlier; that UI is not readiness, and its commands should receive expected pre-insertion refusals until capacity activation and target-marker proof exist. No all-daemons pause or account-wide legacy drain is required.

> **v0.5 upgrade quarantine.** The first daemon start after a v0.5-to-v0.6 upgrade migrates local state but never infers provider-account authority that v0.5 did not record immutably. Every affected nonterminal session enters recovery_required: pending or prepared effects are cancelled, begun effects remain uncertain, scheduled work pauses, pending interactions expire while begun responses become resolution-unknown, and associated Work execution is retired or fenced. Provider threads and local records are not deleted. This is not a generic automatic-recovery state. Inspect the session first; use `hra session abandon <session>` only when you accept terminalizing HRA's local session with provider state still unknown.

### Optional full local-data removal

Full local-data removal is a separate destructive operation. While HRA remains installed, complete `hra auth delete --acknowledge-erasure` if `hra auth status` says you are signed in, then wait for `hra auth status` to report terminal deletion. Run `hra account list`, then run `hra account logout <profile>` for every Codex profile. HRA does not sign Claude Code out; use Claude Code's own authentication flow inside every isolated `CLAUDE_CONFIG_DIR` whose credential should be removed. Stop the daemon and require `hra daemon stop --json` itself to exit zero as the authority-release proof. A successful `hra daemon status --json` result whose `data.running` is `false` is only an optional no-listener confirmation before touching local data.

```text
hra auth delete --acknowledge-erasure
hra auth status
hra account list
hra account logout <profile>
hra daemon stop --json
hra daemon status --json
```

> **Permanent local-data loss.** HRA deliberately has no recursive local-delete command. The exact state directory is `$HOME/Library/Application Support/HRA Control Plane v1` on macOS and `$HOME/.local/state/hra-control-plane-v1` on Linux. After every prerequisite above, a human who explicitly accepts permanent loss of all local provider profiles, Codex credential stores, Claude Code configuration directories, sessions, ledgers, encryption keys, device credentials, and recovery evidence may move only the exact platform directory to Trash. Claude Code may also own credentials outside that directory, including provider-managed system credential storage; sign out through Claude Code before deletion. Do not move or remove the state directory's parent. Inspect the trashed directory before emptying Trash.

An agent must resolve the canonical exact state-directory path, present that path and the permanent-loss consequences to the user, and obtain explicit destructive approval before moving or removing it. An install, update, or daemon-stop request does not authorize local-data removal.

## Authority boundaries

Codex app-server and Claude Code remain authoritative for their provider-native authentication, sessions, execution, tools, approvals, models, and hidden runtime state; Codex additionally owns its plugin, usage, and native transcript surfaces. HRA owns isolated profiles, the durable provider-neutral conversation record and commands, process generations, local projections, optional encrypted sync, and recovery records. The frozen work contract assigns local coordination records to HRA rather than either provider runtime.

Cloud service availability is not required for local provider authentication, local execution, local work coordination, local recovery, or reading local sessions. Provider accounts remain independent subscriptions. HRA does not pool quota or replay a limited turn under another account or provider. SQLite remains the local work execution authority; Turso is deferred and non-authoritative.

## Next

- [Install and check HRA](/docs/start/)
- [Release notes](https://github.com/hraness/hra/blob/main/docs/beta-release-notes.md)
- [Security support policy](https://github.com/hraness/hra/blob/main/SECURITY.md)
