Skip to content

ltm: bare-spelled feeder of un-hoisted multi-source reducer gets silent wrong changed-last loop score (per-element partial vs broadcast execution) #779

Description

@bpowers

Summary

The BARE-spelled feeder of an un-hoisted multi-source reducer gets a silently wrong (unwarned, sustained) loop score from the GH #743 changed-last partial: the partial compiles per-element while the executed equation broadcasts the bare reference.

Fixture:

D1 = {a, b}, D2 = {c, d}
matrix[D1, D2]                            -- co-source
frac                                      -- feeder, referenced BARE (unsubscripted)
growth[D1] = SUM(matrix[D1, *] * frac)    -- execution iterates the bare frac over D1
... feedback loops closed through matrix and through frac

This is the unfinished bare-spelling sibling of #743, whose fix covered the SUBSCRIPTED feeder spelling frac[D1] (now fully hoisted by the T5 feeder-sub-slice acceptance, #767).

Mechanism

  1. The bare frac reference classifies all-Reduced -- the read-slice vocabulary cannot express a bare iterated read (a reference that execution iterates over the owner's A2A dimension without a subscript). Verified byte-identical pre/post T5 at commit bcb89565 on branch ltm-shape-phase1: this is PRE-EXISTING, not a T5 regression.
  2. Because the slices disagree, the reducer stays un-hoisted. The matrix-closure loops land on the LOUD degraded path (5 fragment warnings + 0-stubs) -- that half is fine.
  3. The frac-closure loop falls to the ltm: un-hoisted multi-source iterated-dim-feeder reducer emits silent garbage arrayed loop score (combined_read_slice slice-disagreement carve-out) #743 changed-last fallback partial, sum(matrix[d1,*] * PREVIOUS(frac)), which compiles per-element -- while the executed growth equation broadcasts the bare frac across all D1 rows (in the probe, growth_0 = 10 = the sum of all 2x2 terms).
  4. Result: a sustained, UNWARNED loop score of ~2.92 for the frac-closure loop, internally inconsistent with the four co-source loop scores of +1 each.

Why it matters

Severity: low-medium. This is a silent wrong number (~3x) for a natural spelling of a common shape (per-row total = SUM(row * shared coefficient) with the coefficient written bare), violating epic #488's standing "no silent wrong numbers" invariant. The subscripted spelling frac[D1] is now fully correct after T5/#767, so users hitting this have an easy workaround they don't know they need.

Components affected

  • src/simlin-engine/src/ltm_agg.rs -- read-slice classification (compute_read_slice / combined_read_slice): no vocabulary for a bare iterated read
  • src/simlin-engine/src/ltm_augment.rs -- the changed-last chooser accepts the bare-feeder shape and emits a per-element partial that disagrees with the executed broadcast
  • src/simlin-engine/src/db/ltm/link_scores.rs -- the emitted frac-closure loop score

Possible approaches

  • Teach the slice vocabulary a bare iterated read (likely the right fix): classify the bare feeder reference the way execution treats it -- iterated over the owner's A2A dim -- so T5's feeder-sub-slice acceptance covers it and the reducer hoists exactly like the frac[D1] spelling. Cf. how classify_iterated_dim_shape already treats bare refs as Bare/diagonal.
  • Or have the changed-last chooser decline the bare-feeder shape loudly (warning + 0-stub), restoring the no-silent-wrong-numbers invariant without the hoist.

Discovery context

Demonstrated by a reviewer during T5 review of the LTM shape-expressiveness phase (branch ltm-shape-phase1, commit bcb89565). Verified byte-identical pre/post T5 -- pre-existing, out of scope for that phase.

Tracking

Part of LTM tracking epic #488 (cluster A) and the array-support umbrella #273. Related: #743 (the subscripted-spelling sibling, fixed -- its changed-last fallback is the partial that goes wrong here), #767 (the feeder-sub-slice hoist extension that fixed the subscripted spelling's co-source closure, closing via the shape-expressiveness phase PR).

Metadata

Metadata

Assignees

No one assigned

    Labels

    ltmLoops that Matter (LTM) analysis subsystem

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions