Files
flamenet-messenger-android/app
Paul HittandClaude Opus 5 9ced7dc3f0 All three deployment shapes, and the one that was unreachable
"Self-hosted with shared identity" could not work. Both clients decided where
accounts lived from a hardcoded list of relay hostnames, and a stranger's relay
is never on that list -- so somebody self-hosting could have the shared FlameNet
account service configured on their relay and the app would still authenticate
against the relay itself. Mode 2 existed on the server and nowhere else.

The relay already published the answer at `/.well-known/flamenet/relay`:
`accounts: shared|local` and the service URL. Nothing read it.

Now the client asks, and then checks the answer against a pinned list of account
SERVICES rather than of relays. That keeps the property the hostname list was
protecting -- an operator cannot point their users' passphrase-derived secrets
at a host they control, because a service the client does not already trust is
treated as local -- while letting any relay adopt the shared service. Unknown or
unreachable descriptor also means local, which is the safe direction: the
passphrase goes only to the server the user typed in.

relay2 is now configured as that third shape, so all three exist to test:
managed (relay.flamenet.io), self-hosted shared (relay2), self-hosted local
(relay1, relay3).

`LiveShapesTest` covers sign-up three rounds per shape, a conversation per
shape, that each relay reports what it actually is, and that a relay naming an
untrusted account service is refused. Fresh handles every round, so rounds are
repeatable by construction rather than by cleanup.

⚠️ Two things worth keeping:

Skips are announced. `return` from an unmet precondition makes a test that did
nothing report PASSED -- I had four of those reporting green before switching to
`assumeTrue`, which is the same silent-skip trap I had already criticised in the
Swift interop harness. A suite of silent skips is indistinguishable from a suite
that works.

The handle travels beside the shared-session token, never inside it. The account
service will not put a handle in a token, so a relay cannot correlate its users
with another product's; the relay keys on the product-scoped pseudonym and uses
the handle only the first time it sees one. Tested by signing in twice and
asserting the same relay account comes back.

Also deploys the discovery-document fix to relay.flamenet.io, with a database
backup and a rollback image. The transparency-log root is byte-identical after
the deploy.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-24 05:28:15 -04:00
..