Spaces:
Paused
Paused
Commit History
-
Phase 3 follow-ups: a false comment, a misplaced label, a false alarm
Claude +1: Claude Opus 5Unverified signatureThree nits from Phase 3's two review lenses, all cheap and all real: - pairing.js's knockout reconciliation note claimed "n - p is exactly the number of FIRST-ROUND MATCHES here", which is false when n is itself a power of two (n=8: n-p=0, but round 1 plays 4). Restated precisely. A comment asserting an invariant the code does not hold is a named defect class in this repo (docs/code-improvement-tiers.md pattern 1), so this is worth the words. - The Tournament screen's "Field" label was appended straight into .comp-screen while every sibling row (Format, Difficulty, Swiss rounds) wraps its label in a .setup-row, so it sat misaligned. Wrapped to match; the field list itself stays outside the row, being a full-width block rather than a label-plus-control pair. - A red "Autosave is failing -- use Save to export a file." banner fired on any menu screen after 36s, with localStorage perfectly healthy. autoSave() returns false both when a write throws AND when there is…f606a83 -
Phase 3 (part 2): the in-game Tournament tab — round-robin, Swiss and knockout
Claude +1: Claude Opus 5Unverified signaturedocs/competitions-and-elo.md's Phase 3 wants real tournaments in the game: a format picker, a field builder, a budget estimate before you commit, round-by-round progress, live standings and a bracket view, with every pairing folding into the ladder. Part 1 landed pairing.js (the shared schedules); this stage wires all three formats into the Worker and the competition screen. Quick Duel, the roster and the standings screen are untouched in behaviour. - competitionWorker.js gains a SECOND job kind: `{ kind: "tournament", format, field, difficulty, worlds, seeds, seedBase, rounds? }` -> runTournamentJob(job, onProgress). A job with no `kind` is still the original single duel, dispatched to runCompetitionJob completely unchanged. The tournament's injected `runPair` is a thin wrapper around runCompetitionJob ITSELF, so a tournament pairing is byte-for-byte the same work a Quick Duel already does — side-swapped both directions, replicate-parity swapAsym, one pinned difficulty for …204faa9 -
Phase 3 (part 1): pairing.js — the shared pairing/scheduling core, plus a knockout bracket
Claude +1: Claude Opus 4.8Unverified signaturedocs/competitions-and-elo.md's Phase 3 needs round-robin, Swiss and a knockout bracket in the game, and its own brief says why the pairing logic must be shared rather than reimplemented: "the Swiss matcher's backtracking, its bye rule, and its already-played-pair avoidance are exactly the sort of code that must not be reimplemented". So this stage extracts that logic and completes it. UI and Worker wiring are the next stage on purpose -- pure logic only here. - pairing.js (new, root, `// @ts-check`, JSDoc-annotated, no DOM/clock/unseeded-pick reference anywhere): pairKey, MATCH_ATTEMPT_CAP, findMatching, greedyMatching, rankStandings, pairRound and buildSwissBracket moved verbatim out of tools/ailab.js, comments included -- they are the record of three real bugs (a bye counted as a win, a rematch a greedy walk could not avoid, standings ranked by total games instead of win rate) and are worth more than the code. The TIER 5 header's PAIRING RULE and BYES paragraphs moved with…3e24f9b