A signed card says who made it and what its seed earns. The machine that receives it does not take its word — it grows the seed itself and only accepts the card if the score comes out the same. A signature proves who. Only a re-run proves what.
Your machine grows the seed on its own copy of the data, then signs only the score it actually got.
No signalling server: one of you makes an invite, sends it however you already talk, and pastes back the one reply.
Send this invite to the other machine:
Paste their reply here, then connect:
Paste the invite you were sent:
Send this reply back:
Send yours — and, to see the refusals for yourself, a copy with one byte changed, or a perfectly signed card that claims a score it did not earn (the false claim is signed with a throwaway demo key, never yours).
Growing a seed takes about a hundred evaluations — slow on a phone. Hand the job to the connected machine: it grows the seed, keeps the result only if it beat the ungrown version, and sends back a signed answer. This machine then checks the answer by re-running it — about a hundred times cheaper than growing it. The job is signed and addressed to that one machine only.
A card can grow. Stage 0 is the ungrown starting model. Each stage after it is grown on the holder's own machine, from the stage before, with a seed number tied to the holder's key — and it only counts if it beats the starting model and every stage before it on a fresh check. The whole history rides on the card, and any machine that holds it re-runs every stage before it believes one. So a stage can't be claimed, copied or bought — only grown.
What it does not prove: where a stage was grown (only that it was grown for that key, reproducibly); that a stage is the best model, or useful beyond this one public task; and the held-out score can fall while stages rise — it is shown, never used to decide.
Each one is checked here: the signature, then whether this machine holds the same data, then a re-run of the seed.