From 05f09005e6a62e831e06a5d9f92156c3862d9265 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 12 Aug 2026 09:56:59 +0000 Subject: [PATCH 1/3] probes/weather-p1: CT-F16 pre-registered BEFORE the run (steering-level scoring) Committing the probe with its four bars stated, before any fetch, so the read cannot be tuned to the result. CT-F16a >= 0.70 sign consistency vs the 500/600/700 hPa steering flow; CT-F16b the PAIRED test (sd of the signed offset must drop >= 10%); CT-F16c anti-vacuity (permuted + 90-deg-rotated references must BOTH stay under 0.70, reported first and voiding the rest if they fail); CT-F16d the level sweep, descriptive. Scope stated up front: this is a RE-SCORING of CT-F14's own 19 storms with ONLY the motion reference changed -- the MECHANISTIC test, explicitly NOT a verdict. A fresh-sample verdict is CT-F17, named and not run. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi --- probes/weather-p1/comet_tail_f16.py | 283 ++++++++++++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 probes/weather-p1/comet_tail_f16.py diff --git a/probes/weather-p1/comet_tail_f16.py b/probes/weather-p1/comet_tail_f16.py new file mode 100644 index 000000000..ffcaee2bc --- /dev/null +++ b/probes/weather-p1/comet_tail_f16.py @@ -0,0 +1,283 @@ +"""EXPLORATORY — CT-F16: score the dipole against the STEERING-LEVEL flow +instead of the 6h surface displacement. NOT an EV; bars mine, unaudited. + +WHY THIS TEST, AND WHAT IT IS NOT. + +CT-F14 -- the properly-powered, pre-registered, displacement-filtered sample -- +scored the dipole's low-pole bearing against the **6h surface-centre +displacement** and returned 13/19 = 0.684, p=0.0835, NO-VERDICT. The report +names ONE moderator that this chain actually MEASURED and never wired: the +steering level. The height ladder (report SS5.2/5.8) runs monotonically 92-102 +deg with a zero-crossing at 400-650 hPa on both storms it was measured on. The +physics SS2 lays out is a vortex embedded in a STEERING flow -- and 10m surface +displacement is a noisy proxy for that flow, not the flow itself. + +So CT-F16 swaps ONLY the motion reference. Same storms, same centres, same +decomposition, same `err_deg` convention -- one variable changed. + +**THIS IS A RE-SCORING, AND IT IS NOT A VERDICT.** The arc's own rule (SS5.10) +is explicit: *"the correct way to chase a post-hoc lead is a FRESH +pre-registered sample with the filter applied a priori -- not a re-scoring of +the sample that already failed."* That rule was written about re-FILTERING +(choosing which storms count after seeing them), and this is a change of +PREDICTOR on a fixed storm set -- a different operation, and the one the report +pre-named. It is still the same 19 storms whose surface-displacement scoring +already came back NO-VERDICT, so: + + * CT-F16 is the MECHANISTIC test -- does the physically-motivated predictor + improve on IDENTICAL data? That question is answerable here and is worth + answering before spending a fresh sample. + * A VERDICT on the directional claim needs a fresh, pre-registered, + steering-scored sample. That is **CT-F17**, named here, NOT run. + +Reusing CT-F14's stored centres also removes centre-finding as a variable: +nothing about the storm selection or the disk geometry can move between arms. + +STEERING FLOW, defined before the run: the disk-mean (u, v) over the SAME +1200 km disk, averaged over the **500/600/700 hPa** layer -- the textbook +extratropical steering layer, and the band containing the ladder's measured +400-650 hPa zero-crossing. Bearing = `arctan2(v_mean, u_mean)`, the identical +CCW-from-east convention `mth = arctan2(disp[1], disp[0])` uses in CT-F14, so +`err_deg` is untouched. + +PRE-REGISTERED (all four stated before any fetch): + +CT-F16a PRIMARY. Sign consistency (fraction with error < 0, the same + left-of-motion direction as every prior probe) scored against the + steering flow, on CT-F14's 19 qualifying storms, >= 0.70. + CT-F14's surface-displacement figure on these SAME storms is 0.684. + +CT-F16b THE PAIRED TEST, and the real content. If the steering level is the + moderator, swapping to it should not merely nudge the sign count -- + it should TIGHTEN the residual. Bar: the standard deviation of the + signed offset must DROP by >= 10 % versus the surface-displacement + scoring on the same storms. **This can fail in both directions**: the + spread can widen (steering flow is the wrong reference) or move < 10 % + (it is not the moderator at this magnitude). + +CT-F16c ANTI-VACUITY / CAN-IT-STAY-SILENT. Two deliberately WRONG references + are scored through the identical pipeline: + (i) the steering bearings DETERMINISTICALLY permuted across storms + (storm i gets storm (i+7) mod 19's steering flow), and + (ii) the true steering flow rotated by +90 deg. + Neither may reach 0.70. If a scrambled or rotated reference scores as + well as the true one, this probe measures nothing and F16a/F16b are + void regardless of what they say. Reported FIRST in the verdicts. + +CT-F16d DESCRIPTIVE, not a bar. Sign consistency scored at EACH level + (400/500/600/700/850 hPa separately). The ladder predicts an optimum + inside 400-650 hPa; a flat sweep, or an optimum at 850/1000, would + say the level structure is not what is driving any improvement. + +NOT tested here: SH, tropical cyclones, or any claim beyond the extratropical +steering-flow framing. A fresh-sample verdict is CT-F17 and is not run. +""" +import json +import pathlib +import urllib.request +from math import comb + +import numcodecs +import numpy as np + +B = ("https://storage.googleapis.com/weatherbench2/datasets/era5/" + "1959-2022-6h-1440x721.zarr") +R_E, R_DISK, RING = 6371.0, 1200.0, 100.0 +STEER_LEVELS = (500, 600, 700) # pre-registered steering layer +SWEEP_LEVELS = (400, 500, 600, 700, 850) + +op = urllib.request.build_opener(urllib.request.ProxyHandler({})) +meta = json.loads(op.open(B + "/.zmetadata", timeout=90).read())["metadata"] + + +def fetch(var, key): + """Fetch and decode one zarr chunk from the WB2 store.""" + za = meta[f"{var}/.zarray"] + raw = op.open(f"{B}/{var}/{key}", timeout=900).read() + dec = numcodecs.get_codec(za["compressor"]).decode(raw) + return np.frombuffer(dec, dtype=np.dtype(za["dtype"])).reshape(za["chunks"]) + + +def wrap_deg(d): + """Wrap degrees into [-180, 180) — the identical convention CT-F14 uses.""" + return (d + 180.0) % 360.0 - 180.0 + + +def err_deg(low_pole_rad, motion_rad): + """Signed alignment error vs the left-of-motion prediction. VERBATIM from + comet_tail_f14.py:205 — the paired comparison is only valid if the scoring + function is byte-identical and ONLY the motion reference changes.""" + return float(wrap_deg(np.rad2deg(low_pole_rad - (motion_rad + np.pi / 2)))) + + +def binom_sf_ge(k, n, p=0.5): + """Exact one-sided binomial tail P(X >= k) for n trials at probability p.""" + return sum(comb(n, i) * (p ** i) * ((1 - p) ** (n - i)) + for i in range(k, n + 1)) + + +lat = fetch("latitude", "0").astype(np.float64).ravel() +levels = fetch("level", "0").astype(int).ravel() +NY, NX = lat.size, 1440 +phi = np.deg2rad(lat) +lon_deg = np.arange(NX) * 0.25 +LEV_IDX = {int(v): i for i, v in enumerate(levels)} +print(f"levels: {list(levels)}") +print(f"steering layer (pre-registered): {STEER_LEVELS} hPa", flush=True) + + +def geom_ll(latc, lonc): + """dx, dy, r (km), azimuth (rad CCW from east) about a continuous centre.""" + phic = np.deg2rad(latc) + dlon = np.deg2rad((lon_deg[None, :] - lonc + 180) % 360 - 180) + dx = R_E * np.cos(phic) * dlon * np.ones((NY, 1)) + dy = R_E * (phi[:, None] - phic) * np.ones((1, NX)) + return dx, dy, np.hypot(dx, dy), np.arctan2(dy, dx) + + +def low_pole_bearing(field, latc, lonc): + """Ring-profile + per-ring wn-1 fit; returns the amplitude-weighted low-pole + bearing. VERBATIM shape from comet_tail_f14.py's decompose_ll.""" + _, _, r, th = geom_ll(latc, lonc) + disk = r <= R_DISK + vals, rr, tt = field[disk], r[disk], th[disk] + nb = int(R_DISK / RING) + rings = np.clip((rr / RING).astype(int), 0, nb - 1) + prof = np.zeros(nb) + a1 = np.zeros(nb) + b1 = np.zeros(nb) + for b in range(nb): + m = rings == b + if not m.any(): + continue + v, t = vals[m], tt[m] + prof[b] = v.mean() + a1[b] = 2 * ((v - prof[b]) * np.cos(t)).mean() + b1[b] = 2 * ((v - prof[b]) * np.sin(t)).mean() + amp = np.hypot(a1, b1) + w = amp * np.arange(nb) + ph = np.arctan2(np.sum(b1 * w), np.sum(a1 * w)) + return float((ph + np.pi) % (2 * np.pi)) + + +def disk_mean_uv(u3, v3, latc, lonc, lev_list): + """Disk-mean (u, v) over the 1200 km disk, averaged across `lev_list`.""" + _, _, r, _ = geom_ll(latc, lonc) + disk = r <= R_DISK + us, vs = [], [] + for lev in lev_list: + li = LEV_IDX[lev] + us.append(u3[li][disk].mean()) + vs.append(v3[li][disk].mean()) + return float(np.mean(us)), float(np.mean(vs)) + + +# ---- CT-F14's OWN qualifying storms (paired: nothing about selection moves) -- +src = json.loads( + pathlib.Path(__file__).with_name("comet_tail_f14.json").read_text()) +storms = [r for r in src["rows"] + if r.get("status") == "OK" and r["displacement_km"] >= 250.0] +assert len(storms) == 19, f"expected CT-F14's 19 qualifying storms, got {len(storms)}" +print(f"paired sample: {len(storms)} storms (CT-F14's qualifying subset)\n", + flush=True) + +rows = [] +for i, s in enumerate(storms): + t0, la, lo = s["t0"], s["center_lat"], s["center_lon"] + p = fetch("mean_sea_level_pressure", f"{t0}.0.0")[0].astype(np.float64) + u3 = fetch("u_component_of_wind", f"{t0}.0.0.0")[0].astype(np.float64) + v3 = fetch("v_component_of_wind", f"{t0}.0.0.0")[0].astype(np.float64) + + lp = low_pole_bearing(p, la, lo) + um, vm = disk_mean_uv(u3, v3, la, lo, STEER_LEVELS) + steer_rad = float(np.arctan2(vm, um)) + e_steer = err_deg(lp, steer_rad) + + per_level = {} + for lev in SWEEP_LEVELS: + ul, vl = disk_mean_uv(u3, v3, la, lo, (lev,)) + per_level[str(lev)] = err_deg(lp, float(np.arctan2(vl, ul))) + + rows.append({ + "date": s["date"], "t0": t0, "center_lat": la, "center_lon": lo, + "displacement_km": s["displacement_km"], + "err_surface_deg": s["error_deg"], # CT-F14's own number + "err_steering_deg": e_steer, + "steer_speed_ms": float(np.hypot(um, vm)), + "steer_bearing_rad": steer_rad, + "low_pole_rad": lp, + "err_by_level_deg": per_level}) + print(f"[{i+1}/{len(storms)}] {s['date'][:10]} " + f"surface {s['error_deg']:+7.1f} steering {e_steer:+7.1f} " + f"|steer| {np.hypot(um, vm):5.1f} m/s", flush=True) + +out = {"store": B, "source": "comet_tail_f14.json qualifying subset", + "steer_levels_hPa": list(STEER_LEVELS), "n": len(rows), "rows": rows, + "scope": ("PAIRED re-scoring of CT-F14's own storms with ONLY the motion " + "reference changed. MECHANISTIC test, NOT a verdict — a " + "fresh-sample verdict is CT-F17, not run.")} + +e_surf = np.array([r["err_surface_deg"] for r in rows]) +e_steer = np.array([r["err_steering_deg"] for r in rows]) +n = len(rows) + + +def frac_neg(e): + """Fraction with error < 0 — the left-of-motion direction.""" + return float((e < 0).mean()) + + +# ---- CT-F16c FIRST: if the wrong references also pass, nothing else counts --- +perm = np.array([rows[(i + 7) % n]["steer_bearing_rad"] for i in range(n)]) +e_perm = np.array([err_deg(rows[i]["low_pole_rad"], perm[i]) for i in range(n)]) +e_rot = np.array([err_deg(r["low_pole_rad"], r["steer_bearing_rad"] + np.pi / 2) + for r in rows]) +f_perm, f_rot = frac_neg(e_perm), frac_neg(e_rot) +c_ok = (f_perm < 0.70) and (f_rot < 0.70) + +print("\n=== CT-F16c ANTI-VACUITY (reported first — gates everything else) ===") +print(f" permuted steering bearings : {f_perm:.3f} (must be < 0.70)") +print(f" steering rotated +90 deg : {f_rot:.3f} (must be < 0.70)") +print(f" -> {'PASS — the test discriminates' if c_ok else 'FAIL — VOID: a wrong reference scores as well'}") + +f_surf, f_steer = frac_neg(e_surf), frac_neg(e_steer) +p_steer = binom_sf_ge(int((e_steer < 0).sum()), n) +sd_surf, sd_steer = float(e_surf.std(ddof=1)), float(e_steer.std(ddof=1)) +drop = (sd_surf - sd_steer) / sd_surf + +print("\n=== CT-F16a PRIMARY — sign consistency vs the steering flow ===") +print(f" surface displacement (CT-F14) : {f_surf:.3f} ({int((e_surf<0).sum())}/{n})") +print(f" steering flow 500/600/700 hPa : {f_steer:.3f} ({int((e_steer<0).sum())}/{n}), " + f"one-sided p={p_steer:.4f}") +print(f" -> {'PASS' if f_steer >= 0.70 else 'FAIL'} (bar >= 0.70)") + +print("\n=== CT-F16b PAIRED — does the residual TIGHTEN? ===") +print(f" sd(signed offset) surface : {sd_surf:7.2f} deg") +print(f" sd(signed offset) steering : {sd_steer:7.2f} deg ({100*drop:+.1f} %)") +print(f" -> {'PASS' if drop >= 0.10 else 'FAIL'} (bar: >= 10 % reduction)") + +print("\n=== CT-F16d DESCRIPTIVE — sign consistency by level ===") +lev_frac = {} +for lev in SWEEP_LEVELS: + e = np.array([r["err_by_level_deg"][str(lev)] for r in rows]) + lev_frac[str(lev)] = {"sign_neg_frac": frac_neg(e), + "sd_deg": float(e.std(ddof=1))} + print(f" {lev:4d} hPa : frac {frac_neg(e):.3f} sd {e.std(ddof=1):6.1f} deg") +best = max(lev_frac, key=lambda k: lev_frac[k]["sign_neg_frac"]) +print(f" best level: {best} hPa " + f"({'inside' if 400 <= int(best) <= 650 else 'OUTSIDE'} the ladder's " + "400-650 hPa zero-crossing band)") + +out["verdicts"] = { + "CT_F16c_antivacuity": {"permuted_frac": f_perm, "rotated90_frac": f_rot, + "discriminates": bool(c_ok)}, + "CT_F16a": {"surface_frac": f_surf, "steering_frac": f_steer, + "one_sided_p": p_steer, "n": n, + "pass": bool(f_steer >= 0.70)}, + "CT_F16b": {"sd_surface_deg": sd_surf, "sd_steering_deg": sd_steer, + "sd_reduction_frac": drop, "pass": bool(drop >= 0.10)}, + "CT_F16d_by_level": lev_frac, "best_level_hPa": int(best)} + +with open(pathlib.Path(__file__).with_name("comet_tail_f16.json"), "w") as fh: + json.dump(out, fh, indent=2) +print("\nwrote comet_tail_f16.json") From 5f066f6767f435cb1e07f067369bc2fea17ef491 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 12 Aug 2026 10:01:02 +0000 Subject: [PATCH 2/3] probes/weather-p1: CT-F16 RUN -- the leading moderator fails, and the control scored the headline Bars were committed before the run (05f09005). Both primary bars FAIL, in the direction that cuts against this arc's own hypothesis. CT-F16a sign consistency vs 500/600/700 hPa steering flow: 0.579 (11/19), p=0.324, against a 0.70 bar -- WORSE than the surface displacement's 0.684 on the identical storms. CT-F16b paired residual: sd 68.29 -> 87.71 deg, 28.4% WIDER, where a >=10% tightening was predicted. Opposite direction. CT-F16d level sweep improves MONOTONICALLY toward the surface (400 hPa 0.579 -> 850 hPa 0.684; sd 89.5 -> 77.0), best at 850 hPa, OUTSIDE the 400-650 hPa band the height ladder predicted. No mid-tropospheric optimum exists on this sample. Report SS9.2 called steering level "the single most promising fix". It is now measured and it is not a fix; that row is superseded in place. THE CONTROL IS THE LARGER FINDING. F16c scored two deliberately WRONG references through the same pipeline. The 90-deg-rotated steering reference returned 13/19 = 0.684, p=0.0835 -- numerically identical to CT-F14's headline, the figure this arc has carried as "suggestive". At n=19 the ladder is 11->0.324, 13->0.0835, 14->0.0318. CT-F14 was never one storm short of significance; it was one storm short of distinguishability from an answer built to be wrong. Rule banked: an anti-vacuity control measures the RESOLVING POWER of the instrument, not only the test it is attached to. SECOND, INDEPENDENT FINDING: the sign test conflates a systematic rotation with a correct prediction. Weak steering (<10 m/s, n=6): sign 0.833, median |err| 103 deg. Strong steering (>=10 m/s, n=13): sign 0.462, median |err| 55 deg. corr(speed,|err|) = -0.407. Magnitude accuracy improves with steering strength as physics expects while sign consistency moves the opposite way -- because a one-sided sign test on a distribution not centred at zero reports which SIDE the bias falls on. This arc has used it as the primary instrument since SS4. NOT falsified: the height ladder decomposed the FIELD per level about its own centre; CT-F16 keeps the SURFACE dipole and swaps the FLOW reference. Different quantities. The ladder stands; its operational reading is what died. The structural claim (SS9.1) is untouched. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi --- .claude/board/EPIPHANIES.md | 64 ++++ probes/weather-p1/COMET_TAIL_REPORT.md | 82 ++++- probes/weather-p1/comet_tail_f16.json | 417 +++++++++++++++++++++++++ 3 files changed, 562 insertions(+), 1 deletion(-) create mode 100644 probes/weather-p1/comet_tail_f16.json diff --git a/.claude/board/EPIPHANIES.md b/.claude/board/EPIPHANIES.md index 6941004dc..7357082c9 100644 --- a/.claude/board/EPIPHANIES.md +++ b/.claude/board/EPIPHANIES.md @@ -1,3 +1,67 @@ +## 2026-08-12 — E-THE-CONTROL-SCORED-THE-HEADLINE-1 + +**Status:** FINDING `[G]` — `comet_tail_f16.py` / `.json`, bars committed +BEFORE the run (`05f09005`); report §5.12. EXPLORATORY, not an EV. + +**The arc's leading rescue was measured and it failed — and the anti-vacuity +control accidentally calibrated the instrument that had been judging it.** + +CT-F16 swapped ONE variable: the dipole's motion reference, from 6h surface +displacement to the 500/600/700 hPa steering flow, on CT-F14's OWN 19 storms +(paired; stored centres reused, so selection and disk geometry cannot move). +Report §9.2 had named this *"the single most promising fix"*. Measured: +**sign consistency 0.579 against a 0.70 bar** (worse than surface's 0.684), +**residual sd 68.29° → 87.71°, 28.4 % WIDER** where a ≥10 % tightening was +predicted, and a level sweep improving **monotonically toward the SURFACE** — +best at 850 hPa, outside the 400–650 hPa band the height ladder predicted, +converging exactly on the surface-displacement figure. There is no +mid-tropospheric optimum on this sample. + +**The control is the larger finding.** F16c scored two deliberately WRONG +references through the identical pipeline. The **90°-rotated** steering +reference returned **13/19 = 0.684, p=0.0835** — *numerically identical to +CT-F14's headline*, the number this arc has carried as "suggestive" since +§5.11 (a different set of 13 storms, so the count coincides, not the +identity). At n=19 the one-sided ladder is 11→p=0.324, 13→p=0.0835, +**14→p=0.0318**. So **CT-F14 was never one storm short of significance; it was +one storm short of distinguishability from an answer built to be wrong.** + +**Rule: an anti-vacuity control does not only guard the test it is attached to +— it measures the RESOLVING POWER of the instrument.** This one was written to +protect CT-F16 and instead retro-calibrated CT-F14. Attach a +deliberately-wrong reference to any claim whose headline is a rate, and read +the control's score as the floor that headline must clear. Had F16c existed at +§5.11, "0.684, suggestive" would have been reported as "0.684, indistinguishable +from a rotated control". + +**Second finding, independent of the first: the sign test conflates a +SYSTEMATIC ROTATION with a correct prediction.** Stratified by steering +strength — weak flow (<10 m/s, n=6) **sign 0.833 / median |err| 103°**; strong +flow (≥10 m/s, n=13) **sign 0.462 / median |err| 55°**; `corr(speed,|err|) = +−0.407`. The prediction gets **more accurate in magnitude** as steering +strengthens, exactly as the physics expects, while sign consistency moves the +**opposite** way. High sign consistency in the weak subset is errors clustered +near −103°: a systematic rotation, which a sign test reports as success. **A +one-sided sign test on a distribution not centred at zero measures which SIDE +the bias falls on, not whether the prediction holds** — and this arc has used +it as the primary instrument since §4. The apparatus story told since §5.9 +(*slow storms have noisy bearings → filter on displacement*) is not what these +data show: the well-steered storms are the ones whose signs split at chance +while their magnitudes are best. + +**What is NOT falsified.** The height ladder (§5.2/5.8) decomposed the FIELD at +each level about that level's own centre; CT-F16 keeps the SURFACE dipole and +swaps the FLOW reference. Different quantities — the ladder stands as a +measurement (n=2, unreplicated), and what died is the operational reading §9.2 +built on it. The structural claim (§9.1: ring profile, wn-1 dominance, the +12-byte carrier) is untouched; nothing in CT-F16 touches it. + +**Cross-ref:** `E-ZERO-FOR-ELEVEN-THE-AUTHOR-CANNOT-AUDIT-HIS-OWN-FALSIFIERS-1` +(the author is the wrong person to find a spec's vacuous pass routes — here a +control found a *live* one, in a number already published); +`E-THE-HEADLINE-NUMBER-MEASURED-A-MODEL-NOBODY-CLAIMED-1` (the other time this +arc's headline described something other than what was claimed). + ## 2026-08-11 — E-THE-BYTE-WAS-ONLY-THE-SELECTOR-THE-PAIR-IS-THE-CARRIER-1 **Status:** FINDING `[H]` — operator correction + `l4_rail_probe.py` (commit diff --git a/probes/weather-p1/COMET_TAIL_REPORT.md b/probes/weather-p1/COMET_TAIL_REPORT.md index a8a181d93..b1c6e6ae3 100644 --- a/probes/weather-p1/COMET_TAIL_REPORT.md +++ b/probes/weather-p1/COMET_TAIL_REPORT.md @@ -770,6 +770,86 @@ this quantity. No stronger attribution is claimed at n = 2. --- +### 5.12 CT-F16 — the steering-level moderator, measured: **it makes the directional claim WORSE** + +`comet_tail_f16.py` / `.json`. Bars pre-registered and **committed before the +run** (`05f09005`). §9.2 named this "the single most promising fix" for the +directional claim. It has now been tested and it **fails on both bars.** + +**Design.** A *paired* re-scoring of CT-F14's OWN 19 qualifying storms with +**only the motion reference changed** — same storms, same stored centres, same +decomposition, byte-identical `err_deg`. Surface 6h displacement → disk-mean +500/600/700 hPa steering flow. Reusing the stored centres removes storm +selection and disk geometry as variables. **This is a mechanistic test, NOT a +verdict** — a fresh steering-scored sample is CT-F17 and is not run. + +| bar | prediction | measured | verdict | +|---|---|---|---| +| **F16a** sign consistency vs steering flow | ≥ 0.70 | **0.579** (11/19), p=0.324 | **FAIL** — and *worse* than surface's 0.684 | +| **F16b** paired residual tightening | sd drops ≥ 10 % | **68.29° → 87.71°, +28.4 % WIDER** | **FAIL** — opposite direction | +| **F16c** anti-vacuity | permuted & rotated both < 0.70 | 0.421 / 0.684 | PASS — but see the caution below | +| **F16d** level sweep (descriptive) | optimum inside 400–650 hPa | **monotone toward the SURFACE; best 850 hPa** | outside the predicted band | + +The level sweep is the clearest signal, and it points the wrong way: + +| level | 400 | 500 | 600 | 700 | 850 | +|---|---|---|---|---|---| +| sign frac | 0.579 | 0.579 | 0.632 | 0.632 | **0.684** | +| sd (deg) | 89.5 | 87.8 | 82.1 | 80.3 | **77.0** | + +Both columns improve **monotonically as the reference level approaches the +surface**, converging at 850 hPa on exactly the surface-displacement figure. +There is no mid-tropospheric optimum. On this sample the surface displacement +was already the best available motion reference, and mid-level flow is a +*worse* one. + +**⚠ Does this falsify the height ladder (§5.2/5.8)? No — and the distinction +matters.** The ladder decomposed the **field at each level about that level's +own centre**; CT-F16 keeps the **surface dipole** and swaps only the **flow +reference**. Those are different quantities, so the ladder is untouched as a +measurement. What CT-F16 falsifies is the **application** §9.2 proposed on top +of it — "score the dipole against steering-level motion". That inference is now +measured and dead. The ladder (n=2) remains an unreplicated observation whose +operational reading has failed its first test. + +**⚠ The anti-vacuity arm accidentally calibrated the noise floor — and CT-F14's +headline sits exactly on it.** The deliberately **90°-rotated** steering +reference scored **13/19 = 0.684, p=0.0835** — numerically identical to +CT-F14's own headline figure (on a *different* set of 13 storms, so the count +coincides rather than the identity). **A reference constructed to be wrong +produces this arc's "suggestive" number on this sample.** F16c's bar was +`< 0.70` and 0.684 clears it, so the gate passes as written — but the margin is +the finding. At n=19 the one-sided ladder is 11/19 → p=0.324, 13/19 → p=0.0835, +**14/19 → p=0.0318**: the test only separates from chance at 14. CT-F14's +0.684 was never one storm short of significance; it was one storm short of +*distinguishability from a deliberately wrong answer*. + +**⚠ And the sign test is not measuring what the arc assumed.** Stratifying by +steering-flow strength inverts the two statistics against each other: + +| subset | n | sign frac | median \|error\| | +|---|---:|---:|---:| +| weak flow (< 10 m/s) | 6 | **0.833** | **103°** | +| strong flow (≥ 10 m/s) | 13 | **0.462** | **55°** | + +`corr(steering speed, |error|) = −0.407` — the prediction gets **more accurate +in magnitude** as the flow strengthens, which is physically sensible. But sign +consistency moves the *opposite* way. High sign consistency in the weak-flow +subset is not the prediction working: those errors cluster near **−103°**, a +systematic rotation, and a sign test on a distribution centred far from zero +reports the *side* of the offset, not its correctness. The apparatus story this +arc has told since §5.9 — *slow storms have noisy bearings, so filter on +displacement* — is not what these data show; the well-steered storms are the +ones whose signs split at chance while their magnitudes are best. + +**Consequence for the arc.** The directional claim does not merely remain +unproven; its **leading mechanistic rescue is now measured and failed**, and +the instrument used to judge it is shown to conflate a systematic rotation with +a correct prediction. §9.2's ranking of the dry moderators is superseded to +that extent: steering level is no longer "the single most promising fix". The +**structural** claim (§9.1) is untouched — nothing here involves the ring +profile, the wn-1 dominance, or the 12-byte carrier. + ## 6. Product / encoding consequence `[S]` > **⚠ Read with §5.9–5.11 AND the compression correction in §1.** The figures @@ -1119,7 +1199,7 @@ already more explicit structure than a learned model exposes. | moderator | measured evidence | wiring | |---|---|---| -| **Steering level** (baroclinic tilt) | the 92–102° monotone height ladder, zero-crossing 400–650 hPa (§5.2/5.8) | score the dipole against the *steering-level* motion (500–700 hPa flow) instead of the 6h surface displacement — the single most promising fix, **CT-F16** | +| ~~**Steering level** (baroclinic tilt)~~ **— TESTED, FAILED (§5.12)** | the 92–102° monotone height ladder, zero-crossing 400–650 hPa (§5.2/5.8), n=2 | ~~score the dipole against steering-level motion — the single most promising fix, **CT-F16**~~ **RUN: 0.579 vs a 0.70 bar, residual 28.4 % WIDER, level sweep monotone toward the SURFACE (best 850 hPa, outside the predicted band). The ladder as a measurement stands; this operational reading of it is dead.** | | **Displacement magnitude** (label noise) | 6/7 pooled at ≥250 km vs 14/20 unfiltered; CT-F14 0.684 | model the motion-bearing *uncertainty* explicitly instead of a hard cutoff | | **Surface type / friction** | +14° ocean vs +34° land inflow, paired within one disk (§5.7) | a wind-level correction; second-order on the pressure dipole | | **Latitude / f, regime** | the low-wn1 July cases; the 75°N outlier | intake covariates, already computed per storm | diff --git a/probes/weather-p1/comet_tail_f16.json b/probes/weather-p1/comet_tail_f16.json new file mode 100644 index 000000000..a84b42866 --- /dev/null +++ b/probes/weather-p1/comet_tail_f16.json @@ -0,0 +1,417 @@ +{ + "store": "https://storage.googleapis.com/weatherbench2/datasets/era5/1959-2022-6h-1440x721.zarr", + "source": "comet_tail_f14.json qualifying subset", + "steer_levels_hPa": [ + 500, + 600, + 700 + ], + "n": 19, + "rows": [ + { + "date": "1996-03-16T12:00:00", + "t0": 54358, + "center_lat": 37.7606455990929, + "center_lon": 158.35550138007275, + "displacement_km": 394.9627752490917, + "err_surface_deg": -68.29092173098762, + "err_steering_deg": -55.4964456402418, + "steer_speed_ms": 20.893884867023488, + "steer_bearing_rad": -0.013620107639295798, + "low_pole_rad": 0.5885805195793288, + "err_by_level_deg": { + "400": -59.838329834513104, + "500": -57.49978406139752, + "600": -54.938639108651955, + "700": -53.22854650717882, + "850": -57.484084991766565 + } + }, + { + "date": "1997-01-15T12:00:00", + "t0": 55578, + "center_lat": 49.30630498741868, + "center_lon": 329.96462355455805, + "displacement_km": 276.131907815995, + "err_surface_deg": -37.85248283720318, + "err_steering_deg": -41.88760036753982, + "steer_speed_ms": 11.192600318905614, + "steer_bearing_rad": 0.820961163679052, + "low_pole_rad": 1.660680948300792, + "err_by_level_deg": { + "400": -51.67577943655738, + "500": -45.44834257952496, + "600": -41.112301832278064, + "700": -37.77928195663105, + "850": -30.331307443751598 + } + }, + { + "date": "1997-03-17T12:00:00", + "t0": 55822, + "center_lat": 47.12116315432716, + "center_lon": 218.75905030400767, + "displacement_km": 328.84589939421153, + "err_surface_deg": 9.241906494550676, + "err_steering_deg": 19.06883133778618, + "steer_speed_ms": 15.044165553272386, + "steer_bearing_rad": 0.9234407431273538, + "low_pole_rad": 2.827050961274094, + "err_by_level_deg": { + "400": 22.148791083297112, + "500": 20.298922020143806, + "600": 19.17046608541341, + "700": 17.093253022613055, + "850": 10.061778026058306 + } + }, + { + "date": "1999-11-18T12:00:00", + "t0": 59726, + "center_lat": 56.26681556574107, + "center_lon": 178.97969837924182, + "displacement_km": 296.0538640285731, + "err_surface_deg": -32.31823290971391, + "err_steering_deg": -33.380163227723756, + "steer_speed_ms": 9.67421077131886, + "steer_bearing_rad": -0.08184762628111478, + "low_pole_rad": 0.9063549473368648, + "err_by_level_deg": { + "400": -46.26534227865537, + "500": -37.40866178865471, + "600": -32.93849579300499, + "700": -29.360379287813146, + "850": -28.56830161219824 + } + }, + { + "date": "2001-09-19T12:00:00", + "t0": 62410, + "center_lat": 45.102734243947886, + "center_lon": 307.4108806847002, + "displacement_km": 271.6480406924297, + "err_surface_deg": -135.8866370078875, + "err_steering_deg": -124.0206169115745, + "steer_speed_ms": 11.200927732930534, + "steer_bearing_rad": 0.4017789347713794, + "low_pole_rad": 6.091192463284326, + "err_by_level_deg": { + "400": -130.7464895092748, + "500": -126.65603177349436, + "600": -123.87382735163453, + "700": -118.87266160071198, + "850": -113.08014650051786 + } + }, + { + "date": "2002-01-19T12:00:00", + "t0": 62898, + "center_lat": 52.23181291184118, + "center_lon": 328.6795165909927, + "displacement_km": 322.77297720503896, + "err_surface_deg": -9.43809335671719, + "err_steering_deg": -15.690933942651071, + "steer_speed_ms": 17.519419964503772, + "steer_bearing_rad": 0.3769628197504792, + "low_pole_rad": 1.6739006865331794, + "err_by_level_deg": { + "400": -17.81015575023497, + "500": -16.28210608881895, + "600": -15.990736839584656, + "700": -14.559292663684744, + "850": -9.623656106435277 + } + }, + { + "date": "2002-03-21T12:00:00", + "t0": 63142, + "center_lat": 38.751726980533526, + "center_lon": 323.6873562719305, + "displacement_km": 274.6911720596344, + "err_surface_deg": -98.33221272712603, + "err_steering_deg": -74.58270648240982, + "steer_speed_ms": 13.145852615473832, + "steer_bearing_rad": 0.7290192723249141, + "low_pole_rad": 0.9981018059532412, + "err_by_level_deg": { + "400": -76.22661238593426, + "500": -76.85073879438357, + "600": -75.67082544119826, + "700": -68.75360529208191, + "850": -52.26477799004101 + } + }, + { + "date": "2002-07-21T12:00:00", + "t0": 63630, + "center_lat": 28.845082353475743, + "center_lon": 67.81185755361025, + "displacement_km": 457.5499062282751, + "err_surface_deg": 49.13517569045763, + "err_steering_deg": -115.81070042696979, + "steer_speed_ms": 5.595079917438299, + "steer_bearing_rad": -0.8869450228208542, + "low_pole_rad": 4.945758579662202, + "err_by_level_deg": { + "400": -132.17326331006063, + "500": -115.07432656360731, + "600": -107.4572465601405, + "700": -125.95165040211839, + "850": -163.03941412603047 + } + }, + { + "date": "2003-07-22T12:00:00", + "t0": 65094, + "center_lat": 40.20503910539359, + "center_lon": 79.34242857084944, + "displacement_km": 591.8334818738821, + "err_surface_deg": -87.62762374253634, + "err_steering_deg": -89.20263010464555, + "steer_speed_ms": 7.257228643381492, + "steer_bearing_rad": -0.10536566977492949, + "low_pole_rad": 6.191736367434874, + "err_by_level_deg": { + "400": -87.3072468758283, + "500": -89.40694788266802, + "600": -91.43351254962721, + "700": -85.53375362454096, + "850": -65.80408906300465 + } + }, + { + "date": "2004-07-22T12:00:00", + "t0": 66558, + "center_lat": 54.20799369844886, + "center_lon": 130.25559414294094, + "displacement_km": 429.6171401779512, + "err_surface_deg": 126.4843089002764, + "err_steering_deg": 117.50853289638326, + "steer_speed_ms": 10.119190692307956, + "steer_bearing_rad": -0.02762976240892321, + "low_pole_rad": 3.5940773626159297, + "err_by_level_deg": { + "400": 111.82758288577708, + "500": 115.52685640828088, + "600": 117.07038531969937, + "700": 121.64124193134762, + "850": 122.00984677857912 + } + }, + { + "date": "2004-11-21T12:00:00", + "t0": 67046, + "center_lat": 54.75, + "center_lon": 188.15043347333307, + "displacement_km": 306.60785355366534, + "err_surface_deg": -13.583816972829794, + "err_steering_deg": 18.377084048600693, + "steer_speed_ms": 16.251132252644478, + "steer_bearing_rad": 0.9397407008191558, + "low_pole_rad": 2.8312776511778646, + "err_by_level_deg": { + "400": 20.73660070719555, + "500": 18.99933069673773, + "600": 18.21456129585468, + "700": 17.717903526921532, + "850": 5.988347332778545 + } + }, + { + "date": "2005-05-23T12:00:00", + "t0": 67778, + "center_lat": 49.66383829643146, + "center_lon": 338.7627794330812, + "displacement_km": 307.28577630573585, + "err_surface_deg": -0.6118558893321051, + "err_steering_deg": 14.233197222440708, + "steer_speed_ms": 10.90237942206143, + "steer_bearing_rad": 0.24556012017853057, + "low_pole_rad": 2.0647726015907293, + "err_by_level_deg": { + "400": 14.031168703738501, + "500": 13.091975117165447, + "600": 15.948834027319549, + "700": 13.938485092428152, + "850": 6.901574005296283 + } + }, + { + "date": "2006-01-22T12:00:00", + "t0": 68754, + "center_lat": 41.63454690695439, + "center_lon": 158.0240357377511, + "displacement_km": 291.43078891941735, + "err_surface_deg": 46.520425963822305, + "err_steering_deg": 87.97929041259249, + "steer_speed_ms": 18.888531375646444, + "steer_bearing_rad": 0.7827201144252919, + "low_pole_rad": 3.889044732488208, + "err_by_level_deg": { + "400": 93.33934084003317, + "500": 89.4431851363114, + "600": 89.01523573680828, + "700": 83.97358398331141, + "850": 49.431471370709176 + } + }, + { + "date": "2006-03-24T12:00:00", + "t0": 68998, + "center_lat": 40.081768429120515, + "center_lon": 316.97489409322253, + "displacement_km": 282.49422464834026, + "err_surface_deg": -58.900962386334385, + "err_steering_deg": -54.82071331935245, + "steer_speed_ms": 13.663558939602074, + "steer_bearing_rad": 0.09416265739708433, + "low_pole_rad": 0.708157038477371, + "err_by_level_deg": { + "400": -61.540008229027066, + "500": -58.20688097688398, + "600": -54.72627767299666, + "700": -49.70249285208149, + "850": -33.27679812600337 + } + }, + { + "date": "2007-01-23T12:00:00", + "t0": 70218, + "center_lat": 39.33113364502934, + "center_lon": 174.7526838816152, + "displacement_km": 317.67915242399596, + "err_surface_deg": 108.08865494211045, + "err_steering_deg": 110.83868457970243, + "steer_speed_ms": 22.460354498807664, + "steer_bearing_rad": 0.27944717000506025, + "low_pole_rad": 3.784743481295231, + "err_by_level_deg": { + "400": 112.57962589311364, + "500": 113.095942073213, + "600": 111.60153107752132, + "700": 105.90251809828118, + "850": 82.57016302173577 + } + }, + { + "date": "2009-05-26T12:00:00", + "t0": 73634, + "center_lat": 32.081890067957204, + "center_lon": 85.29824266895127, + "displacement_km": 585.0246566127836, + "err_surface_deg": -53.08536899757155, + "err_steering_deg": 177.88228339735582, + "steer_speed_ms": 5.360588233148435, + "steer_bearing_rad": -0.1406915616760268, + "low_pole_rad": 4.5347362913683735, + "err_by_level_deg": { + "400": 146.88706422182213, + "500": 164.80969521013878, + "600": -174.62541647760298, + "700": -172.08372255443373, + "850": -161.97648447470897 + } + }, + { + "date": "2009-07-26T12:00:00", + "t0": 73878, + "center_lat": 34.14437390359832, + "center_lon": 71.81849475304371, + "displacement_km": 363.2025023438297, + "err_surface_deg": -93.58088940292669, + "err_steering_deg": -148.69260686646555, + "steer_speed_ms": 3.4780222783006693, + "steer_bearing_rad": -0.8830706971097777, + "low_pole_rad": 4.375735373671352, + "err_by_level_deg": { + "400": -176.60909933579978, + "500": -158.19430225088678, + "600": -149.47506431516194, + "700": -134.93946522107103, + "850": -152.45008516792728 + } + }, + { + "date": "2009-09-25T12:00:00", + "t0": 74122, + "center_lat": 69.01585282912403, + "center_lon": 353.4343585345505, + "displacement_km": 562.8503596905939, + "err_surface_deg": 0.13717943106883013, + "err_steering_deg": 1.4961231807097874, + "steer_speed_ms": 14.058687512366305, + "steer_bearing_rad": 0.4892440056722573, + "low_pole_rad": 2.0861526079859494, + "err_by_level_deg": { + "400": 3.4097472141104106, + "500": 1.7990182929773084, + "600": 2.0847834302397814, + "700": 0.40412512958917546, + "850": -6.870111260628079 + } + }, + { + "date": "2009-11-25T12:00:00", + "t0": 74366, + "center_lat": 59.52619677699913, + "center_lon": 352.03934730709716, + "displacement_km": 270.81659311746546, + "err_surface_deg": -30.594845686320213, + "err_steering_deg": -41.24289549429341, + "steer_speed_ms": 6.876359597323519, + "steer_bearing_rad": 0.381631449382264, + "low_pole_rad": 1.2326034567458064, + "err_by_level_deg": { + "400": -58.25206976979618, + "500": -49.115244831619066, + "600": -39.77289855449334, + "700": -32.383346410420245, + "850": -22.24999021670004 + } + } + ], + "scope": "PAIRED re-scoring of CT-F14's own storms with ONLY the motion reference changed. MECHANISTIC test, NOT a verdict \u2014 a fresh-sample verdict is CT-F17, not run.", + "verdicts": { + "CT_F16c_antivacuity": { + "permuted_frac": 0.42105263157894735, + "rotated90_frac": 0.6842105263157895, + "discriminates": true + }, + "CT_F16a": { + "surface_frac": 0.6842105263157895, + "steering_frac": 0.5789473684210527, + "one_sided_p": 0.3238029479980469, + "n": 19, + "pass": false + }, + "CT_F16b": { + "sd_surface_deg": 68.28621577501147, + "sd_steering_deg": 87.71263184119131, + "sd_reduction_frac": -0.284485175312478, + "pass": false + }, + "CT_F16d_by_level": { + "400": { + "sign_neg_frac": 0.5789473684210527, + "sd_deg": 89.54592193903673 + }, + "500": { + "sign_neg_frac": 0.5789473684210527, + "sd_deg": 87.8040436831529 + }, + "600": { + "sign_neg_frac": 0.631578947368421, + "sd_deg": 82.06685657920383 + }, + "700": { + "sign_neg_frac": 0.631578947368421, + "sd_deg": 80.25137388442171 + }, + "850": { + "sign_neg_frac": 0.6842105263157895, + "sd_deg": 77.02385632711038 + } + }, + "best_level_hPa": 850 + } +} \ No newline at end of file From bd2f93d650a4ce88093c87ca7c5e731f5e30dfb5 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 12 Aug 2026 10:46:07 +0000 Subject: [PATCH 3/3] probes/weather-p1: the 0.684 plateau was the INSTRUMENT -- circular resultant resolves the same rows at p=0.005 Operator: "die irrationale Aufsummierung hilft, dass der Dipol nicht auf 0.68 kollabiert." Measured on the SAME 19 stored storms, no fetch, post-hoc and explicitly NOT a verdict: referent sign<0 R_bar mu Rayleigh p surface (F14) 0.684 0.516 -30.2deg 0.0050 steering (F16) 0.579 0.343 -40.5deg 0.107 CONTROL rot+90 0.684 0.343 -130.5deg 0.107 CONTROL permuted 0.421 0.142 -- 0.689 Three findings: 1. The 0.684 plateau was a property of the STATISTIC, not the data. The sign test collapses each error vector to one bit; 19 bits saturate below the 14/19 floor. The vector Aufsummierung (circular resultant) resolves the identical rows at p=0.0050 -- concentration and offset become two numbers instead of eating each other. The arc's ~-40deg systematic offset is now ESTIMATED (-30.2 +/- 36.5 deg) instead of penalized. 2. The wrong referent is VISIBLE. The rotated control that scored an indistinguishable 0.684 under the sign test shows the same R_bar with mu shifted 100.3 deg -- separated far beyond both CIs. Instrument hierarchy: real (0.516) > structured-but-wrong (0.343, wrong mu) > permuted (0.142, below the uniform floor 0.203). 3. Every prior sign-consistency number in the arc (2/2, 6/10, 8/10, 13/19) was read through an instrument that cannot estimate the offset it penalizes and cannot distinguish a rotated referent at these n. Bounded in BOTH directions: the sign test neither established the claim nor could it have. Faltung reading folded into SS5.13: the resultant is the first circular Fourier coefficient (Faltung with e^{i theta}); the W6 two-component fit is a DEconvolution (component mix conv apparatus noise, +/-3-7 deg from CT-F4); on Z_256 the circular Faltung is substrate-native (DistanceLut::circular's domain, FFT-able). Not promoted: same sample, post-hoc. CT-W6 = the pre-registered circular- statistics use; CT-F17 = the fresh-sample verdict. Co-Authored-By: Claude Claude-Session: https://claude.ai/code/session_01CcpLeEC3XK8Eye53GKBVvi --- probes/weather-p1/COMET_TAIL_REPORT.md | 54 +++++++ .../comet_tail_resultant_instrument.json | 38 +++++ .../comet_tail_resultant_instrument.py | 138 ++++++++++++++++++ 3 files changed, 230 insertions(+) create mode 100644 probes/weather-p1/comet_tail_resultant_instrument.json create mode 100644 probes/weather-p1/comet_tail_resultant_instrument.py diff --git a/probes/weather-p1/COMET_TAIL_REPORT.md b/probes/weather-p1/COMET_TAIL_REPORT.md index b1c6e6ae3..cf5e3acc2 100644 --- a/probes/weather-p1/COMET_TAIL_REPORT.md +++ b/probes/weather-p1/COMET_TAIL_REPORT.md @@ -850,6 +850,60 @@ that extent: steering level is no longer "the single most promising fix". The **structural** claim (§9.1) is untouched — nothing here involves the ring profile, the wn-1 dominance, or the 12-byte carrier. +### 5.13 The instrument was the collapse: circular resultant vs sign test, same 19 storms + +`comet_tail_resultant_instrument.py` / `.json`. **Post-hoc re-analysis of +stored rows — explicitly NOT a verdict.** Operator framing: *"die irrationale +Aufsummierung hilft, dass der Dipol nicht auf 0.68 kollabiert."* Measured: + +| referent | sign < 0 | R̄ | μ | μ 95 % CI | Rayleigh p | +|---|---:|---:|---:|---:|---:| +| **surface (CT-F14)** | 0.684 | **0.516** | **−30.2°** | ±36.5° | **0.0050** | +| steering (CT-F16) | 0.579 | 0.343 | −40.5° | ±64.3° | 0.107 | +| CONTROL rot+90° | **0.684** | 0.343 | **−130.5°** | ±64.7° | 0.107 | +| CONTROL permuted | 0.421 | 0.142 | — | ±152° | 0.689 | + +(uniform-expectation R̄ at n=19 ≈ 0.203) + +Three things, in order of importance: + +1. **The 0.684 plateau was a property of the STATISTIC, not the data.** The + sign test collapses each storm's error vector to one bit; 19 bits saturate + below the 14/19 distinguishability floor (§5.12). The circular resultant — + the *Aufsummierung*: sum the unit error vectors, read length and direction + — resolves the identical rows at **p = 0.0050**, because concentration (R̄) + and offset (μ) come out as two numbers instead of eating each other. The + systematic ≈−30° offset the arc has chased since §5.1 is now *estimated* + (−30.2° ± 36.5°) instead of *penalizing the score*. +2. **The wrong referent is now visible.** F16c's rotated control scored + 0.684 = indistinguishable under the sign test. Under the resultant it has + the same R̄ (rotation preserves concentration, by construction) but μ + shifted **100.3°** — separated by well over both CIs. The instrument + hierarchy is clean: real referent (0.516) > structured-but-wrong (0.343, + wrong μ) > permuted (0.142, below the uniform floor). +3. **NOT a promotion.** Same sample, post-hoc — the p=0.0050 demonstrates the + instrument, it does not establish the directional claim. CT-W6 is the + pre-registered use of circular statistics on these rows (with the + two-component Faltung decomposition); a fresh-sample verdict is CT-F17. + +**The Faltung reading (operator, same exchange):** the resultant IS the first +circular Fourier coefficient — a Faltung of the empirical error distribution +with `e^{iθ}`. The generalization is the full harmonic/kernel readout (von +Mises smoothing = circular Faltung; n=19 supports the first 2–3 harmonics), +and the W6 decomposition is a DEconvolution: the measured dipole distribution += (referent component mix) ⊛ (apparatus noise, ±3–7° measured in CT-F4). +Components add linearly in the transform domain, which is exactly what makes +the multi-referent separation solvable — and on the palette ring `Z_256` the +circular convolution is native to the substrate (`DistanceLut::circular()`'s +own domain, FFT-able at 256 points). + +**Consequence for every prior sign-consistency number in this document:** +§4's 2/2, §5.9's 6/10, §5.10's 8/10, §5.11's 13/19 were all read through an +instrument that (a) cannot estimate the offset it penalizes and (b) cannot +distinguish a rotated referent at these n. They stand as recorded, but their +evidential weight is bounded by this section, in both directions — the sign +test neither established the claim nor could it have. + ## 6. Product / encoding consequence `[S]` > **⚠ Read with §5.9–5.11 AND the compression correction in §1.** The figures diff --git a/probes/weather-p1/comet_tail_resultant_instrument.json b/probes/weather-p1/comet_tail_resultant_instrument.json new file mode 100644 index 000000000..4b0bb8ac4 --- /dev/null +++ b/probes/weather-p1/comet_tail_resultant_instrument.json @@ -0,0 +1,38 @@ +{ + "n": 19, + "source": "comet_tail_f16.json rows (paired, stored)", + "scope": "POST-HOC instrument comparison on the same storms whose sign test returned NO-VERDICT. Not a verdict; CT-W6 is the pre-registered use, CT-F17 the fresh-sample one.", + "referents": { + "surface (CT-F14)": { + "sign_neg_frac": 0.6842105263157895, + "R_bar": 0.5164480996096197, + "mu_deg": -30.193114037358924, + "mu_ci95_deg": 36.52016531393819, + "rayleigh_p": 0.004967482150890209 + }, + "steering (CT-F16)": { + "sign_neg_frac": 0.5789473684210527, + "R_bar": 0.342632911535701, + "mu_deg": -40.52194970164434, + "mu_ci95_deg": 64.29776042051351, + "rayleigh_p": 0.10672421673666334 + }, + "CONTROL rot+90": { + "sign_neg_frac": 0.6842105263157895, + "R_bar": 0.34263291153570086, + "mu_deg": -130.52194970164436, + "mu_ci95_deg": 64.69069385224262, + "rayleigh_p": 0.10672421673666359 + }, + "CONTROL permuted": { + "sign_neg_frac": 0.42105263157894735, + "R_bar": 0.14168656351290035, + "mu_deg": -28.449526845634523, + "mu_ci95_deg": 152.15618068129842, + "rayleigh_p": 0.688473350954606 + } + }, + "discrimination": { + "mu_separation_deg": 100.3288356642854 + } +} \ No newline at end of file diff --git a/probes/weather-p1/comet_tail_resultant_instrument.py b/probes/weather-p1/comet_tail_resultant_instrument.py new file mode 100644 index 000000000..d0e986dc2 --- /dev/null +++ b/probes/weather-p1/comet_tail_resultant_instrument.py @@ -0,0 +1,138 @@ +"""EXPLORATORY — the INSTRUMENT comparison: sign test vs circular resultant, +on the SAME 19 stored storms. Post-hoc re-analysis, explicitly NOT a verdict. + +Operator (2026-08-12): "die irrationale Aufsummierung hilft, dass [der] Dipol +nicht auf 0.68 kollabiert." This probe measures that claim's core mechanism. + +THE ANATOMY OF THE 0.684 COLLAPSE. CT-F14/F16 scored the dipole with a SIGN +test: each storm's signed angular error collapses to one bit (error < 0?), and +19 bits saturate — F16c measured that a 90-deg-ROTATED reference also scores +0.684, i.e. the statistic cannot distinguish the real referent from a wrong +one at this n. Two distinct losses happen at the binarization: + + (1) MAGNITUDE is discarded — a tight cluster at -103 deg and a loose cloud + straddling zero can produce the same bit count (measured in F16's + weak/strong stratification). + (2) The MEAN DIRECTION is discarded — a systematic offset (the arc's -40 + deg) EATS the sign margin instead of being estimated. + +THE FIX IS AN AUFSUMMIERUNG: keep the error VECTORS and sum them. The +circular resultant R_bar (mean resultant length) + mean direction mu is the +standard directional statistic (Rayleigh test). It preserves exactly what the +sign test destroys: concentration (R_bar) and offset (mu) come out as two +separate numbers. A rotated control then shows the SAME R_bar with mu shifted +by 90 deg — visibly wrong — where the sign test scored it identically. + +Where the IRRATIONALITY enters (the operator's framing, demarcated honestly): +the vector summation itself is what prevents the collapse; the irrational +(golden/low-discrepancy) structure is what keeps the summation UNBIASED — +no resonance between sampling geometry and signal harmonics (within-storm, +load-bearing once the dipole is estimated from SPARSE spiral samples instead +of the dense grid), and natural phase diversity across storms (which is what +makes the CT-W6 multi-component fit identifiable at all). + +SCOPE: same 19 storms whose sign test returned NO-VERDICT. This is an +instrument demonstration on stored data — the verdict-grade use of the +resultant is CT-W6 on the same rows with pre-registered bars, and any FRESH +claim needs a fresh sample (CT-F17). Nothing here promotes the directional +claim; it measures what the previous instrument could not see. +""" +import json +import pathlib + +import numpy as np + +N_BOOT = 20_000 +RNG_SEED = 20260812 # fixed before running; bootstrap is deterministic + + +def wrap_deg(d): + """Wrap degrees into [-180, 180) — the identical convention CT-F14/F16 use.""" + return (d + 180.0) % 360.0 - 180.0 + + +def circular(errs_deg, n): + """Resultant length R_bar, mean direction mu (deg), Rayleigh p. + + R_bar in [0,1] measures CONCENTRATION (1 = all vectors identical, 0 = + uniform); mu is WHERE the cluster sits — the offset the sign test could + only penalize. Rayleigh Z = n*R_bar^2 with the standard small-n corrected + p-approximation (Zar/Mardia). Under uniformity E[R_bar] ~ sqrt(pi)/(2*sqrt(n)). + """ + th = np.deg2rad(np.asarray(errs_deg)) + c, s = np.cos(th).mean(), np.sin(th).mean() + r = float(np.hypot(c, s)) + mu = float(np.rad2deg(np.arctan2(s, c))) + z = n * r * r + p = float(np.exp(-z) * (1 + (2 * z - z * z) / (4 * n) + - (24 * z - 132 * z**2 + 76 * z**3 - 9 * z**4) + / (288 * n * n))) + return r, mu, max(min(p, 1.0), 0.0) + + +def boot_mu_ci(errs_deg, n, rng): + """Bootstrap 95% CI half-width (deg) for the mean direction mu.""" + th = np.deg2rad(np.asarray(errs_deg)) + idx = rng.integers(0, n, size=(N_BOOT, n)) + c = np.cos(th)[idx].mean(axis=1) + s = np.sin(th)[idx].mean(axis=1) + mus = np.rad2deg(np.arctan2(s, c)) + mu0 = np.rad2deg(np.arctan2(np.sin(th).mean(), np.cos(th).mean())) + dev = wrap_deg(mus - mu0) + lo, hi = np.percentile(dev, [2.5, 97.5]) + return float(max(abs(lo), abs(hi))) + + +rows = json.loads(pathlib.Path(__file__).with_name( + "comet_tail_f16.json").read_text())["rows"] +n = len(rows) +assert n == 19, f"expected CT-F14's 19 qualifying storms, got {n}" +rng = np.random.default_rng(RNG_SEED) + +e_surf = np.array([r["err_surface_deg"] for r in rows]) +e_steer = np.array([r["err_steering_deg"] for r in rows]) +lp = np.array([r["low_pole_rad"] for r in rows]) +sb = np.array([r["steer_bearing_rad"] for r in rows]) + +# the two F16c controls, recomputed per-row with the identical err convention +e_rot = wrap_deg(np.rad2deg(lp - (sb + np.pi / 2 + np.pi / 2))) +perm = sb[(np.arange(n) + 7) % n] +e_perm = wrap_deg(np.rad2deg(lp - (perm + np.pi / 2))) + +out = {"n": n, "source": "comet_tail_f16.json rows (paired, stored)", + "scope": ("POST-HOC instrument comparison on the same storms whose " + "sign test returned NO-VERDICT. Not a verdict; CT-W6 is the " + "pre-registered use, CT-F17 the fresh-sample one."), + "referents": {}} + +print(f"{'referent':<22} {'sign<0':>7} {'R_bar':>7} {'mu':>9} " + f"{'mu 95% CI':>10} {'Rayleigh p':>11}") +for name, e in (("surface (CT-F14)", e_surf), + ("steering (CT-F16)", e_steer), + ("CONTROL rot+90", e_rot), + ("CONTROL permuted", e_perm)): + r, mu, p = circular(e, n) + ci = boot_mu_ci(e, n, rng) + frac = float((np.asarray(e) < 0).mean()) + out["referents"][name] = {"sign_neg_frac": frac, "R_bar": r, + "mu_deg": mu, "mu_ci95_deg": ci, + "rayleigh_p": p} + print(f"{name:<22} {frac:>7.3f} {r:>7.3f} {mu:>+8.1f}° " + f"±{ci:>7.1f}° {p:>11.4f}") + +su, ro = out["referents"]["surface (CT-F14)"], out["referents"]["CONTROL rot+90"] +sep = abs(wrap_deg(su["mu_deg"] - ro["mu_deg"])) +print(f"\nuniform-expectation R_bar at n={n}: " + f"{np.sqrt(np.pi) / (2 * np.sqrt(n)):.3f}") +print(f"\nTHE DISCRIMINATION THE SIGN TEST LACKED:") +print(f" sign test : surface {su['sign_neg_frac']:.3f} vs rotated control " + f"{ro['sign_neg_frac']:.3f} -> conflated at n={n}") +print(f" resultant : mu separated by {sep:.1f}° " + f"(CIs ±{su['mu_ci95_deg']:.0f}°/±{ro['mu_ci95_deg']:.0f}°) at " + f"near-identical R_bar -> the wrong referent is VISIBLE") +out["discrimination"] = {"mu_separation_deg": sep} + +with open(pathlib.Path(__file__).with_name( + "comet_tail_resultant_instrument.json"), "w") as fh: + json.dump(out, fh, indent=2) +print("\nwrote comet_tail_resultant_instrument.json")