# Pre-analysis plan — The INP Yield-Gaming Audit
# Separating earlier paint from less work in web responsiveness, 2024–2026.
# Article: https://pagespeedaudit.com/research/earlier-paint-or-less-work
# License: CC BY 4.0. This plan is registered BEFORE outcomes are inspected.
#
# Design intent: the public record proves yield adoption can move INP at population
# scale; it does NOT, on its own, quantify how much of the 2024–2026 improvement is
# real work reduction versus displaced work, nor whether tasks completed faster.
# This plan specifies the estimands and guardrails that close that gap.

version: 1.0
registered_utc: "2026-06-22"
population:
  frame: "Origins present in BOTH CrUX and HTTP Archive, mobile/phone, 2024-01 .. latest complete 2026 month."
  primary_form_factor: phone
  unit_study1: origin-month
  unit_study2: interaction-scenario (e.g. consent-accept, add-to-cart, menu-open, filter)
  generalizes_to: "the CrUX-eligible public web; NOT all browsers and NOT low-traffic origins."

# ---- Outcome-based definitions (no inferred intent) -------------------------
definitions:
  yield_pattern: "A scheduling pattern that inserts a task boundary so paint/other work can run before continuation: scheduler.yield(), scheduler.postTask(), setTimeout wrapping, rAF+continuation, GPT threadYield, Prebid command-queue yield."
  semantic_first_response: "Earliest post-input paint that accurately represents task progress/state (pressed button, opened menu, real pending indicator, validation feedback)."
  cosmetic_first_response: "Post-input paint not tied to task state (flash, generic spinner, class toggle that says nothing about started/succeeded/failed/blocked)."
  total_interaction_work_TW: "Main-thread work attributable to an interaction from input start to task completion (JS + style + layout + paint + LoAF blocking attribution where available)."
  task_completion: "First time the user's intended task is semantically complete and usable (cart updated, results rendered, consent persisted, menu usable)."

# ---- Classification thresholds (preregistered guardrails) -------------------
# Applied only to interventions with a detectable INP improvement.
classification:
  inp_improvement_gate: { min_ms: 20, min_pct: 10 }       # below this -> "no detectable effect"
  work_reducing:        { dTW_pct_max: -5, completion_harm: false }
  yield_only_beneficial:{ dTW_pct_abs_max: 5, completion_or_control: improves }
  yield_only_neutral:   { dTW_pct_abs_max: 5, completion_or_control: unchanged }
  yield_shifting_harmful: # any of:
    - dTW_pct_min: 5
    - completion_worse_ms: 100
    - completion_worse_pct: 10
    - carryover_input_delay_worse: true   # next interaction within 1s
  sensitivity_grid:
    inp_ms: [10, 20, 50]
    work_pct: [3, 5, 10]
    completion_ms: [50, 100, 250]

# ---- Estimands --------------------------------------------------------------
estimands:
  E1_adoption_effect:
    question: "Change in good-INP share and p75 INP associated with first adoption of yield patterns."
    design: "Two-way fixed-effects event study (origin + month); vendor diff-in-diff for GPT/CMP/Prebid windows."
    model: "fast_inp ~ i(event_month, ref=-1) | origin + yyyymm ; cluster by origin (and vendor-month for vendor specs)."
    evidence_rung: 2   # causal adoption effect
  E2_yield_only_share:
    question: "Share of aggregate INP improvement from interventions that do NOT reduce total work."
    formula: "sum_i |dINP_i| * 1[yield_only_i] / sum_i |dINP_i| * 1[dINP_i < 0]"
    source: lab_replay
    evidence_rung: 3
  E3_work_reduction_share:
    question: "Share of aggregate INP improvement from interventions that reduce total work."
    formula: "sum_i |dINP_i| * 1[work_reducing_i] / sum_i |dINP_i| * 1[dINP_i < 0]"
    source: lab_replay
    evidence_rung: 3
  E4_task_completion_impact:
    question: "Effect of yield-only patterns on completion time, success, error rate, next-interaction delay, perceived control."
    source: [lab_replay, micro_ux]
    evidence_rung: 4   # the only rung that proves user benefit

primary_outcomes: [fast_inp, p75_inp, total_interaction_work, completion_time, carryover_input_delay]

# ---- Falsification tests (a wrong study must be able to fail) ---------------
falsification:
  detector_precision: "No origin-level estimate published before manual validation reports precision/recall + Cohen's kappa by yield class."
  pre_trend: "Event-study leads (months -6..-2) must be statistically indistinguishable from zero."
  placebo_metric: "Yield adoption must NOT 'improve' unrelated metrics (e.g. TTFB) the same way."
  vendor_window: "GPT/CMP effects must concentrate around documented release windows and among EXPOSED origins only."
  trace_equivalence: "No-yield and yield lab variants must reach the same semantic final state, else exclude."
  carryover: "Every lab scenario must include a SECOND interaction to detect shifted-work harm."
  multiple_comparisons: "FDR control on secondary vendor/rank-bucket analyses; primary outcomes fixed above."

honesty:
  no_fabricated_share: "This release is the design + verified public facts. It does NOT report a fitted global yield-only share; the kit is built to produce one and to be audited when it does."
