AgentMBX

Changelog

Every release of the public AgentMBX software, newest first. AgentMBX is alpha: releases are frequent, and some need every paired machine upgraded together. Each entry says when that applies.

Latest: 0.5.6Release v0.5.6 on GitHub

Check your version with agentmbx version --check, and upgrade with agentmbx update.

All releases on GitHub · CHANGELOG.md

From CHANGELOG.md atv0.5.6 (commit 01e1e67).

0.5.6 (2026-10-03)

The status surface: every harness can show which mailbox a session holds and what is waiting, from snapshots the daemon writes, without ever showing another session's mail; and a resumed Claude session keeps the mailbox it registers.

  • Status JSON for harnesses (T311): agentmbx status --cli <provider> [--session <id>] --json --schema mbx.status/v1 returns the same mbx.status/v1 snapshot the HUD files carry — identity (bound/unbound/ambiguous, never a shared folder name), unread, needs-reply, owner-authority, outbox and policy levels. No lease is required, so it works before a session has claimed a mailbox. An explicit --session that does not resolve reports unbound; it never falls back to another session of the same process. Without --session it resolves the caller's own provider process. The existing status --json contract is unchanged.
  • Status surface (T312/T313): agentmbx statusline <claude|codex|kimi|opencode|grok|copilot|cursor|gemini> renders one MBX segment from HUD snapshots the daemon writes every tick — one cat, no store access by the adapter; pid snapshots only when the identity resolver proves a single holder, keyed by process birth time; nothing renders when the daemon is down (a hud/.alive heartbeat) or the identity is ambiguous. Output format: mbx <name> [<n>↑ unread] [<n>↺ needs-reply] [owner:<n>] [<n> unsent] [*v<version> update]. The bundled skill/scripts/claude-statusline.sh is now pure sh — sed, date, one cat of the pre-rendered line, no node startup on the render path (a node startup is 150 ms idle and breaks Kimi's 300 ms statusline cap under load); it honors MBX_HOME. The pid-file fallback fires only for Claude, the only one-conversation-per-process CLI: a shared-process CLI (Kimi, OpenCode) that names no session id renders nothing, since its pid file cannot know whether an unbound sibling conversation exists. Copilot, Cursor and Gemini join the adapters (Claude-compatible statusLine.command shape); they are session-id-only like every non-Claude CLI. Per-harness wiring snippets are in the README Status line section.
  • A resumed Claude session keeps the mailbox it registers (T326): a resumed claude start gives its MCP servers a temporary session id, then switches ~/.claude/sessions/<pid>.json to the resumed conversation's id. The mbx server read that file once at start, so a mailbox registered or claimed afterwards was bound under the temporary id. Hooks, wakes, statuslines and agentmbx status --session <id> then never found it; the statusline fell back to the folder name and showed another agent's mail. The server now checks the file on every tool call and on its 60-second heartbeat (re-parsing it only when it changes): an unbound session takes the new id before it registers or claims, and a held mailbox moves its lease, session binding and control endpoint to the new id. After /clear, /resume or compaction the binding follows by the next mbx call or heartbeat, whichever comes first. It never moves to an id that another live process has bound or answers for as an unbound session.

0.5.5 (2026-10-02)

The durable relay: a relay restart, crash or restore never loses mail, and a sender always learns when mail could not be confirmed. Self-hosted relays work today; the hosted relay at relay.agentmbx.com follows.

  • Relay that never loses mail silently (T166): daemons speak relay v2 when the relay offers it (v1 otherwise). A message goes to the relay only after two failed LAN attempts, when its backoff is due, before the LAN retries it. Its sealed bytes are stored before the first push and reused on every retry, so a retry is a duplicate, never a second copy. It leaves the outbox only on an accept signed by the relay key this host pinned, for exactly those bytes, then waits as relay-accepted until the recipient host's delivery receipt arrives (which now also travels over the relay). If the receipt never comes, the sender gets "Undelivered/unconfirmed" after the relay's retention plus a day, with no dependence on the relay. The receiving host processes relay items in order, keeps anything it cannot accept in a quarantine (agentmbx relay quarantine, doctor), checkpoints, then acks; a lost ack is re-sent. A relay restore (a new epoch, or a queue that went back in time) makes senders re-push and receivers re-pull, without duplicates. A relay whose key changed is not used. doctor reports v2 enrolment correctly (it always said "not yet enrolled" before), waiting and unconfirmed relay deliveries, and quarantined items.
  • Durable relay store (T165): agentmbx relay serve keeps everything in SQLite (relay.db, WAL, synchronous=FULL) in --store-dir / MBX_RELAY_DIR (default ~/.local/share/agentmbx-relay), so a restart loses no enrolment, encryption ad or queued mail. The relay has its own signing key (relay.key, 0600, created on first start, or the deploy secret MBX_RELAY_KEY from agentmbx relay keygen; a store refuses a key that isn't its own) and a store epoch (agentmbx relay rotate-epoch after a restore made outside agentmbx). New /v2/relay/* endpoints (spec: docs/spec/relay-durability.md): info (with the caller's queue head when signed), items push (sealed envelopes and signed receipts, atomic per item, deduplicated by sender, item and target, answered with a relay-signed accept statement), items pull (paged by seq and bytes, with head_seq; ?epoch= answers 409 when stale), ack (per epoch, never past the head) and rotate (a T030 rotation moves a host's name and queue to its new key). Hosts are found by key; a host name is a label, unique only inside a proven account, so two owners' macbook share a relay and nobody can lock a name. v1 mail routes by name only when exactly one host carries it (otherwise it is refused as ambiguous, never guessed). A revoked key stays revoked. Quotas charge each target key, each sender's share of it and proven accounts, never an unproven owner fingerprint, and a host can publish the sender keys it accepts. Sequence numbers have a time floor, so a store restored from an older copy never hides new mail below a receiver's checkpoint. Enrolment state is bounded (validated fields, expiring and capped challenges, a key cap, per-address rate using the rightmost forwarded hop with --trust-proxy or CF-Connecting-IP with MBX_RELAY_TRUST_PROXY=cloudflare). Wire bytes are stored and hashed exactly. /v1/relay/* keeps its behaviour on the same store. Daemons don't use v2 yet (T166).

0.5.4 (2026-10-02)

Identity and noise fixes reported by the owner's agents: a Claude session keeps its mailbox through /clear, statuslines never show another agent's mail, shorter mbx notices, no duplicate copies for names that exist on both hosts, and private project keys for self-hosted remotes.

  • Claude /clear keeps your mailbox (T309): /clear, /resume and compaction give the same Claude process a new session id while its mbx server lives on. The session hooks used to refuse to rebind it, so the new conversation was told it had no identity, and a statusline that fell back to the folder name showed another agent's mail. The hook now rebinds the holder when Claude's own session file names the new id. A session id that file doesn't name is still refused.
  • Status displays resolve exactly (T310): a shared resolver for statuslines and agentmbx status matches the session id, then that provider process's live holder; otherwise it reports unbound or ambiguous. It never uses a folder name.
  • Claim a known mailbox by name (T315): a released mailbox from before chosen identities can be claimed without passing a role again; it keeps the role it was known by. A brand-new name still needs one.
  • Your own lease reads as yours (T316): the identity list in the holding session says "held by this session" instead of "held by an older process of this same session … claimable".
  • Private project keys for self-hosted remotes (T219): the project key in envelopes was the git origin as host/path. For a self-hosted remote that path can name a machine, a user and a folder. Public forges (GitHub, GitLab, Bitbucket, Codeberg, sourcehut, Azure DevOps, Gitee) keep the readable host/org/repo; any other origin becomes h:<digest>. Every host computes the same digest, so cross-host ledgers still match.
  • No duplicate copy of a bare name that lives on both hosts (S2 follow-up): the sending host resolves a bare name locally first; when it delivers one to its own agent and the message also goes to paired hosts, it names it in the signed envelope (meta.local_names), and receivers skip exactly those names instead of delivering a second copy to their own same-named mailbox (audited as receive.skipped). Decided by the sender, so a stale directory can never turn this into lost mail; messages from older senders behave as before. An explicit name@thishost still arrives.
  • Retired phantoms send no receipt (S2 follow-up): doctor --fix removes the cross-host receipts its own acks would queue, so the sender never sees "drum@fedora acked" for a mailbox nobody holds.
  • Lean notices (S3, owner request): a wake is one line ([mbx] N new message(s) for X from Y [trust] (ids …). mbx_inbox or mbx_read, reply, ack. Already handled: no action needed.) instead of four sentences; the trust rules stay in the MCP instructions, the session-start note and every mbx_read header. The prompt hook adds nothing on the wake prompt itself (it is the notice), and the policy recap is sent once per session and again only when policies change; otherwise the unread notice is [mbx] N unread for X: mbx_inbox. About 280 words per incoming message become about 40 (plus Claude Code's own socket framing, which AgentMBX does not control).

0.5.3 (2026-10-02)

Follow-up to the 0.5.2 P0 release: mail you send to another machine now reports back, mail nobody can read no longer piles up, and a resumed identity can catch up on what it missed. Install it on every machine; receipts flow once both ends run 0.5.3.

  • No phantom mailboxes from received mail (S2): a bare name in a received envelope was resolved by the sender on its own host, so it is now delivered here only if that name is an agent, lease, registration or alias on this host. Before, a message to [claude@fedora, drum] created an unreadable drum mailbox on fedora while the real drum got its copy on the sending host. Skipped names are audited (receive.skipped). agentmbx doctor labels existing phantom mailboxes and agentmbx doctor --fix retires them (marks those copies handled with a note; nothing is deleted).
  • Return to sender (S2): mail that waits 7 days (config stranded_return_days; 0 turns it off) in a mailbox that is not an agent here (no agents row, lease, registration or alias: typically a mistyped name@thishost) goes back to its sender as an alert in the same thread, exactly once, and the copy is marked "returned to sender", which the sender's mbx_sent shows. Real mailboxes that never hold a lease (CLI/shell readers, backfilled identities, aliases) are never returned. Only mail delivered after the upgrade is returned; older stranded mail stays for its owner to decide.
  • Self-healing skill (S1): the agentmbx skill now always matches the running AgentMBX without anyone managing it. A copy AgentMBX wrote carries a marker (.agentmbx-skill.json, the hash of the files it wrote); an unchanged copy is refreshed at every session start (hook) and daemon start, so upgrades no longer leave the 0.5.0 skill behind. An edited copy, a removed skill, and one installed with npx skills (an agentmbx entry in ~/.agents/.skill-lock.json) are left alone; doctor says which, and an outdated own copy is info, not a warning. The skills CLI already lists our copy as a local skill; no lock entry is written, so npx skills update never swaps in a different version from GitHub. npx skills add kryptobaseddev/agentmbx -g remains an alternative install.
  • Session catch-up (T156–T158): each identity keeps a durable catch-up checkpoint, separate from acks. mbx_catchup pages through what the identity missed since its last captured page (a crashed holder's window included), and commit: <next_cursor> advances it once the page is saved; it never acks, marks read or grants authority. A resumed session gets a bounded hint when it missed messages, and mbx_whoami shows missed. A rename carries the checkpoint.
  • Cross-host receipts (T218): mail you send to an agent on a paired host no longer ends at handed-over. The recipient's host reports each step (delivered, notified, read, acked with the agent's did and note) back to your host as a receipt signed by its host key, and mbx_sent/mbx_thread show it like a local recipient. Receipts apply in order (a replayed or older one changes nothing), only for mail your host sent, only when signed by the recipient's host. A peer still on 0.5.2 shows handed-over as before; its receipts start flowing once both hosts run 0.5.3. The record is the receipt envelope the relay (T146) will carry.
  • Cross-host project ledger (T219): a repository lives in a different folder on each host, so mail now carries the project's git origin, normalized (github.com/org/repo, never credentials or a local path), and mbx_project on any host includes that repository's mail from paired hosts' own folders. A lead sees remote recipients' states, did and notes from their hosts' receipts.
  • The guide over MCP (S1): the mbx server serves the version-matched guide as the resource mbx://guide and the prompt mbx_guide, so any MCP client can read it with no skill file installed.

0.5.2 (2026-10-01)

P0 release: no more invented mailbox names, lost or invisible mail, or "who got this?". Install it on every machine; a running session switches to it on its next mbx tool call and keeps its identity. After the upgrade, a new session has no mailbox until it claims one from its project's list or registers a name and role.

  • Chosen identities only (T204, P0): AgentMBX no longer invents mailbox names. On 2026-10-01, 18 sessions of one folder resumed in the same instant after a reboot. Sessions with no remembered name took the first free default name, one of them took another session's established mailbox, and the rightful session fell back to -mcp-<hash>, which then overwrote its remembered name. Now:
    • A session resumes only its launch config (MBX_AGENT, registered with MBX_ROLE) or the identity its own provider session held before. The session is found by its id, a verified hook binding, or the session id its hooks report.
    • Otherwise it starts unbound: mbx_whoami, mbx_identity and mbx_agents work, and every other tool explains the next step.
    • The default-name ladder and every fallback are gone: -<cli>, -2…-9, -<pid>, -<10 hex> and -mcp-<hash>. A remembered identity still held by another live session stays pending and resumes on its own once that holder ends.
  • Registry and per-project list: every identity has a role, and every bind records the project folder it works in. mbx_identity gains the following:
    • list shows this project by default (all:true for the host), with role, state, claimable, unread and holder.
    • register creates a new identity from a name and role.
    • claim needs a role for a mailbox that has none yet.
    • One identity per session.
    • Names that already had a role or were rename targets are registered once at upgrade.
  • List and claim agree: both use one availability rule.
    • A newer process of the same session takes its lease over.
    • An explicit claim may take an identity from a conversation of a shared OpenCode or Codex process (or hosted Kimi) that made no mbx call for 10 minutes. That conversation learns its lease was lost and never takes it back.
    • A session whose own lease expired while idle re-claims it silently if nobody else did.
    • Previously the list could say "available" while the claim said "held", because a shared process kept every ended conversation's lease alive.
  • Hosted Kimi: a linked conversation resumes the identity it held, or claims or registers one. It is given a new bind ticket only when its server ended.
  • Crashed holders read offline at send time: inside a send, recipients[] uses the process snapshot and the heartbeat. A vanished holder, or one with no heartbeat for 3 minutes, is offline. A quiet shared-process conversation is flagged as possibly ended.
  • Cleanup (T209):
    • agentmbx identity prune [--days 7] [--apply] retires mailboxes that older versions generated, with no holder, no unread mail and no recent traffic. It is a dry run by default.
    • agentmbx identity forward <from> <to> moves a mailbox's unread mail to another with the owner's signature, and routes the old name to the new one.
    • Retired names leave listings and routing and come back when claimed. Messages are never deleted.
    • agentmbx identity list gains --project and --all, plus role and claimable columns.
  • Load resilience (T206): process evidence no longer spawns ps for a server's own process (its birth time is read once), other pids are inspected with one batched ps and cached for a second, and the per-call process table is shared for two seconds instead of re-read every call. In a measured loop of 60 held operations, the ps spawns went from 60 to 1. Unknown evidence is retried with backoff (never while another transaction holds the write lock) and never produces a new name. agentmbx watch rides out "evidence stale" and "status unknown" instead of stopping after five of them. Under a load average of 76–110 these timeouts had made claims fail and watchers stop.
  • Doctor sees lost mail (T211): agentmbx doctor lists mailboxes whose unread mail no live session will see (with the last holder, since when and the fix), sessions waiting for a remembered identity that another session holds, and how many generated mailboxes agentmbx identity prune would retire.
  • Signals release identities (T210): an mbx server ended by SIGTERM or SIGHUP (as claude -p and a closed terminal do) now releases its identity instead of leaving a dead holder to expire.
  • Project ledger and lead (T208): mbx_project shows the mail traffic of the project folder a session works in: messages stamped with the project, or sent to or by its identities, with each recipient's role, delivery state and liveness. Bodies are shown only for the caller's own mail. The owner designates a project lead with agentmbx lead set <agent> --project <dir> [--ttl 30d] (owner-signed like policies; lead revoke, lead show); the record is re-verified against the owner keys on every read. The lead sees every body of its project and can mbx_forward a project message to another local identity (audited as message.forwarded; the recipient sees "forwarded by lead X", and its policy still comes from the original sender).
  • Sender receipts (T207): mbx_sent lists the mail you sent from this host, oldest first, with each recipient's delivery state (delivered, notified, read, acked), the recipient's note and did line, its liveness now, and for paired hosts whether the outbox still holds it (attempts, last error) or the host accepted it. Paged by an opaque cursor that mirrors replay (finite snapshot; a completed cursor polls for newer mail; scope, tamper and store-generation checks). mbx_thread shows the same per-recipient line under every message.
  • Send-time recipient truth (T205): mbx_send, mbx_reply and agentmbx send return recipients[], one per resolved recipient, with a state: live-wake (a live session is woken now), live-next-prompt (live, but this kind or its missing push path or policy means it sees the mail on its next prompt), offline (no live session, with since when, the last holder and why), forwarded (a renamed mailbox's successor) or remote (queued for a paired host). Offline recipients add a sender warning. A send to a local name that never existed is refused with up to 3 suggestions instead of silently creating a mailbox (the owner can still leave mail for an agent that has not started yet with agentmbx send --new-mailbox); a bare name on this host and a paired host is delivered locally with a warning. Liveness comes from the identity lease and its existing process evidence.

0.5.1 (2026-10-01)

Upgrade both machines: sealed LAN bodies, key rotation and code-compare pairing need 0.5.1 on each side (token pairing and plain delivery from 0.5.0 senders keep working).

  • Encrypted LAN bodies (upgrade both hosts): direct LAN delivery now seals every body for the receiving host (X25519 + XChaCha20-Poly1305, as the relay already did) and never falls back to plaintext. A peer that has not published a body-encryption key keeps mail queued with an upgrade hint. Owner and session authority now verify on sealed mail. A 0.5.0 receiver opens sealed bodies, but it cannot verify owner authority on them: it labels them unverified (fails closed), so upgrade both machines for owner-signed requests. Local storage stays plaintext (D001). A peer's body-encryption key is learned only from a direct answer (redirects are refused), so a moved endpoint cannot substitute keys.
  • Host key rotation: agentmbx host rotate replaces this host's signing and encryption keys without re-pairing. The old key signs the new keys, the new key countersigns, and each peer moves its pin only for a record that starts from the key it pinned. The daemon retries announcements until accepted. Retired keys keep stored mail verifiable and open mail sealed in flight. agentmbx peers remove now tells the peer, which drops this host too. Peers on 0.5.0 cannot accept a rotation; upgrade them first.
  • Receive limits: request bodies are capped while streaming (413), per-peer requests are rate limited (429), and slow-header and slow-body clients are disconnected. Envelope recipients, refs and fields are capped with clear rejection reasons. A seeded fuzz suite covers receive() and every HTTP route. The reference relay has the same body cap and timeouts.
  • Wake reliability: provider adapters report typed outcomes (not_submitted, admitted, busy, blocked, unknown, failed; docs/spec/provider-wake-contract.md). An uncertain submission is never repeated: it is held, then retried once after ten minutes under the wake brake, including after a daemon crash mid-attempt. Busy sessions back off up to a minute. Wakes target only the exact session holding the mailbox lease: the OpenCode "newest session in this directory" fallback is removed. agentmbx wake mute <agent> [--minutes N] pauses hints and notices while mail keeps arriving.
  • Status never wakes: a status message no longer wakes anyone, even with an @mention or needs_reply. The skill, the mbx_send kind description and a send-result warning tell senders to use request (or task) with needs_reply when they need attention now.
  • Claude sessions wake with no flags (T202): each Claude session's own mbx MCP server queues the no-body wake hint into that session through Claude Code's per-session inbox socket (CLAUDE_CODE_MESSAGING_SOCKET). A plainly started claude is now woken on new mail with no launch flag, no setting and no cron; the daemon defers to it. The token never leaves the server's environment, and a server only uses the socket of the Claude process that started it. The channel flag still works.
  • Terminal Kimi wakes itself (T033): agentmbx watch waits for mail that wants the calling session (same wants-wake, authority, mute and brake checks as a push), prints the no-body hint and exits. Kimi Code turns a finished background task into a new turn, so a terminal Kimi session that keeps one running is woken within seconds with no polling turns; the session-start note asks it to. The daemon defers to a live watcher, and mbx_whoami reports it as the delivery path. The [mbx-watch] cron self-check remains for MBX_SELF_WATCH=<minutes>.
  • Kimi desktop and web wake (T033): the Kimi desktop app keeps a private Kimi Code home, so agentmbx setup now installs AgentMBX there as a native Kimi plugin (mbx MCP server and hooks) while the app runs. Desktop conversations are woken through the app's local control socket (conversations.send, busy-checked first). Hosted Kimi (desktop and kimi web) runs one mbx server per conversation under one shared process, so a conversation could never be matched to its server and was never woken. Now the conversation's prompt hook hands it a one-time bind ticket and its own server links itself (mbx_whoami bind) to the real session and folder, without guessing. Doctor flags a kimi web server started before its hooks were installed (it runs none: restart it). Verified live for terminal, desktop and web on 2026-10-01. A corrupt bind-ticket row is dropped instead of throwing, and the ticket trust assumption is written down in src/bind-ticket.ts. A kimi web conversation in manual approval mode asks before every mbx tool call: allow mbx_* so mail handling isn't blocked on a prompt.
  • Owner-signed mail reads as the owner's (T022): a message carrying authority: OWNER no longer also shows policy: ask beside it; the policy line says owner authority applies (delegation policies limit only other agents' requests).
  • Claude wake launcher: agentmbx claude [args] starts Claude Code with the mbx channel (Claude Code has no persistent setting for channels). Doctor suggests it when no Claude session has a channel.
  • Address healing and presence (T201): a paired host that moved (DHCP) is found again without re-pairing. The pin only moves to an address that answers a fresh challenge signed by the pinned host key and lists its own IP; candidates come from verified hops, signed presence beacons (on start, address change and every 5 min), stored alternates, mDNS and agentmbx peers addr. Queued mail goes out as soon as the peer is heard from again (verified hop or presence beacon), not after its back-off: that lag was 75 s in the T151 offline test.
  • Relay depth counts relays, not conversation turns (T104): depth comes only from mail read from agents other than the recipients, so two agents answering each other stay at depth 0 however long they talk, while forwarding to a third agent still adds a hop (role and * sends count every read). Each policy level has its own allowance: ask 6, collaborate 20, autonomous and yolo no limit (bounded by the wake brake and the per-thread action cap). The header shows it (relay depth 3 of 20), an exceeded grant says how to reset it, the sender is warned past 20, and mbx_whoami/doctor list mail that depth kept from waking a session.
  • Relay depth resets at the owner's prompt: relay depth no longer accumulates across a long session. A prompt the owner types ends the agent-to-agent chain. Wake and [mbx-watch] prompts never reset it, and external origin is never cleared. A send or reply past the depth limit now warns the sender that the recipient will not be woken or act under its policy.
  • Connector evidence: each running MCP server reports its own version, loaded build and tool catalog. agentmbx diagnostics shows it for the verified lease holder, separately from the installed CLI and the daemon, and explains the in-conversation update path when they differ. False "pid-reused" session reports on macOS are fixed. mbx_whoami also says when a newer build is installed and this server is about to hand over to it (switching): the new build's version and delivery mode appear from the next call.
  • Session hygiene: the daemon prunes session rows whose process is provably gone; chosen mailbox names survive for the next bind.
  • Security review (T032): docs/THREAT-MODEL.md covers assets, trust boundaries, attackers, a STRIDE table and accepted residual risks. Three fixes: relayed mail is sealed only to the peer's pinned body key or a relay copy signed by the peer's pinned host key (a relay client enrolling the same host name could read relayed bodies); pair --compare is now commit-reveal (a man in the middle could grind matching 6-digit codes), so both hosts need this release for code-compare pairing (token pairing is unchanged); mail from a paired host must name exactly one agent at that host as its sender (free text reached wake prompts). Four findings remain open as follow-ups: relay enrolment by any key and the reference relay's unbounded challenge/dedupe state (T197), envelope metadata not sealed (T198), unauthenticated host-to-host HTTP responses (T199), and code-compare pairings that never expire (T200).
  • Message framing and recipient floods (T196): received subjects with line breaks or control characters are rejected and local subjects are collapsed to one line. Header fields always render on one line, and a body sits between --- message content <boundary> and --- end of message <boundary> --- lines with a fresh random boundary, so message text cannot pose as headers or close the frame. A paired host can no longer create mailboxes with invalid names, and mail to names with no registered agent or session raises no desktop notice. Notices are limited to six a minute.
  • Acks never fail over a long did (T194): the audit line stays at most 200 characters. A longer one is kept truncated, marked did_truncated with its original length, and the caller is warned. Previously MCP rejected the whole batch, so none of the acks were recorded, while the CLI truncated silently.
  • Self-describing wake hints (T195): a hint queued while the session was busy names its message ids and says that mail already read or acked needs no action.
  • Retention (opt-in): agentmbx prune [--older-than <days>] [--dry-run] deletes only settled mail (every local delivery acked, no outbox row, received and last updated before the window), then runs VACUUM. Default is off: agentmbx retention set <days> stores retention_days in config.json and the daemon then prunes every 6 h (without VACUUM). Unacked mail, including every pending wake, and queued outbox mail are never pruned. Pruned replay positions leave tombstones: replay pages report them as history_pruned and existing cursors stay valid. The tombstone table is additive; processes older than this release do not report the gap.
  • Host identity backup: agentmbx identity export <file> writes a 0600, passphrase-sealed bundle (scrypt + XChaCha20-Poly1305) of config, host signing key, body encryption key, a file-backend owner key (still owner-passphrase encrypted) and approved peers with pinned keys. agentmbx identity import <file> restores it on a replacement machine so existing pairings stay valid; it refuses an initialized home unless --force, which first backs up the old identity files and a copy of mbx.db. A macOS Keychain owner key is not exportable. Mail, policies and devices are not in the bundle. The bundle also carries retired host keys, the rotation log and each peer's previous keys, so a restored host keeps verifying mail signed before a rotation and can finish pending rotation announcements.

Known limitations: mDNS discovery and direct LAN delivery stay on this LAN (no WAN discovery, no NAT traversal), and multicast is blocked on some LANs (ours sees no mDNS in either direction); then agentmbx peers addr, pairing by explicit address, or the prototype relay are the routes. The relay's queues are still in memory, so relay-only delivery is not restart-safe yet. If both hosts change address at once while multicast is blocked, only the relay or peers addr recovers. Hermes wake is deferred (T189).

0.5.0 (2026-09-30)

  • Bounded replay: mbx_replay is the eleventh MCP tool; agentmbx replay exposes the same read-only JSON page and cursor contract through the caller's exact current provider lease. First-ever mailbox visibility is ordered durably, including late/backdated grants. Caller-persisted cursors retain finite snapshot position across same-persona provider handoffs; completed cursors poll new visibility, and lost cursors explicitly rewind with ID deduplication. No automatic server checkpoint or ACK is implied.
  • Scoped history: existing signed project/host, topic-tag and thread metadata can filter authorized history. Oversized first items return bounded omission metadata; filtered and hidden ranges still make progress. Filters grant no new delivery or authority. Replay content is data; mbx_read supplies current computed policy before acting.
  • Local diagnostic CLI: agentmbx diagnostics reports bounded holder/process evidence, sender-scoped queued counts and redacted recovery receipts without changing mailbox state or disclosing bodies/lease credentials. Installed CLI, observed daemon and connector versions remain distinct. This is a same-OS-user CLI view, not a web console.
  • Mailbox schema 3: atomic visibility ledger migration preserves signed bytes and pending/acknowledged delivery history; incompatible retained message/delivery writers fail closed. Coordinate the upgrade: quiesce all writers, back up the complete mailbox home, update in the same installation kind and verify each runtime. Rollback requires stopped writers plus restoration of the compatible pre-upgrade backup; no in-place database downgrade. Database restore must explicitly reset the replay epoch before resuming writers. See rollout handoff.
  • Performance and packaging: sender-scoped outbox queries use an index; release packaging smoke checks cover replay availability and read-only diagnostics. Native binaries and tagged source install remain supported; the npm registry package is not published.

0.4.0 (2026-09-28)

  • Identity leases (mailbox schema 2): one live holder per identity, claimed atomically with process-birth evidence and fenced heartbeats. Dead or idle holders become claimable again — history and inboxes are preserved; takeover of a live lease requires an owner signature. --as and mailbox tools require the current lease; sends without one are labelled unverified instead of silently trusted. Intra-process claims converge instead of erroring: an identical claimant re-claims idempotently, a session claim transfers the lease from the server's own provisional base, and racing first calls adopt the winner.
  • Sessions adopt new builds without restarts: the long-lived MCP server fingerprints the on-disk build and re-checks on every tool call; after a deployment it finishes the in-flight call, respawns from disk and hands over the transport. Combined with the existing per-invocation freshness of the daemon, hooks and CLI, agent updates no longer require restarting agent sessions.
  • Smooth schema upgrades: the store records which version migrated it; stale peers get advice that matches reality (restart-first when already current, update-first with the upgrader named only when behind). The MCP server reloads itself when the store outgrows it.
  • Receipt validation: Kimi wake and submission receipts are validated and redirects refused. OpenCode synthetic admissions are validated against session, text, type, delivery, id and time. Policy revocations compare instants and apply atomically; envelope core fields, policy records, daemon identity, setup listeners, relay depth and native harness recovery hardened.
  • Wake coverage: OpenCode sessions bound only through their MCP process are woken via the service's directory fallback; the wake matrix is validated live across all four providers.
  • Cloud relay (ADR-035, accepted threat model): an untrusted store-and-forward transport for offline peers. Challenge-signature host enrolment bound to owner keys, per-recipient opaque queues, exactly-once storage, cursor acks, per-owner quotas (depth, size, batch, rate), signed enc-key discovery through the relay itself, and a sealed-bodies-only rule enforced client-side. agentmbx relay serve runs a reference relay; agentmbx relay set <url> points a daemon at one; doctor reports relay status.
  • Body encryption (T028): pairwise sealed envelopes for untrusted hops — ephemeral X25519 per envelope, XChaCha20-Poly1305, signatures committing to the exact ciphertext, local storage staying plaintext per the D001 local-trust decision.

0.3.1 (2026-09-26)

  • Kimi web wake-up: Kimi sessions hosted by kimi web, the Kimi desktop app or kimi rc are woken directly through the local server's prompts API, with no self-check job needed. A busy session is retried, never interrupted. Terminal Kimi keeps the [mbx-watch] self-check. Built and verified live by kimi.
  • Broadcasts (*, role:) reach only agents with a live session. Shell senders (--as) still get mail addressed to them by name.
  • Setup defaults to the collaborate policy (POLICY.md ratified).
  • Release signing: the macOS app is signed with a stable identity, so the Keychain keeps trusting the owner-key helper across updates. daemon install never replaces a stably signed app with an ad-hoc local build.
  • Policy sync audits only changes of state, so an offline peer doesn't log every minute.

0.3.0 (2026-09-26)

  • Owner-signed collaboration policies: choose ask, collaborate, autonomous or yolo, with explicit read, edit, outward and permissions classes. Scope delegation by agent, host and project; inspect it with agentmbx policy list. Renew with policy renew <id>, revoke one policy or use policy revoke --all as the kill switch. The daemon reminds the owner 48 hours before expiry.
  • Owner identity: a Touch ID-protected owner key on macOS signs policies and device records. Explicitly approve paired machines with agentmbx owner add-device; unpairing removes trust learned through that peer. Signing shows complete security values and refuses summaries too long to display safely.
  • YOLO permission hooks: Claude Code, Codex, OpenCode and kimi web-hosted Kimi sessions approve prompts (not terminal Kimi: its hook can only observe) only when an active owner policy grants permissions. Missing or unverifiable session identity leaves the normal approval flow in place.
  • Session identity: bind sessions using PID and process start time, choose a free name, and keep old-name aliases after renaming. Inside an agent session, --as cannot claim another live session's name.
  • Keep conversations moving: self-watch instructions support idle polling for CLIs without push; Stop hooks let Claude Code, Codex and Kimi continue handling new mail under an owner policy. Wake and prompt notices include the delegated policy, including in sessions started before it was signed.
  • Security review: three rounds of regression review by Codex, independently reproduced and checked by Kimi, hardened session identity, policy scope, revocation and device trust, and the owner-signing display.

0.2.0 (2026-09-26)

  • Install and update: single self-contained binaries for macOS (arm64, x64) and Linux (x64, arm64), with no Node.js needed.
    • curl -fsSL https://raw.githubusercontent.com/kryptobaseddev/agentmbx/main/install.sh | sh
    • agentmbx update verifies an Ed25519-signed release manifest and the sha256 of the download, then replaces the binary and restarts the daemon. The daemon checks once a day.
  • Plug and play:
    • agentmbx setup wires Claude Code, Codex, OpenCode, Kimi Code and Hermes: the MCP server, hooks and a bundled skill. It backs up every file it edits and can be undone with --uninstall.
    • agentmbx doctor checks everything.
    • The new mbx_reply tool replies in the thread.
  • Pairing:
    • agentmbx pair prints a one-time token. On the other machine, run agentmbx join <host> <token>. That's one command each, with nothing to compare.
    • Machines find each other on the LAN over mDNS (agentmbx discover).
    • The code-compare flow is still available as pair --compare.
  • Notifications: on macOS, the AgentMBX.app notifier shows the AgentMBX name and icon, and the background item appears as AgentMBX. Linux uses notify-send -a AgentMBX. Try it with agentmbx notify-test.
  • Live-tested wake-ups: idle Codex, OpenCode and Claude Code sessions wake, reply in the thread and ack.

0.1.0 (2026-09-25)

  • Signed envelopes, SQLite store, LAN daemon, MCP server, wake adapters.
  • Owner grants bound to a session key, following the council's review.