Skip to content

Implement final adversarial statistical audit - #6

Open
rickyjreyes wants to merge 25 commits into
mainfrom
agent/final-adversarial-stat-audit
Open

rickyjreyes wants to merge 25 commits into
mainfrom
agent/final-adversarial-stat-audit

Conversation

@rickyjreyes

@rickyjreyes rickyjreyes commented Sep 7, 2026

Copy link
Copy Markdown
Owner

Goal

Implement the strict final adversarial statistical audit for the NIST atomic-line analysis without changing the canonical scanner.

What changed

  • Adds R/run_final_adversarial_audit.R, a fail-closed one-command final runner with explicit full-resolution budgets and no hidden 500/1,000-trial caps.
  • Adds R/run_alternative_nulls.R with five scan-global null stress tests:
    • canonical fixed-baseline Poisson,
    • baseline-refit Poisson,
    • conditional multinomial,
    • overdispersed negative binomial,
    • block-residual/baseline-misspecification diagnostic.
  • Expands R/global_multiple_testing.R from the old limited family to the complete declared Fe preprocessing multiverse plus source and neighbouring-ion controls.
  • Corrects dependence language: Holm/Bonferroni do not require independence; adds Benjamini-Yekutieli FDR for arbitrary dependence while retaining BH and the approximate family-max calibration.
  • Hardens frozen holdouts: k remains train-only and locked, while test-null calibration is now computed both with the observed smoothing baseline fixed and with the smoothing baseline re-estimated in every null replicate. The final holdout verdict uses the larger p-value.
  • Adds R/build_final_adversarial_summary.R to emit conservative global evidence, strict claim-by-claim verdicts, and failed_claims.csv containing every non-passing claim.
  • Adds a dedicated Quarto report and run documentation.
  • Adds fast R tests for null helpers, holdout/refit behavior, failure-preserving verdict logic, and source/parse safety of the final entry points.

Final default budgets

  • bootstrap: 5,000
  • primary scan/null: 5,000
  • observed/Ritz bootstrap: 2,000
  • specification null per specification: 1,000
  • frozen holdout null per design/calibration: 5,000
  • full-family max null: 5,000
  • outer null calibration: 10,000
  • injection/recovery: 2,000 per amplitude/frequency
  • injection decision null: 5,000
  • alternative null: 5,000 per model

Failure preservation

The final claim matrix deliberately does not soften negative results. For example:

  • bin stability below the audit-declared 80% threshold is fail, not silently promoted;
  • partial frozen-holdout success is mixed;
  • negative held-out M1-vs-M0 predictive transfer is fail even when the in-sample fit is very strong;
  • independent experimental confirmation and a WCT physical mechanism remain not established.

largest_reported_global_p is only a conservative diagnostic maximum across reported global/multiplicity/alternative-null p-values. It is explicitly not a newly combined formal p-value.

Resolution-mode follow-up

The branch also contains a standalone exploratory follow-up in R/run_resolution_mode_diagnostics.R, documented by RESOLUTION_MODE_DIAGNOSTICS.md.

This follow-up does not run inside the final audit and cannot overwrite its verdicts. It was added to diagnose the observed resolution-dependent winner by:

  • comparing the original fixed sigma=6-bins baseline with sigma(B)=6*B/160, which approximately fixes smoothing width in ell=log(wavenumber) space;
  • tracking both the canonical Fe primary mode and the previously frozen GWTC k=9.602325620315224 at every dense bin resolution;
  • storing the top five distinct local peaks so a winner swap is distinguished from disappearance of a mode;
  • running conservative fixed-frequency tests for the exact frozen GWTC target across Fe wavenumber/observed/Ritz and Cr/Mn/Co/Ni/Ti ion-II data, with both fixed-baseline and baseline-refit nulls.

The GWTC value predates this NIST follow-up, but noticing the NIST/GWTC match is post-hoc. These diagnostics are therefore explicitly exploratory and do not rescue a failed 80% bin-stability claim.

Reproduction

Final audit:

Rscript R/run_final_adversarial_audit.R --parallel true --render-report true

Resolution follow-up, after preserving the final audit outputs:

Rscript R/run_resolution_mode_diagnostics.R --parallel true --fixed-null-n 5000

The heavy full-resolution audit is intentionally separate from CI. CI sources/parses the new R modules, runs the unit tests, and checks the canonical Python scanner/container. Final Monte Carlo outputs are produced by the commands above.

Copy link
Copy Markdown
Owner Author

Release gate update (2026-09-11):

  • Full-family multiplicity rerun at 5,000 simulations: family-max p=0.0002; Holm FWER p=0.0118; BY FDR p=0.0009485.
  • Five adversarial null models x 5,000 replicates: worst-case p=0.0005999 (block_residual_refit).
  • Bootstrap peak stability: 5000/5000 within the 2% reference region.
  • Specification multiverse: 89.4% in the reference region.
  • Observed/Ritz/wavenumber representations all select k=31.32653 at the Monte Carlo floor.
  • Frozen holdouts: 8/8 direction-consistent; median conservative fixed-k p=0.001.
  • Null calibration is compatible at 0.10, 0.05, and 0.01.
  • Injection recovery is calibrated at A=0 and reaches high correct-detection power by A=0.075-0.10.
  • Original fixed-sigma bin-grid failure is preserved (70% in region). Exploratory matched-ell smoothing selects the primary Fe branch across 60-240 bins, diagnosing the resolution/smoothing confound without rewriting the original verdict.

Release blocker fixed in this PR: model_comparison.R previously recomputed polynomial centering/scaling on the held-out test block while applying training coefficients. The branch now freezes the training transform for test prediction and includes a regression test. The previous held-out gain (-36.836) must therefore not be used in the final release; rerun only Rscript R/model_comparison.R, then rebuild R/build_final_adversarial_summary.R before freezing/tagging.

Also fixed dependency metadata: viridis is now required because several plotting modules call it directly.

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