Bet Data Labs improved today.
What this log is
The standard is simple: the product gets visibly better every single day. This page is the receipt. Newest first, no gaps, no excuses.
The standard is simple: the product gets visibly better every single day. This page is the receipt. Newest first, no gaps, no excuses.
Tonight's Slate means tonight, and the six-check play has a name: Sharp Play
- Tonight's Slate was choosing from tonight's games and tomorrow's, so a puck drop 29 hours out could take one of tonight's slots. It now chooses only from games that start on tonight's Eastern calendar day.
- A card that passes all six checks (a real line, a model edge, positive EV, a prediction market on our side, no injury, weather or lineup flags, no playbook fades) is now a Sharp Play and carries the fin. The filter that used to say 6 of 6 was reading an older three-gate test, so it and the badge disagreed; both read the same six checks now.
- Player props cannot be Sharp Plays yet, and the board says so: Kalshi and Polymarket price game winners, not player stats, so check four has nothing to confirm a prop against.
- The top bar is four places to read (Props, Game Lines, Tonight's Slate, Scorecard) plus Sports and More. Parlay, Line Shop and Ledger moved into More. Games is now Game Lines, because that is what it is: moneylines, spreads and totals.
- Definitions no longer print as a paragraph above the cards. They sit behind one line, What do these mean, and open as a list, one term per row.
- First visit gets a black bar that says so: First time here? Explain is on, tap any dotted word.
- On cards with a caution flag, the flag was squeezed into a red sliver on top of Details. It is now a small count you can hover, and the full flags are on the card page.
- The 80/20 bankroll rule: Sharp Plays share up to 80% of the 8u night, everything else up to 20%, and neither bucket is ever scaled up. A night with no Sharp Plays bets at most 1.6u. The slate shows both buckets and leads with its Sharp Plays.
- Pages are lighter: the front page and the props board ship about 45% less to your phone, sport pages about half. Every card used to carry its full card-page detail (reference books, reasons, bet-slip links for every book) into tiles that never show it. The card page still has all of it.
- Scorecard fixes: STRONG no longer loses its first letter in the tier charts, a negative CLV value no longer prints on top of its tier name, the biggest bar's number is no longer cut off, the breakeven tick no longer strikes through the hit rate, and the CLV trend labels a readable handful of dates instead of 33 on top of each other. Days with no recommended plays are counted under the table instead of listed as rows of dashes, and the model honesty table shows eight markets with the rest one tap away. The page is about a third shorter.
- The front page counts tonight's open Sharp Plays under the slate button, one tap from the list.
- Game Lines lists its open Sharp Plays first, with the six checks spelled out above them.
- Every NFL, NBA, NHL and MLB game page now shows the prediction market's own prices from Kalshi: who wins, the full total ladder and the spread ladder, each as a chance and the decimal price that breaks even on it.
- A range calculator sits under it: pick over one line and under another (say over 36.5, under 60.5) and it reads the chance straight off the market, P(over the low line) minus P(over the high line). It only offers lines the market actually lists, so the number is never invented.
- The prediction-market check was flaky. Kalshi limits how fast it can be asked, and we asked once per game all at once, so on an ordinary 17-game night three runs in a row priced 1, 8 and 1 games and silently skipped the rest. It now asks once per league: the same night prices 16 of 17 games, every run, at the same numbers. More cards get a real check four, and more Sharp Plays are possible.
- Game totals for every sport now come from the prediction market. We pull the real over and under prices from DraftKings, FanDuel and Fanatics, and compare them with Kalshi's own probability at the exact same line. When one side pays better than the market says it is worth, by at least 4 points and at a price that is still positive EV, it becomes a card. No model of ours is in the number. It used to be MLB weather totals only, priced at an assumed -110.
- College football is on the board: moneylines and spreads for FBS games, built only when Kalshi prices the game (57 of 58 games this week match). The fallback model is off for college, because rating a 6-0 team off its record alone printed fake edges. Team names match the odds feed exactly or not at all, so Miami (OH) can never take Miami's price. Whole-number college spreads are skipped because they can push. No college player props.
- Every sport page opens with its games: matchup, kickoff, the market's favourite and how often it wins, and the total it treats as a coin flip. One tap opens the game.
Preseason games are off the board, and the board now refreshes every ten minutes
- The board was pricing seven NBA preseason spreads and moneylines tonight. Exhibition rosters are not a market we should ever quote, and treating preseason as the season is exactly the trap we have logged other services falling into. ESPN labels these games; they are filtered at the source now, for every sport.
- Our hosting plan only runs the scheduled rebuild twice a day, so between visits the board could sit stale for hours. A refresher now hits the rebuild endpoint every ten minutes around the clock, so lines, anchors and props on the published board are never more than ten minutes old.
NFL is on the board. It never was.
- The list of sports the board pulls from ESPN read MLB, WNBA, NBA, NHL and soccer. Football was not on it, so for five weeks of the season the site showed no NFL game, no moneyline, no spread, no total and no prop. Every downstream table already knew the sport (scoring floors, labels, grading keys, injuries, standings). One line was the gate.
- NFL games now load like every other sport, with Kalshi and Polymarket as the sharp anchors (Kalshi files them as KXNFLGAME, Polymarket dates night games on the UTC day, both handled), real multi-book moneyline and spread prices, and a 13.5-point margin model for covers.
- Player props: passing yards, rushing yards, receiving yards and receptions, from DraftKings, FanDuel and Fanatics, with the alternate ladders. Anytime touchdown is a one-sided market and waits for its own pricing path.
- The projection is the player's own two-season game log. A 17-game schedule means week 5 has four rows, so last season is blended in by sample size and leans out fast when this season clearly disagrees with it (a new role, a new team). The card shows which season drove the number.
- Grading: a receiver with no catch has no receiving row in the box score at all. For these four props an active player with no row settles as zero, so an under can win instead of waiting forever.
- Injury flags: a healthy NFL team lists three or four OUTs on a normal week, so the two-body rule written for a 12-player bench would have flagged every football card. Football starts at five.
- First real build: Falcons at Saints, 32 prop cards plus the game markets, nine new tests, all 48 test files green.
The props feed had been dead in production for a month
- The odds provider deactivated our access key on September 3. The fix was written and tested on September 8 (a loud, once-a-day alert plus an honest feed-down banner instead of the old 'books have not posted' copy) and then never deployed. Production also still carried the dead key.
- The key is rotated and the alert ships with this build. If it ever happens again, the site says so the same day.
Re-grading a finished day could quietly delete results we had already settled
- Our grader wrote whatever it could see over whatever was stored. That is fine while a day is still finishing and the feed keeps getting better. It is destructive once the feed starts getting worse, which is what happens to old games: the box scores stop being served.
- Run against a fully settled day, that took 90 real results and turned them back into unsettled. A Ketel Marte total bases card went from a win worth +0.65u to nothing. The only reason last night's record survived was that we had taken a backup first.
- A re-grade can now only ever make a card MORE settled, never less. Unsettled can become a result. A result can never go back to being unsettled.
- The version of this we nearly shipped only guarded the obvious case. Testing found the quieter one: when a box score comes back thinned rather than missing, a player who really did play reads as absent, and we book it as a void refund. A void looks like a clean answer, it pays nothing, and it is skipped everywhere we report, so an erased win leaves no trace at all. We caught two cards worth 1.82u going that way in testing. Both are blocked now.
- A genuine stat correction still goes through, because those are real, but it now gets flagged with the exact unit swing instead of moving the record silently.
- Proved on real data: re-grading two already finished days changed nothing but the timestamp, and every card, outcome and unit total came back byte for byte identical.
- Nothing you see changes today. This protects the record from a bug that had already fired once.
Every page was re-reading our entire grading history, several times over
- Yesterday we found the injury feed being downloaded once per page instead of once. Same defect, different file: our own graded history was being read off storage and parsed again for every part of a page that wanted it.
- That history is now 32 files, 8,564 graded cards, 5.9 MB. Thirteen places in the app ask for it, and several of them render on the same screen.
- Measured on a clean server: one view of Receipts read all of it twice. One view of the home page read it three times. Six people opening Receipts at the same moment cost 20 full reads, because nothing was shared and the work only got remembered after it finished.
- It now gets read once and handed to everyone waiting. The same run that cost 25 reads costs 1. A full pass over all 24 pages of the site now costs 3, and those 3 are just the cache refreshing on schedule.
- The board build was doing this too. Every rebuild re-derived our own per-player record and the calibration table from that same history, so cold builds were paying for it repeatedly.
- You should notice this as pages that settle faster, most of all Receipts, the home page and the board.
- No card, price, tier or unit total changed. This is the same graded history, read the same way, just not read over and over. A fresh grade still shows up immediately.
Our receipts page was grading itself against the wrong number
- Receipts held every record against 52.4%, the rate you need to break even at standard -110 juice. We said we did that because a graded card does not keep the price it was taken at. It does. All 8,564 of them carry it.
- So the bar is now the real one: the average breakeven of the prices we actually published. That is 55.6%, not 52.4%, and it changes the headline rather than decorating it.
- The recommended book hit 53.5%. Against 52.4% that read as 1.1 points clear of the vig. Against the prices we really took it is 2.1 points short. We were showing you a beat that is not there, so it is gone.
- It was worse per market. Total Bases is bought at heavy juice and needs 63.3%, so a 54.9% hit rate was printing as +2.6 points when it is really -8.4. Three way soccer moneylines are plus money and need 34.1%, so a 50% hit rate was printing as a 2.4 point miss when it is a 15.9 point beat.
- By Sport and By Market now carry a Hit / Needs column, so every row is judged against its own prices instead of one number borrowed from a different market.
- The hit-rate-by-tier chart had the same flaw against a 50% coin flip, which painted all five tiers green. Each bar now carries a gold tick at the rate that tier's prices need. Only the top tier clears it, at +5.6 points.
- That chart was also counting voids as losses. Voids are refunds, postponements and did-not-plays, so they are out of the denominator now.
- No card, price, tier or unit total changed. ROI was always computed off real prices and was always right. This is only about what we compare a win rate to.
Every page was re-downloading the injury report from scratch
- Injury news is what drives our kill signals, so we pull the full league injury feed and cache it for 30 minutes. The caching had not worked in a long time and nothing said so.
- ESPN attaches a complete player profile to every injury record, headshots and article links and all. That makes the baseball feed 2.87 MB and the football feed 8.54 MB, and our cache refuses anything over 2 MB. Every save failed silently and every page went back to the source.
- Measured on a clean server, one pass over the site pulled the baseball feed 26 separate times. About 108 MB downloaded and parsed for a file that had not changed.
- We now cache the part we actually use. Of that 2.87 MB, 2.80 MB is profile data we throw away on arrival, so what gets stored is 72 KB instead. Same pass over the site now pulls it once.
- You should notice this as pages that settle faster, especially the sport boards and anything that reads a game's injury list.
- No card, price or tier changed. This is the same injury data arriving the same way, just not fetched over and over.
We will never again tell you to back two things that cannot both happen
- A soccer match has three outcomes and we publish all three, so you can see the whole market. That is deliberate and it stays. What was broken is that two of those three could carry a recommendation at the same time.
- It happened on 2 of the 8 World Cup matches we ever published. On 7/10 we called Belgium a STRONG play and the draw a LEAN, in the same match. Back both and one of them has to lose.
- Only one side of a game's moneyline can be a recommendation now. The highest scoring side keeps it. The others stay on the board, stay graded, and sit in the watch band with a line saying which side outscored them and by how much.
- Nothing is deleted. You still see all three prices and the full market. Only the recommendation changes.
- We already fixed this for two way markets on 7/27. Three way markets were exempted from that guard on purpose, and the exemption reached further than it should have.
- On the two matches it would have caught, keeping only the top side returns +2.00 units against what we published. Two matches is not a track record, and the reason to fix it is not the two matches.
- Effect on today's board: none. No soccer is in season, and no other card changed tier.
How far a market may correct us now depends on how much it has watched
- Every market's correction was capped at 5 points, no matter whether it had watched 42 settled plays or 1,899. One number was doing two opposite jobs: a safety rail on a thin market, a gag on a thick one.
- Total bases overs are the clearest case. Across 1,899 settled plays we predicted 53% and hit 45%. The market asked to cut those cards by 7.8 points and we were only letting it cut 5.
- The cap now scales with evidence: 3 points for a market that has just qualified, widening toward 8 as settled plays accrue. A market that has watched thousands of results may move a card further than one that has watched forty.
- This is not a loosening. It moved four markets in two directions. Total bases overs opened to 6.7 points because 283 effective plays earned it. Threes unders, assists unders and points-plus-assists unders all tightened below the old 5, because roughly 45 plays did not, and their double-digit asks are what a thin sample overreaching looks like.
- Switching a market on is stricter than before, not looser. At the qualifying threshold the cap is 4.2 points, tighter than the flat 5 it replaces.
- The track record page now marks any market pinned at its cap and says, on hover, how far the evidence wanted to go and why it was not allowed. A capped number and an earned one used to print identically.
- Effect on today's board: no card changed tier. The one total bases over on the board had its expected value marked down from -2.6% to -6.2%.
We measured how much of our own edge is real
- Every prop market now gets asked one question against its graded history: when our number sits further from the line, does the result actually follow? Measured over 5,673 settled props.
- Only total bases answered yes cleanly, and even there the market absorbs about 85% of what the model thinks it sees. Threes and rebounds came back positive but thin.
- WNBA points, assists, PRA, PA and PR came back negative: a bigger claimed edge has meant a worse bet. Those cards now price at the market, earn no EV credit and no stake, and say so in plain language on the card.
- The lean the model is allowed off the market price is per market now instead of a flat number, and it can only tighten. A market with no graded history keeps the full lean rather than being silenced on no evidence.
- Effect on today's board: 94 cards in the unproven lanes dropped to a zero recommended stake. The board still publishes, it just stops sizing money into its own noise.
- Later the same day: we stopped grading today's model on yesterday's model's results. Our corrections were built from every card ever graded, as if the model had not changed. It had, three times in the last week alone.
- Each graded card is now weighted by how much it still says about the model running right now, halving for every change that moved the published win probability. Across every prop market, only about 13% of the graded history described the model actually running.
- Corrections shrank accordingly. Total bases went from a 4.7 point cut to 4.0 on an effective sample of 386 rather than 2,953. WNBA rebounds-plus-assists lost its correction entirely, having too little current evidence to justify one.
- The reliability curve on the track record page stays unweighted on purpose. It is the record of what we said and what happened, and reweighting that by our own opinion of which cards still count would be marking our own homework.
- Later still: we found we did not know which ballparks have roofs. The indoor check read a field our data provider never fills in. Across 409 games and all 30 venues this season it was empty every single time, Tropicana Field included, so the check had been doing nothing at all.
- Three things were running on it. Rain kills on games that cannot be rained out, heat and cold flags describing the weather outside a sealed building, and the only lean the game-total lane is allowed to take.
- The game total was the worst of it. That lane only fires at 96.7F and above or 43.3F and below, and outdoor baseball is almost never that hot. Retractable-roof parks are, and they are built in the hot markets for exactly that reason. So nearly every total it could publish was a game played indoors with the air conditioning on.
- Roofs now come from a table keyed on the venue id, which survives renames: Minute Maid Park became Daikin Park and kept the same id. Rain is dead at all 8 roofed parks. Temperature still applies at T-Mobile Park, whose roof is a cover rather than an enclosure and leaves the air outdoors.
- It can only take signals away, never add one, so it can cost a card its edge and can never invent one. On today's board it cleared a rain kill and a 95F heat flag off the nine cards in Texas at Houston, played under a shut roof with a 45% chance of rain outside it.
The Desk Ledger ships
- New Desk Ledger page: every play the human desk graded, fired or not, settled in the open.
- Kill-audit honesty: community hot-list and community-video boards graded at a flat $100 per play next to the real card, so the kill engine's value is measurable, not claimed.
- Seeded with 7/29 and 7/30. The 7/30 head-to-head: desk fired 1-2 for -$26.47 while the community hot list went 4-5 for -$232.57 at flat $100 stakes.
- Same-game cap: cards ranked 3rd or deeper inside their own game went 22-43 (33.8%, -13.3u) in July while the 1st and 2nd reads went 127-114 (52.7%, +9.7u). Deep reads now decay a tier band, are barred from the parlay, and show how often the whole group loses together.
The Fire Card ships
- The Fire Card page: today's hand-vetted, confidence-ranked slate with tier badges, price gates, and killed-with-reason calls, updated through the day by Vesper.
- Y3 Paper Ledger page: the reverse-NRFI lane tracked in the open, entry by entry, including no-play days.
- This changelog: every day Bet Data Labs ships, the receipt lands here.
- Homepage: Fire Card spotlight and daily shipping strip.
Slate OS v2 under the hood
- Slate OS v2: rebuilt slate engine with tighter scoring and verification gates.
- PDF pipeline: the Final Fire Card renders to a shareable PDF automatically.
- Outlier mastery pass: deeper L5/L10/L20 and H2H validation wired into vetting.
- Y3 lane study: the reverse-NRFI thesis researched, framed, and moved to paper.