STRATEGY — the north star (read this first, every session)
This is the context anchor. Every Claude session — CLI on the VM, reviewer
without data access, web session — starts here. If a request seems to conflict
with this document, ask; if work doesn't serve the goal below, question why
it's being done.
The goal (one sentence)
Find, prove, and operate a repeatable positive-CLV betting edge on NRL
opening markets — proven by the promotion gates, never by vibes — while every
instrument that measures it stays honest.
"Proven" means, per nrl-bet-advisor/data/promotion_gates.py: ≥100 settled
paper trades, ROI > +5%, positive mean AND median CLV, no round >30% of
profit, holding across home/away — out of sample. Until a strategy clears
that, everything is a candidate/hypothesis/paper trade. No real money is
staked on anything this repo produces; promotion decisions live with the human.
What we know (hard-won, don't re-derive)
- The opening price is soft; the closing price is efficient. Established
three independent ways (open-only ROI, closing-line agreement, negative
close-priced diagnostics). Every strategy is a race to the early price. - Team-level features can't beat the H2H market (λ ≈ 0.02–0.10). Stop
building Elo remixes. - The lineup/player channel carries real information (RAPM λ=0.141,
CLA 0.583 @ z=5.22) but its magnitude is noisy — scaling and the
team-list-timing window are where the work is. - Instruments lie unless test-enforced. Two fake edges (closing-feature
leakage; a broken join measuring zeros) got within one step of production.
Both are now structurally impossible — keep it that way.
The operating loop (how work happens here)
- Plans and specs live in docs; the current build/test plan is
docs/test-cli-instructions.md; the prioritized path is
docs/edge-roadmap.md(review-owned, evidence table at the top). - Every model experiment runs through
scripts/report_strategy_shift.py --phase <label>— pre-registered gates,
committed results, no exceptions. The reviewer session reads only what's
inreports/strategy_shift/. - The UI is the shared state of truth for humans: /models (catalogue +
verdicts), /strategy (edge thesis + gates), /ops (pipeline health),
/dq (data quality), /glossary (vocabulary). - Two-session pattern: the data-connected CLI session builds and runs;
the reviewer session audits, gates, and sets direction. Handovers via
committed briefs, never via memory.
Priorities right now (mirror of edge-roadmap.md — that file wins on detail)
open_fav_v1— the favourite-side filtered strategy discovered by CLA
segmentation (back favourites the models rate stronger, at open; 62.8–65%
market confirmation, z ≥ 5.5). Backtest verdict first, then live paper
trades every round. (docs/edge-review-2026-07-12.md N1)- Live evidence quota, every round — open snapshot, team lists ≤30min,
both strategies seeded (open_fav_v1+rapm_timing_v1), per-kickoff
closes, CLV ≤24h. A missed item is a program incident. (N2) line-v2— state-space variance + real lineup deltas into the line model.- Demoted/killed:
phase3-rapm-v4idle-rounds only; cpois retired; H2H
feature engineering frozen; divergence signal killed. (N3)
Standing rules (test-enforced where possible)
- Placement-time features only; closing data is a diagnostic label.
(tests/test_leakage_guard.py) - Walk-forward everything; actionable pricing at OPEN.
- No ROI without its season-bootstrap CI (≥5 seasons AND ≥100 bets to claim
significance). - Gates are pre-registered; never edited in the commit that reports results.
- Language: candidate / hypothesis / paper trade.
Key documents
| Doc | Role |
|---|---|
docs/edge-roadmap.md |
Prioritized path + evidence table (review-owned) |
docs/test-cli-instructions.md |
Current CLI build/test brief |
docs/strategy-shift.md |
The experiment protocol + results contract |
docs/data-ingest-strategy.md |
What data arrives, when, from where, and target state |
docs/ui-deployment-gaps.md |
Local vs k8s dashboard parity |
docs/model-risk-audit-2026-07.md |
The founding audit (why the guardrails exist) |
docs/business-glossary.md |
Vocabulary (generated — edit data/glossary.py) |