Skip to content

engine: VECTOR ELM MAP full_source_len has no genuine-Vensim numeric end-to-end test gate (defense-in-depth coverage gap) #579

@bpowers

Description

@bpowers

Problem

The VECTOR ELM MAP opcode's full_source_len field has no genuine-Vensim NUMERIC end-to-end test gate. Its behavior is invisible in the current simulate corpus: a wrong/corrupted full_source_len reaching the VM cannot be caught by any numeric .dat comparison today.

What full_source_len does

Phase 5 of the element-level cycle resolution work (branch clearn-hero-model) added a full_source_len field to the VectorElmMap opcode:

  • Computed in src/simlin-engine/src/compiler/codegen.rs:216 (fn full_source_len), emitted into the opcode at codegen.rs:1126,1131.
  • Consumed in src/simlin-engine/src/vm_vector_elm_map.rs:37 (parameter), used at :47 (full_len) for exactly two things:
    1. the full-array-vs-strict-slice branch threshold, and
    2. the out-of-range [0, full_source_len) -> NaN (:NA:) loud-safe guard.

The gap (verified by TDD red-green investigation)

The genuine-Vensim simulate corpus -- test/sdeverywhere/models/vector_simple/vector_simple.dat and test/sdeverywhere/models/vector/vector.dat -- deliberately has:

  • no out-of-range ELM MAP offset (nothing exercises the [0, full_source_len) -> NaN guard), and
  • no shape that flips the full-array-vs-strict-slice branch.

Therefore an incorrect/corrupted full_source_len reaching the VM is behaviorally INVISIBLE in every end-to-end simulate test: simulates_vector_simple_mdl (tests/simulate.rs:847), simulates_vector_xmile_genuine (tests/simulate.rs:747), and simulates_arrayed_models_correctly (tests/simulate.rs:704). The bug-fixer empirically proved this: hard-forcing full_source_len = 999 in renumber_opcode left all three simulate tests passing while the symbolic unit test correctly failed.

Current coverage of full_source_len (sound but structural-only)

  • Symbolic round-trip is guarded by two #[cfg(test)] unit tests in src/simlin-engine/src/compiler/symbolic.rs:
    • test_renumber_vector_builtin_temp_ids (symbolic.rs:2943) -- isolated renumber invariant.
    • test_vector_elm_map_full_source_len_survives_fragment_roundtrip (symbolic.rs:2983) -- exercises the real concatenate_fragments -> renumber -> resolve merge path.
  • The strict-slice carried-axis invariant has a debug_assert! at vm_vector_elm_map.rs:74.

These are sound and sufficient for the renumber/structural invariants (full_source_len is absolute, not a temp id, and must survive symbolize -> fragment-merge -> renumber unchanged).

THE GAP: there is no NUMERIC end-to-end (genuine-Vensim .dat) gate that would catch a wrong full_source_len actually reaching the VM and producing a wrong OOB->NaN decision or a wrong full-array/strict-slice branch decision. A regression in the full_source_len computation (codegen) or its VM consumption that only manifests as a wrong OOB/branch decision (not as a renumber-invariant violation) would pass the entire corpus.

Why it matters

Phase 6/7 of the element-cycle-resolution plan finalize C-LEARN, which exercises the full incremental + LTM compile path. full_source_len gates the loud-safe :NA:/NaN behavior of VECTOR ELM MAP. The symbolic round-trip is unit-guarded, but a computation or VM-consumption regression that manifests only as a wrong OOB/branch decision would not be caught by any numeric corpus gate.

Low severity today -- the field is correct and unit-guarded for the renumber invariant. This is a real defense-in-depth coverage gap on a value that gates loud-safe behavior, not a live correctness bug.

Components affected

  • src/simlin-engine/src/vm_vector_elm_map.rs:37,47,74 -- full_source_len consumption + the carried-axis debug_assert!
  • src/simlin-engine/src/compiler/codegen.rs:216,1126,1131 -- full_source_len computation + opcode emission
  • src/simlin-engine/src/compiler/symbolic.rs:2943,2983 -- the two existing (structural-only) unit tests
  • test/sdeverywhere/models/vector_simple/vector_simple.dat, test/sdeverywhere/models/vector/vector.dat -- genuine-Vensim fixtures that lack any OOB / branch-flip shape
  • src/simlin-engine/tests/simulate.rs:704,747,847 -- the three simulate tests blind to full_source_len corruption

Possible approaches

Add a genuine-Vensim VECTOR ELM MAP fixture (.mdl/.xmile + hand-computed .dat, ideally cross-checked against real Vensim DSS) that exercises:

  • (a) an offset that lands out of the full source range (expected :NA:/NaN per Ventana docs), and/or
  • (b) a shape that flips the full-array-vs-strict-slice branch,

wired into the simulate corpus so full_source_len corruption (in codegen computation or VM consumption) is caught end-to-end numerically, complementing the structural symbolic unit tests.

Context

Discovered during the Phase 5 code-review fix cycle of the element-level cycle resolution work (branch clearn-hero-model; hardening commit bceeb949 on top of Phase 5 fold 889bfb89). The invisibility was empirically proven via a TDD red-green investigation (hard-forcing full_source_len = 999 in renumber_opcode: all three simulate tests stayed green, only the symbolic unit test went red).

Distinct from #576 (dormant 2-D VECTOR SORT ORDER fixture / unverified multi-dim VSO semantics -- different builtin and concern), #577 (docs/README.md plan-dir index gap -- docs only), and #578 (scalar-source + arithmetic-offset ELM MAP compile failure / shape inference -- a compile-time gap on a different code path; this issue is a numeric runtime test-coverage gap on the full_source_len opcode field specifically).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions