Give scoring something to anchor on: focal athlete, per-sport target class, thread cap - #14
Merged
Conversation
… nothing Three findings from a real basketball run that produced 1287 tracks and zero suggested moments. Without an athlete to follow, a moment is arithmetically impossible. Three of the seven scoring signals need a focal track and together carry 0.6 of the 1.15 total weight. With no focal track the only signal that can fire is high_motion at 0.1, so the best any window can score is 0.087 against a threshold of 0.35. The app said "Nothing suggested yet — run analysis", ran analysis for a minute, and completed with nothing — never mentioning that it could not have succeeded. It now says so before the work starts, not after. Scoring looked for a track named `goal` whatever the sport. Basketball tracks a `hoop`, hockey a `net`, football an `end_zone`, so for those sports both target signals were permanently dark even with a model that saw the thing perfectly. Soccer worked by luck of naming. Sports now declare the class that is their scoring target, derived from the noun where the two agree and stated explicitly where they do not. A sport with no trackable target resolves to null rather than to a name nothing will match. The thread cap from #10 was tuned on a four-core laptop and production turned out to have twenty-four: worker: threads: using 4 (cgroup-aware 24, visible cores 48) Those two numbers disagreeing is what #10 existed to reveal, and it was right to pin the pool — onnxruntime would have sized from 48. But four is now the limit rather than the protection, so the cap moves to eight, which is where a model this small stops benefiting rather than the size of the machine it was measured on. REELEEL_CV_THREADS overrides it without a deploy, so the ceiling can be found without another release. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 10, 2026
ralyodio
added a commit
that referenced
this pull request
Aug 10, 2026
"we should use team color and names not just names — that would help with detection (ie: #14 in white team not #14 on black team)." Correct, and the column was already there: `jersey_color` has been on the athlete row since the first migration, and nothing has ever written it or shown it. So the picker offered a name — the one attribute a detector cannot help you match against — while the two things a parent actually points with, the number and the shirt, went unrecorded. Both teams have a 14 and on a school court they are regularly on screen together. Identity is now collected where the user is already looking at the child, in the picker itself, rather than in a separate "Add an athlete" form they would have to find first: name, number, shirt colour, team, all optional. Quick-identify no longer produces "My athlete" when the user told us who it was. Everywhere an athlete is named now reads "Fred #14 in white (Triton)", colour before team because colour is the part visible in the footage. The appearance matcher already separates the teams — a shirt signature is how it refuses the black team's 14 — so this makes the thing it keys on visible to the person judging its suggestions, rather than adding a second mechanism. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Three findings from your basketball run — 1,287 tracks, 34,089 detections, zero suggested moments.
1. Without an athlete to follow, a moment is arithmetically impossible
Three of the seven scoring signals need a focal track, and together they carry 0.6 of the 1.15 total weight. With no focal track the only signal that can fire is
high_motionat 0.1.Not "unlikely" — impossible. The app said "Nothing suggested yet — run analysis", ran analysis for a minute, and completed with nothing, never mentioning it could not have succeeded. It now says so before the work starts.
2. Scoring looked for
goalwhatever the sportBasketball tracks a
hoop, hockey anet, football anend_zone. For those sports both target signals were permanently dark even with a model that saw the thing perfectly. Soccer worked by luck of naming.Sports now declare their target class, derived from the noun where the two agree and stated explicitly where they don't:
A sport with no trackable target resolves to
nullrather than a name nothing will ever match.3. The thread cap was tuned on the wrong machine
Those two numbers disagreeing is exactly what #10 existed to reveal, and pinning the pool was right — onnxruntime would have sized from 48 on a 24-core allowance. But 4 is now the limit rather than the protection. The cap moves to 8, which is where a model this small stops benefiting rather than the size of the laptop it was measured on.
REELEEL_CV_THREADSoverrides it without a deploy, so the real ceiling can be found on the box that has 24 cores instead of guessed on one with 4.Verification
393 tests pass (7 new), eslint and typecheck clean. The ceiling arithmetic above was computed by running the real plugin weights through the real scoring code, not derived by hand — after a first attempt that got it wrong by counting
user_marker, which has a weight but no implementation and so never reaches the denominator.What to expect
Mark an athlete, re-run on
fast. Detection already works; this gives scoring the anchor it needs. If it still finds nothing, the log will now say whether tracks existed and the threshold is simply too high for this footage — which is a tuning conversation, not a bug hunt.