feat(nlos): add consumer transient sensing pipeline

This commit is contained in:
rUv
2026-08-22 20:46:26 -04:00
parent 0df48df7b2
commit a373ff666b
100 changed files with 16218 additions and 6698 deletions

180
.github/workflows/consumer-nlos-ci.yml vendored Normal file
View File

@@ -0,0 +1,180 @@
name: Consumer NLOS
on:
push:
branches: [main, 'feat/**', 'feature/**']
paths:
- 'v2/crates/ruview-nlos/**'
- 'ui/ios-nlos/**'
- 'ui/mobile/**'
- 'harness/ruview/**'
- 'docs/adr/ADR-32[8-9]*'
- 'docs/adr/ADR-33[0-1]*'
- 'docs/research/consumer-nlos-acceptance-protocol.md'
- 'docs/schemas/ruview-nlos-*.schema.json'
- 'docs/security/consumer-nlos-threat-model.md'
- '.github/workflows/consumer-nlos-ci.yml'
- 'v2/Cargo.toml'
- 'v2/Cargo.lock'
pull_request:
branches: [main]
paths:
- 'v2/crates/ruview-nlos/**'
- 'ui/ios-nlos/**'
- 'ui/mobile/**'
- 'harness/ruview/**'
- 'docs/**consumer-nlos*'
- '.github/workflows/consumer-nlos-ci.yml'
- 'v2/Cargo.toml'
- 'v2/Cargo.lock'
workflow_dispatch:
permissions:
contents: read
jobs:
rust-core:
name: Rust core, security, and performance
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
with:
submodules: recursive
- name: Install Rust
uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4
with:
components: rustfmt, clippy
- name: Cache Cargo
uses: Swatinem/rust-cache@e18b497796c12c097a38f9edb9d0641fb99eee32
with:
workspaces: v2
- name: Test dependency-free core
working-directory: v2
run: cargo test -p ruview-nlos --no-default-features
- name: Formatting and lint
working-directory: v2
run: |
cargo fmt --package ruview-nlos -- --check
cargo clippy -p ruview-nlos --all-features --all-targets -- -D warnings
- name: Test server and hardware adapters
working-directory: v2
run: cargo test -p ruview-nlos --all-features
- name: Check all targets
working-directory: v2
run: cargo check -p ruview-nlos --all-features --all-targets
- name: Audit Rust lockfile
working-directory: v2
run: |
cargo install cargo-audit --version 0.22.2 --locked
cargo audit
- name: Measure synthetic architecture gate
working-directory: v2
run: |
cargo run -p ruview-nlos --release -- benchmark --frames 300 --particles 1000 > /tmp/nlos-benchmark.json
python - <<'PY'
import json
from pathlib import Path
report = json.loads(Path('/tmp/nlos-benchmark.json').read_text())
assert report['evidence'] == 'SYNTHETIC_L0'
assert report['hardwareReproductionGatePassed'] is False
assert report['throughputFps'] >= 30.0, report
assert report['lostTrackReductionPercent'] >= 25.0, report
print(json.dumps(report, indent=2, sort_keys=True))
PY
web-ios:
name: Expo web iOS client
runs-on: ubuntu-latest
defaults:
run:
working-directory: ui/mobile
steps:
- name: Checkout
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
- name: Set up Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
with:
node-version: '22'
cache: npm
cache-dependency-path: ui/mobile/package-lock.json
- run: npm ci --ignore-scripts
- run: npm test -- --runInBand
- run: npx tsc --noEmit
- run: npm run lint
- name: Export browser bundle
run: npx expo export --platform web
- name: Export Expo iOS bundle
run: npx expo export --platform ios --output-dir /tmp/ruview-expo-ios
- name: Audit web dependency boundary
run: |
npm audit --json > /tmp/mobile-audit.json || true
node <<'JS'
const report = require('/tmp/mobile-audit.json');
const severe = Object.entries(report.vulnerabilities ?? {})
.filter(([, finding]) => ['high', 'critical'].includes(finding.severity));
if (severe.length) {
console.error(JSON.stringify(severe, null, 2));
process.exit(1);
}
console.log(JSON.stringify(report.metadata?.vulnerabilities ?? {}, null, 2));
JS
native-ios:
name: Native Swift and iOS Simulator build
runs-on: macos-15
defaults:
run:
working-directory: ui/ios-nlos
steps:
- name: Checkout
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
- name: Swift protocol and security tests
run: swift test
- name: Unsigned iOS Simulator build
run: >-
xcodebuild
-project RuViewNLOS.xcodeproj
-scheme RuViewNLOS
-sdk iphonesimulator
-destination 'generic/platform=iOS Simulator'
CODE_SIGNING_ALLOWED=NO
build
metaharness:
name: Advisory MetaHarness
runs-on: ubuntu-latest
defaults:
run:
working-directory: harness/ruview
steps:
- name: Checkout
uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262
- name: Set up Node
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
with:
node-version: '22'
cache: npm
cache-dependency-path: harness/ruview/package-lock.json
- run: npm ci --ignore-scripts
- run: npm test
- run: npm run test:security
- run: npm run brain:verify
- run: npm run flywheel:verify
- run: npm run manifest:verify
- run: npm pack --dry-run

View File

@@ -40,9 +40,10 @@ jobs:
- dir: harness/ruview
build: false
publishable: true
# ADR-283/325: brain + local hosts + replay assets + guarded Spaces OAuth adapter;
# still runtime-dependency-free. 160 KiB is the reviewed hard ceiling.
unpacked_budget: 163840
# ADR-283/325/331: brain + local hosts + replay assets + guarded
# Spaces OAuth + consumer-NLOS verifier; still runtime-dependency-free.
# 220 KiB is the reviewed hard ceiling after the bounded NLOS addition.
unpacked_budget: 225280
- dir: harness/homecore
build: false
publishable: true

View File

@@ -104,8 +104,9 @@ jobs:
run: |
set -euo pipefail
case "${{ inputs.package }}" in
# ADR-283/325: brain + hosts + replay + guarded Spaces OAuth; no runtime deps.
harness/ruview) export UNPACKED_BUDGET=163840 ;;
# ADR-283/325/331: brain + hosts + replay + guarded Spaces OAuth +
# bounded consumer-NLOS verifier; no runtime dependencies.
harness/ruview) export UNPACKED_BUDGET=225280 ;;
# ADR-285: CLI + MCP + reviewed brain + WASM-kernel adapter.
harness/homecore) export UNPACKED_BUDGET=180000 ;;
# ADR-264 O2: map-free tarball (was 188 kB with maps).