RAIN RNG · PRE-SUBMISSION PACKAGE v1.2 · DOCUMENT
REVIEW-RESPONSE-R1 — REVIEW ROUND 1: FINDINGS → ACTIONS → STATUS
Source
sdk-v2/lab/REVIEW-RESPONSE-R1.md · commit 96368332 · GLI CSR §2.2: Review record · ← package index · raw on GitHub ↗Review response — round 1 (Joni's review of the RNG lab package), 2026-09-14
Scope: RNG component only (@rain/rng-core, @rain/rng-session, @rain/rng-node, lab/). Each of the seven findings → what was done → where the evidence is → status. Status vocabulary: CLOSED (nothing left for us to do), PARTIAL (exact remainder stated), OUT-OF-OUR-HANDS (needs a third party, an org owner or a host we do not have). Everything committed on the sdk-v2 branch; live counters (background jobs still running when this was written) are read from disk by node lab/tools/evidence-index.mjs → EVIDENCE-INDEX.md.
| # | Finding | What was done | Evidence | Status |
|---|---|---|---|---|
| 1 | "Collection tool + hundreds of millions of draws after scaling, not just raw bits" | The data existed but was presented as rounds; the report now shows an explicit rounds × draws/round → scaled outcomes (draws) column per data set and totals in words: chacha20 one hundred million dice / roulette / coin outcomes and reel stops each, two million decks (1.04 × 10⁸ placements), 3 × 10⁸ adversarial dice — 8.04 × 10⁸ scaled outcomes; hmac-drbg 2.0 × 10⁸ (twenty million per game incl. legacy comparisons). New EVIDENCE-INDEX.md (auto-generated) lists every artifact with path, size, count, what it proves, GLI CSR §2.2 item. hmac sets are being raised to 10⁸ per game (dice, roulette, coin, slot-reel) by a resumable runner. |
REPORT-STATISTICAL.md §0 headline + §5.1 table (generator tools/report_tables.py); EVIDENCE-INDEX.md; results/outcomes/{chacha,hmac}/*.meta.json; runner tools/run-outcomes-hmac-1e8.sh, output results/outcomes/hmac-1e8/ |
CLOSED for presentation and for chacha20 volume. PARTIAL for hmac 10⁸: at 06:45Z the four 10⁸ sets stood at ≈ 1.15–1.22 × 10⁵ rounds each (≈ 1.15 × 10⁷ outcomes per game, 4.7 × 10⁷ total) — ≈ 12 %; ETA ≈ 4 h of wall time under the current load (they are checkpointed; bash lab/tools/run-outcomes-hmac-1e8.sh resumes). Exact counts at any time: node lab/tools/evidence-index.mjs. |
| 2 | "Dieharder full battery for HMAC-DRBG" | Main stream chain kept running (resumable, one dieharder process per test, never rewinds); the summary tool was re-run and the report re-filled. To speed up the long pole, a second parallel chain with its own producer (tools/run-dieharder-stream-subset.sh, independent seed derivation recorded in RUN.txt) was started on rgb_lagged_sum 0–5 while the main chain works through rgb_permutations/rgb_*/dab_*. |
results/dieharder/hmac-stream/{SUMMARY.txt,dieharder-a.log,RUN.txt,tests/*.log+.DONE}; REPORT-STATISTICAL.md §3.2 (hmac table) and §9 |
PARTIAL — 38 / 80 combinations done, 67 PASSED / 3 WEAK / 0 FAILED, ≈ 17 GB consumed (06:45Z; the report regenerates the exact list). Remaining 42: 202-n3..5, 204–209 (≈ 3 GB, ≈ 1 h) and rgb_lagged_sum n = 0…32 ≈ 0.44·(n+1) GB each = ≈ 250 GB — at the HMAC_DRBG rate of ≈ 1 MB/s per core (≈ 55 µs per 256-bit block through the full ceremony path) that is ≈ 9 core-days; not achievable in this leg. Both chains keep running detached and bash lab/tools/summarize-dieharder-stream.sh hmac && bash lab/tools/report-tables.sh fill picks up every finished test; a lab with an idle 32-core host finishes in ≈ 7 h (run-dieharder-stream.sh hmac 32). |
| 3 | "Pipelining measured on a real network, not loopback" | Deployed an unmodified @rain/rng-node (vendored dist/ of the three packages; memory store; ephemeral key) as a Render web service (origin GCP us-west1 Oregon, behind Cloudflare) and ran a new client tool from this AWS us-east-1 host: 1,000 spins per run × {HTTPS, WebSocket} × {pipelining OFF, ON}, at 60 ms, 0 ms and 1,000 ms animation gaps; every round verified client-side. Measured application RTT p50 ≈ 101 ms. 60 ms gap: HTTPS p50/p95/p99 88.5/101.8/119.3 ms OFF → 36.0/49.0/67.5 ms ON; WS 91.1/100.2/101.5 → 23.3/39.7/57.9 ms; 4,000/4,000 settled, 0 errors, 0 replays. 0 ms gap: ON ≈ OFF (nothing to overlap — honest boundary). 1,000 ms gap: network off the critical path. Whitepaper bumped to v1.2 (abstract, G4, §5.2, §8.2, §11.2, §11.3, §12, CHANGES line in §10.3), PDF regenerated, copied to site/downloads/ and project media. |
results/latency-real-network/{REPORT.md,RUN.txt,results.json,results-gap0.json,results-gap1000.json,loadtest-*.txt,network-baseline.txt,deploy-manifest.txt,server.mjs}; tool examples/slot-spin-endpoint/loadtest-remote.mjs; REPORT-STATISTICAL.md §6a; whitepapers/RAIN-RNG-Whitepaper-v1.2.{md,pdf} |
CLOSED. Caveats stated in the report: one sequential client (no concurrency), memory store on the server, pessimistic transcontinental placement. Cost note: the Render service rain-rng-node-lab (starter, ≈ $7/month via AgentBase credits, workflow 84ae47f7… backend) is left live for the reviewer to re-run (node examples/slot-spin-endpoint/loadtest-remote.mjs https://rain-rng-node-lab-polt.onrender.com 1000 60); delete when the review closes. |
| 4 | "CI in repo, two maintainers per PR, annual pentest, contract audit — GLI App. B" | Added .github/workflows/ci.yml (npm ci, build, typecheck, all unit tests incl. KATs/crash/selftest/e2e, test:py, lab:verify-build ×2 + fingerprint-drift check, dependency review, npm audit), .github/CODEOWNERS (both teams on every path; placeholder handles @Quecko-Org/rain-maintainers-a/-b, noted in README), PR template carrying the change-control record, docs/GOVERNANCE.md (branch protection: 2 approvals, code-owner review, required checks, signed commits/tags, gh api one-liner; honest status table), lab/process/SECURITY-PROGRAM.md (annual pen-test, per-deployment contract audit, per-major-version crypto review, per-PR supply-chain scanning, disclosure policy with SLAs, records; everything external marked "pending — not contracted"). SDLC.md §5 and CHANGE-CONTROL.md §3 now reference these instead of "[TO ESTABLISH: no CI]". |
the files named; docs/LAB-SUBMISSION-REQUIREMENTS.md §7 rows 8, 9, 11, 12 |
PARTIAL / OUT-OF-OUR-HANDS. In repo: CI, CODEOWNERS, governance, security program — done. Not done and not doable from here: (a) branch protection must be applied by a GitHub org owner (settings are written out verbatim), (b) a second real maintainer must exist for "two approvals" to mean anything (repo is single-maintainer today — stated, not hidden), (c) pen-test and audits are procurement decisions — cadence fixed, no vendor under contract. CI has not yet executed on GitHub: the mirror PAT lacks the workflow scope (push rejected: "refusing to allow a Personal Access Token to create or update workflow"), so on the mirror branch the file sits at .github/workflows-pending/ci.yml with a README; an org owner moves it to .github/workflows/. |
| 5 | "Formal argument for % N vs unbiased, or intBelow" |
Extracted to a stand-alone one page SCALING-PROOF.md: certified path = intBelow rejection sampling → theorem + proof of exact uniformity, rejection-probability bound (2³² mod n)/2³² < n/2³² ≤ ½, expected words ≤ 2, independence of consumption from value, Fisher–Yates 1/len!, replay determinism; legacy uint256(r) % N → absolute bias < 1/2²⁵⁶, relative < N/2²⁵⁶ with numeric examples N = 100 (8.6 × 10⁻⁷⁶) and N = 37 (3.2 × 10⁻⁷⁶), ≈ 10¹⁵³ draws to detect, explicit statement that it is out of certification scope (kept only for byte-identity with deployed Solidity verifiers). Linked from README.md, RNG-DESCRIPTION.md §6, EVIDENCE-INDEX.md, docs/LAB-SUBMISSION-REQUIREMENTS.md §7 row 6. |
lab/SCALING-PROOF.md |
CLOSED |
| 6 | "One-page doc for GLI-19 §3.3.2(c) external entropy / state modification" | Extracted to STATE-MODIFICATION-3.3.2c.md: what the state is; three layers — (A) every round mixes both parties' fresh reveals, the player's reveal being external to the house state (continuous, not merely periodic), (B) chain rotation at 90 % with fresh CSPRNG secrets and a new commit-reveal, (C) per-round DRBG instantiation with no cross-round state; a table of what an attacker holding a full house-state snapshot at time t can and cannot do (reproduce past — yes but public; predict/bias next — no; one-round window after player reveal — same as an honest house; extend past the session — no; learn player secret — no); certificate wording; evidence pointers (adversarial data sets, meta session counts, rotation tests). Linked from README.md, RNG-DESCRIPTION.md §3, EVIDENCE-INDEX.md, §7 row 16. |
lab/STATE-MODIFICATION-3.3.2c.md |
CLOSED |
| 7a | "npm public" | Not published (owner decides). Made it one command away: npm pack --dry-run verified for rng-core (24 files, 21.8 kB), rng-session (13, 20.8 kB), rng-node (34, 35.4 kB); registry checked — @rain/rng-core, @rain/rng-session, @rain/rng-node all 404 (free); no package exists under @rain/; whether the rain org itself is claimable cannot be read anonymously (npmjs.com 403 to bots) → alternatives verified free: @rain-risk-markets/*, @rainriskmarkets/* (also @rain-rng, @rainrng). PUBLISHING.md §5 has the checklist with --provenance and the exact commands. |
PUBLISHING.md §5 |
CLOSED (as "ready"; publication itself is the owner's call — OUT-OF-OUR-HANDS by instruction) |
| 7b | "HA proof" | Tried: apt-get install docker.io / podman → no root (uid 1000, no sudo, elevated exec disabled for this agent; user namespaces allowed but no /dev/fuse and no privileged daemon possible). Render alternative evaluated: Render's LB gives no control to SIGKILL one of two instances mid-run and the AgentBase deploy path exposes no per-instance handle, so a "kill one worker under load" proof cannot be staged there honestly; a two-instance Render deploy would only prove round-robin, not failover, and would need a Postgres add-on (pg SSL config) — not spent. What was exercised for real: a single remote node under 12,000+ settled rounds with zero errors (item 3), and the in-process HA/crash semantics remain proven by packages/rng-node/test/crash.test.mjs (SIGKILL before/after persist, torn WAL tail) and the store tests. |
docs/LAB-SUBMISSION-REQUIREMENTS.md §7 row 13; lab/process/HOSTING-HA-DR.md; packages/rng-node/scripts/ha-test.sh (ready to run) |
OUT-OF-OUR-HANDS here. Needs any host with Docker: bash packages/rng-node/scripts/ha-test.sh 300 (≈ 3 min) and archive its output to lab/results/ha/. Documented exactly what is blocked and why. |
Summary
- CLOSED: 1 (presentation + chacha volume), 3, 5, 6, 7a.
- PARTIAL, running detached: 1 (hmac 10⁸ sets, ≈ 12 % at write time, resumable), 2 (hmac Dieharder 38/80; the
rgb_lagged_sumtail ≈ 250 GB is a CPU-days job at HMAC_DRBG speed — the runners are resumable and a lab host finishes it). - OUT-OF-OUR-HANDS: 4 (org-owner branch protection, a second human maintainer, contracting pen-test/audits — all written up, none faked), 7b (Docker host).
Live jobs at hand-off (see results/PROGRESS.md)
| job | check | picks results up |
|---|---|---|
| hmac Dieharder main chain | bash lab/tools/status.sh |
bash lab/tools/summarize-dieharder-stream.sh hmac && bash lab/tools/report-tables.sh fill |
hmac Dieharder rgb_lagged_sum 0–5 parallel chain |
tail lab/logs/dieharder-stream-hmac-subset-lagged0-5.log |
same |
| hmac 10⁸ outcomes (4 games) | node lab/tools/evidence-index.mjs |
bash lab/tools/report-tables.sh fill once results/outcomes/hmac-1e8/*.csv.meta.json exist |
| real-network gap-1000 run | ls lab/results/latency-real-network/.DONE |
numbers already in loadtest-gap1000.txt; REPORT §3.1 references it |
← Back to the package index · Rendered 2026-09-14 09:34 UTC from the repository copy; the markdown in the zip / repo is the document of record.