Translates .gitlab-ci.yml to .gitea/workflows/ci.yml and deletes it. Every gate is kept: secret sweep, unit tests with the vector pin check and the 700-test floor, UI tests with the 10-ran floor, vectors-head (advisory), parity scrub. Xcode jobs run on the pauls-imac runner; the sweep, vectors-head and the scrub run on mac1/mac2. Builds and tests only, no signing. The Obfs4 submodule and the sibling clones now come from git.extant2000.com/extant2000, as do the README links. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6.7 KiB
The original nine
Verified by driving the apps and the relays, not by reading code. Where something is unproven it says so.
Re-checked 45 commits after the baseline. Three rows moved. What was re-run this time is marked; anything not marked is carried forward from the baseline and has not been re-driven.
| # | Item | Status |
|---|---|---|
| 1 | Sign-up on managed / shared self-hosted / local self-hosted, iOS and Android | done, with one caveat |
| 2 | Sign-up against each type, both platforms | done |
| 3 | Messages between relay types | server yes, iOS built, Android no |
| 4 | Everything wired and usable, repeat rounds | done on the managed relay |
| 5 | iOS → Android message | done |
| 6 | api-docs self-hosting documentation | done |
| 7 | Public / donation / comparison pages | done |
| 8 | Relay deployed to relay.flamenet.io | deployed and current |
| 9 | Self-hosted accounts. Files optional | done |
1 & 2, sign-up across relay types
Both platforms, all four relays.
| relay | kind | iOS | Android |
|---|---|---|---|
relay.flamenet.io |
managed (accounts: shared) |
yes | yes |
relay2.flamenet.io |
shared self-hosted | yes | yes |
relay1.flamenet.io |
local self-hosted (accounts: local) |
yes | yes |
relay3.flamenet.io |
local self-hosted | n/a | yes |
"Three clean rounds" cannot be run back to back against a shared account
service, and that is correct. It allows 3 new accounts per hour per IP;
rounds 2 and 3 exhaust it and the service answers 429 Too many accounts created from here recently, which the app shows verbatim. The suites report
that as SKIP, not FAIL, a suite that fails for a service working properly
teaches everyone to ignore it.
Only local self-hosted survives repeated rounds, because it keeps its own accounts and has no such quota.
Repeatable via Scripts/android-signup.sh and RelayTypesUITests.
3, cross-relay messaging
The relays do it. test/federation.mjs (in flamenet-e2e since the split) against the live fleet:
11 passed, 0 failed: relay1 fetches bob's devices from relay2, sends
across the boundary, bob's relay accepts exactly one envelope, he polls and it
is there, it carries no sender attribution across the boundary, a relay off
the allowlist is refused, and an unknown address is reported rather than
silently dropped.
Re-run against the live fleet: 11 passed, 0 failed. Unchanged.
iOS now has the client path; Android still does not. E2EClient gained
remoteDevices, remoteBundles and sendRemote, and E2EInbox gained
transmitRemote, deliverRemote and a separate remoteThreads keyed on
fnid@relay. Android calls none of it, it still reads the federation field
from the descriptor and never acts on it.
Built is not proven. The iOS path compiles and its unit tests pass; it has NOT been driven across a real relay boundary from the app. The distinction matters here more than anywhere else on this list, because the Node harness passing is exactly what made the previous row look better than it was.
The comparison page still overstates it. "Servers can talk to each other Yes" is now true of the relay and of one client out of two. Reword the row or finish Android; a row that is half true reads as false to the half it is false for.
8, deployed
Deployed and current, verified by checksum. Re-checked after
two deploys: Config.swift, RoutesAccount.swift and Retention.swift on the
box are md5-identical to flamenet-relay HEAD. Production has the signup rate
limit (verified live: five signups pass, the sixth is 429), the reset-token
sweep, and retention logging at a level that is actually visible.
Since the split, deploys rsync from a flamenet-relay checkout,
flamenetmessenger/server/ no longer exists.
Production also runs FN_LOG_LEVEL=error, which suppresses the hourly
retention line entirely. Retention is working, verified by
querying the database directly and finding zero rows past any window, oldest
envelope hours old, but there is no way to see that from the logs, which is
the same unverifiable claim the retention code says it exists to avoid.
4, wired and usable
Three consecutive demo rounds on the managed relay, both directions, with the
group visible each time, DemoRoundUITests plus the Android half. Not run
against the other relay types.
6, documentation
api-docs.relay.flamenet.io now carries a compose file, every environment
variable with whether it is actually required, and curl commands to check a
relay is up. It previously documented the protocol thoroughly and never said
how to start one.
7, public pages
Live and on production keys: sk_live / pk_live confirmed on the
box. Stripe.js loads, the form is present, and the card fields appear after
Continue by design.
Not exercised: a payment taken end to end. Doing so means creating a real PaymentIntent on the live connected account, so it was left alone. Closed on the owner's call. Recorded here rather than dropped, because "we verified the donation page" and "we watched a payment complete" are different claims and only one of them is true.
Found after the baseline
Android silently lost messages. A send to somebody with no registered device, anyone signed out, looped over an empty device list, made no request, and returned an empty failure map, which every caller reads as success. 1:1 text wrote nothing to the thread at all; group text wrote a bubble nobody received. iOS never had this. Fixed, with a regression test proved failing without the guard, and both platforms now hold undelivered messages in an outbox and retry rather than dropping them.
Android → iOS calls do not connect, cause unknown. Ruled out: wire
shapes match, iOS hooks onCallSignal eagerly at sign-in, Android sets no
from_addr so the federated fork is not swallowing it, and every clock agrees
within a second so the 45s staleness check is not misfiring. The real defect
found was that Android discarded the send result entirely, so an offer that
reached nobody was indistinguishable from one that rang. Both sides are now
instrumented; the next attempt will say where it stopped.
iOS conversation history had been written and never merged. The encrypted store sat alone on a parked branch while main moved 174 commits past it, so the app discarded every conversation on quit. Restored and now covered by five tests.
Known gaps at this tag
- iOS push is built and never observed: needs a
.p8and a real device. - Call audio has never been heard by anyone.
- No third-party audit, no reproducible builds, no post-quantum below iOS 26.
FN_DELETE_ON_ACKis off and must stay off until it has an end-to-end test. It deleted a message on production.