interlink-mcp 0.4.1

Cryptographically-authenticated, cross-machine agent-to-agent chat for Claude Code, over MCP channels
Documentation
# Deferred work

Signed identity with pre-shared keys is **built** — each agent has an Ed25519
keypair and knows peers' public keys via `peers.json`. How it works (signing,
`verify_strict`, the inbound gate) is in [`DESIGN.md`](DESIGN.md) and the code
(`src/identity.rs`, `src/policy.rs`, `src/agent.rs`).

This file records what was researched and deliberately left for later. None of
it is needed for a trusted mesh; the natural trigger for each is noted.

## Peer discovery / registry / presence — **built** (v0.2.0)

Implemented: a bus roster with TTL presence, `discover`, and a human-gated
pairing handshake (`request_pair` / `accept_pair`), keys pinned TOFU. See
[`docs/DISCOVERY.md`](docs/DISCOVERY.md).

## Opening the relay to strangers

A trusted mesh needs none of this (Tailscale is the boundary — see
[`DEPLOY.md`](docs/DEPLOY.md)). To let anyone join a *public* relay safely:

- **Signed `/recv`** — the bus challenges the poller to sign a nonce, proving it
  holds the private key for the queue it's draining (the Nostr NIP-42 pattern,
  native to our Ed25519 keys). Stops anyone who merely knows a public key from
  stealing messages.
- **Rate limits** — token bucket per verified pubkey, plus a coarse per-IP cap;
  optional proof-of-work on send.
- **End-to-end encryption** — X25519 (Ed25519 keys convert) → HKDF →
  ChaCha20-Poly1305 sealed box, so the relay is a blind forwarder and can be
  hosted on untrusted infrastructure.

## Reply / thread correlation

Today a reply is just another message; conversations are correlated **by peer**
(`conversation_history` groups on the petname, in time order). That's enough for
two-party, human-in-the-loop chat. It falls short once you **fan out to several
peers with concurrent async requests** and need to match a reply to the request
it answers — the natural trigger to build this.

The shape is the standard one (email `In-Reply-To`/`References`, Slack `thread_ts`,
Matrix `m.in_reply_to`, Nostr NIP-10 `root`/`reply` markers): carry the parent's
`msg_id` (and optionally a thread `root`). interlink already has a stable per-message
`msg_id` to point at, so it's additive — an optional `reply_to` on `SignedMessage`,
a `send_message` argument, and a threaded `conversation_history` render. The one
care point is that `reply_to` must enter the signed `canonical()` encoding, which
bumps the domain tag `interlink-v1\0` → `interlink-v2\0`.

## Post-quantum signatures

If long-lived authenticity or a shifted threat model ever warrants it: a hybrid
**Ed25519 + ML-DSA-65** composite (both must verify) via `ed25519-dalek` +
`fips204`/RustCrypto `ml-dsa`. Additive, not a rewrite. Cost is ~4.5 KB per signed
message — the reason it's deferred. Falcon/FN-DSA is not an option (FIPS 206
unpublished, no production Rust crate). Note: harvest-now-decrypt-later is an
*encryption* threat, not a signature one, so PQ signing is not urgent.