Commit graph

2 commits

Author SHA1 Message Date
Shay
260e56ca5c feat(reader-arc): compare compiler-side guards for inverse + chained shapes
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
2026-07-18 17:14:16 -07:00
Shay
9136c1819b feat(reader-arc): compare_multiplicative compiler tier (increment 1, compiler half)
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
2026-07-18 16:35:09 -07:00