← All findingssource · memory/feedback_role_anchor_flag_gap.md
Rebecca Allen (NYL) 2026-08-01: snapshot said mispriced_under on points 6.5
(z=+0.58, L10 avg 3.7). The user pushed back — "she's been in the starting
lineup" — and was right. Splitting by role:
| era | games | min/g | pts/g |
|---|---|---|---|
| starter (from 7/20) | 4 | 26.5 | 8.5 |
| bench (prior) | 6 | 6.8 | 0.5 |
| pooled L10 (what fired the edge) | 10 | 15.3 | 3.7 |
The 0,0,0,0 games dragging the average were 3-7 minute bench appearances.
The guard did not fire. recent_vs_baseline_flag = stable and
minutes_source_confidence = stable while minutes went 6.8 -> 26.5. The
methodology-lockdown role-anchor check (project_methodology_lockdown)
catches minutes DIVERGENCE between sources, not a role CHANGE over time. A
promotion is invisible to it.
It compounds. adjustment_notes applied matchup: H2H L5 avg 1.6 -> -1.1 shift — that H2H sample is also bench-era, so the same artifact is charged
twice: once in the baseline, once as a matchup penalty.
How to apply — before trusting ANY line_edges quality:
- Pull
recent_gamesand checkrole(or the new SDS boxscoreparticipants[].starter, see project_sds_participation_receipts) for the L10 window. If role flips inside it, the pooled average is meaningless. - Re-average within the CURRENT role only, and cross-check against
min_conditionalat the bucket matching tonight's projected minutes — that block is role-agnostic and was right here (>=20 min: avg 10.33). - Ask WHY the role changed. Allen's 4 starts all had Sabally AND Fiebich out — both out again that night, so the sample was the matched comparable, not something to regress away from. A promotion caused by injuries that have since healed is the opposite case.
- Don't quote the raw EV off a 4-game split. The arithmetic said +8.5%; the honest read is "the under case is disproven, roughly break-even to modestly positive." See feedback_model_edge_calibration.
Reinforces feedback_verify_before_extend: I led with the system's verdict instead of checking the game log first. The user's domain knowledge beat the model, and the model was wrong for a knowable, checkable reason.
FIXED 2026-08-02 (data-hydrator a8e5088 + 845499d, live-verified):
detectRoleTrend compares L3 minutes avg vs prior-window avg (ratio ≥1.6 AND
≥7 min absolute AND all 3 recent games direction-consistent vs the prior avg
— the consistency rule exists because the mean-only version misfired on
Aliyah Boston within an hour of deploy: a 5-min anomaly read as "collapse"
the night after she played 30). On a break the window re-anchors to ±8 min
of the L3 (n≥3) and stamps flags.role_trend + role_trend_adjusted;
un-anchorable breaks ship the flag alone. Allen's exact case is a regression
test: points 6.5 flips mispriced_under → no_edge. Steps 1-2 of "how to
apply" are now automatic; steps 3-4 (WHY did the role change; don't quote
raw EV off n=4) remain judgment.
THIRD ITERATION (2026-08-05, live-verified): the lineup role-SPLIT —
categorical, from per-game started flags now on BOTH SDS gamelog routes
(153682f + 0ea22fa: the combined /stats/player/{id} route builds
recent_games in its OWN query; patching only /games left DH's WNBA path
blind — caught live). DH detectRoleSplit (17728e4 + ac083fa) compares
the newest game's role against the ADJACENT preceding era (consecutive
runs), NOT a window majority — majority-vote v1 missed Sabally live
because her June starter era outvoted her July benching. Day-one changes
flag without re-anchoring (run<3); established changes re-anchor to the
current run. Categorical outranks the minutes-trend detector. Verified on
the rebuilt 8/04 snapshot: Sabally=lineup_promotion,
Harrison=lineup_demotion, Morrow=lineup_demotion (fresh activation —
technically a "return", reads as demotion-era; acceptable). Rolewatch
surfaces lineup_* trends sorted with the up-trends (grading 1b3db82).
Remaining gap: the scout pkl still UNDER-biased in prod — its fix sits
unpushed on feat/xgboost-plus-v5-missingness in sports-scout-service.
BACKTESTED (2026-08-05, 2,345 settled priced props / 20 nights):
- Flag = validated. Fresh promotions (run ≤ 2) → overs 19-12, +5.8u (61%). The market lag is SHORT: established promotions (3+ starts) → overs 42% — books reprice within ~3 games. Bet the promotion in its first 1-2 games or not at all. Demotion fades ≈ nothing (51/49).
- Re-anchor as direction-flipper = refuted. Role-window vs pooled
DISAGREEMENTS: new direction −17.5u vs old +3.8u (n=33, ~z2.6). Kills
near-neutral (18-11). Correction shipped (DH 6dc027f):
windows_disagreequality when the two windows point opposite ways — no mispriced_* matcher fires on it, so disagreement = kill, not conviction. - Caveats: line universe = bet_clv rows (1000/day cap hit every day → truncated), single-game outcome grading, in-sample. Forward test = rolewatch lineup_promotion candidates from 8/05 on.