OSDtools
Side Guard Studio
OSD / Studio / Side Guard

Side Guard — reverse-middle & ladder caps

How SideGuard works

SideGuard is a family of structural gates that prevent correlated or conflicting bets across the same game. Five distinct checks layered together, all consulted by getSideGuardStatus(dom, now) in the badge eval pipeline. The gate consults both confirmed positions (positionsByBaseKey) and in-flight attempts (inFlightLockByKey) so cross-tab and cross-book races are caught.

The five checks

  1. Same-side ladder cap — caps open + in-flight bets on the same {game, market, side} at automation.ladderingMaxLinesPerSide (default 2). Pure geometry, not cooldown-gated.
  2. Reverse-middle (totals + spreads) — blocks opposite-side bets at lines that create a both-LOSE region. Time-decoupled as of 2026.4.25.2 — fires whenever the geometry creates the bad shape, regardless of how long ago the prior was placed. Min gap: sideGuardReverseMiddleMinGap (default 0.5).
  3. Same-line opposite-side lock (added 2026.4.28.6) — blocks opposite-side bets at the EXACT same line on totals or spreads. Catches the degenerate case reverse-middle's gap test produces 0 for and skips (e.g. Cubs Over 13.5 + Cubs Under 13.5; Lakers +5 + Lakers −5). No time-based bypass; structural geometry.
  4. Matching-line flip cooldown — symmetric flip block within sideGuardSymmetricFlipCooldownMs (default 5 min). Per-market overrides available via sideGuardMoneylineFlipCooldownMs / sideGuardMatchingSpreadFlipCooldownMs / sideGuardMatchingTotalFlipCooldownMs.
  5. Generic opposite-side lock — broader cooldown (sideGuardCooldownMs, default 45 min) for any opposite-side bet on the same game/market that doesn't hit one of the geometry tests above.

Order of checks (precedence)

Inside checkOppositeSnapshot, the geometry tests run in this order — first-fire wins:

  1. Reverse-middle total → "Reverse-middle total lock"
  2. Reverse-middle spread → "Reverse-middle spread lock"
  3. Same-line opposite-side → "Same-line opposite-side lock"
  4. Matching-line flip cooldown → "Matching {moneyline|spread|total} flip cooldown"
  5. Generic opposite-side lock → "Opposite side lock"

Worked examples (from production)

Sign-based vs team-aware spread keying (2026.6.12.0)

Historically the subsystem keyed spreads/RL by normalizeSideKey, which returns "plus" / "minus" / "pk" based on the sign of the line, not team identity. (Totals are keyed separately as "over" / "under".) Two known blind spots, the second observed live on 2026-06-11 (Caesars Liberty +7.5 + Dream +5.5, same game — both plus, guard never engaged):

As of 2026.6.12.0 the gate carries a parallel team-aware spread keying (sideGuardTeamAwareSpreads, default true): each spread snapshot resolves a team slug from the side text vs eventAway/eventHome (game-label fallback; unresolvable/ambiguous sides degrade to legacy sign keys). When BOTH ends of a pair resolve: same team = same side (laddering), different team = opposite side; the reverse-middle gap is −(lineA + lineB) for any sign combination, and "matching line" means mirror lines (lineA + lineB = 0). Cross-team both-dog middles are NOT structurally blocked — they route into the standard opposite-side cooldown with the EV/edge-improvement bypass, so deliberate middles survive. Rollout: sideGuardTeamAwareSpreadsLogOnly (default true) means the legacy sign-based verdict still ENFORCES while divergences are logged ([sideGuard:teamAware]); the replay math on this page mirrors the enforced legacy behavior until the flag is promoted. Documented in memory/project_sideguard_sign_based.md.

Implementation: getSideGuardStatus, getSideGuardLockDetail, checkOppositeSnapshot, normalizeSideKey, reverseMiddleGapTotal, reverseMiddleGapSpread, and the inFlightLockByKey registry in osd-auto-edge-bb.js. Both evaluation entry points sync the in-flight registry from localStorage at the top so they see the same cross-tab view as the lock-acquire APIs (tryAcquireInFlightLock, getInFlightLockInfo).

Data

Load remote positions to begin.

Controls

Run Settings

This is the score the optimizer maximizes when ranking candidates.
Requires at least this many bets for a recommendation to be eligible.

Sweep Setup

Single sweep tests one knob across a range.
0 disables sharp-count gating.
Run-engine safety cap for Grid and Sharp sweeps (not a segment filter).

Guardrails

Requires recommendations to span at least this many settled days. Set 0 to disable.
Rejects recommendations when worst-day profit drops by more than this amount. Set 0 to disable.
Requires this minimum share of profitable days for recommendations. Set 0 to disable.

Segment Filters

Sub-selection filters below are applied after Run Mode + Objective Metric.

Data Quality & Output

Allow overrides
Load remote positions to start.

Summary

Rows Loaded
-
Settled Matched
-
Baseline (ROI)
-
Best Delta
-
Baseline snapshot: ROI -, Profit -, Win Rate -, Bets -
This is historical replay on bets you already took. It cannot estimate bets that were never placed.
Coverage Event Key
-
Coverage Market Key
-
Coverage Side Key
-
Coverage Ordering Timestamp
-
Coverage Source ID
-
Coverage Attempt ID
-
Unique Events
-
Unique Markets
-
Unique Sides
-
Top Baseline Gate Loss: -
Parameter results are ranked here first. In Auto mode, charts below use the top-ranked parameter row.
Param Baseline Best Bets Baseline Score Best Score Delta
Run a single-parameter sweep or Auto mode to populate these charts.
Shaded band = top-performing value zone (top 20% by selected objective metric).
Gold dot = best score in this sweep.
Line + dots = metric result for each tested value.
X-axis = tested parameter value.
ROI Curve
Run a single-parameter sweep (or Auto mode) to render ROI curve.
Profit Curve
Run a single-parameter sweep (or Auto mode) to render profit curve.
Win Rate Curve
Run a single-parameter sweep (or Auto mode) to render win-rate curve.
Bet Count Curve
Run a single-parameter sweep (or Auto mode) to render bet-count curve.

Distribution

Rows are tested parameter values. Each row shows aggregate results for that value.
Parameter Value Bets Pass Rate Distinct Days Green Day % Worst Day Win Rate ROI Profit Stake Avg EV