# Mailbox — one page

**Reviewed by:** GitHub Copilot Agent

**What it is:** rows in D1 table `mailbox`. The live worker exposes a **send / read / acknowledge** mailbox, not a lease-based claim queue.

## Simple model

- When this computer is up, the local vault syncs mailbox state down from the worker.
- When this computer is down, the worker keeps the mailbox rows in D1.
- When the vault resumes, the daemon or local sync script catches the vault back up from the worker.
- Reads can resume incrementally with `after_id`; the worker returns `next_after_id` / `last_id` so local mirrors and simple pollers can keep a cursor.
- A person's **NAME** is their live seat key.
- The master write key exists for operator/version updates, not as a second mailbox identity layer.

## Live lanes

| Lane | Routes | Auth |
|---|---|---|
| Public discovery | `GET /mail/schema`, `GET /tool/guide` | None |
| Person key | `mail.send`, `mail.read`, `mail.ack` | `X-UOS-Key`, usually sourced locally from `ASTRONOMICON_KEY` or `u_os_dev/.astronomicon_key` |
| Master operator key | same keyed mail routes plus mirror/version surfaces | `WRITE_TOKEN` / `GET_WRITE_KEY` |
| Bearer mailbox | `POST /mail/inbox`, `GET /mail/outbox`, `POST /mail/ack` | `MAILBOX_WRITE_TOKEN` / `MAILBOX_READ_TOKEN` |

The old queue verbs `mail.next`, `mail.claim`, `mail.release`, `mail.done`, and `mail.fail` are not live on the current worker.

## Local resume

For the simple "worker holds mail while local is asleep, then local catches up" posture:

```bash
python scripts/vault_daemon.py --interval 30
```

If `ASTRONOMICON_KEY`, `UOS_READ_KEY`, or `08_Project_Astronomicon/u_os_dev/.astronomicon_key` is present, the vault daemon now resumes mailbox sync automatically.

The local mirror stores the latest mailbox cursor in `local_mirror/sync_status.json`, so restart behavior is incremental instead of repeated top-of-inbox snapshots.

## Minimal patterns

| Goal | How |
|---|---|
| Notify a named recipient | `mail.send` with `to`, `from`, `topic`, and `sensitivity` |
| Review inbox | `mail.read?limit=N&to=<id>&status=<status>&after_id=<last_seen_id>`; omit `after_id` for a latest snapshot |
| Mark a message handled | `mail.ack/<id>?ack_by=<id>&status=acked` |
| Notify Jules watcher | Send to `jules-watcher` (or `JULES_DAEMON_TO` if configured) |

If you need lease / claim semantics, add them in a separate bridge layer or reintroduce them in the worker first; do not assume they exist because older docs or notebooks mention them.

## Notes

- `JULES_KEY` can send mailbox alerts and read what its key is allowed to read, but it does not expose a dedicated watcher queue API.
- `GET /control` uses separate write/read token fields because the bearer mailbox plumbing is intentionally split behind the simpler NAME-key surface.
- Tokens stay in Cloudflare secrets or local MCP env vars, never in chat logs or committed files.

## References

- [worker/README.md](worker/README.md)
- [worker/IMMUNE_SYSTEM.md](worker/IMMUNE_SYSTEM.md)
- [THRONE_NAME_MODEL.md](THRONE_NAME_MODEL.md)
