← All findingssource · memory/feedback_devig_phantom_edge.md
Building a both_agree WNBA screen on 2026-06-22, my script produced two "top plays" (Hiedeman pts OVER 14.5 "+2.0%", Jordin Canada pts UNDER 12.5 "+0.7%"). Adversarial verifiers killed BOTH — they were artifacts, not edges. Final slate verdict: zero bettable +EV on a 4-game WNBA board. That is the correct, common result for a maturing props market — do not force a pick.
Trap 1 — phantom de-vig edge (the bug I keep almost making):
- Single-book de-vig. If Pinnacle isn't posted at the exact line, my screen fell back to DraftKings and de-vigged off DK's own two-sided juice. Comparing that DK-derived "fair" against the best cross-book price invents an edge that is really just the DK↔FanDuel vig gap. Hiedeman's "+2.0%" was pure DK self-reference; consensus fair was ~49.7% → −0.8%, and Pinnacle had her line UP at 15.5 (sharp money on the under).
- Stale line-number drift. The grid line where line_edges fires an edge may no longer be the consensus line. Canada's "+0.7%" compared a fresh Pinnacle 12.5 fair against a 3-hour-stale DK 12.5 price; the live consensus had already moved 12.5 → 11.5 with the over juiced. At the live line the play is −2.1%.
How to apply (de-vig hygiene):
- De-vig off Pinnacle first; else a MULTI-book consensus (avg fair across ≥2 books). Never quote an edge off one non-sharp book's juice.
- Pin to the current consensus line and the freshest scraped_at. If the line where the edge appears ≠ today's consensus line, the edge is stale — discard it. Check that the price you're crediting is from the latest scrape.
- A model-vs-Pinnacle gap >~10pp on a Pinnacle-priced starter means the MODEL is wrong, not the market. Default to the market. (Reinforces feedback_pinnacle_default, feedback_model_edge_calibration.)
Trap 2 — WNBA adjusted_projection. PACE ANCHOR NOW FIXED (verified 2026-07-31):
The old bug: pace adjustment hard-anchored to the NBA average total 218, giving a
uniform ~−10% haircut on every WNBA counting stat. That shipped a fix —
data-hydrator/internal/snapshot/diagnostic.go now has LeaguePaceAnchor(league)
returning 218.0 for nba and 163.0 for wnba (ok=false for unknown leagues, so
callers skip the pace signal rather than haircut off the wrong anchor). The
"ignore WNBA adjusted_projection" rule is RETIRED for the pace reason.
The adjusted_projection == 0 defect (24% of players, 2026-07-31 audit) is
FIXED — data-hydrator a8e5088 (2026-08-02, live-verified 0/19 zeros on a
force-refreshed snapshot): missing engine joins now fall back to the
role-anchored recency window, then season averages, each disclosed in
adjustment_notes ("baseline: engine q50 missing → …"). baseline_q50
deliberately stays engine-only (0 = no join) as the join-health signal; a
zero adjusted_projection now genuinely means "no data anywhere."
Net process: both_agree = recency line_edges (direction) + multi-book/Pinnacle de-vig at the CURRENT line (magnitude). adjusted_projection is a tie-breaker for NBA only, ignored for WNBA. When the screen says "nothing clears ~1.5%," report that honestly and offer price-triggers, not a manufactured best bet. See also feedback_check_line_edges_before_quoting, daily_props_tool.