Thibaut Forest Claude Opus 5 (1M context) commited on
Commit
ab4b0fd
·
1 Parent(s): e44c7a4

Phase 44: leaderboard inversion - appetite closed on numbers, tail transfer is the defect, no local instrument sees it

Browse files
Files changed (2) hide show
  1. EXPERIMENTS.md +87 -0
  2. batteryswap_example/cv.py +51 -1
EXPERIMENTS.md CHANGED
@@ -2226,3 +2226,90 @@ Every axis now has a measurement against it: appetite (public), features
2226
  demonstrably extractable by someone. We cannot account for them from any
2227
  mechanism measurable here, and the only path this sweep demonstrated is the
2228
  one in (a), which we are not taking.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2226
  demonstrably extractable by someone. We cannot account for them from any
2227
  mechanism measurable here, and the only path this sweep demonstrated is the
2228
  one in (a), which we are not taking.
2229
+
2230
+ ## Phase 44 - why our late_swap is the field's highest (full leaderboard inversion)
2231
+
2232
+ The public board exposes all 14 teams' components. Inverting each team's
2233
+ `late_swap` through the emergency-queue cost model (each miss = one dedicated
2234
+ day at `(24 + k) * 10`, solved for k self-consistently) gives, per scenario:
2235
+
2236
+ | team | swaps | misses | caught | precision |
2237
+ |---|---|---|---|---|
2238
+ | J2W | 14.9 | 2.45 | 7.65 | 0.51 |
2239
+ | YassY | 17.4 | 2.37 | 7.73 | 0.44 |
2240
+ | CarlAlbert | 15.5 | 2.80 | 7.30 | 0.47 |
2241
+ | sackriti | 14.5 | 3.21 | 6.89 | 0.48 |
2242
+ | **us** | **12.1** | **4.69** | **5.41** | **0.45** |
2243
+ | kalsach | 28.2 | 2.14 | 7.96 | 0.28 |
2244
+
2245
+ Deaths solve to ~10.1/scenario (local all-48 is 9.5 - good agreement).
2246
+
2247
+ **Our per-swap precision, 0.45, is mid-pack in a field of 0.28-0.51.** The
2248
+ ranking is not broadly worse. We simply buy the fewest swaps in the
2249
+ competition - 580, against 695 for the next-lowest and 1355 for the highest -
2250
+ so we catch 5.41 where everyone else catches 7.3-8.0, and each of the ~2 extra
2251
+ misses costs ~285.
2252
+
2253
+ ### Appetite is genuinely closed - now with numbers, not an argument
2254
+
2255
+ From phase 28's own measurement: +8.2 swaps/scenario moved `early_swap` +444,
2256
+ so a **marginal false swap costs 54**. Our ops (309 at 4.69 misses) against
2257
+ J2W's (252 at 2.45) prices the emergency day at **25 per miss**, so a miss
2258
+ costs 260 + 25 = **285**. Break-even is therefore **15.9%**, and our local
2259
+ precision in ranks 13-20 is `(0.705-0.564)*9.5/8` = **16.7%**. The marginal
2260
+ pick sits exactly on break-even. Raising alpha cannot pay.
2261
+
2262
+ The cliff-contamination escape is also closed: **cliff rows die at 39.4%, 17x
2263
+ the base rate**, at 12.0 rows/scenario. They are good picks, so phase 28's
2264
+ "zero extra catches" was not an artifact of the boost's reordering.
2265
+
2266
+ ### The real defect, and why no local instrument can see it
2267
+
2268
+ Our ranks 13-20 are 16.7% precise locally and **~0% on public** (phase 28: 395
2269
+ extra swaps bought `late_swap +13`). J2W's 13th-15th picks run at **80%**. The
2270
+ head transfers to a foreign fleet; the tail is noise.
2271
+
2272
+ Where the misses live (native, 454 deaths):
2273
+
2274
+ | rank band | n | frac stale > 7d | median n_30 |
2275
+ |---|---|---|---|
2276
+ | 1-12 (head) | 256 | 0.04 | 30 |
2277
+ | 13-30 (tail) | 104 | 0.03 | 30 |
2278
+ | 31+ | 94 | **0.30** | 30 |
2279
+ | fleet baseline | - | 0.16 | - |
2280
+
2281
+ Rank 31+ is the closed silent-death channel (staleness at 2x the base rate).
2282
+ The tail is **fully-observed devices** - 3% stale, 30 readings in 30 days -
2283
+ that we simply order below rank 12 and J2W orders above it.
2284
+
2285
+ Two things were tested against it and both failed:
2286
+
2287
+ - **Fleet calibration shift.** The half-fleet gate splits ONE fleet, so it has
2288
+ no calibration offset by construction. Injected one (+/-0.03, +/-0.06 V on
2289
+ the target fleet only, with tau moved along the curve at 572 d/V). Recall
2290
+ moved by at most 0.005 at every N. The reason is elementary and closes the
2291
+ hypothesis: **a uniform offset shifts every device's linear predictor
2292
+ equally and cannot reorder a linear model at all.** It also explains why
2293
+ `vrel` does nothing - it protects against the one perturbation that was
2294
+ already harmless.
2295
+ - **Regularisation.** Effective n is ~80 death-batteries, not 66503 rows, so
2296
+ `logbag`'s `C=1.0` is tuned for a sample ~800x too large. Swept C over 100x:
2297
+
2298
+ | | C=1.0 | C=0.3 | C=0.1 | C=0.03 | C=0.01 |
2299
+ |---|---|---|---|---|---|
2300
+ | gate, tail gain 13-30 | 0.154 | 0.155 | 0.157 | 0.158 | 0.153 |
2301
+ | native, tail gain 13-30 | 0.229 | 0.231 | **0.247** | 0.244 | 0.240 |
2302
+ | native rec@12 | **0.564** | 0.562 | 0.551 | 0.557 | 0.555 |
2303
+
2304
+ Flat on the gate. Natively it trades head for tail (C=0.3: +5 at N=16 and +6
2305
+ at N=20, both 5W/0L, but -1 at N=12). At our operating N of ~12 it is
2306
+ negative. Rejected.
2307
+
2308
+ **The blocker is instrumental.** The gate reports a perfectly healthy tail -
2309
+ rec@12 0.766, tail gain 0.154 - while public reports ~0% marginal precision
2310
+ there. No local protocol reproduces the defect, so no local protocol can
2311
+ validate a fix for it. That is the honest reason this stops here rather than
2312
+ a claim that nothing is left: J2W demonstrably finds 2.2 deaths per scenario,
2313
+ in well-observed data, that our ordering puts below the cut.
2314
+
2315
+ Standing champion remains **3c7b883 at 1661.45**.
batteryswap_example/cv.py CHANGED
@@ -352,9 +352,52 @@ def _order_stats(p42, deaths, ns):
352
  return out
353
 
354
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
355
  def ablate(variants=ABLATION, protocol='all48', origins=range(48),
356
  ns=(8, 12, 16, 20, 30), seeds=(0, 1, 2, 3, 4),
357
- dataset_path=Path('dataset')):
358
  """Phase-39's standing directive, made runnable.
359
 
360
  A feature ablation scored on COST cannot answer whether a feature helped:
@@ -393,6 +436,10 @@ def ablate(variants=ABLATION, protocol='all48', origins=range(48),
393
  else:
394
  locations, timeseries, eol_times, scenarios = mc.load_dataset(
395
  dataset_path / 'train')
 
 
 
 
396
  dev_b = locations.drop_duplicates('battery').set_index('battery')['building']
397
  t['bldg'] = t['device_id'].map(dev_b)
398
  closed = t['origin'] <= t['origin'].max() - pd.Timedelta(days=WINDOW_DAYS)
@@ -416,6 +463,9 @@ def ablate(variants=ABLATION, protocol='all48', origins=range(48),
416
  & (e <= T + pd.Timedelta(days=WINDOW_DAYS))])
417
  if not deaths:
418
  continue
 
 
 
419
  for v in variants:
420
  mc.FEATURES = list(VARIANTS[v](t))
421
  p = models[v].predict(rows)['p42']
 
352
  return out
353
 
354
 
355
+ # Voltage-LEVEL features. A fleet whose sensors sit at a different calibration
356
+ # offset shifts all of these together; every other feature in FEATURES is a
357
+ # difference, a rate, a count or a self-relative fraction (below_frac is scored
358
+ # against the device's OWN baseline) and is therefore offset-invariant. vrel
359
+ # and vmin7_rank are invariant BY CONSTRUCTION - that is what they are for.
360
+ LEVEL_FEATURES = ('v_last', 'v_min_30', 'v_min_7', 'v_corr_last', 'thresh_dist')
361
+
362
+
363
+ def apply_fleet_shift(rows, delta, dtau_dv=None):
364
+ """Simulate a differently-calibrated target fleet.
365
+
366
+ The half-fleet gate splits ONE fleet, so both halves share sensor
367
+ calibration, battery batches and the maintenance era - it has no
368
+ fleet-level offset by construction and therefore CANNOT test transfer
369
+ under one. This injects the offset a real held-out fleet may carry.
370
+
371
+ vrel and vmin7_rank are recomputed from the shifted values and come out
372
+ numerically identical; that is the whole point of the comparison.
373
+ """
374
+ r = rows.copy()
375
+ for c in LEVEL_FEATURES:
376
+ if c in r.columns:
377
+ r[c] = r[c] + delta
378
+ if dtau_dv and 'tau_projected' in r.columns:
379
+ # tau is days-to-threshold read off the temp-corrected curve, so an
380
+ # offset moves it along the local slope of that curve
381
+ r['tau_projected'] = r['tau_projected'] + delta * dtau_dv
382
+ if 'vrel' in r.columns:
383
+ r['vrel'] = r['v_last'] - r['v_last'].median()
384
+ if 'vmin7_rank' in r.columns:
385
+ r['vmin7_rank'] = r['v_min_7'].rank(pct=True)
386
+ return r
387
+
388
+
389
+ def estimate_dtau_dv(t):
390
+ """Empirical days-of-tau per volt, from the fleet's own corrected curve."""
391
+ d = t[['tau_projected', 'v_corr_last']].dropna()
392
+ d = d[d['tau_projected'].abs() < 400]
393
+ if len(d) < 100:
394
+ return 0.0
395
+ return float(np.polyfit(d['v_corr_last'], d['tau_projected'], 1)[0])
396
+
397
+
398
  def ablate(variants=ABLATION, protocol='all48', origins=range(48),
399
  ns=(8, 12, 16, 20, 30), seeds=(0, 1, 2, 3, 4),
400
+ dataset_path=Path('dataset'), shift=0.0, shift_tau=True):
401
  """Phase-39's standing directive, made runnable.
402
 
403
  A feature ablation scored on COST cannot answer whether a feature helped:
 
436
  else:
437
  locations, timeseries, eol_times, scenarios = mc.load_dataset(
438
  dataset_path / 'train')
439
+ dtau_dv = estimate_dtau_dv(t)
440
+ if shift:
441
+ print(f'TARGET-fleet shift {shift:+.3f} V, dtau/dv {dtau_dv:.0f} d/V',
442
+ file=sys.stderr)
443
  dev_b = locations.drop_duplicates('battery').set_index('battery')['building']
444
  t['bldg'] = t['device_id'].map(dev_b)
445
  closed = t['origin'] <= t['origin'].max() - pd.Timedelta(days=WINDOW_DAYS)
 
463
  & (e <= T + pd.Timedelta(days=WINDOW_DAYS))])
464
  if not deaths:
465
  continue
466
+ if shift:
467
+ rows = apply_fleet_shift(
468
+ rows, shift, dtau_dv if shift_tau else None)
469
  for v in variants:
470
  mc.FEATURES = list(VARIANTS[v](t))
471
  p = models[v].predict(rows)['p42']