Commit History
-
Phase 48: public refutes cert-first (+43.19, ghost force-swaps at ~111 early-days each); default off
Thibaut Forest +1: Claude Opus 5 (1M context)Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>e382bfa -
Phase 46 addendum: threshold sweep - cert-first works only at the label rule's exact parameters; direction closed
Thibaut Forest +1: Claude Opus 5 (1M context)Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>54b578c -
Phase 49: four new ordering-signal families opened and closed - longitudinal cross-origin, interactions, tau re-rank, temporal ensembling; the marginal-rank defect is missing information, not noise
Thibaut Forest +1: Claude Fable 5Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>2cabcac -
Phase 48 submission: isolate cert-first (HELDOUT_POOL default off)
Thibaut Forest +1: Claude Opus 5 (1M context)Public look spent on the phase-46 certainty-first ordering: rank_score = 2+p42 for devices whose gated daily median sustained <2.40 V for 3 consecutive gated readings, all confirmed <= origin. Local all-48 cost 1661.7 -> 1623.7, 3W/0L/45T; loss-free at every fixed N on both instruments; fires 0.46 devices/scenario (the label-lag wobble population). Pooling default flipped off per its public verdict (phase 42: 1665.89 vs 1661.45, 3x training deaths bought zero recall), so this submission is cert-first against the 1661.45 champion with no confound. Rehearsed on the 2x held-out fixture: static foreign fit both splits, cert-first fired at 32 scenario-instances, 79560 rows in 162s, no fallbacks. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>9438aac -
Phase 47 renumber: blind-champion adjudication (was duplicate Phase 46); register blind4/blind3 cv variants
Thibaut Forest +1: Claude Fable 5The blind4 writeup was swept into 4e17cd1 with a colliding Phase 46 header. Renumbered to 47 per cross-session coordination. cv.py gains the rejected blind4/blind3 variants with the verdict inline so the port cannot be re-attempted by inspection. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>a94f6b9 -
Phase 46: overfitting audit - luck bounds, certain pool; ADOPT cert-first (k=3) ordering, all-48 1661.7 -> 1623.7, 3W/0L/45T
Thibaut Forest +1: Claude Opus 5 (1M context)Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>4e17cd1 -
Phase 45: pairwise ranking objective rejected - no new information, demotion artifact exposed; all axes now measured
Thibaut Forest +1: Claude Opus 5 (1M context)Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>25432c8 -
Phase 44: leaderboard inversion - appetite closed on numbers, tail transfer is the defect, no local instrument sees it
Thibaut Forest +1: Claude Opus 5 (1M context)Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>ab4b0fd
-
Phase 43: innovation sweep - queue pricing, lead-time bias, late decomposition; and a verified data leak we are not taking
Thibaut Forest +1: Claude Opus 5 (1M context)Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>e44c7a4 -
Phase 41-42: fixed-N ablation rejects the vrel port; public says pooling is a wash
Thibaut Forest +1: Claude Opus 5 (1M context)Phase 41 discharges phase 39's standing directive ("do not port anything from that lineage without re-running the ablation on recall at fixed N"). Adds cv.ablate: holds N fixed and varies only the score, so a feature's effect on ORDERING is separated from its effect on the topsum count. No planner and no evaluator - recall at fixed N and the rank distribution of misses are functions of the score alone. Deaths caught at fixed N, paired per origin, bootstrap 95% CI: native N=12 native N=20 static N=12 static N=20 vrel alone -6 [-12,-1] +4 [-1,+9] +6 [+0,+13] -1 [-9,+7] vmin7_rank alone -1 [ -5,+2] +4 [+0,+9] -5 [-11,+1] +0 [-4,+4] both -7 [-15,+0] +5 [-1,+11] +4 [ -2,+10] -1 [-9,+7] v_last alone -39 [-57,-22] -8 [-20,+5] +7 [-10,+25] +5 [-10,+20] REJECT the port. The sign flips with N on both instruments, every CI straddles zero, and the ordering is byte-identical at 36-41 of 48 native origins and 228-230…41a82cd -
Track *.png via LFS (HF rejects non-LFS binaries)
Thibaut Forest +1: Claude Opus 5 (1M context)Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>d5b03a1 -
Phase 40: port the research loop's CV discipline + ship in-fleet pooling
Thibaut Forest +1: Claude Opus 5 (1M context)CV protocols move out of /tmp into batteryswap_example/cv.py, with the champion config itself promoted from /tmp/all48.py into cv.CHAMPION: all48 full-fleet walk-forward, three-regime scorecard static the deployment gate - one foreign-fleet fit, no refits, 11s a seed, ORDERING questions only (this construction manufactures a sum(p42) undercount; phase 26 believed it and public went 1661 -> 2189) screen offline model screen grouped by BATTERY, never by scenario/row models_cv.rank_stats now runs inside walk_forward, so dev/panel/test also report rec12/rec20, operating-point recall+precision, the count actually bought, and the median rank of missed deaths beside the cost. Base reproduces 1661.7 / 2379.7 / 1679.2 / 604.8 byte-exact - the additions are diagnostic only. What the new metrics show: the panel's missed deaths sit at median rank 57, 45 ranks past the cut. That is the closed appetite axis as a measurement rather than an argument. screen s…c7d5d98
-
Phase 37: dq_g20 cannot be made always-on - benefit and harm come from the same rows
Thibaut Forest +1: Claude Fable 5H1 (devw harm was a double-bootstrap artifact): refuted. Re-implemented with true sample_weight in a manual bagging loop plus a uniform-weight control; devw is +389 vs that control, clean dose-response, harm unchanged. H2 (quar's 2.48 threshold is over-broad): refuted. It does drop 77 devices vs the ~26 real ghosts, but tightening toward the ghosts is monotone in the wrong direction on s_8-47 (2.40 +36.7 ... 2.48 +509.5) with the trend's limit being 'do not filter'. At 2.40 warm-up is identical to base, so the tight filter that spares the panel also yields no cold-start gain. Devices that look dead and survive are label noise at 3-20 positives and informative hard negatives at 800+; the effect changes sign rather than attenuating. Champion unchanged: all-48 1661.7, s_8-47 1518.0. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>9fd6de6 -
Phase 36: fit-protocol axis - warm-up mechanism validated (-49.8+/-6.0 across 6 seeds) but inert in deployment (static_uniq=82 vs gate 20)
Thibaut Forest +1: Claude Fable 5quar (drop 26 'looks dead, labeled survives' ghosts) and devw (device-equal resampling) each improve warm-up substantially and wreck the panel; gated at train_deaths<20 they leave panel/near-end byte-identical. Stacked (dq_g20): all-48 1619.1 vs 1661.7, every one of 6 resampling seeds improves. Not adopted. submit.py scores public,private - both held-out, both static branch, train_uniq = static_uniq = 82 unique dead devices in the foreign pool. Every gate tested is far below that, so the branch never runs where it is scored. The whole warm-up regime (23.9% of the checksum) is absent from the scored splits, which is why the cold-start floor's huge local gain (2146.9->1851.0) never showed on public. Deployment-faithful window is s_8-47, base 1518.0. Re-ranked all 86 screened configs on it: no hidden winner, only the known s_39-46 tail artifacts. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>c64ca4a -
Phase 34-35: retire cross-fleet CV, re-screen 72 configs, champion unchanged
Thibaut Forest +1: Claude Fable 5No behaviour change to the shipped path. models_cv.py is untouched; the only code edits are docstrings and four unused imports (planner.py numpy/FEATURES, train.py Field, submit.py sys). Champion config verified in submit.py: logbag, ALPHA=ALPHA_STATIC=0.8, EC_MARGIN=0.8, EC_PMAX=25, SPLIT_DAYS=7, FLOOR=2.5/gate 20, CLIFF_SCALE=1.0 (off). all-48 = 1661.7, public 1661.45. Phase 34: cross-fleet CV retired after a second confident false positive. rankavg won it at -18.4 (27/32 folds, p=0.0002) and is +55.3 on the real full-fleet all-48 - losing on the panel alone (+23.9), so not a warm-up weighting artifact. Root cause: every fold trains on the full history, so the harness cannot reproduce cold-start scarcity. Also closed: warm-up physics prior (logbag already best at cold origins), optimizer budget (2x60 optimal), feature LOO (best removal +2/308). Phase 35: everything ever judged on a retired instrument re-run on the surviving one. 72 configs, base reproduced 1661.7 in every group, no…7d93fb8 -
Phase 33: late-swap root cause - count is optimal, ranking is the wall
Thibaut Forest +1: Claude Opus 5 (1M context)Forensics (panel s_8-41): late is 97.9% MISSES, 2.1% caught-late; we already swap a median 12.2d before EOL, so no timing lever exists. Recall 176/308. Missed deaths are LINGERERS (median days_below_245 63 vs 29.5 caught) sitting at median rank 35 of ~450. Definitive alpha curve on the SHIPPING rolling path (full evaluator cost): 0.6:1844 0.8:1679 1.0:1771 1.2:1862 1.5:2084 2.0:2369. Clean U with the minimum at 0.8. More swaps DO cut late (1019->691) but early rises 3x faster (444->1409); at 28.5 swaps our late still never reaches the leader's 499 while early is 2.3x theirs. No alpha reaches the leader profile - their 19 swaps are a consequence of better ranking (~40% marginal hit rate vs our 8%), not a cause. Independently reproduces public 6ea03da (+8 swaps, late -13, early +444). Six ranking attacks rejected, all with the same signature - AUC UP, top-12 recall DOWN: zone features, v_corr_last+thresh_dist, RF ranking, rank blends, cohort-restricted model, sub-daily/intra-day f…eb395ee -
Phase 28 public refutation: revert static appetite to 0.8, cliff boost off
Thibaut Forest +1: Claude Fable 5Public look 2026-08-20 (6ea03da): 2188.78 vs 1661.45 (3c7b883). First public exposure of the whole static stack at once; component signature is pure over-inclusion - battery_swap +68%, early +444, late +13 (zero recall gain). - ALPHA_STATIC default 1.5 -> 0.8: phase 26's undercount premise is refuted on the real held-out fleet; phase 20 (the probability scale transfers / overcounts) was right. The half-fleet holdout manufactures the undercount (~6 deaths/scenario makes inclusions look cheap; marginal exchange rate 0.46 late-saved per early-spent locally, ~0.03 on public, break-even 1.0) and is hereby refuted as an appetite adjudicator - count decisions are public-look-only now. It stays valid for structural questions. - CLIFF_SCALE default 2.2 -> 1.0: the boost was only ever adjudicated on top of the refuted 1.5 baseline, and the public look condemns it transitively (every cliff device was included at 1.5 + boost and late did not move). - Retained: static-fit machinery…bb5a0c1 -
Phase 28: cliff-gated static appetite (cliff_count22) for held-out splits
Thibaut Forest +1: Claude Fable 5- submit.py: on the static held-out path ONLY, rows whose raw hourly readings show a knee (>=35% of the last 7 days' readings below 2.45 V, >=20 readings, corrected voltage < 2.46) get rank_score / p42_sum = clip(2.2 * p42, 1) while raw p42 - and hence every timing curve - stays untouched. Train/rolling path byte-inert by construction. Env: BATTERYSWAP_CLIFF_SCALE (1.0 disables). - Adjudication (exp_x28.py; EXPERIMENTS.md phase 28): mined from the public Attention-Heads repo. Real-label static holdout -54.5/scenario (4/5 fleet splits, baseline at ALPHA_STATIC=1.5 so the gain is additive to phase 26, not double-counted); barrier-event resampler -66.8 with the sign held in 120/120 draws; correlated per-quarter-shock variant -66.1, also 120/120; beats plain alpha raises on mean, variance and tail (alpha=2.5 turns negative). Panel rejected it on the native path (+27): static branch only. - Verified: cliff-mask parity 1.0000 vs the adjudication harness at s_16/28/40;…6ea03da
-
Phase 27: held-out-parity audit - penalty wiring + 3-layer failure isolation
Thibaut Forest +1: Claude Opus 5 (1M context)Dress rehearsal (Docker main() over fake public+private with renamed device IDs) exposed that one bad split could destroy the whole submission: a check_dataset assertion killed the adaptive path AND the pickle fallback identically, escaped main()'s handler, and no submission.csv was written. - load_best_effort(): dataset consistency check demoted to a logged warning - fallback guarded individually; new raw-file last resort (defer-everything plans, alive-filtered) guarded again - a split can at worst lose itself - cost_curves penalty constants (EARLY/LATE) wired from each scenario's settings (evaluator charges these; constant 0.5/10.0 in train, byte-inert at defaults); planning_window_days != 42 logs loudly - audit: per-scenario settings vary only in base_location/base_room (16 bases; mobility sim already reads them live) Rehearsal after fixes: both splits static-path, complete 2-split submission.csv in 35s; all-48 checksum 1851.0186805555559 byte-exact. Co-Authored-By: Claud…fc780fa -
Phase 24b+26: static per-split fit + ALPHA_STATIC=1.5 for held-out splits
Thibaut Forest +1: Claude Opus 5 (1M context)- submit.py: held-out splits (own-fleet frac < 0.5 vs the packaged table) now fit ONE model per split on the full foreign train pool and skip the per-origin split-table build and refit loop. Holdout harness: statistical tie on score (static 1057.7 vs rolling 1087.0), minutes instead of ~17 per split, near-zero time-budget fallback risk. Train-fleet splits keep the rolling self-masked path. - ALPHA_STATIC=1.5 (env BATTERYSWAP_ALPHA_STATIC): the static foreign fit's sum(p42) undercounts on held-out fleets, so the deployment path needs a larger inclusion appetite than the panel's 0.8. Sweep won on ALL FOUR independent fleet-splits (0.8: 1156.3 -> 1.5: 916.4 mean; plateau from 1.5). Only the static branch reads it; panel champion unchanged. - EXPERIMENTS.md: phases 24b + 26 (incl. public 1717.8 -> 1661.45 from the phase-23 submission, matching the holdout prediction band). All-48 Docker checksum: 1851.0186805555559 byte-exact (train path untouched); static branch end-t…faf80ea -
Phase 21-23: unmasked foreign pooling for held-out splits + Docker PATH fix
Thibaut Forest +1: Claude Opus 5 (1M context)- submit.py: pool the packaged train table UNMASKED on held-out splits (66,890 closed-window pairs, 82 dead devices from origin 0); the target split's own fleet stays under the T-42d mask; byte-inert when the target IS train (all-48 Docker reproduces 1851.0186805555559 exactly). Holdout-validated (fleet A=packaged, B=target): warm-up 1108.6 vs floor's 1091.0 (tie) vs starved 1478.9; mid/late spots 1088.4 vs 1141.9. The cold-start floor gate now never opens on held-out splits (by design); it remains live for local warm-up regimes. - Dockerfile: pin /app/env/bin onto PATH - newer base-image entrypoints shadow the competition env with miniconda at runtime, breaking `python3 script.py` with ModuleNotFoundError. - models_cv.py: phase-21 comment (evaluator emergency queue truly opens at end-of-week, day 48; exact pricing tested and rejected) + inert nn_order visit-ordering machinery (phase 22, rejected: panel tie 1679.4 vs 1679.2). - EXPERIMENTS.md: phases 21 (emergency…3c7b883 -
Phase 19-20: cold-start count floor (all-48 2146.9->1851.0) + CV harness upgrade
Thibaut Forest +1: Claude Opus 5 (1M context)Gated floor k=2.5 wins warm-up 8/8, panel byte-identical. Ungated and foreign-fleet variants refuted (panel +21..+114; fleet-holdout harness shows the probability scale transfers across device subsets). Near-end block s_42-47 added: top-up worth -273 there, censor pricing -64. Three-regime scorecard codified; tie-aware selection stability; component decomposition by default. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>bd56acd -
Phase 18: limit-aware constructive initializer rejected; limit tail is a correct trade
Thibaut Forest +1: Claude Opus 5 (1M context)Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>3d2958f -
Phase 17: label-arrival hazard, domain-split, cost-weighting, backtest-alpha all refuted; count channel closed
Thibaut Forest +1: Claude Opus 5 (1M context)Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>a354f2b -
Phase 16: dataset semantics verified (2451-device fleet, end_time = admin snapshot; no model change)
Thibaut Forest +1: Claude Opus 5 (1M context)Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>2de326a -
Phase 15: swap-truncation/ghost/quarantine all rejected by panel; label 'noise' is the label process
Thibaut Forest +1: Claude Opus 5 (1M context)Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>e3fa964 -
Phase 14: building day-splitting (sd7) + censoring-aware pricing adopted
Thibaut Forest +1: Claude Opus 5 (1M context)Panel 1679.2 vs 1702.0, sd7 selected in 100% of random and blocked splits; censoring-aware curves -32 on TRUNC=30 counterfactual, inert on covered windows. Hazard-WHEN and park_mobility rejected. All-48 Docker metric 2146.9 (was 2175.4). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>2ba75d6 -
Phase 13: gap/heat/room-cascade plunger hypotheses all rejected by panel
Thibaut Forest +1: Claude Opus 5 (1M context)Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>2662738
-
Phase 12: spatial peer features rejected (panel +106, 0% selection); pm40 sweep closed
Thibaut Forest +1: Claude Opus 5 (1M context)Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>08031d9 -
Phase 11: price-adaptive break-even top-up (fresh-only, m0.8/pm25) + two-sided cost-curve fix
Thibaut Forest +1: Claude Opus 5 (1M context)Panel 1702.0 vs 1715.8, 63% random-split selection, never beaten in a decided blocked split. All-48 Docker metric 2175.4 (was 2202). Includes user's phase-10 CohortGate + merged-block protocol write-up. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>4fb1dc8 -
Silent-death campaign closed: precursor found (volatility) but unactionable
Thibaut Forest +1: Claude Opus 5 (1M context)Precursor screen on the blind zone (11,599 healthy-voltage pairs, 24 deaths): 30d voltage range/std carry AUC 0.83/0.81 before the plunge starts; diurnal drift, beta drift, reading-rate, low-side outliers ~ chance. Both deployment mechanisms fail CV: as global features (test 1438.7 vs champion 1397.5) the signal dilutes; as a scale-free blind-zone ordering override (SilentFix) it is inert at safe weights and harmful at active ones. Root cause quantified: 0.2% blind-zone prevalence makes precursor precision a few percent, so every action loses in expectation against the 0.5/10 penalty arithmetic. Champion unchanged (dev 2073.9 / test 1397.5). Features and SilentFix kept in code as documented-rejected; ceiling moves only with new information. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>cedc5cb -
Classifier-family sweep: RF/ExtraTrees/MLP + rank-hybrid all rejected by CV
Thibaut Forest +1: Claude Opus 5 (1M context)RandomForest (default/deep/class-balanced), ExtraTrees, and a small MLP all lose 170-820 dev points to bagged logistic. RF ranks better at some origins (AUC 0.94 vs 0.85 at s_23) but its compressed probabilities break topsum's count; a rank_rf hybrid preserving logbag's probability scale while using mean-rank ordering still loses (+92). Champion unchanged. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>fbe4c36 -
Phase 7: full coordinate sweep finds nothing - champion is a local optimum
Thibaut Forest +1: Claude Opus 5 (1M context)~25 knob values across forecast (C, bags, day-model GBR, recency weighting, training-set variants incl. discrete hazard and determined labels, blends) and optimization (emergency-day anchor, search budget, tspig/tspig2 routing-aware inclusion). Acceptance rule (>=60 dev AND >=10/16 origins) adopted nothing; best was bags=30 at -9.4. dthaz statistically tied using a different likelihood. Champion unchanged: logbag/tsroute/a0.8, dev 2073.9, test 1398, public 1767.87 (rank 2). EXPERIMENTS.md updated with phases 5-7, public LB readings, and full champion spec. Also wires SklearnRUL variant specs (bags/dtrees/ddepth/q6) and per-config search knobs into the harness. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>30e8503 -
Explore voltage-silent deaths: cohort clock rejected by CV, champion unchanged
Thibaut Forest +1: Claude Opus 5 (1M context)Silent deaths are fast plungers (same 2.40V crossing, ~3-week collapse), not a separate mechanism. Candidates tested on the silent subpopulation: - spatial clustering: AUC ~0.52, dead - mean temperature: AUC 0.64, too weak - install-cohort clock: AUC 0.906 in isolation (batch explains ~90% of lifetime variance) but degrades dev CV in every encoding (2074 -> 2279 raw, 2433 overdue-neutral) due to 14%/54% coverage; kept in features.py as documented-rejected, excluded from FEATURES. Champion reproduces exactly after revert: dev 2073.9 (logbag/tsroute/a0.8). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>b636dfd -
Revert alpha to 0.8: local CV sweep rejects the leaderboard-motivated 1.15
Thibaut Forest +1: Claude Opus 5 (1M context)Dev sweep 0.7-1.3: minimum at 0.8 (2074; 1.15 scores 2219, losing on 12/16 origins). Test block confirms from the existing ledger (0.8: 1398 vs 1.15: 1516). Late_swap saturates ~1100 for alpha >= 1.15 while early keeps climbing - remaining misses are voltage-silent deaths, not an inclusion problem. Selection stays on local CV, not public feedback. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>c9e7e41 -
Raise inclusion alpha to 1.15 based on public leaderboard evidence
Thibaut Forest +1: Claude Opus 5 (1M context)Both public readings show late/early ratio ~8 for us vs ~1 for every top team: the public fleet rewards more insurance swaps than the local test block. alpha=1.15 reproduces the leader timing profile locally (late 722 / early 550 vs 851/312 at 0.8). Clean A/B vs fc9c286: adaptive pipeline identical, one constant changed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>82d9553 -
Adaptive runtime submission: per-scenario refits, bagging, stronger routing
Thibaut Forest +1: Claude Opus 5 (1M context)Uses the 30-minute runtime budget instead of a static pickle: - submit.py: refits the model at every scenario origin on the target split's own history pooled with packaged train features, with labels self-masked to windows closed before each origin (assertion-enforced; never reads future eol_times). Time-budget + mid-split deadline guards fall back to the static pickle per split. - logbag model: 15-fold bagged logistic (dev 2126 -> 2074, test 1440 -> 1398) - stronger routing search: merge moves + restarts, and within-day visits now sorted by building/room (the evaluator pays repeated building changes for interleaved rows) - tau_projected feature: master-curve inversion minus staleness, targeting devices that go dark and keep discharging (test 1476 -> 1439) - synthetic training origins every 4 days back to Feb-2025 (2.7x positives) Walk-forward: dev 2074, test 1398, honest all-48 train metric 2202 with mobility+limits at 242 vs current leaderboard leader's 280. Runtime: 2…fc9c286
-
Logistic RUL model with adaptive top-sum planner (walk-forward CV selected)
Thibaut Forest +1: Claude Opus 5 (1M context)- features.py: cached (device, origin) feature table; leak-free per-origin slicing - models_cv.py: walk-forward CV harness; logistic/GBM/AFT/rank models, threshold/topsum/batching planners; dev s_8-s_23, test s_24-s_41 - planner.py: final TopSumPlanner (logistic p42, N = 0.8 * sum(p42), q05 day placement, building batching); refit on all closed windows - harness.py: baseline comparisons (defer-all, lowest-voltage-k, oracle) - best.pickle trained inside the competition Docker image (sklearn 1.7.2) to avoid version skew; verified via script.py + metric in the image Test-block walk-forward mean total_cost 1368 (voltage-15 2034, defer 2512, oracle 186); train split via official metric: 2150 vs 8673 for the example. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>b89e779 -
BatterySwapAI submission 001: test
Thibaut Forest6d45918 -
Duplicate from batteryswapaichallenge/BatterySwapAI2026-Example
Co-authored-by: Jon Nordby <jonnor@users.noreply.huggingface.co>fe26a1a