# The Companion — the device-side trusted runtime

> **Status: roadmap (designed, not shipped).** This describes the direction and why it matters, marked honestly.
> Today's interim for reach-me is content-free **Web Push**; the native Companion is the destination, not a live
> feature.

A Witbitz app is a **pure static page** — which is exactly what makes its privacy checkable, but a static page
*can't* do the things that persist: hold a key safely, notify you while you're away, decrypt a peer's message
locally. Today those land on the **link** and in **browser storage** — the source of every bearer-link lifecycle
problem ([identity-lifecycle](https://docs.witbitz.chat/docs/identity-lifecycle.md)). The **Companion** is where
they should live instead: **one native app, installed once, that provides the un-static capabilities on behalf of
every Witbitz app** — and the single device-side thing we certify.

It is the concrete, near-term form of the platform's "trusted runtime": not a server you trust more, but a runtime
**on your own device** that moves trust to your side.

---

## What it does

- **A real key home.** Keys live in the **device keystore**, not `localStorage` and not a URL you can screenshot,
  sync, or paste by accident. The secret stops riding the link — which directly answers the copy / history / sync /
  referrer leakage a bearer link suffers.
- **Local decrypt of peer content.** The Companion holds `mk` and decrypts peers' messages **on-device**, so for a
  couple's own content the platform is content-blind **in use** as well as at rest — a software step toward the
  attested tier.
- **Rotation & recovery, user-side.** The natural place to receive **re-keyed epochs** (rotation without re-sharing
  a link) and to hold **your own** recovery — a recovery code and/or **k-of-n social recovery** (the same Shamir
  split the couple key uses). Recovery is yours, never an operator key.
- **Install-once notifications.** One app reaches you across **every** Space — no install-per-app — using
  content-free, sealed push endpoints.

## Why it's the right shape

Keep each app a **pure, certifiable static page**, and put the one thing that must persist — keys, recovery,
reach — in a **single device-side runtime the user controls and we can certify**, instead of smeared across links
and browser storage. The un-static capabilities become **one thing to audit**, not N per-app implementations.

## The honest boundaries

- **Roadmap, not shipped.** The design lives at `docs/witbitz-companion.md`; the interim (no native app) is
  **content-free Web Push** — sealed endpoints, presence-triggered.
- **It closes the *peer* half only.** The **agent** turn runs on server compute (an LLM), so an agent's turn still
  decrypts server-side until the **attested / on-device inference tier**. The Companion is a step toward that, not a
  substitute for it.
- **It consolidates, not removes, one metadatum.** A **device ↔ room linkage** (stored sealed) plus push-service
  metadata is what lets you be reached while away — the Companion concentrates and certifies that, rather than
  making it vanish.

## Where it sits

| Layer | Today | With the Companion |
|---|---|---|
| Key storage | link fragment + `localStorage` | **device keystore** |
| Rotation | re-issue links | receive re-keyed epoch to the device |
| Recovery | none (lose the link → lose access) | **user-held** (recovery code / k-of-n social) |
| Notifications | per-app / content-free Web Push (interim) | **install-once**, all apps |
| Peer content in use | decrypted in the browser tab | decrypted in the Companion (one audited runtime) |
| Agent turn | server-side (declared program) | still server-side until the attested tier |

See also: [identity-lifecycle](https://docs.witbitz.chat/docs/identity-lifecycle.md) (the questions it answers) and
[the double blind](https://docs.witbitz.chat/docs/the-double-blind.md) (what's blind today vs the attested tier).
