{
  "null_id": "EXP002_NULL_V0_3_1_POLL_INDEX_BLOCK_BOOTSTRAP",
  "protocol_version": "v0.3.1-PROPOSAL",
  "status": "PROPOSAL_REVISED_NOT_RUN_PENDING_INDEPENDENT_REVIEW",
  "selection_basis": "Predeclared by v0.3 \u00a75\u2013\u00a76: primary null = poll-index block bootstrap preserving gaps / irregular cadence. NOT chosen after seeing \u0394B. Irregular phase-randomization explicitly NOT primary.",
  "estimand": "Among episodes with admissible B1 windows, mean \u0394B = mean(B1 \u2212 B0). This audit does NOT compute the observed statistic on real episodes.",
  "algorithm": {
    "name": "poll_index_block_bootstrap_preserving_cadence",
    "steps": [
      "1. Work on the ordered poll series x[0..n-1] with irregular field_dates (cadence fixed on date axis; values resampled).",
      "2. Form overlapping blocks of length L_block polls on the poll-index axis (not calendar days). Block starts = 0..n-L_block inclusive.",
      "3. TRIM/PAD (DEFINED): Draw blocks with replacement until concatenated length >= n; concatenate in draw order; then TRIM to exactly the first n values. Never pad with zeros/means/noise. If a draw somehow undershoots (should not under this rule), continue drawing. Map the length-n value vector onto the ORIGINAL fixed field_dates vector.",
      "4. On each bootstrap series, run the SAME frozen episode machine (D,K,M,spans,G_max,confirm<=540d) under the Astra-reviewed confirmation rule once v0.3.1 is accepted (full-machine semantics \u2014 not hybrid row-delete).",
      "5. SIM ELIGIBILITY (ALIGNED TO OBSERVED SPARSE GATE): A sim is VALID only if it produces N_ep_confirmed >= 6 AND admissible_B1_count >= 6 under the same definitions as the observed sparse gate (v0.3 \u00a76). Sims failing that gate \u2192 NULL_SIM_INSUFFICIENT (excluded from p-value denominator; counted in failure tallies). Do NOT accept sims with merely >=1 admissible B1 while observed inference requires min-six.",
      "6. p-value primary = one-sided left-tail toward more-negative mean \u0394B: p=(1+#{\u0394B_sim<=\u0394B_obs})/(1+n_valid_sim). TWO-SIDED: do NOT use |\u0394B| vs 0. If a two-sided sensitivity is reported, use equal-tailed percentiles of \u0394B_sim about the calibration-DGP null mean (estimated from sims), or omit two-sided until calibration DGP is accepted. Fixed dates alone do not claim to preserve calendar-time dependence beyond the poll-index block structure."
    ]
  },
  "parameters": {
    "L_block": 8,
    "L_block_rationale": "Equals baseline window M=8 so blocks match the minimum local dependence scale of the baseline estimator; preserves short-run serial structure without calendar-day interpolation.",
    "L_block_sensitivity_registered_not_primary": [
      6,
      10
    ],
    "n_simulations": 5000,
    "seed": 20260909,
    "rng": "numpy.random.Generator(numpy.random.PCG64(seed))",
    "preserve_cadence": true,
    "preserve_field_dates": true,
    "value_resampling_axis": "poll_index_blocks",
    "confirmation_rule_binding": "MUST use the Astra-reviewed v0.3.1 confirmation clarification; do not run inference under unresolved E005 look-ahead ambiguity.",
    "episode_machine_thresholds": {
      "D": 8,
      "K": 2,
      "M": 8,
      "MIN_SPAN": 365,
      "MAX_SPAN": 2920,
      "G_max": 730,
      "confirm_days": 540,
      "H": 3650
    },
    "admissible_B1_definition": "RECOVERED episode with B1 window of M polls immediately after detection satisfying min/max span and G_max; episode not INVALIDATED under confirmation-ordering rule.",
    "trim_pad_rule": {
      "draw_until_len_ge_n": true,
      "then_trim_to_n": true,
      "forbidden_padding": [
        "zeros",
        "series_mean",
        "gaussian_noise",
        "circular_wrap_without_draw"
      ]
    },
    "sim_validity_requires": {
      "n_confirmed_episodes_min": 6,
      "admissible_B1_min": 6,
      "rationale": "Match predeclared sparse gate (v0.3 \u00a76 N_ep>=6). Prior draft accepting >=1 B1 / failing only if observed B1<4 is REJECTED as a lowered gate."
    }
  },
  "statistic": "mean_delta_B_over_admissible_B1_episodes",
  "p_value_calculation": {
    "primary": "one_sided_left_tail_ratchet_direction",
    "formula": "p = (1 + count(\u0394B_sim <= \u0394B_obs)) / (1 + n_valid_sim)",
    "n_valid_sim_excludes": "sims with N_ep_confirmed<6 OR admissible_B1<6 (NULL_SIM_INSUFFICIENT)",
    "two_sided_sensitivity": "NOT |\u0394B| vs 0. Optional equal-tailed vs null mean of \u0394B_sim after calibration DGP accepted; otherwise OMIT."
  },
  "calibration": {
    "pre_inference_requirement": "Before ANY observed \u0394B test: Type-I calibration on synthetic no-ratchet series using SAME null.",
    "calibration_DGP_specified": {
      "name": "POLL_INDEX_AR1_MEAN_REVERTING_NO_RATCHET",
      "steps": [
        "Fit AR(1) on the poll-index series of observed individual_pct (not calendar interpolation): x_t = mu + phi*(x_{t-1}-mu) + e_t with OLS phi, mu=mean(x), residual variance s2.",
        "Generate synthetic series on the SAME n and SAME field_dates by iterating the AR(1) from x_0=observed x_0 with e_t ~ N(0,s2) using PCG64; clip to [0,100].",
        "Truth class = no ratchet: constant unconditional mean; no episode-linked permanent baseline drop. Mean-reversion is via |phi|<1 only.",
        "Optional sensitivity (registered, not primary): residual shuffle of fitted AR(1) innovations preserving poll-index order of dates."
      ],
      "typeI_gate": "Empirical Type-I at alpha=0.05 within [0.02, 0.08] over >=1000 synthetic truths; else NULL_VALIDITY_UNPROVEN."
    },
    "failure_rule": "FAIL if: (a) Type-I calibration outside [0.02, 0.08]; (b) n_valid_sim < 0.8 * n_simulations; (c) observed N_ep_confirmed < 6 OR observed admissible_B1 < 6 (ORIGINAL sparse gate \u2014 NOT B1<4); (d) confirmation-ordering / full-machine semantics still unresolved; (e) any threshold retuned after seeing \u0394B_obs. On FAIL \u2192 publish NULL_VALIDITY_UNPROVEN / INSUFFICIENT_EPISODES / DATA_INSUFFICIENT; do NOT claim ratchet support/not-support; do NOT compute/publish observed ratchet as a decision statistic.",
    "explicit_rejection_of_lowered_gate": "Prior draft failure clause (c) 'admissible B1 < 4' is a NEW lowered gate and is NOT permitted. Restored to N_ep>=6 / admissible B1>=6 consistent with v0.3 \u00a76."
  },
  "explicitly_not_selected_after_results": true,
  "not_run_on_observed_outcomes": true,
  "review_required_by": "ASTRA_AFTER_AUDIT",
  "revision_note": "Responds to Codex/ChatGPT PRESERVE_SPARSE_SAMPLE_GATE challenges. Spec fixes only; null NOT executed; observed \u0394B NOT computed.",
  "observed_ratchet_statistic": "NOT_COMPUTED",
  "sparse_sample_gate": {
    "decision": "PRESERVE_SPARSE_SAMPLE_GATE",
    "rule": "N_ep >= 6 confirmed required for any inferential \u0394B claim; else INSUFFICIENT_EPISODES / DATA_INSUFFICIENT",
    "current_counts": {
      "look_ahead_confirmed": 6,
      "strict_or_forward_only_confirmed": 5,
      "admissible_B1_hybrid_or_forward_only": 4
    },
    "gate_status": "FAIL \u2014 do not run null on observed; do not compute observed ratchet"
  }
}
