← All findingssource · memory/feedback_check_line_edges_before_quoting.md
Before recommending any player prop, pull the snapshot's
prop_diagnostic.stats.{stat} block for that player and check:
line_edges[str(line)].quality— one of:mispriced_over,stretched_over,no_edge,stretched_under,mispriced_under. If the line is on the WRONG side for the direction you're recommending, walk away. Example: line_edges at 3.5 showsstretched_over(z=-0.39) → OVER is the mispriced side, UNDER is the bad bet. Don't recommend UNDER no matter what Pinnacle de-vig says.adjusted_projection— the system's calibrated projection after H2H, DvP, momentum, minutes adjustments. If it's clearly on the opposite side of the line from the pick direction, walk away.flags.recent_vs_baseline_flag— ifhot_streakorslumping, the recent average is regressing toward baseline — be skeptical of recent-form-driven recommendations.momentum—trending_up/trending_down/stable. A trending_down pick OVER (or trending_up pick UNDER) needs extra justification beyond raw averages.
Why: Pinnacle de-vig math is a market-vs-market signal. The system's
line_edges and adjusted_projection are constructed from H2H,
DvP, recency, minutes, momentum — a fuller picture. When the two
disagree, the system's read is more carefully built. Pinnacle's "edge"
can show +7pp on a pick the system flags as no_edge because
Pinnacle's posted line doesn't reflect the matchup-specific dynamics
the system encodes.
How to apply:
- After computing Pinnacle de-vig edges, IMMEDIATELY pull
prop_diagnostic.stats.{stat}.line_edgesfor each candidate pick - Drop any pick where
line_edges.qualityisno_edgeor where the direction is wrong (e.g., recommending UNDER when quality isstretched_over/mispriced_over) - For surviving picks, surface both signals to the user: "Pinnacle +Xpp edge, system says quality=[Y], adjusted_projection=Z"
- This is the project_methodology_lockdown rule applied to pick generation: "Read flags BEFORE any pick" (commit 8354c43, live since 2026-05-20)
Confirmed mistakes (so this stays sticky):
- 2026-05-25 NYK@CLE: recommended Evan Mobley ast UNDER 3.5;
system flagged
stretched_over(z=-0.39, adjusted_projection 2.21). Direction was wrong per system. - 2026-05-26 SAS@OKC: recommended Jalen Williams ast UNDER 3.5;
system flagged
stretched_over(z=-0.47). Recommended SGA ast OVER 8.5; system flaggedno_edge(z=+0.15, adjusted_projection 6.5). Recommended Champagnie reb UNDER 5.5; system flaggedno_edge. 3 of 4 picks were directionally wrong or no-edge per system. - 2026-05-26 SAS@OKC (corrective): swung the other way and gave "highest system z" picks (Fox pts OVER 13.5, SGA reb UNDER 4.5, Champagnie stl OVER 0.5) — all directionally correct per system but on structurally OBVIOUS sides where books charge juice accordingly. Dropped Fox reb OVER 3.5 @ +110 which was the actual best read (cross-validated: stretched_over z=-0.35 AND Pinnacle +6.0pp AND plus money AND H2H 6.0 reb vs OKC last 5 — real matchup edge that books underprice). User correctly called it "dumb plays" — I optimized for system z-score instead of for edge quality.
Both incidents came from the same root: jumping from one signal straight to recommendation without the cross-check. Same mistake three times now = process gap, not one-off.
Filter that produces real edge (use this, not "highest z"):
- System direction-positive (
mispriced_*ORstretched_*— NOT no_edge, NOT wrong direction) - Pinnacle de-vig also positive (>= +2pp at same line)
- PREFER plus money — you make more per win and edge isn't eaten by vig. Juiced favorites (-200, -300) often have small edge in pp terms but are betting structurally obvious sides
- Articulable "why is the book wrong" story — matchup, role change, recent injury affecting role. If you can't articulate it, it's probably not real edge — just system noise.
Workflow (per user 2026-05-27): When asked for picks, do NOT pre-filter and quote only the "best" formula. Instead:
- Show ALL formula outputs side-by-side: pinn_devig picks, system_lineedges picks, both_agree picks, scout_ml picks (when healthy). User wants to see what each signal is saying, not just my synthesis.
- Then synthesize a combined recommendation with explicit
reasoning ("I'd take these N because both_agree + plus money +
matchup story"). This becomes the
claude_combinedformula in the harness. - Invite user's own picks explicitly. User wants to put their
own reads in alongside the formulas — this becomes the
user_manualformula in the harness. - ALL of these (every formula + my synthesis + user picks) get
tracked with their
formula_idfor CLV measurement. After n>=100 per formula, the data shows which one actually beats the close.
The point: stop using my judgment as a gatekeeper. Show the user everything, synthesize transparently, let user add their own, measure all of them.
The harness (project_multi_formula_clv_harness) automates this end-to-end. Until it ships, the same workflow done manually: enumerate each formula's picks in chat, synthesize, ask user for theirs, log everything for retroactive measurement when harness lands.
See also: project_methodology_lockdown, feedback_betting_discipline, feedback_model_edge_calibration, feedback_verify_before_extend.