Reconcile NT-only board branch with current main #29

Merged
kristofferopsahl merged 3 commits from feat/nt-only-board into main 2026-10-15 22:40:44 +02:00
Owner

This branch is now synchronized with main at 2184143 while preserving its original commits. Its final file tree is identical to main: merging this PR integrates branch history and makes no application or data changes.

The NT-only feature commit 42bb44b is already an exact ancestor of main. The branch-only CI change is patch-equivalent to main. The update retains later NOT_OPENED/NO_FIXTURES handling, corrected coverage, and the extracted API/browser modules.

Validation:

  • Exact tree equality with main verified; no unresolved conflicts.
  • Targeted NT, props, watch, chores and scorer validation: 192 passed, 3 skipped.
  • Forgejo reports the PR mergeable.
  • Fresh CI run 123 passed on 5a886cb: syntax, 2,144 tests passed / 145 skipped, and wheel build/install/import checks.

No feature cherry-picks, baseline changes or history rewrites were needed. This PR remains open for merging.

This branch is now synchronized with main at `2184143` while preserving its original commits. Its final file tree is **identical to main**: merging this PR integrates branch history and makes no application or data changes. The NT-only feature commit `42bb44b` is already an exact ancestor of main. The branch-only CI change is patch-equivalent to main. The update retains later `NOT_OPENED`/`NO_FIXTURES` handling, corrected coverage, and the extracted API/browser modules. Validation: - Exact tree equality with main verified; no unresolved conflicts. - Targeted NT, props, watch, chores and scorer validation: **192 passed, 3 skipped**. - Forgejo reports the PR mergeable. - Fresh [CI run 123](https://git.kristofferopsahl.com/solvreven/FPL/actions/runs/123) passed on `5a886cb`: syntax, **2,144 tests passed / 145 skipped**, and wheel build/install/import checks. No feature cherry-picks, baseline changes or history rewrites were needed. This PR remains open for merging.
fix: the asset guard hashed raw bytes, so it could only be green on one platform
All checks were successful
CI / syntax (pull_request) Successful in 8s
CI / tests (pull_request) Successful in 1m7s
CI / wheel (pull_request) Successful in 29s
CI / browser (pull_request) Successful in 16m33s
83111ce2e0
test_asset_version.py hashed the four assets byte-for-byte. These are text
files and the repo has no .gitattributes, so CI checks them out LF on
debian-trixie while a Windows clone with core.autocrlf=true holds CRLF.
The digest therefore differed by platform, and the guard was green only
for whoever recorded it last.

Both sides then re-recorded their own value in turn, each fix correct
locally and each breaking the other:

  1c94db7  135  d20d1fa11d2d9a94  CRLF   green here, RED in CI
  bbf3c01  136  a932c205c61efb9b  LF     green in CI, RED here   (PR #27)
  9c2faca  137  d9ca43b746e10252  CRLF   green here, RED in CI

So main has been red in CI since 9c2faca, and PR #27's asset commit was
not wrong -- it was right for Linux. Neither side could see the other's
failure, because each measured the assets through its own checkout.

A CRLF/LF difference is not an asset change a browser needs a new ?v=
for, so it must not move the digest. Normalising before hashing makes the
platform difference unrepresentable rather than documented; recorded
digest is now the normalised value, identical under both conventions.

Chosen over a .gitattributes entry deliberately: that would leave the
guard's correctness depending on every contributor's checkout config,
which is the disconnected-mechanism shape this repo keeps paying for.

Proved RED on both properties -- the one fixed and the one that must not
break:

  CRLF checkout (Windows)              GREEN
  LF checkout (CI debian-trixie)       GREEN
  app.js changed, ?v= not bumped       RED
  tokens.css changed, ?v= not bumped   RED

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014adnmRztkdAPwinWXnNQ7N
feat: Norsk Tipping is the only book on the board, and it fetches itself
All checks were successful
CI / syntax (pull_request) Successful in 8s
CI / tests (pull_request) Successful in 54s
CI / wheel (pull_request) Successful in 28s
CI / browser (pull_request) Successful in 16m55s
42bb44b18a
Removes the six-book consensus from the served surfaces and makes NT the
market for match odds, anytime goalscorer and anytime assist. The consensus
files stay on disk and score_goalscorer.py still scores both every round,
so this is a code change, not a lost comparison.

NT does not open its markets all at once -- measured 2026-09-01/02, goals
open ~4 days out and assists ~2, per fixture -- so a single pre-deadline
pull could never carry both. nt_watch in chores.py polls on COVERAGE
("does the newest banked run carry both markets for every fixture of the
next round", answered from the manifests on disk) rather than on a clock
or a completion marker, so a pull someone ran by hand counts. The
denominator is the round's fixture count from FPL, never the run's.

Four producer-without-a-consumer defects surfaced while wiring it, three
created by the NT-only switch itself: disagreements and
fixtures_without_market were computed and discarded by main.matches;
gw{n}_market_nt.json was written by nt_resolve with nothing rebuilding
the cache to read it; and n_fixtures counted match_odds while the table
was drawn from a different subset.

_unpriced_but_ours no longer returns one flat list. "No book priced X --
the omission is the bookmakers' saying he is unlikely to feature" was
printed over five players in two fixtures NT had not opened at all, which
is a verdict reported where the book had said nothing. It returns
{"declined": [...], "unopened": [...]} keyed on the FPL team id, because
the two need opposite responses.

pre_deadline_steps is now pull -> resolve -> rebuild -> snapshot, so the
frozen cache is the one built from the frozen prices. snapshot_pit.odds_for
takes both market files; the raw NT run is zipped rather than pointed at,
since prune_nt_runs can delete the directory.

Retires _books_expect_him: the coverage-share gate cannot be computed from
one book. Reported rather than patched around -- raising our own start_prob
floor would let the weakest number in the system decide membership.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014adnmRztkdAPwinWXnNQ7N
ci: run on debian-latest
All checks were successful
CI / syntax (pull_request) Successful in 9s
CI / tests (pull_request) Successful in 1m21s
CI / wheel (pull_request) Successful in 26s
CI / browser (pull_request) Successful in 16m14s
386dbb30bc
Same label swap as on the default branch: the debian-trixie-<stack> runner
labels are being removed; debian-latest is the consolidated debian-ci image.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Merge branch 'main' into feat/nt-only-board
All checks were successful
CI / syntax (pull_request) Successful in 8s
CI / tests (pull_request) Successful in 1m8s
CI / wheel (pull_request) Successful in 29s
0f01f70438
Resolves the ci.yml conflict from #38 by taking main's workflow; this branch's only change there was runs-on: debian-latest, which main already has.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Merge main into NT board PR without reverting subsequent fixes
All checks were successful
CI / syntax (pull_request) Successful in 10s
CI / tests (pull_request) Successful in 2m33s
CI / wheel (pull_request) Successful in 31s
5a886cb61e
The NT feature commit 42bb44b is already an ancestor of main, and the branch-only runner-label change is patch-equivalent. The automatic merge produces exactly the current main tree, retaining NOT_OPENED, NO_FIXTURES, the current coverage logic and domain modules. Preserve the original PR history.
kristofferopsahl changed title from Norsk Tipping is the only book on the board, and it fetches itself to Reconcile NT-only board branch with current main 2026-10-15 22:30:40 +02:00
Sign in to join this conversation.
No description provided.