You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Core test coverage is low, and it is lowest precisely on the code the Game/index.ts decomposition (#132) is about to move. Extracting untested methods means the test suite cannot catch extraction regressions where the risk is highest.
Measured baseline (COVERAGE=1 npx jest, 2026-07-15):
Scope
Stmts
Branch
Funcs
Lines
core (all files)
56.5%
40.9%
56.8%
57.3%
Game/index.ts
53.7%
45.6%
61.2%
55.5%
Uncovered ranges in Game/index.ts map directly to extraction targets:
Raise coverage on the methods being extracted to a level where the extraction is verifiably behavior-preserving, then lift core coverage more broadly. Approach: characterization tests first — capture current behavior as tests before the code moves, so a passing suite after extraction is proof of equivalence.
Phase B — broader core lift (after / independent of #132)
Raise core coverage to 75% (statements, branches, functions, lines) from the current ~57% line / ~41% branch.
Add a coverageThreshold gate of 75% to jest.config.js (currently coverage is opt-in via COVERAGE=1, no threshold) so coverage cannot regress silently. The gate lands once coverage clears 75% — adding it earlier would fail the suite immediately at the current ~41% branch. Interim option: ratchet the threshold up as coverage rises rather than one jump at the end.
Identify and cover other low-coverage core areas surfaced by the full report (e.g. debugSingleGame.ts ~54%, and the sub-50% files in the full run).
Problem
Core test coverage is low, and it is lowest precisely on the code the
Game/index.tsdecomposition (#132) is about to move. Extracting untested methods means the test suite cannot catch extraction regressions where the risk is highest.Measured baseline (
COVERAGE=1 npx jest, 2026-07-15):Game/index.tsUncovered ranges in
Game/index.tsmap directly to extraction targets:rollinternalsturnFlow.tsswitchDiceturnFlow.tsexecuteAndRecalculateturnFlow.tsrestoreStatelifecycle.tscanOfferDouble/doublecube.tsacceptDouble/refuseDoublecube.tsresigncube.tsconfirmTurnWithRobotAutomationrobot.tsundoLastInActivePlay/canUndoActivePlayundo.tsGoal
Raise coverage on the methods being extracted to a level where the extraction is verifiably behavior-preserving, then lift core coverage more broadly. Approach: characterization tests first — capture current behavior as tests before the code moves, so a passing suite after extraction is proof of equivalence.
Scope (phased, ordered to unblock #132)
Phase A — safety net for the decomposition (do before the matching #132 phase)
cube.tstargets:canOfferDouble,double,canAcceptDouble,acceptDouble,canRefuseDouble,refuseDouble,resign— cover accept/refuse/resign outcomes, cube value/ownership transitions, Crawford interaction. (Blocks refactor: split Game/index.ts god file into cohesive modules #132 Phase 3.)undo.tstargets:undoLastInActivePlay,canUndoActivePlay, and the snapshot push insidemove— cover push→undo round-trip restores exact priormovingstate, empty-stack error, wrong-state error. (Blocks refactor: split Game/index.ts god file into cohesive modules #132 Phase 2.)lifecycle.tstarget:restoreState. (Blocks refactor: split Game/index.ts god file into cohesive modules #132 Phase 4.)turnFlow.tstargets:switchDice(incl. the must-use-larger-die guard),executeAndRecalculate,rollbranches. (Blocks refactor: split Game/index.ts god file into cohesive modules #132 Phase 5.)robot.tstarget:confirmTurnWithRobotAutomation,handleRobotMovedState.Phase B — broader core lift (after / independent of #132)
coverageThresholdgate of 75% tojest.config.js(currently coverage is opt-in viaCOVERAGE=1, no threshold) so coverage cannot regress silently. The gate lands once coverage clears 75% — adding it earlier would fail the suite immediately at the current ~41% branch. Interim option: ratchet the threshold up as coverage rises rather than one jump at the end.debugSingleGame.ts~54%, and the sub-50% files in the full run).Delivery
Game.<method>API unchanged.Notes / constraints
COVERAGE=1injest.config.js(reporters: text, lcov). Full report: runCOVERAGE=1 npx jestfrompackages/core.Game/index.tsremediation epic; coordinate phase ordering with refactor: split Game/index.ts god file into cohesive modules #132.