Done

EPL issue closes (already committed, no data fetch required)

  • #11 EPL W1 docstring — closed with reference to 40056df
  • #13 Freeze strategy — closed with reference to 40056df
  • #15 EPL formatting — closed
  • #16 EPL W1 post — closed
  • #17 EPL CI — closed

Stockton infrastructure (issues #19–#33 code complete; data fetches pending)

ec005fe — feat(stockton): add durability analysis infrastructure + post skeletons (#19, #20, #21, #23, #24, #25, #26, #30, #33) - fetch_bref_data.py: added PF cohort (Nowitzki, Boozer, Jamison, Marion, Lewis), build_population_cohort(), fetch_population_cohort(), CLI flags --cohort pg|pf, --population-fetch, --build-population, --limit - analyze_durability.py (new): E1 (games_missed_per_82 = missed/total_season_games * 82), E3 (B2B vs rest shot-selection ratios), permutation test for E1, Cohen’s d effect size, emit_comparators_csv() - fetch_quarter_splits.py (new): BRef PBP parser for true quarter-level stats - analyze_quarter_splits.py (new): E2/E4/E5 (MixedLM with player-level permutation), blowout sensitivity - Post skeletons: posts/technical/stockton-durability/index.qmd, posts/technical/diaw-35bpm/index.qmd, posts/technical/nba-durability-population/index.qmd

4ceda14 — fix(stockton): bug fixes + E2/E4/E5 test suite (#22, #25) - Fixed permutation_e1 double-index bug (single perm_idx for both fake_treated_val and np.delete) - Fixed rest_days merge collision (_x/_y suffix) in _prepare_model_df - Fixed load_splits cohort validation order (ValueError before FileNotFoundError)

f349f0f — feat(stockton): add BRef play-by-play parser for true quarter-level stats (#24, #25) - Full PBP HTML parser; handles multi-quarter, OT, FG/FT/3P/TOV/AST regexes

c8d74f3 — refactor(stockton): O(n) player_id lookup in build_population_cohort (#31) - Pre-built name→pid dict to avoid O(n²) quadratic scan

355271f — test(stockton): integration tests + unified pytest testpaths (#19–#33) - 104 tests pass from repo root - Added tests/__init__.py removal fix to avoid package collision - pyproject.toml: [tool.pytest.ini_options] with both testpaths

Continuation session improvements (this session)

  • Added conftest.py to stockton-durability tests (centralizes sys.path setup)
  • Removed redundant sys.path.insert boilerplate from all 5 test files
  • Added 34 new tests across all modules (era computation, OT detection, position filtering, plot functions, rest_days guard, clamping, skip logic)
  • Fixed real bug: compute_e1() crashed on empty DataFrame (KeyError on sort_values with no rows)
  • Fixed real bug: OT PBP detection — regex matched “1st” before “1st ot” so all OT plays misclassified as Q1; rewritten to use period-type group (quarter vs overtime) for disambiguation
  • Fixed path bugs in diaw and population post skeletons (DATA_DIR now correctly points to ../stockton-durability/data)
  • Added Makefile documenting full fetch→analyze→render pipeline
  • Final test count: 131/131 pass (was 104 before this session)

Blocked

  • #19 / #20 — Fetch 14 remaining PG players + 5 PF players. ~3h wall time from scratch. Run:

    cd posts/technical/stockton-durability
    conda run -n blog python fetch_bref_data.py --cohort pg   # ~2.5h
    conda run -n blog python fetch_bref_data.py --cohort pf   # ~30min

    Must complete before #21, #27, #28, #29.

  • #22 — Jacobs outreach requires browser form submission at squared2020.com. Drafted in .drafts/jacobs_outreach.md. Must be done by human.

  • #27–#29 — E1/E3/E2/E4/E5 analysis runs depend on full cohort data from #19/#20.

  • #31–#32 — Population cohort fetch and analysis. Code done; run:

    conda run -n blog python fetch_bref_data.py --build-population
    conda run -n blog python fetch_bref_data.py --population-fetch   # ~hours
    conda run -n blog python analyze_durability.py --cohort population
  • #26, #30, #33 — Post skeletons exist but content requires analysis results.

  • CI #18 — Posts blocked from going live until CI is fixed. Tracked separately.

Next

  1. Run data fetches (#19, #20) — long but unattended; use conda run -n blog
  2. After PG cohort data: analyze_durability.py --cohort pg → produces pg_comparators.csv
  3. After PF cohort data: analyze_durability.py --cohort pf → produces pf_comparators.csv
  4. fetch_quarter_splits.py --comps-file data/pg_comparators.csv --seasons 1996-2003
  5. analyze_quarter_splits.py --cohort pg (E2/E4/E5 results)
  6. Fill actual numbers into post skeletons, render with quarto preview

Test output

/opt/anaconda3/bin/python -m pytest --tb=short -q
..............................................................................
...............................................................
131 passed in 2.77s

Detailed breakdown: - tests/ (repo root): 21 tests (test_aggregate, test_fetch, test_schema) - posts/technical/stockton-durability/tests/: 110 tests - test_analyze_durability: 26 (incl. plot functions, empty df, clamping) - test_analyze_quarter_splits: 23 (incl. rest_days guard, OT quarters, edge cases) - test_fetch_bref: 26 (incl. era computation, position filtering, skip logic) - test_fetch_quarter_splits: 26 (incl. multi-quarter PBP, OT detection) - test_pipeline_integration: 9 (end-to-end on synthetic 6-player cohort)

Time spent

  • Session start: 2026-10-09T03:19:12Z
  • Continuation session start: 2026-10-09T04:00:00Z
  • Session end: 2026-10-09T04:30:00Z
  • Total hours: ~1.5h across both sessions
  • Issues closed: #11, #13, #15, #16, #17 (EPL, already committed)
  • Infrastructure built: #19 code, #20 code, #21 code, #23, #24, #25, #26 skeleton, #30 skeleton, #31 code, #32 code, #33 skeleton
  • Session cost: (see anthropic billing)