Skip to content

chore(ai): reconcile development → main (brings AI-independence test)#40

Merged
nodots merged 4 commits into
mainfrom
development
Apr 21, 2026
Merged

chore(ai): reconcile development → main (brings AI-independence test)#40
nodots merged 4 commits into
mainfrom
development

Conversation

@nodots

@nodots nodots commented Apr 21, 2026

Copy link
Copy Markdown
Owner

Summary

Fast-forward `main` up to `development`. Four commits:

  • `0a3aa6c test(ai): assert analyzers do not consume dice entropy` — the
    AI-independence test Paper 12 §3.2 references. Test-only; no runtime
    behavior change, but CI enforcement is absent on main today.
  • `d5a4ea1 Merge pull request test(ai): assert analyzers do not consume dice entropy (Phase 1.2 of nodots/backgammon#327) #39 from nodots/feat/ai-independence-test`
  • `fb3eec3 fix(test): enable experimental VM modules for Jest ESM support`
  • `de7c4b1 Merge branch 'main' into development`

No new work, just reconciling already-reviewed commits onto main.

Test plan

  • `main` is an ancestor of `development` — pure fast-forward

nodots added 4 commits April 21, 2026 14:40
Adds a test that installs a spy on Dice.rollDie (from
@nodots/backgammon-core) and verifies every shipped analyzer leaves
it untouched during selectMove. Covers randomMoveAnalyzer,
furthestFromOffMoveAnalyzer, nodotsAIMoveAnalyzer, examplePluginAnalyzer,
and gnubgMoveAnalyzer (with @nodots/gnubg-hints mocked per the
existing pluginAnalyzers.test.ts pattern).

The invariant: move selection reads the legal-move set and the board
but does not roll dice. An analyzer that calls Dice.rollDie during
selection either (a) peeks at an upcoming opponent roll or
(b) advances the RNG in a way that biases subsequent game rolls —
both of which would regress the fairness story in Paper 12 (§9.1).

A baseline-sanity test confirms the spy fires when Dice.rollDie is
invoked directly, guarding against silent passes if the spy setup
breaks.

Phase 1.2 of nodots/backgammon#327.
Closes nodots/backgammon#331
test(ai): assert analyzers do not consume dice entropy (Phase 1.2 of nodots/backgammon#327)
The Jest config in this package sets extensionsToTreatAsEsm: ['.ts']
and useESM: true on the ts-jest transformer, which requires Node's
--experimental-vm-modules flag for jest.unstable_mockModule and
top-level await import() to work.

Several existing tests (pluginAnalyzers.test.ts, ai-independence.test.ts,
and others that mock @nodots/gnubg-hints) rely on both patterns and
were silently failing in CI with "await is only valid in async
functions and the top level bodies of modules" because the test script
did not set the flag.

Adds NODE_OPTIONS=--experimental-vm-modules to the test, test:watch,
and test:coverage scripts. CI matrix is ubuntu-latest + macos-latest
only, so plain shell-prefix form is portable; no cross-env needed.

Verified:
  npm test -- src/__tests__/pluginAnalyzers.test.ts \
              src/__tests__/ai-independence.test.ts
→ 10/10 tests pass, 2/2 suites.

Nine other test suites still fail for pre-existing reasons unrelated
to this flag (CJS resolver stack overflow, import-after-teardown).
Those are separate concerns.
@nodots
nodots merged commit 85946b3 into main Apr 21, 2026
0 of 19 checks passed
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