Skip to content

Commit df61714

Browse files
ruvnetruv
andauthored
feat(ADR-262 P3): live /api/field + /ws/field — RuView sensing speaks RuField (fail-closed egress) (#1071)
* feat(ADR-262 P3): live RuField surface — RuView sensing speaks RuField on /api/field + /ws/field Wire the P1 `wifi-densepose-rufield` bridge into the live `wifi-densepose-sensing-server` so the governed sensing cycle emits real signed RuField `FieldEvent`s on two additive endpoints. - Cargo: add the `wifi-densepose-rufield` path dep (the single coupling point, ADR-262 §5.4 — no new RuView-internal coupling). - New `src/rufield_surface.rs` (kept out of the 8k-line main.rs): `FieldSurface` holds a dedicated ed25519 `Signer` + a bounded ring of recent events + the `/ws/field` broadcast topic; `GET /api/field` and `GET /ws/field` handlers; a standalone `router()` for isolated testing. - Signer (defers the P2 key decision, ADR-262 §8 Q1): a STANDALONE dev/sensing key from `WDP_RUFIELD_SIGNING_SEED`, else a deterministic dev default with a logged WARN. Reusing the `cog-ha-matter` Ed25519 key is the deferred P2 call — P3 does not pre-empt it. - Tap: at the ESP32 governed-trust cycle (`main.rs` ~5886 observe_cycle / ~5938 SensingUpdate build), `emit_rufield_event` joins the cycle's features/classification/signal_field with the engine's effective_class/demoted trust state into a `SensingSnapshot` and surfaces it via the bridge. Existing endpoints (`/ws/sensing` etc.) are unchanged — purely additive. - Privacy egress: `network_egress_allowed` is fail-closed for an unattended live surface — only P1/P2 leave the box; P0 raw and P3/P4/P5 (identity/biometric/aggregate) are held edge-local. A `Derived` cycle maps to P4/P5 and never surfaces. - No-phantom: `emit` drops no-presence cycles (no fabricated events). Gates (tests/rufield_surface_test.rs, tower::oneshot, 4/0): well-formed signed event (WifiCsi, P2 not P1, is_fusable, real timestamp); empty cycle → no phantom; Derived trust never surfaces; mixed stream surfaces only egress-safe events. Honesty (ADR-262 §0/§6): real plumbing on a live endpoint, NOT accuracy. Single-link CSI with its existing caveats (no validated room-coordinate accuracy); dedicated dev signing key pending the P2 ownership decision; no accuracy claim. Co-Authored-By: claude-flow <ruv@ruv.net> * docs(ADR-262 P3): mark P1+P3 implemented; document /api/field + /ws/field; CHANGELOG - ADR-262 Status → "P1 + P3 implemented"; add a P3 implementation-status block (tap site, endpoints, dedicated dev signer deferring the §8 Q1 key decision, fail-closed egress, gates). Keep the honesty framing: real plumbing on a live endpoint, not accuracy. - CHANGELOG [Unreleased]: add the ADR-262 P3 entry. - user-guide: add `/api/field` to the REST table + a "RuField surface (ADR-262 P3)" section covering `/api/field` + `/ws/field`, the fail-closed P1/P2-only egress, the WDP_RUFIELD_SIGNING_SEED dev key, and the no-accuracy honesty note. Co-Authored-By: claude-flow <ruv@ruv.net> * ci: checkout submodules everywhere + Dockerfile copies vendor/rufield Making wifi-densepose-rufield (ADR-262 bridge) a v2 workspace member means EVERY cargo-on-workspace context must have the vendor/rufield submodule present (cargo loads all member manifests). P1 only fixed the rust-tests job; this adds `submodules: recursive` to all workflow checkouts that run cargo (mqtt-integration was failing on the missing submodule manifest), and makes Dockerfile.rust COPY vendor/rufield/ to /vendor/rufield (matches the bridge's ../../../vendor/rufield path-dep under the collapsed Docker layout). update-submodules.yml left alone (it manages submodules itself). Co-Authored-By: claude-flow <ruv@ruv.net> --------- Co-authored-by: ruv <ruvnet@gmail.com>
1 parent f250149 commit df61714

31 files changed

Lines changed: 915 additions & 9 deletions

.github/workflows/aether-arena-harness.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ jobs:
3333
working-directory: v2
3434
steps:
3535
- uses: actions/checkout@v4
36+
with:
37+
submodules: recursive
3638

3739
- name: Install Rust toolchain
3840
run: rustup show && rustc --version

.github/workflows/bfld-mqtt-integration.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ jobs:
5353
steps:
5454
- name: Checkout
5555
uses: actions/checkout@v4
56+
with:
57+
submodules: recursive
5658

5759
- name: Install Rust toolchain
5860
uses: dtolnay/rust-toolchain@stable

.github/workflows/cd.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ jobs:
4242
steps:
4343
- name: Checkout code
4444
uses: actions/checkout@v4
45+
with:
46+
submodules: recursive
4547

4648
- name: Determine deployment environment
4749
id: determine-env
@@ -86,6 +88,8 @@ jobs:
8688
steps:
8789
- name: Checkout code
8890
uses: actions/checkout@v4
91+
with:
92+
submodules: recursive
8993

9094
- name: Set up kubectl
9195
uses: azure/setup-kubectl@v3
@@ -132,6 +136,8 @@ jobs:
132136
steps:
133137
- name: Checkout code
134138
uses: actions/checkout@v4
139+
with:
140+
submodules: recursive
135141

136142
- name: Set up kubectl
137143
uses: azure/setup-kubectl@v3

.github/workflows/ci.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ jobs:
2929
continue-on-error: true
3030
uses: actions/checkout@v4
3131
with:
32+
submodules: recursive
3233
fetch-depth: 0
3334

3435
- name: Set up Python
@@ -82,6 +83,8 @@ jobs:
8283
steps:
8384
- name: Checkout code
8485
uses: actions/checkout@v4
86+
with:
87+
submodules: recursive
8588
# ADR-262 P1: `wifi-densepose-rufield` path-deps the `vendor/rufield`
8689
# submodule. Without a recursive checkout the workspace build fails to
8790
# resolve those path deps in CI even though it passes locally.
@@ -207,6 +210,8 @@ jobs:
207210
- name: Checkout code
208211
continue-on-error: true
209212
uses: actions/checkout@v4
213+
with:
214+
submodules: recursive
210215

211216
- name: Set up Python ${{ matrix.python-version }}
212217
continue-on-error: true
@@ -272,6 +277,8 @@ jobs:
272277
steps:
273278
- name: Checkout code
274279
uses: actions/checkout@v4
280+
with:
281+
submodules: recursive
275282

276283
- name: Set up Python
277284
uses: actions/setup-python@v6
@@ -340,6 +347,8 @@ jobs:
340347
- name: Checkout code
341348
continue-on-error: true
342349
uses: actions/checkout@v4
350+
with:
351+
submodules: recursive
343352

344353
- name: Set up Docker Buildx
345354
continue-on-error: true
@@ -412,6 +421,8 @@ jobs:
412421
steps:
413422
- name: Checkout code
414423
uses: actions/checkout@v4
424+
with:
425+
submodules: recursive
415426

416427
- name: Set up Python
417428
uses: actions/setup-python@v6

.github/workflows/clone-tracking.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ jobs:
3535
runs-on: ubuntu-latest
3636
steps:
3737
- uses: actions/checkout@v4
38+
with:
39+
submodules: recursive
3840

3941
- name: Fetch /traffic/clones + /traffic/views from GitHub
4042
env:

.github/workflows/cog-ha-matter-release.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ jobs:
2828
runs-on: ubuntu-latest
2929
steps:
3030
- uses: actions/checkout@v4
31+
with:
32+
submodules: recursive
3133

3234
- name: Setup Rust
3335
uses: dtolnay/rust-toolchain@stable
@@ -78,6 +80,8 @@ jobs:
7880
runs-on: ubuntu-latest
7981
steps:
8082
- uses: actions/checkout@v4
83+
with:
84+
submodules: recursive
8185

8286
- name: Setup Rust
8387
uses: dtolnay/rust-toolchain@stable
@@ -145,6 +149,8 @@ jobs:
145149
vars.HAS_GCP_CREDENTIALS == 'true'
146150
steps:
147151
- uses: actions/checkout@v4
152+
with:
153+
submodules: recursive
148154

149155
- name: Download x86_64 artifact
150156
uses: actions/download-artifact@v4

.github/workflows/dashboard-a11y.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ jobs:
2020
runs-on: ubuntu-latest
2121
steps:
2222
- uses: actions/checkout@v4
23+
with:
24+
submodules: recursive
2325

2426
- uses: dtolnay/rust-toolchain@stable
2527
with: { targets: wasm32-unknown-unknown }

.github/workflows/dashboard-pages.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ jobs:
2626
steps:
2727
- name: Checkout main
2828
uses: actions/checkout@v4
29+
with:
30+
submodules: recursive
2931

3032
- name: Install Rust + wasm32 target
3133
uses: dtolnay/rust-toolchain@stable

.github/workflows/desktop-release.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ jobs:
2828
steps:
2929
- name: Checkout
3030
uses: actions/checkout@v4
31+
with:
32+
submodules: recursive
3133

3234
- name: Setup Node.js
3335
uses: actions/setup-node@v6
@@ -83,6 +85,8 @@ jobs:
8385
steps:
8486
- name: Checkout
8587
uses: actions/checkout@v4
88+
with:
89+
submodules: recursive
8690

8791
- name: Setup Node.js
8892
uses: actions/setup-node@v6
@@ -131,6 +135,8 @@ jobs:
131135
steps:
132136
- name: Checkout
133137
uses: actions/checkout@v4
138+
with:
139+
submodules: recursive
134140

135141
- name: Download all artifacts
136142
uses: actions/download-artifact@v4

.github/workflows/firmware-ci.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ jobs:
2222
if: github.ref_type == 'tag'
2323
steps:
2424
- uses: actions/checkout@v4
25+
with:
26+
submodules: recursive
2527
- name: Check firmware version.txt == tag
2628
run: |
2729
# Tag form: vX.Y.Z-esp32 → expect version.txt to contain X.Y.Z
@@ -71,6 +73,8 @@ jobs:
7173

7274
steps:
7375
- uses: actions/checkout@v4
76+
with:
77+
submodules: recursive
7478

7579
- name: Build firmware (${{ matrix.variant }})
7680
working-directory: firmware/esp32-csi-node

0 commit comments

Comments
 (0)