fix(train): wire wifi-densepose-signal into the pipeline + correct MODEL_CARD env-sensor claim (audit #1/#2/#3) - #536
Merged
Conversation
…EL_CARD env-sensor claim Addresses three findings from the 2026-05-11 training-pipeline audit: #1/#2 — `wifi-densepose-signal` was a phantom dependency of `wifi-densepose-train` (listed in Cargo.toml, never imported), and vitals/CSI signal features were absent from the pipeline. New module `wifi_densepose_train::signal_features`: `extract_signal_features(&Array4<f32>, &Array4<f32>) -> Array1<f32>` (and the convenience method `CsiSample::signal_features()`) runs a windowed observation's centre frame through `wifi_densepose_signal::features::FeatureExtractor`, producing a fixed-length (FEATURE_LEN=12) amplitude / phase-coherence / PSD feature vector — the hook for a future vitals / multi-task supervision head (breathing- and heart-rate-band power are read off the PSD summary). The vector is produced on demand and is not yet fed back into the loss; wiring it as a training target is the documented follow-up. `wifi-densepose-signal` is now an actually-used dependency. 5 new tests (2 unit in signal_features.rs, 3 integration in tests/test_dataset.rs); existing wifi-densepose-train tests unchanged and green. #3 — `docs/huggingface/MODEL_CARD.md` presented PIR/BME280 environmental-sensor weak-label fine-tuning as a current capability; there is no env-sensor ingestion in the training pipeline. Marked that path as planned/not-implemented in the training-steps list and the data-provenance section. (#5 — README's "92.9% PCK@20" overclaim — fixed separately in PR #535.) CHANGELOG updated. Co-Authored-By: claude-flow <ruv@ruv.net>
ruvnet
added a commit
that referenced
this pull request
May 12, 2026
Publishing the additive changes from PRs #536/#537 to crates.io: - `signal_features` module — wires `wifi-densepose-signal` into the pipeline (audit #1/#2) - `TrainingConfig::for_subcarriers` / `ht40_192()` / `multiband_168()` presets + the real `MmFiDataset` loader integration test (audit #4/#6/#7) No public API removals or changes — additive only, so 0.3.0 -> 0.3.1 is semver-correct. No other workspace crate depends on `wifi-densepose-train`, so this is a standalone bump. Co-Authored-By: claude-flow <ruv@ruv.net>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three of the seven findings from the 2026-05-11 training-pipeline audit (Stuart's Stage-A audit; tracked in PR #535):
signal_featuresmodule that extracts themwifi-densepose-signalis a phantom dep ofwifi-densepose-train(listed, never imported)MODEL_CARD.mdhas no implementation#1 + #2 —
wifi_densepose_train::signal_featureswifi-densepose-signal(the SOTA signal-processing crate) was inwifi-densepose-train/Cargo.tomlbut neverused — and the training samples carried only raw amplitude/phase, no derived signal features. New module:extract_signal_features(amplitude: &Array4<f32>, phase: &Array4<f32>) -> Array1<f32>— takes a windowed CSI observation ([T, n_tx, n_rx, n_sc]), flattens the centre frame to the antenna-major[n_tx·n_rx, n_sc]shape the signal crate expects, builds awifi_densepose_signal::csi_processor::CsiData, and runswifi_densepose_signal::features::FeatureExtractorover it.FEATURE_LEN = 12vector: amplitude peak/RMS/dynamic-range + mean-of-per-subcarrier amplitude mean/variance, phase coherence + mean phase variance, and a PSD summary (total power, peak power, peak frequency, centroid, bandwidth). Non-finite results are mapped to0.0; degenerate (zero-sized) windows return the zero vector instead of panicking.CsiSample::signal_features(&self) -> Array1<f32>.wifi-densepose-signalis no longer a ghost dep, and the signal features the audit said were "absent" are now computed and accessible on every sample.#3 —
docs/huggingface/MODEL_CARD.mdThe card presented PIR/BME280 weak-label fine-tuning on the Cognitum Seed as a current capability. There is no env-sensor ingestion in the training pipeline. Marked it as planned/not-implemented in the training-steps list, the data-provenance section, and the hardware section.
Tests
cargo check -p wifi-densepose-train --no-default-features— clean (only pre-existingwifi-densepose-signaldead-code warnings).cargo test -p wifi-densepose-train --no-default-features— all existing tests green, plus 5 new tests pass:signal_features::tests::{zero_sized_input_yields_zero_vector, constant_input_is_finite_and_correct_length}tests/test_dataset.rs::{signal_features_have_correct_length_and_are_finite, signal_features_are_deterministic, signal_features_zero_window_is_zero_vector}tch-gated modules, no change to the model input shape or the deterministic proof — purely additive.Follow-up (the remaining audit findings)
proof.rsusesSyntheticCsiDataset: that's correct for a deterministic proof (a reproducible source is the point); the real gap is no smoke-test of the real.npyMmFiDatasetloader path. Recommend adding a round-trip test (generate synthetic → write.npy→ load viaMmFiDataset→ assert shapes) — left out here to keep this PR focused.TrainingConfig::for_mesh(native_subcarriers, n_nodes)constructor + docs. Separate PR.signal_featuresis consumed: add an optional vitals-target field + a small head/loss term. Thetraining-guide.md(delivered to the pulse-seed handoff) describes the end-to-end path.🤖 Generated with claude-flow