mirror of
https://github.com/ruvnet/RuView
synced 2026-07-22 17:23:19 +00:00
1c9727f9cf
Bind the ADR-024 MAT (Mass Casualty Assessment Tool) disaster-survivor detection + START triage surface into the wheel behind a gated [mat] extra / Cargo `mat` feature, mirroring the upstream disaster/ML gating. Also adds the [sota] superset extra (aether+meridian+mat). Surface (bound against the REAL code at HEAD, not the ADR wishlist): - DisasterType (9 variants) / TriageStatus (5, START) enums - DisasterConfig (builder-backed, continuous_monitoring forced off) - DisasterResponse: initialize_event / add_zone / push_csi_data / scan_once / survivors / survivors_by_triage - Survivor (id, triage_status, confidence, location, latest_vitals) - VitalSignsReading (breathing/heartbeat rate, movement, confidence) - ScanZone.rectangle / ScanZone.circle push_csi_data + scan_once are GIL-released. Honest deviations from ADR section 3.4 (documented in module header): - ADR proposed adding a Rust-side sync scan_once() (section 11.3). That was UNNECESSARY: the public async start_scanning() runs exactly one scan_cycle and returns when continuous_monitoring == false. The binding forces that flag off and drives one cycle on a private current-thread tokio runtime -- NO change to wifi-densepose-mat. - scan_cycle requires an active event + Active zone, which the ADR surface omitted; initialize_event + add_zone are bound as required additions. - Survivor.vital_signs is a *history* in the real code; bound as Survivor.latest_vitals -> Optional[VitalSignsReading]. - DisasterType has 9 variants at HEAD (adds Landslide/MineCollapse/ Industrial/TunnelCollapse); all bound. Parity (section 4.1, release-blocking): committed fixture mat_input.json (synthetic breathing-modulated CSI stream) -> native Rust reference (tests/mat_parity.rs, drives DisasterResponse directly) locks tests/golden/mat_result.sha256 over a canonical `count=<K>;triage_priorities=<sorted>` string (survivor UUIDs/timestamps excluded as non-deterministic); pytest (tests/test_mat.py) runs the same stream through the binding and asserts the identical hash. Both detect exactly 1 survivor, triage Delayed. Honest: synthetic fixture proves binding==native path equality, NOT live detection accuracy. Verified: cargo test --features mat --test mat_parity -> 2/2 pass maturin develop --features mat + pytest tests/test_mat.py -> 7/7 pass default cargo build clean, 0 mat/tokio refs in the default dep graph. WHEEL-SIZE FINDING (ADR-185 section 9): default-features=false drops MAT's `api` (axum) and `ruvector` features, but MAT still carries NON-optional tokio (rt/sync/time), wifi-densepose-nn (ort/ONNX + reqwest/hyper), rustfft, geo, ndarray. So a [mat] wheel exceeds the ADR-117 section 5.4 <=5 MB budget -- same leaf-crate-hoist follow-up as AETHER/MERIDIAN. The default wheel is untouched (feature-gated).
114 lines
3.9 KiB
TOML
114 lines
3.9 KiB
TOML
# ADR-117 — `wifi-densepose` v2.x PyPI wheel
|
||
#
|
||
# This is the PyO3+maturin replacement for the legacy pure-Python
|
||
# `wifi-densepose==1.1.0` (last release 2025-06-07). One compiled
|
||
# extension module per OS/arch covers Python 3.10–3.13 via abi3.
|
||
|
||
[build-system]
|
||
requires = ["maturin>=1.7,<2.0"]
|
||
build-backend = "maturin"
|
||
|
||
[project]
|
||
name = "wifi-densepose"
|
||
version = "2.0.0a1"
|
||
description = "WiFi-based human pose estimation, vital sign extraction, and ambient intelligence from Channel State Information (CSI). PyO3 bindings for the Rust core."
|
||
readme = "README.md"
|
||
requires-python = ">=3.10"
|
||
license = { text = "MIT" }
|
||
authors = [
|
||
{ name = "rUv", email = "ruv@ruv.net" },
|
||
]
|
||
keywords = [
|
||
"wifi", "csi", "pose-estimation", "vital-signs",
|
||
"biometric", "ambient-intelligence", "home-assistant", "matter",
|
||
]
|
||
classifiers = [
|
||
"Development Status :: 3 - Alpha",
|
||
"Intended Audience :: Developers",
|
||
"Intended Audience :: Science/Research",
|
||
"License :: OSI Approved :: MIT License",
|
||
"Operating System :: OS Independent",
|
||
"Programming Language :: Python :: 3",
|
||
"Programming Language :: Python :: 3.10",
|
||
"Programming Language :: Python :: 3.11",
|
||
"Programming Language :: Python :: 3.12",
|
||
"Programming Language :: Python :: 3.13",
|
||
"Programming Language :: Rust",
|
||
"Topic :: Scientific/Engineering",
|
||
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
||
"Topic :: Scientific/Engineering :: Image Recognition",
|
||
"Topic :: System :: Hardware",
|
||
"Typing :: Typed",
|
||
]
|
||
dependencies = []
|
||
|
||
[project.optional-dependencies]
|
||
# ADR-117 §5.6 — pure-Python WS/MQTT client. Lands in P4.
|
||
client = [
|
||
"websockets>=12.0",
|
||
"paho-mqtt>=2.1",
|
||
]
|
||
# ADR-185 P1 — AETHER contrastive embeddings. Unlike `client`, this
|
||
# extra carries no pure-Python deps: it is a marker for a *compiled*
|
||
# feature build (`maturin ... --features aether` / a cibuildwheel
|
||
# feature axis, ADR-185 §3.1). Installing the base wheel and importing
|
||
# `wifi_densepose.aether` raises a clear ImportError naming this extra.
|
||
aether = []
|
||
# ADR-185 P2 — MERIDIAN domain generalization. Same compiled-feature
|
||
# marker pattern as `aether` (built via `maturin ... --features meridian`).
|
||
meridian = []
|
||
# ADR-185 P3 — MAT disaster-survivor detection. Same compiled-feature
|
||
# marker (built via `maturin ... --features mat`).
|
||
mat = []
|
||
# ADR-185 §3 convenience — all three SOTA subsystems at once.
|
||
sota = []
|
||
# Developer dependencies for running the test suite + lint.
|
||
dev = [
|
||
"pytest>=8.0",
|
||
"pytest-asyncio>=0.23",
|
||
"ruff>=0.7",
|
||
"mypy>=1.13",
|
||
]
|
||
|
||
[project.urls]
|
||
Homepage = "https://github.com/ruvnet/RuView"
|
||
Repository = "https://github.com/ruvnet/RuView"
|
||
Issues = "https://github.com/ruvnet/RuView/issues"
|
||
Documentation = "https://github.com/ruvnet/RuView/tree/main/docs"
|
||
"ADR-117 (modernization plan)" = "https://github.com/ruvnet/RuView/blob/main/docs/adr/ADR-117-pip-wifi-densepose-modernization.md"
|
||
"Release notes (v0.7.0)" = "https://github.com/ruvnet/RuView/blob/main/docs/releases/v0.7.0-mqtt-matter.md"
|
||
|
||
# Console-script entry points wired up in P5 once the CLI shim exists.
|
||
# [project.scripts]
|
||
# wifi-densepose = "wifi_densepose.cli:main"
|
||
|
||
[tool.maturin]
|
||
# Layout: pyproject.toml + Cargo.toml live at `python/`; the
|
||
# python-source directory `wifi_densepose/` is a sibling (i.e. at
|
||
# `python/wifi_densepose/`). `python-source = "."` tells maturin to
|
||
# look for packages directly under the project root.
|
||
python-source = "."
|
||
module-name = "wifi_densepose._native"
|
||
features = ["pyo3/extension-module"]
|
||
# Strip debug symbols for smaller release wheels (ADR-117 §5.4 5 MB budget).
|
||
strip = true
|
||
|
||
[tool.pytest.ini_options]
|
||
minversion = "8.0"
|
||
testpaths = ["tests"]
|
||
addopts = "-v --strict-markers"
|
||
asyncio_mode = "auto"
|
||
|
||
[tool.ruff]
|
||
line-length = 100
|
||
target-version = "py310"
|
||
|
||
[tool.ruff.lint]
|
||
select = ["E", "F", "W", "I", "UP", "B"]
|
||
|
||
[tool.mypy]
|
||
python_version = "3.10"
|
||
strict = true
|
||
warn_unused_ignores = true
|
||
warn_redundant_casts = true
|