Files
zeekay c328b4f785 The differential counted its gaps and would not say where they were
DECLINED said "cpp 13 of 3625 fields, rust 12 of 3625". Nobody could act on
that. Which vector, which chain, which field and why were computed and thrown
away, so the one number anyone quoted about parity named nothing.

It names them now: every declined field, gathered by implementation, by the
label the corpus files the vector under, by field, and by the reason the port
printed. Grouping is the point — twelve declines under one heading are one gap,
and twelve headings are twelve. Nothing is elided; a list that stopped at six
would be the count again, wearing examples.

The label is the column after the id, which every corpus here already writes:
the chain for the chain corpus, the address for the precompile one. It is the
only thing past the id this program reads, and a vector line without one is now
refused rather than filed under the empty string.

What the naming turned up, in the Q-chain's Rust evaluator: four blocks whose
reason was not about the field they declined. It refused `exec` after its
syntactic pass had already refused the block, and left the syntactic message
behind as the reason. But a refusal reached before the first read of the store
answers BOTH fields — that is the corpus's own rule, in conformance/README.md
under "`syntactic` where verify is one pass" — so the answer was in hand and it
declined anyway. Now it writes the verdict down twice, which is what Go and C++
already did: Q_GENESIS, Q_BLOCK_EMPTY, Q_BLOCK_FOREIGN_CHAIN and
Q_BLOCK_FOREIGN_NETWORK now read SYNTACTIC in all three. The run stays green,
which is the check on the change: had the propagated verdict been the wrong one
it would have met two implementations that disagree.

Rust declines 12 fields, then 8. The gap is 25, then 21, and every one of the
21 has a name.
2026-09-07 19:25:30 -07:00
..