Skip to content

fix: per-room CSPRNG seed for unseeded rooms — the Ctx carried a shared zero #220

fix: per-room CSPRNG seed for unseeded rooms — the Ctx carried a shared zero

fix: per-room CSPRNG seed for unseeded rooms — the Ctx carried a shared zero #220

Workflow file for this run

name: CI
on:
push:
branches: [main]
tags: ["v*"]
pull_request:
schedule:
# Nightly (07:00 UTC): keep the slow release-profile artifact path honest.
- cron: "0 7 * * *"
permissions:
contents: read
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with: { go-version-file: go.mod }
- run: go build ./...
- run: go vet ./...
- run: go test ./...
# The committed crossverify .dgld vectors are a snapshot of the Go
# reference encoder; without this gate a Go-side byte-output change
# leaves them silently representing a HISTORICAL encoder (the rust job's
# golden step keeps passing against the stale bytes). Re-emit from the
# current encoder and require an exact match. Emission is deterministic
# (no RNG; committed .fseq inputs), so this is non-flaky.
- name: crossverify golden vectors are fresh (byte-identity vs the CURRENT Go reference)
run: |
set -euo pipefail
out="$(mktemp -d)"
DIFFBENCH_GOLDEN_DIR="$out" go test -run TestEmitGolden ./internal/diffbench/
if ! diff -r "$out" crossverify/tests/golden; then
echo "::error::committed crossverify golden vectors are STALE: the Go reference encoder's byte output changed."
echo "Review the change (it is wire-visible), then regenerate and commit:"
echo " DIFFBENCH_GOLDEN_DIR=crossverify/tests/golden go test -run TestEmitGolden ./internal/diffbench/"
exit 1
fi
- name: no private imports (the module must build from ABI.md alone)
run: |
! grep -rn "shellcade/shellcade" --include="*.go" . || (echo "FORBIDDEN private import" && exit 1)
# Author journey: prove the experience an author actually has — scaffold a
# fresh game with shellcade-kit built from this PR's source, build the
# dev-profile wasm, and run the arcade's acceptance check on it. The scaffold
# pins a released kit version, so we replace it with the PR's checkout to gate
# THIS repo's code, not a release.
wasm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: { path: kit }
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with: { go-version-file: kit/go.mod }
- uses: acifani/setup-tinygo@dd8a7075d951a7595b2ef2123ed0ab1af0c13e56 # v3.0.0
with: { tinygo-version: "0.41.1" }
# binaryen is intentionally left at the runner's apt candidate: pinning a
# literal apt version (binaryen=<ver>) hard-fails the install whenever the
# ubuntu-latest image ships a different candidate. TinyGo (the artifact
# toolchain that actually shapes the wasm) is the pinned input above.
- run: sudo apt-get update && sudo apt-get install -y binaryen
- name: build shellcade-kit from this PR's source
run: |
set -euo pipefail
go -C kit build -o "${RUNNER_TEMP}/shellcade-kit" ./cmd/shellcade-kit
sudo install "${RUNNER_TEMP}/shellcade-kit" /usr/local/bin/shellcade-kit
shellcade-kit version
- name: scaffold a fresh game
run: shellcade-kit new cigame
- name: build against this PR's kit (dev profile) and check
run: |
set -euo pipefail
cd cigame
# The scaffold pins a released kit; point it at the PR's checkout so
# the gate exercises THIS repo's SDK, then tidy and build.
go mod edit -replace github.com/shellcade/kit/v2=../kit
go mod tidy
go build ./...
tinygo build -opt=1 -no-debug -gc=conservative -o cigame.wasm \
-target wasip1 -buildmode=c-shared .
ls -la cigame.wasm
shellcade-kit check cigame.wasm
# Rust author journey: the Rust mirror of the wasm job above — scaffold with
# shellcade-kit built from this PR's source (`new --rust`), point the
# scaffold's crate dep at the PR's checkout (the cargo equivalent of `go mod
# edit -replace`), build the release artifact, and run the arcade's acceptance
# check on it. This is the gate that catches scaffolder/crate drift at PR time.
wasm-rust:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: { path: kit }
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
with: { targets: wasm32-wasip1 }
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with: { go-version-file: kit/go.mod }
- name: build shellcade-kit from this PR's source
run: |
set -euo pipefail
go -C kit build -o "${RUNNER_TEMP}/shellcade-kit" ./cmd/shellcade-kit
sudo install "${RUNNER_TEMP}/shellcade-kit" /usr/local/bin/shellcade-kit
shellcade-kit version
- name: scaffold a fresh Rust game
run: shellcade-kit new --rust cigame
- name: build against this PR's crate (release profile) and check
run: |
set -euo pipefail
cd cigame
# The scaffold pins a released kit tag; point it at the PR's checkout
# so the gate exercises THIS repo's crate.
sed -i 's|^shellcade-kit = .*|shellcade-kit = { path = "../kit/rust" }|' Cargo.toml
cargo build --release --target wasm32-wasip1
ls -la target/wasm32-wasip1/release/cigame.wasm
shellcade-kit check target/wasm32-wasip1/release/cigame.wasm
# Rust SDK: the shellcade-kit crate (rust/) and its golden-vector harness
# (crossverify/). Gates: unit tests, byte-identity with the Go reference
# encoder, a wasm32-wasip1 release build smoke of the crate, and the
# version lockstep (crate version == package.json version, kept in sync by
# scripts/sync-crate-version.mjs at `changeset version` time).
rust:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
with: { targets: wasm32-wasip1 }
- name: crate version == kit version (lockstep)
run: |
set -euo pipefail
kit_ver="$(node -p 'require("./package.json").version')"
crate_ver="$(grep -m1 '^version = ' rust/Cargo.toml | cut -d'"' -f2)"
if [ "${kit_ver}" != "${crate_ver}" ]; then
echo "version drift: package.json=${kit_ver} rust/Cargo.toml=${crate_ver}" >&2
echo "run: node scripts/sync-crate-version.mjs" >&2
exit 1
fi
- name: SDK tests
run: cargo test --manifest-path rust/Cargo.toml
- name: golden vectors (byte-identity vs the Go reference encoder)
run: cargo test --release --manifest-path crossverify/Cargo.toml
- name: wasm32-wasip1 release build smoke
run: cargo build --release --target wasm32-wasip1 --manifest-path rust/Cargo.toml
# Slow path: the release profile (-opt=2) that ships. Only nightly and on
# tags — it's the artifact authors submit, so keep it building, but don't
# pay its cost on every PR. Mirrors the author journey, release build.
release-wasm:
if: github.event_name == 'schedule' || startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
with: { path: kit }
- uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6.4.0
with: { go-version-file: kit/go.mod }
- uses: acifani/setup-tinygo@dd8a7075d951a7595b2ef2123ed0ab1af0c13e56 # v3.0.0
with: { tinygo-version: "0.41.1" }
# binaryen is intentionally left at the runner's apt candidate: pinning a
# literal apt version (binaryen=<ver>) hard-fails the install whenever the
# ubuntu-latest image ships a different candidate. TinyGo (the artifact
# toolchain that actually shapes the wasm) is the pinned input above.
- run: sudo apt-get update && sudo apt-get install -y binaryen
- name: build shellcade-kit from this PR's source
run: |
set -euo pipefail
go -C kit build -o "${RUNNER_TEMP}/shellcade-kit" ./cmd/shellcade-kit
sudo install "${RUNNER_TEMP}/shellcade-kit" /usr/local/bin/shellcade-kit
shellcade-kit version
- name: scaffold and release-build (-opt=2) against this PR's kit
run: |
set -euo pipefail
shellcade-kit new cigame
cd cigame
go mod edit -replace github.com/shellcade/kit/v2=../kit
go mod tidy
tinygo build -opt=2 -no-debug -gc=conservative -o cigame.wasm \
-target wasip1 -buildmode=c-shared .
ls -la cigame.wasm
shellcade-kit check cigame.wasm