Skip to content

feat(site): ECE floor calculator, held to the Python in CI (phase 1) - #19

Merged
TMHSDigital merged 1 commit into
mainfrom
site/phase-1-floor-calculator
Sep 22, 2026
Merged

TMHSDigital merged 1 commit into
mainfrom
site/phase-1-floor-calculator

Conversation

@TMHSDigital

Copy link
Copy Markdown
Owner

Phase 1 of the Pages site: the floor calculator on its own, and the parity check that keeps it honest. Nothing deploys yet.

Why this shape. The calculator reimplements synthetic_floor in JavaScript. If the JS and the Python disagree, the site misreports the tool. So site/floor.js doesn't approximate the floor. It reproduces numpy's random stream draw for draw: PCG64 (128-bit arithmetic in 16-bit limbs), numpy's ziggurat normal and exponential samplers with its tables copied verbatim, Marsaglia-Tsang gamma, and beta. With the Python's seeds (0 and 1), every Bernoulli outcome the JS draws is the one numpy draws.

Parity tolerance: 1e-9 absolute, and why. Once the streams agree, all that's left is summation order (numpy sums pairwise) and last-bit differences in pow/log/exp. Across all 27 cases the largest difference is 6.6e-15. If a single draw desynchronises, every draw after it shifts and the result moves by around 1e-3. 1e-9 sits far from both, and five orders below the fourth decimal the page prints. Verdict sentences are compared character for character.

What CI checks (.github/workflows/site.yml, separate from ci.yml and release.yml):

  • scripts/floor_golden.py --check: the committed site/floor-golden.json is what the Python produces today, so a change to the floor can't leave the JS matching a stale answer.
  • node scripts/check_floor_parity.mjs: runs on the runner's built-in Node, with the standard library only and no install.

Mutation-tested locally: flipping one bit in the normal sampler's rare tail branch fails 43 lines, and changing one character in the INCONCLUSIVE wording fails every statement.

Fixture spread: n from 1 to 20,000; bins 5 to 100, including more bins than rows; accuracy 0.1 to 0.99, including values where numpy's gamma takes its shape-below-1 path.

Stated on the page: it's a JS reimplementation checked in CI, with a link to the fixture. It also says this is the summary-number floor (synthetic_floor), and that a report's calibration_floor conditions on your real predictions and can differ.

No package.json, no generator, and nothing added to the working copy beyond static files and two scripts.

🤖 Generated with Claude Code

The site needs a calculator that says what the tool says. site/floor.js ports
synthetic_floor and reproduces numpy's seeded stream draw for draw: PCG64,
the ziggurat normal and exponential samplers, Marsaglia-Tsang gamma, and
beta. scripts/floor_golden.py exports golden values from the Python and
refuses a stale fixture; scripts/check_floor_parity.mjs holds floor.js to it
within 1e-9 on the runner's own Node, with no package install.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@TMHSDigital
TMHSDigital merged commit 4648b05 into main Sep 22, 2026
12 checks passed
@TMHSDigital
TMHSDigital deleted the site/phase-1-floor-calculator branch September 22, 2026 22:05
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