# ChannelMessenger

A privacy-preserving opportunistic MANET with delay-tolerant fallback — secure text
messaging with no Internet, no cellular, no infrastructure Wi-Fi, and no server.

**Not a chat app that happens to work offline.** A message travels A→B, or A→relay→relay→B,
or waits in someone's pocket until they walk past the recipient. Relays learn essentially
nothing, and there is no company in the path — not by policy, but because the infrastructure
does not exist.

## Status

| | |
|---|---|
| **Assignment 01 — wire protocol** | ✅ complete |
| **Assignment 02 — `mesh-core-rs` + simulation** | ✅ acceptance set passing |
| Tests | **79**, all green, `clippy -D warnings` clean |
| Radio transports | not started — deliberately |
| Apps | not started — deliberately |

## Read in this order

1. **`CLAUDE.md`** — start here if you are an agent picking this up cold.
2. **`DECISIONS.md`** — every settled decision with the reasoning. **Wins over both specs.**
3. **`PROTOCOL.md`** — the normative wire protocol, §0–§9.
4. **`THREAT-WALKTHROUGH.md`** — what a relay actually learns, including where the honest
   answer is "more than we would like".
5. `SPEC-REVISION.md`, then `SPEC-ORIGINAL.md` — Don's source material, verbatim.
   The revision supersedes the original wherever they conflict.
6. **`LEGAL-RISK.md`** — what can be demanded, what we could produce, and the features that would
   quietly undo it. Read §9 before adding anything touching identity, storage, keys or telemetry.
7. `EXPORT-COMPLIANCE.md` — US encryption export position, checked against primary sources.

`SPEC.md` is a derived distillation and is **lossy**; prefer the two source files.

## Build

Rust is not on the default PATH on Studio (Homebrew's rustup uses its own prefix):

```
export PATH="/opt/homebrew/opt/rustup/bin:$PATH"
cd mesh-core-rs
cargo test
cargo clippy --all-targets -- -D warnings
```

## Why the protocol came before the code

Four platform implementations — iOS, Android, macOS, Windows — drift apart unless something
pins them. `vectors/` is that something: fixed inputs to expected bytes, generated by
`vectors/generate.py` and never transcribed by hand. A second implementation can prove
conformance without a radio.

Two examples of that paying off, both real:

- The worked AAD example in `PROTOCOL.md` §3.3 was hand-written and wrong twice. Computing
  it caught both errors.
- `vectors/04-route-cost.json` does not merely check the weakest-link rule, it **discriminates**:
  an implementation that picks the strongest first hop chooses the wrong route and fails.

## What this deliberately does not do

No server, no accounts, no telemetry, no address-book access, no remote push, no moderation
capability, and no claim of anonymity against a global observer. Each of these is a decision
with reasoning in `DECISIONS.md`, not an omission.
