feat(diagnostics): close the psense refit gap and diagnose the last two holdouts (#381) - #452
Open
frankbuckley wants to merge 1 commit into
Open
feat(diagnostics): close the psense refit gap and diagnose the last two holdouts (#381)#452frankbuckley wants to merge 1 commit into
frankbuckley wants to merge 1 commit into
Conversation
…wo holdouts Refits the 21 fits whose traces predated the log_prior/log_likelihood wiring, so power-scaling could not be reconstructed from their draws. Coverage goes from 170 to 192 of 194 reporting fits. The refits overwrote 19 published mediation and measurement fits, so the first check was whether anything moved. Nothing did: the mediation headlines reproduce the values already quoted in #404 and the findings notes (med-066 NIE_B -0.030 words, med-074 proportion mediated 0.7%), and the three rli-mm models reproduce their documented gate failures to the digit against the 2026-07-21 findings note. That exact reproduction across a two-week gap and the dse-research-utils v0.8.0 bump is a reproducibility check the suite had not previously run. Also wires psense into fit_rlm_joint_growth, which #416 missed. That family is compute_loo=False, so the sampling stage does not attach the groups psense needs and they have to be requested explicitly. The refit shows the real obstacle is not an intractable likelihood: the model draws pm.LKJCorr("measure_corr_chol"), deliberately chosen over LKJCholeskyCov, and PyMC stores the transformed value variable as "measure_corr_chol_cholesky" while the free RV keeps the base name. compute_log_prior and compute_log_likelihood both require an exact name match, so both refuse. That is a naming seam, plausibly fixable, and reconciling it reaches beyond psense coverage — left as a follow-up. The value of the wiring is that the absence is now diagnosed with a specific error rather than silent. rlm-mm-001 remains the one true exemption (non-converged posterior). Note corrected: it had listed rlm-jc-001 as a refit gap when it was a code gap. Refs #381, #383 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
Drafted by an LLM-based AI tool (Claude Code/Opus 5).
Follow-on to #442, which backfilled power-scaling sensitivity for every fit whose stored trace could support it (86 → 170 of 194). This closes the remainder: the fits whose traces predated the
log_prior/log_likelihoodwiring, where power-scaling genuinely could not be reconstructed without resampling.Coverage: 170 → 192 of 194.
The refits
Twenty-one fits refitted at
--config reporting— themedfamily (18) and all threerli-mm— through a resumable per-model driver rather than oneallinvocation. That mattered: the sweep was reaped partway through, and resuming skipped the completed models and cost only the fit that was in flight. TheOutputTransactionstaging design also held up exactly as intended — the killed fit left its published directory intact and its partial work in an abandoned hidden sibling.These overwrote 19 published fits, so the first check was whether anything moved
Nothing did.
Mediation headlines reproduce the values already quoted in #404 and the findings notes:
med-066NIE_B −0.030 words,med-075−0.033,med-074proportion mediated 0.7 %.The three
rli-mmmodels reproduce their documented gate failures to the digit, againstnotes/202607210914-findings-measurement.md(2026-07-21, five days before the refit):mm-001mm-002mm-101Those failures are pre-existing and documented, with the structural legs already on HOLD under the measurement-model policy. Worth noting the exact reproduction is itself a check the suite had not previously run: identical numbers across a two-week gap and the
dse-research-utilsv0.8.0 bump in #437.One consequence for reading the new artefacts: those three fits flag ~96 % of their parameters (168/176, 170/179, 169/176), which corroborates #383's diagnosis that
HalfNormal(1)on loadings-and-residuals puts ~32 % of prior mass on loadings > 1. But they fail the gate, so the reasoning that exemptsrlm-mm-001applies here too — read it as corroboration of #383, not as an independent measurement.rlm-jc-001: a code gap, then a diagnosed naming seam#442's note listed this among the fits needing a refit. That was wrong, and the correction is in this PR.
fit_rlm_joint_growthcalls_run_sampling_and_loo(ctx, compute_loo=False)and never calledcompute_log_likelihood_and_priororrun_psense— #416 added that wiring tofit_mediationandfit_correlated_factorbut not to this family. A refit alone would have burned sampling time and produced nothing.With the wiring added, the refit shows the real obstacle, which is neither what the note assumed nor what I expected before running it:
The model draws
pm.LKJCorr("measure_corr_chol", ...)— chosen deliberately overLKJCholeskyCovto avoid its unidentified nuisance sd scales (factories.py:6315-6319) — and PyMC stores the transformed value variable in the posterior asmeasure_corr_chol_choleskywhile the free RV keeps the base name.compute_log_priorandcompute_log_likelihoodboth require an exact name match, so both refuse; the prior group is blocked as well as the likelihood group.That is a naming seam, not an intractable likelihood, so it is plausibly fixable rather than an intrinsic exemption. Reconciling the LKJCorr value-variable name across the
compute_log_*seam reaches well beyond psense coverage, so it is left as a follow-up. The value of adding the wiring is that the absence is now diagnosed with a specific error instead of being silent — which is the same distinction #381 exists to make.rlm-mm-001remains the one true exemption #381 already records: a non-converged posterior, where a sensitivity diagnostic would not mean anything.Changes
pipeline.py—fit_rlm_joint_growthgainscompute_log_likelihood_and_prior(ctx, strict=False)+run_psense(ctx, var_names=diag_vars), with a comment recording whystrict=Falseis right for acompute_loo=Falsefamily.notes/202607261700-psense-coverage-backfill.md— headline updated to 192/194; new closing section recording the refits, the no-change verification, and therlm-jc-001correction.Verification
ruff check src/,npm run format:check,npm run spellcheckclean.regenerate_psense.py all --dry-runnow reportsneeds refit: 2, present: 192.What remains on #381
prior_pushforwardacross the estimand-reporting families (142 fits) is still blocked on a per-family decision about what the estimand-scale check is for a curve, a ranking or a correlation — #446 is establishing the pattern for the families where it is well-defined. The indicator-scale prior-predictive check forlcf/mm/rlm-mmhas not been started.Refs #381, #383
🤖 Generated with Claude Code