Skip to content

ltm: consider rejecting over-arity builtins at the LTM front door to delete the SiteId unaddressable-child machinery #978

Description

@bpowers

Deliberately-deferred design option, recorded so the reasoning does not stay tribal knowledge in a rustdoc. Not a bug report and not scheduled work -- this is an option a future maintainer should weigh when next touching the LTM occurrence IR.

Current design

The LTM occurrence IR (src/simlin-engine/src/db/ltm_ir.rs) identifies each reference occurrence by a SiteId: a path of u16 child indices from the target equation's slot root. Every AST-shaped child count fits a u16 by construction, EXCEPT builtin arity -- MEAN/SUM and friends are variadic, so a call with 65,536+ arguments is representable and would overflow a child index.

That case is handled today by a three-part mechanism (added on branch roundtrips-track-a, commits b0a2a6f0 and d5eed63b):

  1. UNADDRESSABLE_CHILD -- a reserved u16 sentinel that site_child_index never returns.
  2. A suppress_occurrences depth counter on WalkAccum, so an unaddressable child and its whole subtree record no occurrences while STILL recording their per-edge ReferenceSites. The two views are deliberately asymmetric: a missing per-edge entry is defaulted to Bare by consumers, so suppressing the per-edge entry too would misclassify the reference.
  3. ltm_augment::child_path maps an over-arity child to that sentinel with a checked conversion, so the wrap's lookup provably misses instead of aliasing an earlier sibling.

It also leaves behind one documented conflation: db.rs::module_output_ref_in_document_order cannot distinguish a SUPPRESSED module-output occurrence from "the target reads no output of this module" -- both return None and fall through to the signed magnitude-1 black_box_unit_transfer_equation instead of a real ceteris-paribus partial.

The simplification to consider

Reject an over-arity builtin at the LTM front door -- loudly -- instead of threading a sentinel through the IR and the wrap. That would delete:

  • UNADDRESSABLE_CHILD
  • the suppress_occurrences counter on WalkAccum
  • child_is_addressable
  • the sentinel branch in ltm_augment::child_path
  • the module_output_ref_in_document_order conflation

replacing all of it with a single arity check.

Why it was not done now

  • The trigger is unreachable in practice. It needs a builtin call with 65,535+ arguments. Per ltm: link-score generation is quadratic in an arrayed target's element count ((N+1)^2 equation arms per edge) #977, LTM link-score generation is quadratic in an arrayed target's element count -- (N+1)^2 equation arms per edge, measured at 2.3s for N=400 -- so a model anywhere near that scale is already far past where LTM generation is tractable at all.
  • The fallback is an honest approximation, not a plausible-looking wrong number. The module-output conflation falls through to the same explicit signed-unit-transfer approximation that an unlocatable reference has always taken.
  • The existing mechanism is pinned from both sides (producer boundary + consumer sentinel mapping + the ref-site-preservation contract), so it is not fragile -- just more machinery than the case warrants.
  • Cost. Reopening it would spend another implement-and-review cycle on a branch that had already earned its keep.

What a future implementer should check

  • Where the front-door check lives, so BOTH views agree. The per-edge ReferenceSite view currently keeps its entries even for suppressed children. A front-door reject changes that, and consumers default a missing per-edge entry to Bare -- so the reject must be model-level or edge-level, never a silent drop of an individual site.
  • What "reject" means: skip-the-edge-with-a-warning vs. refuse-LTM-for-the-model, and how either interacts with model_ltm_fragment_diagnostics.
  • That deleting the sentinel does not reintroduce the aliasing bug. The entire point of the reserved value is that a path containing it cannot equal any recorded SiteId; an arity check must fail before any path is constructed, not merely truncate.

References

Recorded during roundtrips-track-a review; the maintainer chose to record rather than act.

Metadata

Metadata

Assignees

No one assigned

    Labels

    engineIssues with the rust-based simulation engineltmLoops that Matter (LTM) analysis subsystemtech debt

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions