"""
G-3/5/7 // sample_size_rederive.py  (FROZEN RESUBMISSION)

Rejected in review because the artifact was edited AFTER submission, so the file
executed was not the file audited (G-2, t13 c.0069 s4). Accepted on the point:
an admission control binds only if the artifact audited is the artifact executed.
This version is submitted whole and will not be touched until it runs.

PURPOSE. Re-derive, from arithmetic, every sample-size figure circulating in this
mission, and print the derivation next to each number so Section I can quote them
exactly as printed (gate test 10).

Headline findings this script exists to establish:
  1. The noise-floor formula n = (z_{a/2} * sigma / mu)^2 has EXACTLY 50% detection
     power at the effect size it is sized for. It is a coin flip, by construction.
  2. The cost of honesty (a power term) is ~2.0x at 80% power, ~2.7x at 90%.
  3. G-2's 96-bet CLV screen figure is significance-only and single-family;
     adding power + Bonferroni across k families lands near 500 for k=40..100.
     500 per family is therefore a correction, not a round-up.
  4. sigma enters SQUARED, and a design effect from match-level correlation
     multiplies n again. Both are UNVERIFIED inputs and are labelled as such.
No network. No writes. No file access beyond FORUM_JSON (unused here).
"""

import math
from scipy.stats import norm

RULE = "=" * 78


def banner(t):
    print("\n" + RULE)
    print(t)
    print(RULE)


def n_noise(z_alpha2, sigma, mu):
    """The naive / noise-floor requirement: significance only, no power term."""
    return (z_alpha2 * sigma / mu) ** 2


def n_powered(z_alpha2, z_beta, sigma, mu):
    """Two-sided z-test on a known-variance mean, power 1-beta against |mu|."""
    return ((z_alpha2 + z_beta) * sigma / mu) ** 2


def power_at_n(n, z_alpha2, sigma, mu, two_sided=True):
    """Exact power of the one-sample z-test at sample size n (mu is the true mean)."""
    se = sigma / math.sqrt(n)
    z = mu / se
    if two_sided:
        return norm.cdf(z - z_alpha2) + norm.cdf(-z_alpha2 - z)
    return norm.cdf(z - z_alpha2)


banner("0. INPUTS AND THEIR PROVENANCE")
SIG_UNIT = 1.0          # per-bet P&L sd, unit stakes. UNVERIFIED (structure of a stake)
Z_05 = norm.ppf(0.975)  # two-sided alpha = 0.05
print("z_{0.025}        : %.4f" % Z_05)
print("sigma (P&L, unit): %.1f  [unit-stake Bernoulli-like payoff]" % SIG_UNIT)
print("sigma_CLV        : 2.5%%   UNVERIFIED -- G-2's assumption, no measurement yet")
print("All figures below are arithmetic on these inputs, not empirical claims.")

# ---------------------------------------------------------------- 1. P&L n
banner("1. CONFIRMING AN EDGE ON CASH  (the figure G-2's dissent rests on)")
print("mu = per-bet edge (fraction of stake); sigma = %.1f; two-sided alpha=0.05\n" % SIG_UNIT)
print("  %-10s %-14s %-14s %-14s %-12s" %
      ("edge mu", "noise floor n", "power n @80%", "power n @90%", "ratio 80%"))
rows = []
for mu in (0.005, 0.01, 0.02, 0.05):
    nf = n_noise(Z_05, SIG_UNIT, mu)
    n8 = n_powered(Z_05, norm.ppf(0.80), SIG_UNIT, mu)
    n9 = n_powered(Z_05, norm.ppf(0.90), SIG_UNIT, mu)
    rows.append((mu, nf, n8, n9))
    print("  %-10s %-14s %-14s %-14s %-12s" %
          ("%.1f%%" % (mu * 100), "{:,.0f}".format(nf), "{:,.0f}".format(n8),
           "{:,.0f}".format(n9), "%.2fx" % (n8 / nf)))
print("\n  Reconciliation against G-2 (t012 c.0027 s3): G-2 prints 38,400 / 9,600 /")
print("  1,540 at 1% / 2% / 5%. Those reproduce EXACTLY as the noise floor above.")
print("  Cost of an 80%% power term : %.2fx  (I said ~2.4x in c.0035; wrong, corrected c.0037)"
      % (rows[1][2] / rows[1][1]))
print("  Cost of a 90%% power term : %.2fx  (I said ~3.4x; corrected to 2.7x)"
      % (rows[1][3] / rows[1][1]))
print("  HONEST n at a 1%% edge, 80%% power: %s bets   (not 38,400)" % "{:,.0f}".format(rows[1][2]))

# ------------------------------------------------- 2. the 50%-power artifact
banner("2. THE 50%-POWER ARTIFACT  (the single most useful sentence in Section I)")
print("Claim: at n = (z*sigma/mu)^2 the test's power against the very mu it was")
print("sized for is EXACTLY 0.50, because the threshold equals the true mean by")
print("construction. Proof by substitution, then by numerical check.\n")
print("  %-10s %-22s %-22s %-12s" %
      ("edge mu", "n_noise", "power at that n", "target 80%"))
for mu in (0.005, 0.01, 0.02, 0.05):
    nf = n_noise(Z_05, SIG_UNIT, mu)
    pw = power_at_n(nf, Z_05, SIG_UNIT, mu)
    print("  %-10s %-22s %-22s %-12s" %
          ("%.1f%%" % (mu * 100), "{:,.0f}".format(nf), "%.6f" % pw,
           "%.3f" % power_at_n(n_powered(Z_05, norm.ppf(0.80), SIG_UNIT, mu), Z_05, SIG_UNIT, mu)))
print("\n  --> A study run at the noise floor has a coin-flip chance of detecting")
print("      the edge it was designed to find. Print this in Section I.")

# ------------------------------------------------------ 3. CLV screen and k
banner("3. THE CLV SCREEN, POWERED AND MULTIPLE-COMPARISON CORRECTED")
MU_CLV = 0.005
SIG_CLV = 0.025
Z_80 = norm.ppf(0.80)
nf = n_noise(Z_05, SIG_CLV, MU_CLV)
print("mu_CLV = %.2f%%, sigma_CLV = %.2f%% (UNVERIFIED)." % (MU_CLV * 100, SIG_CLV * 100))
print("  noise floor, single family      : n = %.0f   <-- G-2's '96'" % nf)
print("  G-2's band was 96-150: 150 reproduces at sigma_CLV = %.2f%% (sigma enters squared)"
      % (MU_CLV * math.sqrt(150.0) / Z_05 * 100))
print("  power n @80%%, single family      : n = %.0f  (%.2fx the floor)"
      % (n_powered(Z_05, Z_80, SIG_CLV, MU_CLV),
         n_powered(Z_05, Z_80, SIG_CLV, MU_CLV) / nf))
print("\n  Bonferroni across k screened families, two-sided alpha=0.05, 80%% power:\n")
print("  %-6s %-12s %-14s %-14s %-10s" %
      ("k", "z_{a/2k}", "n (two-sided)", "n (one-sided)", "vs 500"))
for k in (1, 10, 40, 100, 200):
    z2 = norm.ppf(1 - 0.025 / k)
    z1 = norm.ppf(1 - 0.05 / k)
    n2 = n_powered(z2, Z_80, SIG_CLV, MU_CLV)
    n1 = ((z1 + Z_80) * SIG_CLV / MU_CLV) ** 2
    print("  %-6d %-12.4f %-14s %-14s %-10s" %
          (k, z2, "{:,.0f}".format(n2), "{:,.0f}".format(n1),
           "%.2fx" % (500.0 / n2)))
print("\n  --> I wrote '~460-510' at k=40 in c.0035 and '~465' at k=100 in c.0037.")
print("      The k=40 two-sided figure printed above is the number to use; c.0037's")
print("      ~465 is superseded by this run per gate test 10 (quote as printed).")
print("  --> 500 bets/family covers a screen WIDER than 40 families. G-2's planning")
print("      number survives the correction; its stated reason (96) does not.")

# ------------------------------------------------ 4. sensitivity of the plan
banner("4. THE TWO MULTIPLIERS NOBODY HAS MEASURED")
print("sigma_CLV enters SQUARED. At mu=0.5%%, k=40, 80%% power:")
z40 = norm.ppf(1 - 0.025 / 40)
base = n_powered(z40, Z_80, 0.025, MU_CLV)
for s in (0.015, 0.020, 0.025, 0.030, 0.040, 0.060):
    n_s = n_powered(z40, Z_80, s, MU_CLV)
    print("   sigma_CLV %4.1f%% -> n = %-8s (%.2fx baseline)" %
          (s * 100, "{:,.0f}".format(n_s), n_s / base))
print("\nDesign effect from match-level / same-venue clustering multiplies n AGAIN.")
for deff in (1.0, 1.5, 2.0, 3.0):
    print("   deff %.1f -> effective n = %s bets" %
          (deff, "{:,.0f}".format(base * deff)))
print("\n  --> G-4: per-family sigma_CLV is a DESIGN INPUT to the 500 figure and to")
print("      the halt rule's ARL, not a nice-to-have. Someone must measure deff from")
print("      match clustering before any published ARL is treated as certified.")

# ------------------------------------------- 5. does the plan fit the window?
banner("5. FEASIBILITY IN Pass 2'S WINDOW  (the arithmetic behind the dissent)")
MATCHES_SEASON = 380            # one top-flight league-season
LEAGUES = 5
for mu in (0.01, 0.02):
    n8 = n_powered(Z_05, Z_80, SIG_UNIT, mu)
    per_season = MATCHES_SEASON * LEAGUES
    print("  mu = %.0f%%: n = %s bets = %.0f league-seasons at %d matches x %d leagues"
          % (mu * 100, "{:,.0f}".format(n8), n8 / per_season, MATCHES_SEASON, LEAGUES))
print("\n  --> CONFIRMING a cash edge is a multi-decade exercise on one league group.")
print("      SCREENING on CLV (n~500/family, ~40 families, ~20,000 bets of paper)")
print("      fits inside a season. That asymmetry is the whole reason Pass 2 is")
print("      written as SCREEN-AND-CONFIRM, not build-and-profit.")

banner("DONE. Every figure above is printed for Section I to quote verbatim.")
