Skip to content

scoreboards: one game-over check across all nine, with a FINAL_PERIOD seam (family 5 reconcile) - #625

Merged
ChuckBuilds merged 2 commits into
mainfrom
claude/family5-reconcile
Oct 5, 2026
Merged

ChuckBuilds merged 2 commits into
mainfrom
claude/family5-reconcile

Conversation

@ChuckBuilds

Copy link
Copy Markdown
Owner

Step 4 of the "reconcile, then promote" procedure for family 5, the game-over check SportsLive._is_game_really_over. All nine copies are now byte-identical; the drift report shows one variant. Each plugin declares the per-sport fact as FINAL_PERIOD: Optional[int] on its SportsLive:

  • hockey: 3
  • basketball, football, lacrosse: 4
  • afl, nrl, soccer, baseball, ufc: None, meaning the clock never ends a game

Owner decisions (2026-10-04)

  • One seam: FINAL_PERIOD only. The CLOCK_COUNTS_DOWN described in core's docs was never in code; the companion core PR removes it.
  • ufc: a fight is over only when ESPN marks it final. Neither a round break (-) nor a ticking 0:00 ends it.
  • Ties: equal scores at 0:00 at the end of regulation are not over, so the game stays live through the overtime break. A game that really ends tied still ends through the final text or ESPN's final status.
  • Baseball's not-played override (postponed, cancelled and so on) stays in BaseballLive.
  • Clock guard: only a non-empty string clock counts for the clock rule, as basketball, football, hockey and lacrosse already required.
  • Noise: one docstring and one log wording. The [LIVE_PRIORITY_DEBUG] lines are dropped from the three copies that had them; nothing tested or documented them.

What changes

All changes go from over to not-over, in the 3,115 cells pinned by scripts/test_game_over_check.py (#621):

Plugin Cells Why
afl, nrl, soccer 0 —
basketball, football, lacrosse 1 each Tie at the end of period 4
hockey 2 Ties at the end of periods 3 and 4
ufc 65 No clock rule: 0:00, ":00", or a missing clock in round 4 and later. The 10 recorded ESPN payloads are unchanged
baseball 53 FINAL_PERIOD = None. Every changed cell is a synthetic game with a period key, which real baseball games never carry, so nothing changes in practice

Scores arrive as strings. A missing, empty or non-integer score counts as "not a tie", so the clock decides as before.

Tests updated for the decided changes:

  • The nine test_null_period_really_over stand-ins.
  • Basketball, hockey and lacrosse test_vegas_elements cases that had pinned "a tied game is dropped from live".
  • ufc's "R5 0:00" case.

Versions: patch bumps with versions[] entries; the minimum core version stays at 3.8.0. afl 1.35.3, baseball 1.57.3, basketball 1.42.2, football 3.18.8, hockey 1.42.4, lacrosse 1.36.4, nrl 1.34.3, soccer 2.39.5, ufc 1.19.5.

Verification

All runs use core main.

  • Rendering: all 192 harness PNGs for the nine plugins are byte-identical to main.
  • Plugin tests: run_plugin_tests.py gives the same result per test as main, 346 passed. The 2 failures happen on main too: baseball test_baseball_activity and the interactive test_football_plugin.
  • Repo scripts: all 48 scripts/test_*.py pass.
  • Other checks: check_sports_drift passes, with only this method's baseline entry removed. check_version_bump --base origin/main passes naming all nine ids, and the registry is updated.
  • On ledpi: the pin test passes under the Pi's Python 3.13, run from a separate checkout so the running display wasn't touched (another session's measurement is using the rig).

The next step is the core PR, which adds src/common/sports_game_over.py (SportsGameOverMixin) with this body and a parity test against these copies.

🤖 Generated with Claude Code

…ith FINAL_PERIOD (family 5)

Step 4 of LEDMatrix docs/SPORTS_UNIFICATION.md ("reconcile, then promote")
for the game-over check. The nine SportsLive._is_game_really_over copies
were five bodies; they are now one, byte-identical, and the drift report
shows one variant. The per-sport fact is a class attribute on each
plugin's SportsLive, FINAL_PERIOD: the period from which a 0:00 clock ends
a game -- hockey 3; basketball, football, lacrosse 4; None (the clock never
does) for afl, nrl, soccer (clocks count up), baseball (innings) and ufc.

Differences, classified:
- Fix ported: only a non-empty clock string counts for the clock rule
  (baseball/ufc read a missing/None/non-string clock as 0:00).
- Owner decision: a score level at 0:00 is not over -- the game stays live
  through the break before overtime; a game that really ends tied still
  ends on its final text/status. A missing or unreadable score leaves the
  decision to the clock, as before.
- Owner decision: ufc has no clock rule (FINAL_PERIOD None); a bout ends
  only on ESPN's final.
- Noise: one docstring and one log wording; the [LIVE_PRIORITY_DEBUG]
  lines in the football/baseball/ufc copies are gone (nothing reads them).
- Baseball's BaseballLive postponed/suspended override is unchanged.

scripts/test_game_over_check.py (#621) tables regenerated with --print.
Of 3,115 cells only these changed, all over -> not over: ufc 65 (no clock
rule), baseball 53 (FINAL_PERIOD None; every one a game with a period,
which baseball's games never carry, so dormant in practice), and the tie
guard's 5 (basketball 1, football 1, lacrosse 1, hockey 2). Harness
renders of all nine against core main: 192 PNGs byte-identical.

Plugin tests follow the decisions: the null-period stand-ins carry
FINAL_PERIOD; each clock sport pins a tie at 0:00; baseball/ufc pin that
0:00 no longer ends a game; the vegas tie tests (basketball, hockey,
lacrosse) now expect the level game to stay live; ufc's derived "R5 0:00"
fight stays live until ESPN calls it final.

Patch bump for all nine (released 2026-10-05, floors unchanged),
CHANGELOG entries, registry updated, drift baseline drops the entry.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4f70a5ed-648b-4a8a-a1a5-8bd04da2cea2
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 0 complexity

Metric Results
Complexity 0

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@ChuckBuilds
ChuckBuilds merged commit 8db9d3e into main Oct 5, 2026
5 checks passed
@ChuckBuilds
ChuckBuilds deleted the claude/family5-reconcile branch October 5, 2026 13:21
ChuckBuilds added a commit that referenced this pull request Oct 5, 2026
…ly 5 adopt) (#631)

* scoreboards: inherit core's SportsGameOverMixin; drop the game-over copies (family 5)

Core 3.8.1 ships src.common.sports_game_over, whose
SportsGameOverMixin._is_game_really_over is the body the nine copies were
reconciled to in #625. Each plugin's SportsLive now inherits it, listed
before SportsLiveSharedMixin (the order core documents and tests), keeps its
FINAL_PERIOD declaration and deletes its copy. The import is plain; the next
commit floors every plugin on 3.8.1.

Baseball keeps BaseballLive._is_game_really_over, the postponed/suspended
check; its super() call now reaches core's method.

No behaviour change: scripts/test_game_over_check.py gives the same 3,115
answers, and every harness render is byte-identical.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* scoreboards: floor on core 3.8.1 (minor bumps)

afl 1.36.0, baseball 1.58.0, basketball 1.43.0, football 3.19.0,
hockey 1.43.0, lacrosse 1.37.0, nrl 1.35.0, soccer 2.40.0, ufc 1.20.0.

versions[0].ledmatrix_min_version and compatible_versions rise to 3.8.1,
the first release that ships src.common.sports_game_over, which the
previous commit imports plainly. A floor raise is a minor bump, as for the
3.7.0 and 3.8.0 raises before it. plugins.json regenerated with
update_registry.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* scripts: sunset guard for the game-over copies

scripts/test_game_over_mixin_copies.py, in the shape of the stage 3 and
stage 4 guards. For each of the nine scoreboards it fails when:

- a runtime file defines _is_game_really_over again (any class, or module
  level), except baseball's BaseballLive, which must call super();
- sports.py's import of SportsGameOverMixin is missing, aliased or inside a
  try that catches ImportError;
- SportsLive does not inherit the mixin, or lists it after
  SportsLiveSharedMixin;
- SportsLive's FINAL_PERIOD is not the owner's value (hockey 3; basketball,
  football and lacrosse 4; the rest None), or another class sets it;
- with a core checkout, the mixin defines anything but the method and
  FINAL_PERIOD.

A self-check plants each failure. CI picks it up through the
scripts/test_*.py glob in test-plugins.yml. The shared sports code page
records the 3.8.1 convergence.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* scripts: date the modules core v3.8.1 ships

Core v3.8.1 (a669d781) is tagged. Every None entry in the min-core table
is in it (checked with git show v3.8.1:<path>): fetch_service,
sports_game_over, display_arbiter, screen_runner and plugin_local_files
are now "3.8.1", and the test's tag list gains 3.8.1, so its tag
section checks them. v3.8.1 reports __version__ "3.8.1"; REPORTED_AS
needs no entry.

This clears check_min_core_version for the scoreboards' plain import of
src.common.sports_game_over.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant