Here's your full audit patch — **14 surgical FIND ...
Tạo vào: 11 tháng 3, 2026
Trả lời bằng GPT-5.4 Thinking bởi Chat01
Tạo vào: 11 tháng 3, 2026
Trả lời bằng GPT-5.4 Thinking bởi Chat01
Here's your full audit patch — 14 surgical FIND → REPLACE changes, each one targeting a specific mechanism outside the sets-market gate stack that suppresses the Over 2.5 / decider lane.[1]
Here are the 6 additional suppression points I found on this deeper pass:
dampWinProbForUnderdogSneak excessHold capThe Math.min(0.12, excessHold * 1.2) allows up to 12pp of EXTRA dampening on top of baseX when holds are far above threshold — so a match with two big servers can get 22% total flattening. Patch 2 caps that at 8pp with a softer 0.9 multiplier.[1]
The p3MmC and p3ClP coefficients exist in both the MATCHPICK pipeline and the FINALBETSUMMARY pipeline. Both subtract from p3 based on mismatch level. If you only patch one, the other still suppresses. Patch 9 covers both locations.[1]
When the sim's mean drifts from the book line, the calibration weight ramps to 0.55 at 7g and caps at 0.65. In high-hold coinflip matches where the sim legitimately projects more games, this drags the mean back toward a line that assumes lower p3. Patch 10 lowers every tier by ~30%.[1]
When Elo disagrees, dpBasepv of 0.40-0.45 flattens displayProbA toward 0.50, which distorts the sim's win-prob input and muddies the totals signal. Patch 11 drops it to 0.30-0.35.[1]
lg > 0.55 triggerThe anti-fake-decider fires at laneGap > 0.55 which is too loose — in high-hold matches the 3-set lane naturally has very high Over% (near 0.99) simply because 3-set games > line. The 0.55 trigger catches real signals. Patch 12 tightens to 0.65.[1]
getTotalsConfLabel nearLineMass and adverseTail capsEven when the pick survives as OVER, confidence gets crushed to LOW when nearLineMass > 0.14 (which is most tennis matches since totals cluster tightly) or adverseTail > 0.16. Patch 14 raises both thresholds.[1]
Each patch block has an exact FIND: string and an exact REPLACE: string. Search your script for the FIND text and swap it in. Patch 9 has two locations (MATCHPICK + FBS) — make sure you hit both. Patch 13 requires you to locate your totalsTourPolicy config to adjust minLeanPO/minLeanPU.
// =============================================================================
// FULL AUDIT PATCH — Over 2.5 Sets / Decider Lane Suppression Fix
// v17.10.0 line-mass refactor — 2026-03-11
//
// This patch addresses ALL identified mechanisms outside the sets-market
// gate stack that systematically suppress the 3-set / Over 2.5 path.
//
// HOW TO APPLY:
// Each section below is a FIND → REPLACE block.
// Search for the EXACT "FIND:" text in your script, then replace it
// with the "REPLACE:" text. Every change is minimal and surgical.
// =============================================================================
// ─────────────────────────────────────────────────────────────────────────────
// PATCH 1 of 14: dampWinProbForCoinflip — reduce coinflip dampening strength
// ─────────────────────────────────────────────────────────────────────────────
// PROBLEM: This function pulls displayProbA toward 0.50 by up to ~28% in
// high-hold / small-hold-gap environments. Because displayProbA is
// used later as pFinalA → pWinnerRawA, it compresses the favorite's
// win-prob. A compressed favorite win-prob makes the model think the
// match is closer → LESS likely to be a sweep → inflated p3 inside
// the simulation, BUT the display pipeline already shaved p3 via
// clusterDisplayP3. Net effect: the two compressions fight and the
// final totals pOverMCReweighted ends up in the dead zone (PASS).
//
// FIX: Cut the max dampening coefficient from 0.25/0.28/0.30 to 0.18/0.20/0.22
// and scale the small-sample penalty from 0.15/0.16/0.18 to 0.10/0.12/0.14.
// This preserves the coinflip safety net but stops it from over-flattening.
// FIND:
var f2DampCf = f2TourK === "WTA" ? 0.28 : f2TourK === "CH" ? 0.26 : 0.25;
var f2DampSs = f2TourK === "WTA" ? 0.18 : f2TourK === "CH" ? 0.16 : 0.15;
// REPLACE:
var f2DampCf = f2TourK === "WTA" ? 0.20 : f2TourK === "CH" ? 0.19 : 0.18;
var f2DampSs = f2TourK === "WTA" ? 0.14 : f2TourK === "CH" ? 0.12 : 0.10;
// ─────────────────────────────────────────────────────────────────────────────
// PATCH 2 of 14: dampWinProbForUnderdogSneak — soften the sneak dampener
// ─────────────────────────────────────────────────────────────────────────────
// PROBLEM: When both holds are high AND decider prob is above tour threshold,
// this pulls win-prob toward 0.50 by up to baseX + 0.12. In ATP
// that's up to 0.22 of the distance to 0.50. Same downstream issue
// as Patch 1 — artificially flattened winner prob distorts the totals
// cluster weighting.
//
// FIX: Lower baseX by 30% across all tours and cap the excessHold multiplier
// at 0.08 (was 0.12).
// FIND:
if (tl.indexOf("WTA") >= 0) { thrA = 0.68; thrB = 0.65; thrDec = 0.30; baseX = 0.12; }
else if (tl.indexOf("ITF WOMEN") >= 0 || tl.indexOf("ITFW") >= 0) { thrA = 0.70; thrB = 0.67; thrDec = 0.32; baseX = 0.09; }
else if (tl.indexOf("ITF") >= 0) { thrA = 0.75; thrB = 0.72; thrDec = 0.34; baseX = 0.11; }
else if (tl.indexOf("CH") >= 0 || tl.indexOf("CHALLENGER") >= 0) { thrA = 0.78; thrB = 0.75; thrDec = 0.36; baseX = 0.12; }
else { thrA = 0.79; thrB = 0.76; thrDec = 0.34; baseX = 0.10; }
// REPLACE:
if (tl.indexOf("WTA") >= 0) { thrA = 0.68; thrB = 0.65; thrDec = 0.30; baseX = 0.08; }
else if (tl.indexOf("ITF WOMEN") >= 0 || tl.indexOf("ITFW") >= 0) { thrA = 0.70; thrB = 0.67; thrDec = 0.32; baseX = 0.06; }
else if (tl.indexOf("ITF") >= 0) { thrA = 0.75; thrB = 0.72; thrDec = 0.34; baseX = 0.07; }
else if (tl.indexOf("CH") >= 0 || tl.indexOf("CHALLENGER") >= 0) { thrA = 0.78; thrB = 0.75; thrDec = 0.36; baseX = 0.08; }
else { thrA = 0.79; thrB = 0.76; thrDec = 0.34; baseX = 0.07; }
// ALSO FIND (in same function):
var X = baseX + Math.min(0.12, excessHold * 1.2);
// REPLACE:
var X = baseX + Math.min(0.08, excessHold * 0.9);
// ─────────────────────────────────────────────────────────────────────────────
// PATCH 3 of 14: winnerEngineLayer noisyCompress — reduce the compression cap
// ─────────────────────────────────────────────────────────────────────────────
// PROBLEM: weCompress can reach 0.30 (the Math.min cap). When applied via
// pRawFinal = 0.5 + (pRawFinal - 0.5) * (1 - weCompress)
// it shrinks the favorite's raw edge by up to 30%. This is the
// ENGINE-LAYER compression that feeds pWinnerRawA, which then feeds
// the MC sim as winProbA → totWinProbAraw. Compressing the sim's
// win-prob inflates the decider lane (makes it look like a coinflip)
// but that inflated p3 then gets crushed by clusterDisplayP3 and
// totalsDeciderAuthority — net result is a muddled signal that lands
// in PASS.
//
// FIX: Lower the weCompress cap from 0.30 to 0.20.
// FIND:
weCompress = Math.min(0.30, weCompress);
// REPLACE:
weCompress = Math.min(0.20, weCompress);
// ─────────────────────────────────────────────────────────────────────────────
// PATCH 4 of 14: SHIFTCAPBO3 — widen the p3 shift window
// ─────────────────────────────────────────────────────────────────────────────
// PROBLEM: After blending raw/adj/market/hold, the final p3 is capped within
// shiftAnchor ± 0.10. If the anchor is low (e.g. 0.30), p3 can
// never exceed 0.40, which is below the BET OVER 2.5 threshold.
// The raw simulation may say 0.44 but the cap kills it.
//
// FIX: Widen SHIFTCAPBO3 from 0.10 to 0.14.
// FIND:
SHIFTCAPBO3: 0.10,
// REPLACE:
SHIFTCAPBO3: 0.14,
// ─────────────────────────────────────────────────────────────────────────────
// PATCH 5 of 14: setsMarketPriorBo3 — reduce heavy-favorite p3 penalty
// ─────────────────────────────────────────────────────────────────────────────
// PROBLEM: When favP > 0.72, the market prior subtracts up to 0.020 from p3.
// This makes sense directionally (big favorites sweep more) but is
// too aggressive — it stacks with the hold prior's similar penalty
// AND the sweepPenalty, triple-counting the mismatch signal.
//
// FIX: Halve the max subtraction from 0.020 to 0.010.
// FIND (inside setsMarketPriorBo3):
if (favP > 0.72) p3 -= Math.min(0.020, (favP - 0.72) * 0.12);
// REPLACE:
if (favP > 0.72) p3 -= Math.min(0.010, (favP - 0.72) * 0.08);
// ─────────────────────────────────────────────────────────────────────────────
// PATCH 6 of 14: setsMarketPriorBo5 — same fix for best-of-5
// ─────────────────────────────────────────────────────────────────────────────
// FIND (inside setsMarketPriorBo5):
if (favP > 0.72) p5 -= Math.min(0.035, (favP - 0.72) * 0.20);
// REPLACE:
if (favP > 0.72) p5 -= Math.min(0.018, (favP - 0.72) * 0.12);
// ─────────────────────────────────────────────────────────────────────────────
// PATCH 7 of 14: SWEEPSOFTBO3 / SWEEPHARDBO3 — raise sweep penalty thresholds
// ─────────────────────────────────────────────────────────────────────────────
// PROBLEM: sweepPenalty fires when ANY player's 2-0 > 0.52. In a typical ATP
// match with a moderate favorite, 2-0 mass for the fav is often 0.50-0.55
// which means the penalty fires on MOST matches, not just real blowouts.
// It subtracts 0.010-0.020 from p3Blend BEFORE the shift cap, so the
// cap then locks in the reduced value.
//
// FIX: Raise the soft threshold from 0.52 to 0.56 and hard from 0.58 to 0.62.
// FIND:
SWEEPSOFTBO3: 0.52, SWEEPHARDBO3: 0.58,
// REPLACE:
SWEEPSOFTBO3: 0.56, SWEEPHARDBO3: 0.62,
// ─────────────────────────────────────────────────────────────────────────────
// PATCH 8 of 14: totalsDeciderAuthority — loosen the anchor pull and shave
// ─────────────────────────────────────────────────────────────────────────────
// PROBLEM: When broadSupport is false, p3 gets pulled 32% toward anchor.
// When fragile, 22% toward anchor. Then it shaves 0.04-0.09 off.
// Then it hard-caps at 0.38 or 0.42. This is the most aggressive
// suppression mechanism outside the sets engine.
//
// FIX: Reduce anchor pull weights and raise the hard caps.
// FIND (inside totalsDeciderAuthority):
if (!broadSupport) { p3 = 0.68 * p3 + 0.32 * anchor; }
if (fragile) { p3 = 0.78 * p3 + 0.22 * anchor; }
// REPLACE:
if (!broadSupport) { p3 = 0.80 * p3 + 0.20 * anchor; }
if (fragile) { p3 = 0.88 * p3 + 0.12 * anchor; }
// FIND (inside totalsDeciderAuthority, shave section):
if (!broadSupport) shave += 0.04;
if (fragile) shave += 0.03;
// REPLACE:
if (!broadSupport) shave += 0.02;
if (fragile) shave += 0.015;
// FIND (hard caps inside totalsDeciderAuthority):
if (Number.isFinite(lane3) && lane3 > 0.98 && !broadSupport) { p3 = Math.min(p3, 0.38); }
else if (Number.isFinite(lane3) && lane3 > 0.95 && fragile) { p3 = Math.min(p3, 0.42); }
// REPLACE:
if (Number.isFinite(lane3) && lane3 > 0.98 && !broadSupport) { p3 = Math.min(p3, 0.44); }
else if (Number.isFinite(lane3) && lane3 > 0.95 && fragile) { p3 = Math.min(p3, 0.48); }
// ─────────────────────────────────────────────────────────────────────────────
// PATCH 9 of 14: Mismatch decider alignment — reduce mismatch p3 penalty
// ─────────────────────────────────────────────────────────────────────────────
// PROBLEM: In MATCHPICK's "mismatch decider alignment" block, the code
// computes p3mkAdj = pDecRaw * (1 - p3MmC * mmP3) - set3PenP3.
// p3MmC is 0.22 (ATP) and set3PenP3 = p3ClP * (1 - closeP3).
// For moderate mismatches this subtracts 0.03-0.06 from p3, which
// then feeds into the blowout-correction totalGamesCorr and can
// pull projected totals down by 1-2 games.
//
// FIX: Reduce p3MmC by 25% and p3ClP by 40%.
// FIND (the mismatch coefficients block — appears twice, once in MATCHPICK, once in FBS):
var p3MmC = p3TK === "WTA" ? 0.26 : p3TK === "CH" ? 0.24 : 0.22;
var p3ClP = p3TK === "WTA" ? 0.05 : p3TK === "CH" ? 0.045 : 0.04;
// REPLACE (apply in BOTH locations):
var p3MmC = p3TK === "WTA" ? 0.20 : p3TK === "CH" ? 0.18 : 0.16;
var p3ClP = p3TK === "WTA" ? 0.03 : p3TK === "CH" ? 0.028 : 0.025;
// AND in the MATCHPICK pipeline (same coefficients, different variable names):
// FIND:
var mpMmC = mpTK === "WTA" ? 0.26 : mpTK === "CH" ? 0.24 : 0.22;
var mpClP = mpTK === "WTA" ? 0.05 : mpTK === "CH" ? 0.045 : 0.04;
// REPLACE:
var mpMmC = mpTK === "WTA" ? 0.20 : mpTK === "CH" ? 0.18 : 0.16;
var mpClP = mpTK === "WTA" ? 0.03 : mpTK === "CH" ? 0.028 : 0.025;
// ─────────────────────────────────────────────────────────────────────────────
// PATCH 10 of 14: Market calibration anchor — reduce the calibration weight
// for near-market sims
// ─────────────────────────────────────────────────────────────────────────────
// PROBLEM: When the sim mean drifts > 2.5 games from market line, the
// calibration weight ramps up (0.18 at 2.5g, 0.22 at 3.5g, etc.)
// and blends totAdjMean toward the market line. In matches where
// the sim legitimately projects more games (high-hold coinflip),
// this pulls the mean DOWN toward a line that was set assuming
// lower p3 — effectively suppressing Over.
//
// FIX: Reduce calibration weights by ~30% at each tier.
// FIND:
if (tierTriggered && lineDiff > 2.5) calibrationWeight = Math.max(calibrationWeight, 0.18);
if (lineDiff > 3.5) calibrationWeight = Math.max(calibrationWeight, 0.22);
if (lineDiff > 4.5) calibrationWeight = Math.max(calibrationWeight, 0.30);
if (lineDiff > 5.5) calibrationWeight = Math.max(calibrationWeight, 0.40);
if (lineDiff > 7.0) calibrationWeight = Math.max(calibrationWeight, 0.55);
calibrationWeight = Math.max(0.0, Math.min(0.65, calibrationWeight));
// REPLACE:
if (tierTriggered && lineDiff > 2.5) calibrationWeight = Math.max(calibrationWeight, 0.12);
if (lineDiff > 3.5) calibrationWeight = Math.max(calibrationWeight, 0.16);
if (lineDiff > 4.5) calibrationWeight = Math.max(calibrationWeight, 0.22);
if (lineDiff > 5.5) calibrationWeight = Math.max(calibrationWeight, 0.30);
if (lineDiff > 7.0) calibrationWeight = Math.max(calibrationWeight, 0.42);
calibrationWeight = Math.max(0.0, Math.min(0.50, calibrationWeight));
// ─────────────────────────────────────────────────────────────────────────────
// PATCH 11 of 14: Elo conflict dampening — reduce the pFinalA pull to 0.50
// ─────────────────────────────────────────────────────────────────────────────
// PROBLEM: When eloConflict is true, the code does:
// displayProbA = pFinalA + dampenFactor * (0.50 - pFinalA)
// where dampenFactor starts at 0.40-0.45 and can grow further when
// trustMin < gate. This flattens the winner signal, which makes
// the sim produce a more balanced (higher p3) outcome, but then
// clusterDisplayP3 / totalsDeciderAuthority shave p3 back down —
// and the flattened winner prob stays, making the totals look like
// a dead-zone coinflip.
//
// FIX: Reduce the base dampen factor from 0.40-0.45 to 0.30-0.35.
// FIND:
var dpBasepv = dpIsWtapv ? 0.45 : dpIsChpv ? 0.42 : 0.40;
// REPLACE:
var dpBasepv = dpIsWtapv ? 0.35 : dpIsChpv ? 0.32 : 0.30;
// ─────────────────────────────────────────────────────────────────────────────
// PATCH 12 of 14: Anti-fake-decider safeguard — soften the p3 shave
// ─────────────────────────────────────────────────────────────────────────────
// PROBLEM: When laneGap > 0.55 AND lane3 > 0.985 AND weakSupport, the code
// subtracts 0.03 from p3ForTotals. This fires fairly often in
// matches where the 3-set lane is naturally bullish (high holds,
// both players holding well) because lane3's Over rate approaches
// 0.99 mechanically when 3-set games > line.
//
// FIX: Tighten the trigger conditions (laneGap > 0.65 instead of 0.55)
// and reduce the shave from 0.03 to 0.015.
// FIND:
if (lg > 0.55 && lane3ov > 0.985 && weakSupport) {
totCtx.p3ForTotals = clamp01(p3tot - 0.03);
// REPLACE:
if (lg > 0.65 && lane3ov > 0.99 && weakSupport) {
totCtx.p3ForTotals = clamp01(p3tot - 0.015);
// ─────────────────────────────────────────────────────────────────────────────
// PATCH 13 of 14: getTotalsPick minLean / dead zone — lower the PASS floor
// ─────────────────────────────────────────────────────────────────────────────
// PROBLEM: getTotalsPick returns PASS when chosenProb < minLean. The minLean
// value comes from totalsTourPolicy and is typically 0.52-0.535.
// After all the compressions above, a legitimate Over 2.5 signal
// that started at pOverMC = 0.56 can easily get squeezed to 0.525
// by fragility penalty + mode friction + conviction compression,
// landing just below the PASS threshold.
//
// FIX: Lower minLean thresholds by ~0.5pp in the tour policy config.
// NOTE: You need to find totalsTourPolicy and adjust minLeanPO / minLeanPU.
// The exact location depends on your config block. Look for where
// cfg.minLeanPO is defined. Example fix:
// If your current values are e.g.:
// minLeanPO: 0.530, minLeanPU: 0.525 (ATP)
// minLeanPO: 0.525, minLeanPU: 0.520 (WTA)
// minLeanPO: 0.528, minLeanPU: 0.522 (CH)
// Lower each by 0.005:
// minLeanPO: 0.525, minLeanPU: 0.520 (ATP)
// minLeanPO: 0.520, minLeanPU: 0.515 (WTA)
// minLeanPO: 0.523, minLeanPU: 0.517 (CH)
// ─────────────────────────────────────────────────────────────────────────────
// PATCH 14 of 14: getTotalsConfLabel — stop regime/risk caps from
// killing Over confidence
// ─────────────────────────────────────────────────────────────────────────────
// PROBLEM: Even when getTotalsPick returns OVER, getTotalsConfLabel can
// downgrade it to LOW or PASS via:
// - FRAGILE regime + risk > 0.80 → force LOW
// - nearLineMass > 0.18 → cap to at most MID→LOW
// - adverseTail > 0.16 → force LOW
// These caps fire on legitimate Over matches where the distribution
// is naturally clustered near the line (it's tennis — totals are
// tight) and the UNDER tail is non-trivial.
//
// FIX: Raise the nearLineMass and adverseTail thresholds.
// FIND (inside getTotalsConfLabel):
if (nearLineMass > 0.14) { if (tier === "HIGH") tier = "MID"; }
if (nearLineMass > 0.18) { tier = tier === "HIGH" ? "MID" : "LOW"; }
// REPLACE:
if (nearLineMass > 0.18) { if (tier === "HIGH") tier = "MID"; }
if (nearLineMass > 0.22) { tier = tier === "HIGH" ? "MID" : "LOW"; }
// FIND:
if (Number.isFinite(adverseTail)) {
if (adverseTail > 0.16) { tier = "LOW"; }
else if (adverseTail > 0.12) { if (tier === "HIGH") tier = "MID"; }
}
// REPLACE:
if (Number.isFinite(adverseTail)) {
if (adverseTail > 0.22) { tier = "LOW"; }
else if (adverseTail > 0.16) { if (tier === "HIGH") tier = "MID"; }
}
// =============================================================================
// END OF PATCH SET — 14 surgical changes
// =============================================================================
//
// SUMMARY OF EFFECTS:
// 1. dampWinProbForCoinflip: 25-30% less dampening → cleaner winner signal
// 2. dampWinProbForUnderdogSneak: 30% softer → stops fake coinflip flattening
// 3. noisyCompress cap: 0.30→0.20 → engine raw prob stays closer to true
// 4. SHIFTCAPBO3: 0.10→0.14 → p3 can now swing ±14pp from anchor (was ±10)
// 5. setsMarketPriorBo3: half the favP penalty → stops triple-counting
// 6. setsMarketPriorBo5: same for Bo5
// 7. SWEEPSOFT/HARD: raised thresholds → penalty only fires on real blowouts
// 8. totalsDeciderAuthority: much lighter anchor pull + higher caps
// 9. Mismatch p3 penalty: 25-40% reduction → blowout correction stays small
// 10. Market calibration: 30% lighter → sim drives when it diverges from book
// 11. Elo conflict dampening: base factor down 25% → less artificial flattening
// 12. Anti-fake-decider: tighter trigger + smaller shave
// 13. minLean threshold: lowered 0.5pp → fewer false PASS on legitimate edges
// 14. Confidence caps: raised near-line and adverse-tail gates → Over gets MID+
//
// EXPECTED BEHAVIOR CHANGE:
// Matches that currently show "speculative risk lean Over 2.5" in the sets
// section but PASS on the totals line should now more often produce an
// actual OVER or LEAN OVER pick with at least LOW-MID confidence.
// Genuine blowout mismatches (favP > 0.78) still get appropriately penalized.
// =============================================================================
Apply all 14 patches do not skip them
Then send me the updated script as a downloadable txt link
Done — I applied all 14 patches and saved the updated script here:
Download the patched script (.txt)
I also verified the updated file contains the patched values for all 14 requested areas, including the duplicate mismatch-coefficient locations and the totals policy thresholds.