From be942da371043f8169af1cfea2b4ee7ea9187d2d Mon Sep 17 00:00:00 2001 From: Matthew Beatty Date: Sun, 21 Jun 2026 14:29:46 -0400 Subject: [PATCH] Fix installer full-profile reliability and occupancy test stability - switch example env list settings to JSON-array syntax for parser compatibility - use pip --break-system-packages in installer Python install steps - link OpenBLAS explicitly for workspace Rust tests in install flow - skip Docker image build when root Dockerfile is absent - stabilize baseline eigenvalue floor for noise-only occupancy estimation Co-Authored-By: Oz --- example.env | 8 ++++---- install.sh | 17 ++++++++++++----- .../src/ruvsense/field_model.rs | 19 ++++++++++++++++++- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/example.env b/example.env index 1c538233bc..040f3e7f67 100644 --- a/example.env +++ b/example.env @@ -30,11 +30,11 @@ SECRET_KEY=your-secret-key-here-change-for-production JWT_ALGORITHM=HS256 JWT_EXPIRE_HOURS=24 -# Allowed hosts (restrict in production) -ALLOWED_HOSTS=* # Use specific domains in production: example.com,api.example.com +# Allowed hosts (JSON array; restrict in production) +ALLOWED_HOSTS=["*"] -# CORS settings (restrict in production) -CORS_ORIGINS=* # Use specific origins in production: https://example.com,https://app.example.com +# CORS settings (JSON array; restrict in production) +CORS_ORIGINS=["*"] # ============================================================================= # DATABASE SETTINGS diff --git a/install.sh b/install.sh index 86abeb49ac..46ec0c1489 100755 --- a/install.sh +++ b/install.sh @@ -600,9 +600,9 @@ install_verify_deps() { if $NEED_INSTALL; then echo " Installing numpy and scipy..." if [ -f "${SCRIPT_DIR}/v1/requirements-lock.txt" ]; then - $PYTHON_CMD -m pip install -r "${SCRIPT_DIR}/v1/requirements-lock.txt" 2>&1 | tail -3 + $PYTHON_CMD -m pip install --break-system-packages -r "${SCRIPT_DIR}/v1/requirements-lock.txt" 2>&1 | tail -3 else - $PYTHON_CMD -m pip install numpy scipy 2>&1 | tail -3 + $PYTHON_CMD -m pip install --break-system-packages numpy scipy 2>&1 | tail -3 fi ok "numpy + scipy installed" else @@ -614,7 +614,7 @@ install_python_deps() { echo -e " ${CYAN}Python pipeline dependencies:${RESET}" if [ -f "${SCRIPT_DIR}/requirements.txt" ]; then echo " Installing from requirements.txt..." - $PYTHON_CMD -m pip install -r "${SCRIPT_DIR}/requirements.txt" 2>&1 | tail -5 + $PYTHON_CMD -m pip install --break-system-packages -r "${SCRIPT_DIR}/requirements.txt" 2>&1 | tail -5 ok "Python dependencies installed" else warn "requirements.txt not found" @@ -813,7 +813,7 @@ build_python() { # Install package in development mode if [ -f "${SCRIPT_DIR}/pyproject.toml" ]; then echo " Installing wifi-densepose in development mode..." - (cd "${SCRIPT_DIR}" && $PYTHON_CMD -m pip install -e . 2>&1 | tail -3) + (cd "${SCRIPT_DIR}" && $PYTHON_CMD -m pip install --break-system-packages -e . 2>&1 | tail -3) ok "Package installed in dev mode" fi } @@ -848,7 +848,10 @@ build_rust() { # Run tests echo "" echo -e " ${CYAN}Running Rust tests...${RESET}" - (cd "${RUST_DIR}" && cargo test --workspace 2>&1 | tail -5) + # `cargo test --workspace` can feature-unify ndarray's BLAS path across + # crates, which requires cblas symbols even for crates that don't pull + # ndarray-linalg directly. Link OpenBLAS explicitly for this test run. + (cd "${RUST_DIR}" && RUSTFLAGS="${RUSTFLAGS:-} -l openblas" cargo test --workspace 2>&1 | tail -5) ok "Rust tests completed" else fail "Rust build failed (exit code: ${exit_code})" @@ -893,6 +896,10 @@ build_wasm_field() { build_docker() { echo -e " ${CYAN}Building Docker image...${RESET}" echo "" + if [ ! -f "${SCRIPT_DIR}/Dockerfile" ]; then + warn "Dockerfile not found at ${SCRIPT_DIR}/Dockerfile; skipping Docker image build" + return 0 + fi local target="production" if $VERBOSE; then diff --git a/v2/crates/wifi-densepose-signal/src/ruvsense/field_model.rs b/v2/crates/wifi-densepose-signal/src/ruvsense/field_model.rs index 2653fef142..a2b9b7e0f8 100644 --- a/v2/crates/wifi-densepose-signal/src/ruvsense/field_model.rs +++ b/v2/crates/wifi-densepose-signal/src/ruvsense/field_model.rs @@ -523,7 +523,12 @@ impl FieldModel { // The noise_var slot is 0.0 in the diagonal-fallback paths; the // estimation hot path treats 0.0 as "no anchored noise floor" and // falls back to per-window noise_var, preserving pre-#942 behavior. - let (mode_energies, environmental_modes, baseline_eig_count, baseline_noise_var) = + let ( + mode_energies, + environmental_modes, + mut baseline_eig_count, + baseline_noise_var, + ) = if let Some(ref cov_sum) = self.covariance_sum { if self.covariance_count > 1 { // Compute sample covariance from raw outer products: @@ -631,6 +636,18 @@ impl FieldModel { (e, m, b, 0.0_f64) }; + // Short runtime windows can transiently spread baseline-only energy into + // a couple extra eigenvalues, especially with deterministic periodic + // calibration streams. Keep a conservative floor on the empty-room rank + // from the calibrated ambient modes so `estimate_occupancy` does not + // overcount noise-only windows. + let ambient_rank_floor = mode_energies + .iter() + .filter(|&&e| e > 1e-12) + .count() + .saturating_sub(1); + baseline_eig_count = baseline_eig_count.max(ambient_rank_floor); + // Compute variance explained using the same centered covariance as modes. // total_variance = trace(centered_covariance) = sum of ALL eigenvalues. let total_energy: f64 = mode_energies.iter().sum();