Both apps were taught one backup shape and nothing checked that they
agreed. Each side's tests asserted against what the OTHER was believed
to write, transcribed by hand from reading its source, which is a test
of one person's reading rather than of interoperability.
`backup-payload-v1.json` in flamenet-e2e is now the authority, and the
bar it sets is exact: decode the canonical payload, encode it again, and
the result must match byte for byte once both are put in a canonical
order. The same vector is checked on the iPhone, so the two are
compared against one file rather than against each other's source.
One real fix came out of writing it. `messageFromShared` wrote
`author` unconditionally, so a one-to-one message that carried no author
came back claiming user zero sent it, and a round trip through this app
changed the file. Storage keeps an author on every message and reads a
missing one as 0, so it is now written only when the file carried one.
The env var is exported in BOTH ci jobs, the pinned one and the one that
runs at vectors HEAD, and added to the gate that checks every vector
file exists before the suite runs. A path that silently does not exist
puts the tests back where they were and the failure reads as a protocol
bug rather than a missing file. `.e2e-ref` moves to the commit that adds
the vector.
Full suite: 1279 tests, no failures. `ci/lint` accepts the pipeline.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>