mirror of
https://github.com/ruvnet/RuView
synced 2026-06-09 10:13:17 +00:00
8504638187
Operator-initiated calibration that records 30 s of stationary CSI,
emits a per-subcarrier baseline (amplitude mean+variance via Welford,
phase via circular sin/cos sums with von Mises dispersion), and gates
downstream stages on a deviation z-score. Plugs into multistatic
coherence gating, motion/presence detection, and the new ADR-134 CIR
estimator as a reference-subtracted input.
API surface (under wifi_densepose_signal):
CalibrationConfig::{ht20, ht40, he20, he40}
CalibrationRecorder { record(), finalize(), frames_recorded() }
BaselineCalibration {
subcarriers: Vec<SubcarrierBaseline>,
deviation(&CsiFrame), subtract_in_place(&mut CsiFrame),
to_bytes(), from_bytes()
}
CalibrationDeviationScore { amplitude_z_median, amplitude_z_max,
phase_drift_median, motion_flagged }
CalibrationError { SubcarrierMismatch, TierMismatch,
InsufficientFrames, VersionMismatch, TruncatedBuffer }
Binary baseline format: magic 0xCA1B_0001 + u8 version=1 + u8 tier +
captured_at_unix_s (i64) + frame_count (u64) + num_subcarriers (u32) +
[SubcarrierBaseline; N] as 16 bytes each (amp_mean, amp_variance,
phase_mean, phase_dispersion as f32 LE). Hand-written serialisation so
the format is stable across Rust toolchain versions without serde drift.
CLI: new `wifi-densepose calibrate` subcommand binds a UDP listener
(0xC511_0001 frames), streams them through CalibrationRecorder, prints
a real-time z-score banner per ADR-135 §risk 1 (operator-may-be-moving),
aborts on sustained high deviation, and writes the binary baseline to
disk. Local UDP packet parser duplicated from sensing-server (per ADR
discussion — avoids cross-crate API churn).
Witness: cross-platform-deterministic SHA-256 over the per-subcarrier
quantised baseline profile (u16 LE at 1e-2/1e-4/1e-3, no sort) using
the lesson learnt from the CIR PR #837 libm-jitter fix. Hash:
d6bce07ecb1648e6936561df44bf4a3bfc17bb0ba5f692646b2301d105b52f67
CI guard: new "ADR-135 calibration witness proof (determinism guard)"
step under the Rust Workspace Tests job, adjacent to the existing
ADR-134 CIR guard. Regressions are unambiguously attributable.
Hardware-in-loop validation: full 600-frame capture exercised via the
new scripts/synth-csi-udp.py emitter targeting 127.0.0.1:5005. The CLI
binary received 600 frames at 20 Hz, z_med stable at ~0.7, motion
correctly NOT flagged, finalised baseline written to baseline.bin (860
bytes) with correct magic + version + timestamp in the header. Live
ESP32 capture from COM9 is operator follow-up — requires provisioning
the firmware's UDP target IP to match the host running the CLI.
Test results (cargo test -p wifi-densepose-signal --no-default-features):
lib: 382 pass / 0 fail / 1 ignored
calibration_synthetic: 17 pass / 0 fail
calibration_drift: 5 pass / 0 fail
calibration_roundtrip: 10 pass / 0 fail
cir_*: 9 pass + 6 documented P2 ignores
doctest: 10 pass
Bench: 20 Criterion combinations registered
(recorder_record / recorder_finalize / deviation / record_600 /
to_bytes across HT20/HT40/HE20/HE40 tiers).
Witness: bash scripts/verify-calibration-proof.sh → VERDICT: PASS
Co-Authored-By: claude-flow <ruv@ruv.net>
52 lines
1.9 KiB
Bash
52 lines
1.9 KiB
Bash
#!/usr/bin/env bash
|
|
# verify-calibration-proof.sh — calibration deterministic proof verification (ADR-135)
|
|
#
|
|
# Builds the calibration_proof_runner Rust binary, computes the canonical SHA-256
|
|
# hash of the CalibrationRecorder's output on the synthetic reference signal
|
|
# (xorshift32 seed=42, HT20, 600 stationary frames), and compares it against
|
|
# the committed expected_calibration_features.sha256.
|
|
#
|
|
# Usage:
|
|
# bash scripts/verify-calibration-proof.sh
|
|
#
|
|
# Exit codes:
|
|
# 0 — VERDICT: PASS (hash matches)
|
|
# 1 — VERDICT: FAIL (hash mismatch or build error)
|
|
# 2 — BLOCKED (calibration module not yet implemented — placeholder hash detected)
|
|
|
|
set -euo pipefail
|
|
|
|
cd "$(git rev-parse --show-toplevel)"
|
|
|
|
HASH_FILE="archive/v1/data/proof/expected_calibration_features.sha256"
|
|
|
|
# Check for placeholder — module not yet implemented
|
|
if grep -q "PLACEHOLDER_REGENERATE" "$HASH_FILE" 2>/dev/null; then
|
|
echo "BLOCKED: calibration proof hash is a placeholder."
|
|
echo "The calibration module (ADR-135) is not yet implemented."
|
|
echo ""
|
|
echo "After the implementation lands, regenerate the hash with:"
|
|
echo " cd v2 && cargo run -p wifi-densepose-signal --bin calibration_proof_runner \\"
|
|
echo " --release --no-default-features -- --generate-hash \\"
|
|
echo " > ../archive/v1/data/proof/expected_calibration_features.sha256"
|
|
exit 2
|
|
fi
|
|
|
|
echo "Building calibration_proof_runner..."
|
|
cargo build -p wifi-densepose-signal --bin calibration_proof_runner --release --no-default-features \
|
|
--manifest-path v2/Cargo.toml
|
|
|
|
echo "Computing calibration hash..."
|
|
ACTUAL="$(./v2/target/release/calibration_proof_runner --generate-hash)"
|
|
EXPECTED="$(awk '{print $1; exit}' "$HASH_FILE")"
|
|
|
|
if [ "$ACTUAL" = "$EXPECTED" ]; then
|
|
echo "VERDICT: PASS (calibration hash matches)"
|
|
exit 0
|
|
else
|
|
echo "VERDICT: FAIL"
|
|
echo "expected: $EXPECTED"
|
|
echo "actual: $ACTUAL"
|
|
exit 1
|
|
fi
|