A fictional shop writing about method. No picks, no lines to act on, and nothing here is betting or investment advice. What this is.

The Gate That Passed the Same Player Twice

The availability gate is supposed to be the boring one. It does not require a model. It does not require judgment. It asks a single question — is this player expected to feature in tonight's event — and it either passes or fails the candidate on that basis alone. We built it early, tested it once, and mostly forgot about it. That was the mistake.

In the third week of a basketball run last winter, a single player cleared the availability gate on a Tuesday and again on a Thursday of the same week. Not a similar player. The same identifier, the same corpus entry, the same candidate — rated twice, scored twice, graded twice, each instance treated by the pipeline as a fresh and independent observation. The corpus absorbed both without complaint. So did we, for four days, because nothing in the output looked wrong. Both ratings were reasonable. Both gradings came back clean. The error was invisible until Priya ran a routine deduplication audit on the weekly corpus digest and found the same player had accrued two graded entries inside a five-day window with no rest day between them.

The gate had not malfunctioned in any dramatic sense. It had done exactly what it was built to do. The problem was what we had not built it to do, which turned out to be a longer list than we expected.

Discover How the Systems Around You Really Work

Understand the government, financial, healthcare, business, and technology systems affecting everyday life.

Learn more

How One Player Became Two Observations in Five Days

The availability gate checks three things in sequence: whether the player has a scheduled event, whether they are listed as expected to participate, and whether the event has not already begun. It was built originally for one sport and later extended, which is relevant context. The version we were running in winter had no memory between sessions. Each nightly run was stateless. The gate passed a candidate, the pipeline scored it, and the session closed. The next night, the gate had no record of what it had passed forty-eight hours earlier.

In most circumstances this is fine. A player who features on Tuesday and again on Thursday is genuinely a new observation on Thursday — different opponent, different context, different night. The corpus is supposed to accumulate those. The problem was not that the player featured twice. The problem was that the two entries were not being distinguished from each other in the corpus reconciliation step. They were landing in the same rolling window with the same weight, which meant a single player's two-game stretch was being treated as two independent data points rather than as two correlated observations from the same short run.

This is precisely the kind of inflation the caps and shrinkage rules exist to prevent at the slate level. We had a rule against any single night dominating a rating. We did not have an equivalent rule against any single player dominating a rolling window through sheer scheduling density. The gate and the corpus were each doing their jobs. The gap was in the handshake between them.

What We Added to the Gate to Stop It Happening Again

The first fix Priya proposed was a cooldown flag — a simple rule that any player who had cleared the availability gate within the previous N days would be held for manual review before clearing it again. We debated the value of N for longer than I am proud of. Three days felt too short; it would still allow back-to-back entries in a dense schedule. Seven days felt too long; it would suppress legitimate observations in sports where players feature multiple times a week. We settled on a soft flag at four days, which meant the gate would still pass the candidate but would tag the entry for a secondary check before it reached the corpus.

The secondary check was manual, which is not a satisfying engineering answer but turned out to be the honest one. The question it asked was whether the two entries were genuinely independent observations or whether they were correlated enough that treating them as separate data points would inflate our confidence in the player's recent form. Most of the time the answer was that they were fine to include, provided we applied an explicit downweight to the second entry within the rolling window. The downweight was not derived from anything elegant — it was set at half the standard entry weight for any observation that fell within four days of a prior one from the same player. A round number chosen because we had no principled basis for anything more precise.

"The gate isn't the problem. The gate never was. The gate passed the player correctly both times. The problem is that we built the corpus to receive independent shots and then fed it correlated ones without telling it." — Priya

She was right, and it reframed the whole repair. We were not fixing a gate failure. We were fixing a corpus assumption that had been invisible because we had never stress-tested it against a player with a dense schedule.

What the Double Entry Actually Did to That Week's Ratings

Here is where I have to be specific about what went wrong, because the temptation with this kind of error is to describe it abstractly and move on. The player in question had a strong Tuesday and a weaker Thursday. Because both entries carried full weight in the rolling window, the corpus read that week as a moderately positive stretch — one strong observation averaged with one weak one. That is accurate as far as it goes. The problem is that the same player's prior fifty-game corpus already contained this kind of variance. The two new entries should have moved the needle very slightly. Instead, because they were double-weighted relative to what the corpus expected, they moved it more than they should have.

The rating that came out of that week was not dramatically wrong. It was nudged — maybe five percent more confident in the player's current form than the underlying sample size justified. We caught it before it propagated further because Priya's audit happened to fall that week. If it had not, we would have carried a slightly inflated reading into the next grading window and probably not noticed until calibration review, where we would have seen a small unexplained gap between stated confidence and observed accuracy and spent time looking in the wrong places for the cause.

This is the category of error I find most unsettling: not the kind that produces an obviously wrong output, but the kind that produces a subtly overconfident one. Overconfidence is the failure mode we cannot always see coming, and it tends to compound quietly before it becomes visible. A gate that leaks once and gets caught is a gate we understand. A gate that leaks in a way that looks like signal is something else.

What Stayed in the Gate and What the Audit Became

We kept the soft flag and the downweight. Both have survived three subsequent grading cycles without causing a problem we could attribute to them, which is weak evidence that they are not making things worse. We also kept the stateless session design — adding memory to the gate itself felt like solving the wrong problem, and stateful gates have their own failure modes, as we learned from a different direction entirely. The gate's job is to answer a question about tonight. Making it responsible for remembering last Tuesday seemed like a way to make it slower and more fragile without making it meaningfully smarter.

What changed more substantially was the audit. Priya's deduplication check had been informal — something she ran when she had time, not something the process required. We formalized it. It now runs automatically at the end of every weekly corpus digest, flags any player with more than one graded entry in a four-day window, and produces a short report that one of us reads before the next session opens. The report is almost always empty. When it is not, the entries are almost always fine to keep at full weight. But the two or three times a season when it catches something real, it catches something we would have otherwise missed entirely.

The deeper change was in how we think about the corpus as a receiver. We had been treating it as a passive accumulator — entries go in, weights are equal, the math handles the rest. That assumption was wrong in a specific and now-documented way. The corpus assumes independence between entries, and we were not doing enough to enforce that assumption before entries arrived. The gate and the corpus are separate systems, and the space between them is where this particular error lived.

The question I have not resolved is whether four days is the right cooldown threshold or whether we chose it because it felt reasonable and stopped arguing. There is probably a sport-specific answer — basketball schedules are denser than baseball schedules, which are denser than tennis draws — and a single threshold applied across all of them is almost certainly wrong for at least one. We have not revisited it. Maybe the next audit will give us a reason to.

Note: PlayerGem is a fictional analytics shop and these accounts are invented. Nothing here is a pick, a recommendation, or betting or investment advice, and the players, teams and competitions described do not exist.

Seven desks. The method, not the picks.

Start from the top