Skip to content

DRAFT: LISA ILE driver — AV + --internal-use-lnL was a silent no-op (stacked on #101) - #102

Closed
oshaughnessy-junior wants to merge 1 commit into
claude/lisa-av-statefrom
claude/lisa-av-use-lnL
Closed

DRAFT: LISA ILE driver — AV + --internal-use-lnL was a silent no-op (stacked on #101)#102
oshaughnessy-junior wants to merge 1 commit into
claude/lisa-av-statefrom
claude/lisa-av-use-lnL

Conversation

@oshaughnessy-junior

Copy link
Copy Markdown
Owner

Draft. Stacked on #101 (→ #100#99#98).

This is a pre-existing LISA defect, not one the catch-up introduced — the catch-up is what made it worth finding. Kept as its own PR so it can be reviewed or dropped independently of the ports.

What

The main driver has:

if opts.sampler_method =="AV" and opts.internal_use_lnL:
    return_lnL=True
    pinned_params.update({"use_lnL":True})

with the comment: "without this, --internal-use-lnL --sampler-method AV passed the ok_lnL_methods check but silently did nothing, so exp(lnL) overflowed at high SNR when no logarithm offset was set."

The LISA driver had branches for GMM, adaptive_cartesian_gpu and portfolio — and none for AV.

High SNR is the LISA MBHB regime, so this is the case rather than an edge, and it matters more now that the preceding passes push AV and portfolio into LISA production.

⚠️ Behaviour change for anyone already running --sampler-method AV --internal-use-lnL on this driver: they were silently getting the linear-integrand path and will now get the log-space one the option asks for.

Why the drift gate could not see it

A missing if branch is not a FUNC, OPTION, CONST or ATTR, so it produces zero gap items. The audit is a name-presence set difference — behaviour behind a shared name is invisible to it. That limitation is now documented in LISA_DRIVER_DRIFT.md (in #99), and test_lisa_use_lnL_branches.py closes this particular hole by extracting the per-sampler pinned_params branch table from both drivers and comparing them.

The table comparison immediately earned itself: it shows the portfolio branch still differs by exactly the three --internal-gmm-* forwards (gmm_adaptive, gmm_defensive_frac, gmm_inflate) — the deferred GMM pass. That delta is asserted exactly rather than skipped, so any other divergence still fails and the test tightens by itself when the GMM pass lands.

Revert-checked: removing the AV branch fails test_AV_sets_use_lnL_under_internal_use_lnL and test_branch_table_matches_the_main_driver[AV]; file restored byte-identical.

Reported, not silently patched

Two related items the audit raised that this PR does not fix, because both are judgement calls rather than mechanical ports:

  1. Lines ~2423 and ~3145 read sampler._rvs["integrand"] unguarded (the neighbouring argmax reads are guarded). Under AV that key can be absent, so --maximize-only would KeyError. What those lines should print instead is your call.
  2. sampler.ntotal is not carried by _snapshot_pass_state, so a rejected warm pass reports cold lnZ beside the warm pass's ntotal. Identical in the main driver, so it is a shared defect rather than drift.

🤖 Generated with Claude Code

Found by adversarial audit, NOT by the drift gate.  The main driver has:

  if opts.sampler_method =="AV" and opts.internal_use_lnL:
      return_lnL=True
      pinned_params.update({"use_lnL":True})

with the comment "without this, --internal-use-lnL --sampler-method AV passed the
ok_lnL_methods check but silently did nothing, so exp(lnL) overflowed at high SNR when no
logarithm offset was set."  The LISA driver had branches for GMM, adaptive_cartesian_gpu
and portfolio -- and none for AV.

High SNR is the LISA MBHB regime, so this is the case rather than an edge, and it matters
more now that the preceding passes push AV and portfolio into LISA production.

This is a PRE-EXISTING defect, not one the catch-up introduced; the catch-up is what made
it worth finding.  It is also a behaviour change for anyone already running
--sampler-method AV --internal-use-lnL on this driver: they were silently getting the
linear-integrand path, and will now get the log-space one the option asks for.  Kept as its
own commit and its own PR so it can be reviewed or dropped independently of the ports.

WHY THE DRIFT AUDIT COULD NOT SEE IT.  A missing `if` branch is not a FUNC, OPTION, CONST
or ATTR, so it produces zero gap items.  The audit is a name-presence set difference:
behaviour behind a shared name is invisible to it.  That limitation is now documented in
LISA_DRIVER_DRIFT.md, and test_lisa_use_lnL_branches.py closes this particular hole by
extracting the per-sampler pinned_params branch TABLE from both drivers and comparing them.

The table comparison immediately earned itself: it shows the portfolio branch still differs
by exactly the three --internal-gmm-* forwards (gmm_adaptive, gmm_defensive_frac,
gmm_inflate), which are the deferred GMM pass.  That delta is asserted EXACTLY rather than
skipped, so any other divergence in that branch still fails and the test tightens by itself
when the GMM pass lands.

Revert-checked: removing the AV branch fails test_AV_sets_use_lnL_under_internal_use_lnL
and test_branch_table_matches_the_main_driver[AV]; file restored byte-identical.

Two related items the audit raised and this does NOT fix, both reported rather than
silently patched:
  * bin/..._lisa lines ~2423 and ~3145 read sampler._rvs["integrand"] UNGUARDED (the
    neighbouring argmax reads are guarded).  Under AV that key can be absent, so
    --maximize-only would KeyError.  What those lines should print instead is a judgement
    call, not a mechanical port.
  * sampler.ntotal is not carried by _snapshot_pass_state, so a rejected warm pass reports
    cold lnZ beside the warm pass's ntotal.  Identical in the main driver, so it is a shared
    defect rather than drift.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant