Commit graph

4 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
Shay
3d7d583d83 feat(adr-0250): 2b certified summation turn — full dev holdout 50/50 wrong=0
A total-like unknown (unknown.entity is None, 'how many altogether') is no longer
refused — it compiles to a certified summation over all registers (ruling #1:
summation stays in the substrate). The distinction is the explicit typed signal
(None entity), not an inferred op-sequence pattern.

Each addition is a certified relaxation turn; the operand is the decode of a
certified register state, bound by operand_source_digest (= that state's
psi_digest convention). Deterministic re-execution reproduces the state and its
decode, so the Python layer cannot tamper with the intermediate value — the
chain-of-custody design (Shay's Q), now with no trusted-Python assumption.
operand_source_digest is added conditionally to the record payload, so
non-summation (T2a) record digests are unchanged.

Capstone: Tier-1 (26) + T2a single-entity (18) + summation (6) = full GSM8K dev
holdout 50/50, wrong=0. The reader->Hamiltonian compiler now solves the entire
dev holdout by chained certified relaxation, zero wrong answers.

16/16 pins green (11 multi-register updated + 5 summation incl. capstone).

[Verification]: uv run python -m pytest tests/test_adr_0250_multi_register.py tests/test_adr_0250_summation.py -q
2026-07-18 14:25:44 -07:00
Shay
87f87c9b21 feat(adr-0250): T2a multi-register executor (multi-entity arithmetic)
Multi-entity arithmetic as a product of independent conformal lines: one
register (null point) per entity; per-register affine ops reuse Tier-1 transport;
transfer = coupled T-k/T+k on disjoint registers (exact by P1 per-line exactness).

Transactional atomicity: immutable register mapping, prepare->validate->commit —
both candidate states relaxed into locals, validated (both converged AND
conservation), then a NEW mapping only on full success. Failure anywhere = new
mapping never built, original untouched (no partial mutation, no rollback); abort
raises typed MultiRegisterError and aborts the whole program (fail-closed).

Conservation pin = hard-reject, RELATIVE (|after-before| <= rtol*max(1,|before|)):
decoded-quantity error scales with magnitude (found via gma-050 chaining to 222),
so absolute tol is wrong; relative still catches real violations (off by whole k).

Content-addressed MultiRegisterRecord chain carries entity + certificate id +
step, never a decoded value; GENESIS-linked; verify_multi_register_chain mirrors
verify_replay_chain. Tier-2a fail-closed taxonomy: total-unknown (needs summation
= 2b), derived operand, non-affine kind, non-positive scale, unit mismatch,
unknown endpoints. Off-serving (A-04).

REAL GSM8K single-entity refused holdout: 18/18 solved wrong=0 (26/50 -> 44/50).
11/11 pins green.

[Verification]: uv run python -m pytest tests/test_adr_0250_multi_register.py -q
2026-07-18 14:13:55 -07:00