mirror of
https://github.com/ruvnet/RuView.git
synced 2026-08-26 10:05:54 +00:00
fix: issue triage batch (#1521-1557) + wire the certificate spine together
Reviews and fixes RuView's 10 most recent substantive issues, plus closes the wiring gap flagged in the perception-substrate review (docs/adr, gist, release notes from the PR #1579 review). ## Fixed - #1526: UI falsely claimed "LIVE — ESP32 Hardware Connected" whenever the unauthenticated /api/v1/status probe 401'd. Now sends the bearer token on the probe (the fallback direction was already fixed by ADR-295). - #1554: top-level `classification` (GET /api/v1/sensing/latest) was the last UDP packet's single node, not the fused room aggregate, so it flapped at packet rate with 2+ disagreeing nodes. Now derived from `RoomInference` (ADR-297's `fuse_room`) at both call sites. - #1541: per-node MQTT `presence`/`presence_score` read a `classification` JSON key that does not exist on `NodeInfo` (the real field is `node_inference`), silently falling back to the room aggregate for every node — reproducing the exact "lockstep publish" the field report measured. Also fixed the *existing* regression test for this bug, which used the same wrong key in its own fixture and so never caught it. - #1557: pose-fusion's `wsPortMap` only knew port 3000, so a remapped host port fell through to `localhost:8765` (nothing there for a remote viewer). WS port is now derived from `location.port` instead of a 2-entry lookup table (the "never render simulated as live" half was already fixed by ADR-295's `onVerifiedFrame` gate). - #1525: the no-model pose path already clamps keypoint confidence to a 0.1 floor, but the renderer's own threshold is also 0.1 compared with `<=`/`>` — a keypoint at exactly the floor was still invisible. Floor raised to 0.15 to clear the client's gate. - #1556: `--mqtt-ca-file`/`--mqtt-client-cert`/`--mqtt-client-key` were parsed and stored but never applied — TLS always used the system trust store, so a self-signed broker always failed UnknownIssuer. Now builds `rumqttc::TlsConfiguration::Simple` from the real PEM files (no new TLS dependency needed). A file that can't be read logs why and falls back to system trust instead of failing opaquely later. - #1555: the MQTT availability heartbeat asserted "online" for every known node on a fixed 30s timer regardless of whether that node's data was still arriving. Now tracks each node's last-seen broadcast snapshot and only reports "online" within a 10s freshness window, otherwise "offline" — a frozen sensor can no longer look available. (The other half — restarting a publisher that goes permanently silent — needs a reproduction the reporter themselves weren't certain of; left for a follow-up rather than guessing at the trigger.) - #1540: already fixed on main (node-keyed RateLimiter, ADR-297). - #1521/#1522: not fixable in this repo (published HF model artifact); replied with the ADR-298 gate status and the exact byte-level fix for the safetensors header, and corrected the README row that claimed the file loads with the reference loader. - #1542, #1527: replied — #1542 is a real, larger firmware+server feature left open for follow-up; #1527's suggested fixes were already applied, the one residual sample is an inherent first-frame paint gap. ## Certificate spine wiring (closes the gap flagged in the PR #1579 review) `ruview-certify` and `ruview-policy` now depend on `ruview-ood` and provide real `From<ruview_ood::DomainState>` adapters plus a composed entry point, `ruview_policy::authorize_from_certificate`, matching the adapter contract `ruview-policy`'s own doc comment already described but that no code actually implemented. A new cross-crate integration test (`acceptance_test_b_real_integration`) mints a real signed `CapabilityCertificate` and proves a real post-drift `ruview_ood::Unknown` denies a `SafetyCritical` action through the composed pipeline — not two disconnected unit tests hand-setting the same enum value. Also: - Wires `evaluate_linear_head` (ADR-298 model-release gate) into a new CI job so the checker itself can't silently regress; documents that gating an actual model publish is still a manual step (no HF automation here). - Wires `SourceState::export_watermark()` into `start_recording`: a recording captured while the source is synthetic is now stamped in its metadata (not the filename or per-line JSON, to avoid breaking `delete_recording`'s path reconstruction or the training dataset loader's schema). - Updates docs/user-guide.md's "Developer Preview" section to describe what's now genuinely wired vs. still not (no live continuous calibration/OOD loop in the running server yet). ## Validation - cargo test --workspace --no-default-features: 4391 passed, 0 failed - cargo build --release -p wifi-densepose-sensing-server --features mqtt: clean - Server smoke-tested end-to-end against the simulator (real startup, UDP/WS/HTTP listeners, /api/v1/sensing/latest stable across calls) - Real ESP32-S3 hardware was NOT reachable this session (no COM port present, zero UDP frames received after 40s bound to 0.0.0.0:5005) — the multi-node fixes are validated by the new unit/integration tests and full-workspace regression, not by live hardware. Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
67
.github/workflows/model-release-gate.yml
vendored
Normal file
67
.github/workflows/model-release-gate.yml
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
name: Model release gate (ADR-298)
|
||||
|
||||
# ADR-298 model-release sanity gates (issue #1521): structural checks that
|
||||
# block a degenerate/mislabeled classifier head (unreachable decision
|
||||
# boundary, near-constant output, degenerate class balance, a metric
|
||||
# surfaced under a task name it wasn't computed as) before it ships.
|
||||
#
|
||||
# Checker: v2/crates/wifi-densepose-train/src/model_gates.rs
|
||||
#
|
||||
# IMPORTANT — the honest scope of this job: it protects the *checker itself*
|
||||
# from regressing (the gate logic + its issue-1521 regression fixture are
|
||||
# exercised on every push/PR that touches this crate), and running it is
|
||||
# required before ADR-298 can be called "wired in" at all. It does NOT gate
|
||||
# an actual model publish — this repository does not automate uploading to
|
||||
# the HuggingFace model repo (`ruvnet/wifi-densepose-pretrained`); that
|
||||
# remains a manual, human-run step. Before publishing or replacing a model
|
||||
# artifact there, run this gate against the real head weights locally:
|
||||
#
|
||||
# cargo test -p wifi-densepose-train model_gates
|
||||
#
|
||||
# and, until a CLI entry point exists to run `evaluate_linear_head` against an
|
||||
# arbitrary `.safetensors`/`.rvf` file, load the head's `weight`/`bias` in a
|
||||
# short script and call `wifi_densepose_train::evaluate_linear_head` directly.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- master
|
||||
paths:
|
||||
- "v2/crates/wifi-densepose-train/**"
|
||||
pull_request:
|
||||
paths:
|
||||
- "v2/crates/wifi-densepose-train/**"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
model-release-gate:
|
||||
name: Model release gate check
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
|
||||
with:
|
||||
persist-credentials: false
|
||||
submodules: recursive
|
||||
|
||||
- name: Install Rust toolchain
|
||||
run: rustup toolchain install stable --profile minimal
|
||||
|
||||
- name: Run the model-release gate's own test suite
|
||||
working-directory: v2
|
||||
run: cargo test -p wifi-densepose-train --no-default-features model_gates -- --nocapture
|
||||
|
||||
- name: Summarize result
|
||||
if: always()
|
||||
run: |
|
||||
{
|
||||
echo '### Model release gate (ADR-298)'
|
||||
echo ''
|
||||
echo 'This job protects `model_gates.rs` from regressing. It does not itself'
|
||||
echo 'gate a real HuggingFace model publish — that upload is a manual step'
|
||||
echo 'outside this repository; run `cargo test -p wifi-densepose-train model_gates`'
|
||||
echo 'against real head weights before publishing one.'
|
||||
} >> "$GITHUB_STEP_SUMMARY"
|
||||
Reference in New Issue
Block a user