wai-web binds wai::stage_measure, the code wai_stage_measure runs, compiled to wasm32 (src/measure.rs): evaluateTitle gives the text `eval --json` prints for a title, simulate and simulateModel the text `sim` prints, countObject one envelope's counted bytes or the code it is not countable with, qualityRgb8 one picture pair's integers (sums of squares as decimal strings), outputRoot the output tree's root. A title is read from a map of files; titleMissing names the next file it needs, so a page fetches them one at a time. receipt_claims builds and runs for wasm32 with stage_measure, so signing is exposed: sessionBegin records a session at its entry object (SessionRecorder), decoderFor/presented/received record what the page did, finish seals the reconstruct-session claim with a page-supplied seed (energy null), and verifyClaim runs the claim-conformance runner against the outputs and the objects. CI builds receipt_claims,stage_measure for wasm32 beside the stage_measure guard. demo/verify_measure_wasm.mjs requires, from the wasm32 build, every golden, refusal title, counted object, quality pair and simulator result of staged-measure-conformance/ byte for byte, and a page-recorded session per fixture equal to the native tool's claim byte for byte. demo/verify_measure.sh adds the native `eval --json` of every fixture (cmp against the wasm32 text) and the native and Python claim verifiers' verdicts on every browser-sealed session. wai-web-wasm.yml runs it (the W17 line). Co-Authored-By: Claude Opus 5.5 <[email protected]>
73 lines
3.9 KiB
Shell
Executable file
73 lines
3.9 KiB
Shell
Executable file
#!/usr/bin/env bash
|
|
# The wasm32 measurement binding gives the native figures byte for byte, over the corpus
|
|
# wai/staged-measure-conformance/:
|
|
#
|
|
# 1. demo/verify_measure_wasm.mjs runs the wasm32 build under Node: every fixture's
|
|
# evaluation against goldens.json, the refusal titles, counting.json, quality.json,
|
|
# sim/results.json, the output tree, and the session claim the browser seals;
|
|
# 2. the native tool's `wai_stage_measure eval --json` for every fixture must equal the
|
|
# wasm32 evaluation byte for byte (cmp);
|
|
# 3. every session the wasm32 build sealed, and its altered variants, are verified by
|
|
# the native claim verifier (`wai_claim_vectors verdicts`) and by the independent
|
|
# Python verifier (`claim-conformance/claim_verify.py verdicts`), and each verdict list
|
|
# must equal the one the wasm32 build gave, line for line.
|
|
#
|
|
# from wai-web/: bash demo/verify_measure.sh [path/to/pkg-node/wai_web.js]
|
|
#
|
|
# With no argument the nodejs package is built here (cargo, then the wasm-bindgen CLI at
|
|
# the version Cargo.lock pins); with one, that package is used, as CI does after building
|
|
# it. The native binaries are built in debug under their own target directory, so a
|
|
# CARGO_TARGET_DIR shared with other feature sets is not disturbed. claim_verify.py needs
|
|
# the `cryptography` package. Any missing artifact fails the run.
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")/.." # wai-web/
|
|
WEB="$(pwd)"
|
|
WAI="$(cd .. && pwd)"
|
|
for tool in cargo node python3; do
|
|
command -v "$tool" >/dev/null || { echo "verify_measure: needs $tool"; exit 1; }
|
|
done
|
|
OUT="$(mktemp -d)"
|
|
trap 'rm -rf "$OUT"' EXIT
|
|
|
|
PKG="${1:-}"
|
|
if [ -z "$PKG" ]; then
|
|
command -v wasm-bindgen >/dev/null || { echo "verify_measure: needs the wasm-bindgen CLI"; exit 1; }
|
|
# Build output is not discarded: a failed build must show why.
|
|
cargo build --locked --release --target wasm32-unknown-unknown
|
|
wasm-bindgen --target nodejs --out-dir demo/pkg-node --out-name wai_web \
|
|
"${CARGO_TARGET_DIR:-target}/wasm32-unknown-unknown/release/wai_web.wasm"
|
|
PKG="$WEB/demo/pkg-node/wai_web.js"
|
|
fi
|
|
PKG="$(cd "$(dirname "$PKG")" && pwd)/$(basename "$PKG")"
|
|
[ -f "$PKG" ] || { echo "verify_measure: missing artifact $PKG"; exit 1; }
|
|
|
|
echo "== 1. the wasm32 binding over the corpus"
|
|
node demo/verify_measure_wasm.mjs "$PKG" "$WAI/staged-measure-conformance" --out "$OUT"
|
|
|
|
echo "== 2. the native evaluation equals the wasm32 evaluation, byte for byte"
|
|
NATIVE_TARGET="${CARGO_TARGET_DIR:-$WAI/wai-rs/target}/verify-measure-native"
|
|
( cd "$WAI/wai-rs" && cargo build --locked --no-default-features --features stage_measure,receipt_claims \
|
|
--target-dir "$NATIVE_TARGET" --bin wai_stage_measure --bin wai_claim_vectors )
|
|
BIN="$NATIVE_TARGET/debug"
|
|
for b in wai_stage_measure wai_claim_vectors; do
|
|
[ -x "$BIN/$b" ] || { echo "verify_measure: missing artifact $BIN/$b"; exit 1; }
|
|
done
|
|
n=0
|
|
for dir in "$WAI"/staged-measure-conformance/fixtures/*/; do
|
|
name="$(basename "$dir")"
|
|
[ -f "$OUT/eval-$name.json" ] || { echo "verify_measure: no wasm32 evaluation of $name"; exit 1; }
|
|
"$BIN/wai_stage_measure" eval "$dir" --json > "$OUT/native-$name.json"
|
|
cmp "$OUT/native-$name.json" "$OUT/eval-$name.json"
|
|
echo " $name: identical ($(wc -c < "$OUT/native-$name.json" | tr -d ' ') bytes)"
|
|
n=$((n + 1))
|
|
done
|
|
[ "$n" -ge 4 ] || { echo "verify_measure: only $n fixtures"; exit 1; }
|
|
|
|
echo "== 3. the browser-sealed sessions, verified natively and independently"
|
|
[ -s "$OUT/sessions.json" ] && [ -s "$OUT/verdicts-wasm.txt" ] || { echo "verify_measure: no sessions written"; exit 1; }
|
|
"$BIN/wai_claim_vectors" verdicts "$OUT/sessions.json" > "$OUT/verdicts-native.txt"
|
|
diff "$OUT/verdicts-wasm.txt" "$OUT/verdicts-native.txt"
|
|
python3 "$WAI/claim-conformance/claim_verify.py" verdicts "$OUT/sessions.json" > "$OUT/verdicts-python.txt"
|
|
diff "$OUT/verdicts-wasm.txt" "$OUT/verdicts-python.txt"
|
|
echo " $(wc -l < "$OUT/verdicts-wasm.txt" | tr -d ' ') verdicts: wasm32, native and Python agree"
|
|
echo "verify_measure: OK"
|