The Gate We Inherited From a Sport We Left
At some point in the shop's early years, we covered hockey. Not extensively — a few seasons, a narrow slice of the corpus, enough to build some gates and learn that we were not particularly good at reading the sport. We stopped covering it. What we did not do, with anything like the same care, was clean up after ourselves.
The gate in question was designed around a hockey-specific problem: the way a player could be scratched from a lineup so late in the day that any rating built on their expected participation was already in the grading queue. Hockey scratches were fast, quiet, and frequently undisclosed until warm-ups. The gate we built checked for a confirmation signal — a positive indicator that the player had been listed as active, not merely the absence of a scratch notice. Absence of bad news was not good news. We learned that the hard way, and the gate held.
When we wound down hockey coverage, we migrated the corpus architecture to basketball. The gate migrated with it. Nobody decided that. It just traveled, the way a piece of furniture travels between apartments because nobody stops to ask whether it fits the new room.
A free online course in data analytics with Python: statistics, visualization and finding the signal in the numbers.
What a Hockey Gate Actually Does Inside a Basketball Process
Basketball has its own availability problem, but it is structured differently. Injury designations in the sport we invented our basketball corpus around are reported on a rolling basis, sometimes days in advance, and the confirmation signal we were checking for — active-list inclusion — maps onto the sport reasonably well on paper. So the gate did not obviously break anything. It just added a redundant check that occasionally tripped on timing differences between when rosters were finalized and when our corpus pulled them.
For most of those two years, the gate was effectively invisible. It passed almost everything, because basketball's reporting cadence meant the confirmation signal was almost always present by the time we ran evaluations. The gate looked healthy in our logs. It was closing on roughly two percent of candidates — which we read as evidence it was working, not as evidence it was barely doing anything.
Remi was the one who finally looked at it directly. She had been auditing the gates for a calibration review and pulled the rejection logs for the prior eighteen months. "This gate is closing on players who were already dead at gate two," she said. "Everything it catches, something upstream already caught. It's not a gate. It's a receipt."
She was right. When we traced the two percent it had been rejecting, we found that in every case, the candidate had failed an earlier availability check and was already excluded. The hockey gate was never doing independent work. It was signing off on exclusions that had already happened.
Running It Forward and Backward to Find What It Was Actually Measuring
Before we removed it, we ran a retroactive audit. We wanted to know whether there had ever been a period — including the hockey years — when this gate was doing genuine independent work in the basketball process. We went back to the original migration, which was sloppy enough that we had to reconstruct some of the gate sequencing from notes rather than logs.
What we found was that the gate had done real work for about four months after the migration, during a period when gate two was configured differently and the upstream availability check was less thorough. During those four months, the hockey gate caught eleven candidates that would otherwise have passed into scoring. After gate two was tightened — which happened for unrelated reasons, documented in a different review — the hockey gate's independent catch rate dropped to zero and stayed there.
We had inherited the gate and never questioned it because, for a brief window, it had looked like it was earning its place. That window closed and we did not notice, because we were reading the rejection rate as signal rather than reading the composition of what it was rejecting.
This is a version of a problem we have written about in other contexts: a gate that was closed correctly but for the wrong reason still produces the right output, and the wrong reason goes unexamined. Here the inverse was true. The gate was passing correctly, but only because something else had already done the actual work. The hockey gate was a shadow of a gate that no longer needed to exist.
The Two Years We Spent Maintaining Logic We Didn't Understand
The honest cost was not the two percent false overhead on rejections. That was negligible. The real cost was the maintenance fiction — the two years during which the gate appeared in our documentation as an active, functioning part of the process, and during which anyone reading that documentation would have believed it was doing something.
We wrote about the gate in at least two internal reviews. We defended its presence once, when someone asked whether the basketball process had too many availability checks. I said, from memory, that each gate was there because something had broken without it. That was true of the hockey gate — just not in basketball, and not for the preceding twenty months.
The more uncomfortable finding was what it implied about the audit process. We grade every rating. We check calibration. We do not quietly delete misses. But we were not, apparently, routinely checking whether the gates themselves were doing independent work or simply echoing decisions already made upstream. A gate that never fires looks like a tight process. It can also look like a redundant one. We had been reading tightness where we should have been reading redundancy.
Remi's phrase — "it's not a gate, it's a receipt" — became something we now use in gate reviews. It is a useful question to ask of any check that has a very low rejection rate: is this closing on things that would have survived without it, or is it just confirming what something else already decided?
What the Hockey Gate Left Behind When We Finally Removed It
We removed the gate from the basketball process. We did not replace it with anything, because the upstream check it had been shadowing was already sufficient. The rejection rate on that upstream check did not change. Nothing downstream changed. The gate's removal was, in the most deflating possible sense, uneventful.
What we kept was the question it raised about gate sequencing. We now run a redundancy audit on the full gate stack once per quarter — a mechanical check that asks, for each gate, whether there exists a subset of candidates that it would close on independently of every gate above it. If the answer is no for two consecutive quarters, the gate goes to review. This is not a sophisticated procedure. It is the procedure we should have had when we migrated a sport's architecture into another sport's process without thinking carefully about what we were carrying.
The sequencing problem, incidentally, is distinct from the problem of a gate that was added to one sport and then forgotten inside another. That piece is about gates that survive because nobody remembers adding them. This one is about a gate that survived because it briefly worked, and then kept surviving on the credit of that brief window long after the conditions that made it work had changed. The mechanism is different. The result — a gate doing no independent work — is the same.
We also kept the hockey gate's original logic in a reference file. Not in the active process, but documented. The confirmation-signal check is genuinely useful for sports where scratches are late and quiet. If we ever cover a sport with that structure again, we have a gate already written. We just have to remember to check, this time, which sport we are actually running it in.
There is probably a version of this problem in every part of the process that was built under one set of conditions and has not been interrogated since. I am not sure the quarterly redundancy audit catches all of it — it catches the gates that are doing no independent work, but not the ones that are doing the wrong independent work for reasons that happen to produce acceptable output. That category is harder to find, and I suspect we have some.
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.