Commit Graph
6 Commits
Author SHA1 Message Date
Paul HittandClaude Fable 5.1 4f0f90b4cd The e2e pin moves in step with the iPhone app
Both apps pinned the same flamenet-e2e commit, from before the backup
payload vector widened, and this one's CI has been checking the engine
against that old vector while a developer's machine reads the sibling
checkout at HEAD. The pin moves to HEAD; engine and client pass with the
vector variables pointed there the way the job points them, 1105 of
1105.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-09-17 07:39:32 -04:00
Paul HittandClaude Opus 5 393205ca85 Take the e2e spec update
The pin was nine commits behind, all of them spec: off the record, anonymous
polls, handing a call to another device, the private-reaction flag and the
call-reaction kind, a call answered on one device stopping the others, and
the harness fix that reads a page's stylesheet href rather than naming the
file.

No vector moved, so AccountKdfTest, PQVectorTest and PublishedVectorsTest
check the same bytes they did before. This accepts no protocol change.

flamenetmessenger pins the same commit and moves in step.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-12 16:14:56 -04:00
Paul HittandClaude Opus 5 19add570cb Check the content envelope against envelopes the iPhone emitted
The content layer had no vectors. Everything from section 6.6 onward was
guarded only by same-code round trips: this engine encodes and parses
through its own codec and would pass unchanged if it and the iPhone
disagreed about every key. That is how SPEC 6.18 specified `ment` for as
long as it has existed while both clients have always sent `men`.

`content-v1.json` holds fifteen envelopes generated by RUNNING the
iPhone's encoders, and this suite parses each one and asserts field by
field. "It did not crash" is what the old tests already proved.

One of them pins something easy to get wrong twice: the iPhone writes
`fwd` as the integer 1, not as `true`, and `optBoolean` does not coerce a
number. A parser reading only the boolean answers false and the message
quietly loses the fact that it was passed on.

The suite also fails if the vector file grows a case nobody asserts on.

Separately, and the reason any of this is trustworthy: the test task did
not track the vector files at all. They arrive by environment variable,
Gradle does not track one as an input, so a vector could change under a
build directory that already had results and the task reported
UP-TO-DATE without running. That is not hypothetical here, it is how
twenty vector tests once passed in CI for weeks without executing, on
this same runner, whose build directory survives between runs. All six
vector files are now declared inputs.

Proven rather than asserted: with the inputs declared, flipping `men` to
`ment` in one vector turns the suite red without `--rerun-tasks`. Before
the fix the same change left it UP-TO-DATE and green.

Full suite: 1294 tests, no failures.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11 07:20:17 -04:00
Paul HittandClaude Opus 5 fb68878752 Check the backup payload against the published vector
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>
2026-09-10 19:43:33 -04:00
Paul HittandClaude Opus 5 a70787e960 Hand CI the backup vectors it was never given
The §16 backup port shipped with a vector suite that finds its input by
walking relative paths out of the checkout. That works on a developer's
machine, where flamenet-e2e sits beside this repo, and cannot work on
the runner, where it does not.

The suite fails rather than skips, deliberately, so it said so: nine
BackupVectorTest failures on every pipeline since the port merged, on
main included. Two things were missing, and both had to be fixed or the
gate would have stayed red.

The pin predates the vectors, so `unit-tests` cloned a flamenet-e2e that
has no backup-v1.json in it. Bumped; nothing else under test/vectors
moved between the two commits, so no other suite changes what it checks.

And neither job exported FLAMENET_BACKUP_VECTORS, so even the job that
clones HEAD, which did have the file, never pointed the suite at it. It
is exported in both now, and named in the pre-flight check, which is
there precisely so a missing file reads as a missing file rather than a
protocol bug.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-10 08:39:25 -04:00
Paul HittandClaude Opus 5 625b4516c7 Pair the e2e pin with a loud advisory at HEAD
I pinned the vector clone earlier today on flamenet-relay#56's evidence,
and stopped a step short. flamenet-relay did not: it pins AND keeps
`conformance-head` / `doc-pages-head` running against HEAD with
`allow_failure: true`, and its `.e2e-ref.md` says why in a sentence I had
read and not acted on — "a relay tested against a pinned old harness is
tested against a pinned old spec, and that argument still holds."

A pin alone is worse than HEAD for exactly that reason. HEAD couples this
board to another repository's merges; a bare pin means the vectors can
move and this suite goes on checking last month's protocol, reporting
green, with nothing anywhere saying so. The first failure is loud and
wrong; the second is quiet and wrong, and quiet is worse in a conformance
suite whose whole job is to notice a divergence.

So: `.e2e-ref` holds the commit, `unit-tests` checks against it and
blocks, and `vectors-head` runs the same vector suites against HEAD and
is allowed to fail. Being behind is loud and non-blocking. Being broken
is still a hard stop.

Verified it would actually notice, rather than assuming — pin and HEAD
are the same commit today, so a green advisory run proves nothing. With
one expected value in `account-kdf-v1.json` mutated, `AccountKdfTest`
reddens. `.e2e-ref.md` records the procedure and the deadlock story
behind it.

⚠️ `vectors-head` runs `:engine:test` only. The rest of the suite has
nothing to say about whether flamenet-e2e moved.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 17:21:44 -04:00