Two shapes (PR ruling) pinned compiler-side with tests — reader direction errors
surface as refusals, never wrongs:
- Chained / ordering: a compare whose reference is neither seeded nor
already-defined at that point refuses (compare_reference_not_a_register).
Pinned explicitly with a test (story order != dependency order), not left to
fall out of existing checks.
- Inverse mis-direction: a compare that would DEFINE an already-known (seeded or
earlier-defined) register refuses (compare_redefines_register) — the reader
must bind the unknown side as the target with a fraction factor; the compiler
never overwrites a known quantity.
The 5 real compare cases still solve wrong=0. 27/27 (2 new guards + 25).
[Verification]: uv run python -m pytest tests/test_adr_0250_compare.py tests/test_adr_0250_multi_register.py tests/test_adr_0250_summation.py -q
Cross-register affine definition: actor := factor x reference. Reads the
reference register's field STATE, dilates by -ln(factor), writes the actor.
Reuses quantity_kernel + the multi-register framework + the 2b summation.
Amendments (PR #76):
1. Summation registers-driven: MultiRegisterProgram.register_order (seed order
then compare-defined order); execute sums ALL registers in that order, so a
compare-DEFINED register (no seed) is included in totals. compile validates
the answer target AFTER ops (a concrete unknown may be compare-defined) and
propagates the defined register's unit from the reference.
2. Compare record: RegisterTurn.reference; MultiRegisterRecord.source_entity
(the reference) + operand_source_digest (reference state digest), both
CONDITIONAL in the payload so affine/transfer/summation record digests are
byte-identical to before compare. Re-verification reconstructs the source
register from records alone.
Compare CREATES a quantity (not a transfer) -> exempt from the conservation pin.
fraction direction folded in (factor < 1). compare_additive is a later increment
(refused). Real official data: the 5 compare parses the reader emits today now
solve end-to-end wrong=0 -> corridor real-reach 0/500 -> 5/500 (loop-works proof).
25/25 (9 new + 16 existing regression, digests byte-identical).
[Verification]: uv run python -m pytest tests/test_adr_0250_compare.py tests/test_adr_0250_multi_register.py tests/test_adr_0250_summation.py -q