The README said the engine is held to `engine/test/vectors/protocol-v1.json`, a path from the pre-split subtree layout that does not exist here. The vectors live in flamenet-e2e and are read from there rather than copied, because a copied vector file drifts and a drifting vector file stops being a check. PublishedVectorsTest already searches for it and fails loudly when it cannot find it; the README now says so, and names FLAMENET_VECTORS. CONTRIBUTING records what a JVM test cannot tell you: Conscrypt and the JVM's JCA are different providers, so :engine:test passing proves nothing about a handset, which is what interop/ is for. Also the exception escaping a WebRTC callback that SIGABRTs rather than surfacing, the missing permission that presented as a dead button, and `*/` inside a KDoc reporting an unclosed comment hundreds of lines from its cause. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
78 lines
3.4 KiB
Markdown
78 lines
3.4 KiB
Markdown
# Flamenet Messenger — Android
|
|
|
|
The Android app, and the two libraries under it.
|
|
|
|
```
|
|
engine/ the protocol: X3DH, Double Ratchet, sealed sender, safety numbers,
|
|
key transparency. Plain Kotlin/JVM — no Android in it at all.
|
|
client/ the relay transport: HTTP, auth, the §8 routes.
|
|
app/ the Compose app.
|
|
interop/ the cross-engine driver; not shipped.
|
|
```
|
|
|
|
`engine` and `client` are deliberately plain JVM libraries. The protocol has
|
|
nothing to do with Android, and keeping it off the platform means their tests
|
|
run anywhere a JVM does — no SDK, no emulator, no device, which is also what
|
|
lets them gate in CI on Linux:
|
|
|
|
```
|
|
./gradlew :engine:test :client:test
|
|
```
|
|
|
|
The app's own unit tests need the Android SDK but still no emulator
|
|
(Robolectric):
|
|
|
|
```
|
|
./gradlew :app:testDebugUnitTest
|
|
```
|
|
|
|
## Where it stands
|
|
|
|
**[PARITY.md](PARITY.md) is the definition of done for this app — read that,
|
|
not this.** Every row there names the iOS file it came from so it can be
|
|
re-checked rather than trusted. Headlines as of 2026-08-28: messaging, groups,
|
|
attachments, voice notes, stories, calls, sealed sender, key transparency and
|
|
the encrypted vault are built and tested; a cross-platform round trip against
|
|
iOS was verified on 2026-08-26.
|
|
|
|
⚠️ **This file said "Nothing here is an app yet" until 2026-08-28**, above a
|
|
tree containing the finished app — the README described the repository as it
|
|
was when the engine landed and nothing updated it as the app grew around it. If
|
|
a claim here ever disagrees with PARITY.md or with the tree, believe those, and
|
|
fix this.
|
|
|
|
## Why the engine came first, and is held to the vectors
|
|
|
|
An Android client needs the protocol implemented a third time, and the third
|
|
implementation is the one that finds the places where the specification says
|
|
less than the two existing engines quietly agreed on — but only if it is
|
|
written against the spec and the published vectors rather than against a
|
|
reading of our own Swift and JavaScript. So the engine is held to
|
|
`test/vectors/protocol-v1.json` in
|
|
[flamenet-e2e](https://gitlab.com/paulhitt/flamenet-e2e) — the same file the
|
|
other two engines are checked against, read from that repository rather than
|
|
copied here, because a copied vector file drifts and a drifting vector file
|
|
stops being a check. `PublishedVectorsTest` looks for it beside this checkout
|
|
and fails loudly if it cannot find it; `FLAMENET_VECTORS` overrides the search.
|
|
|
|
Two implementations that agree may both be wrong in the same way, especially
|
|
when one was written while reading the other. The audit-path ordering in §19 is
|
|
the worked example: a top-down reading of a bottom-up path produces the correct
|
|
root for every left-spine index, so it passes any test that only checks index
|
|
0. The vector file pins a right-descending index for that reason, and the
|
|
Kotlin tests assert both that the published path verifies and that the same
|
|
path reversed does not.
|
|
|
|
If this engine ever disagrees with the file, the interesting question is which
|
|
of the three is wrong — not this one by default.
|
|
|
|
## Contributing and security
|
|
|
|
- [CONTRIBUTING.md](CONTRIBUTING.md) — building (JDK 21, `JAVA_HOME` is not
|
|
optional on a Mac), the test gate, and the platform traps that cost an hour
|
|
each.
|
|
- [PARITY.md](PARITY.md) — what iOS does, what this does, and what is left. It
|
|
is the definition of done for this app.
|
|
- [SECURITY.md](SECURITY.md) — threat model and where to send a vulnerability
|
|
report. **Not an issue tracker matter:** security@flamenetmessenger.com.
|