mirror of
https://github.com/ruvnet/RuView
synced 2026-07-22 17:23:19 +00:00
189ac9dfb0
Bind the ADR-027 MERIDIAN cross-environment domain-generalization surface
into the wheel behind a gated [meridian] extra / Cargo `meridian` feature.
Inference/adaptation path only (tch-free), per ADR-185 section 3.3.
Surface (bound against the REAL code at HEAD, not the ADR wishlist):
- HardwareType / HardwareNormalizer / CanonicalCsiFrame (from
wifi-densepose-signal::hardware_norm)
- MeridianGeometryConfig / GeometryEncoder (64-dim, permutation-invariant)
- RapidAdaptation / AdaptationResult (push_frame + adapt, LoRA deltas)
- CrossDomainEvaluator + mpjpe (from wifi-densepose-train, NO tch-backend)
All compute paths GIL-released (py.allow_threads).
Honest deviations from ADR section 3.3 (documented in the module header):
- ADR's RapidAdaptation.calibrate(windows) and AdaptationResult.converged
DO NOT EXIST. Real API is push_frame + adapt(); result carries
{lora_weights, final_loss, frames_used, adaptation_epochs}. Bound as-is.
- ADR's HardwareType.detect exposed as a staticmethod delegating to the
real HardwareNormalizer::detect_hardware.
- ADR's normalize(frame: CsiFrame, hw) is really normalize(amplitude,
phase, hw) over f64 vectors returning Result; bound faithfully.
- CanonicalCsiFrame fields are singular amplitude/phase (ADR said plural).
Training-time types (DomainFactorizer, GradientReversalLayer,
VirtualDomainAugmentor) are out of P6 scope (need the libtorch tier).
Parity (section 4.1, release-blocking): committed fixture
meridian_input.json -> native Rust reference (tests/meridian_parity.rs,
calls hardware_norm + geometry + rapid_adapt directly) locks
tests/golden/meridian_output.sha256 over the concatenated f32 outputs
(esp32+intel canonical frames, 64-dim geometry vector, rapid-adapt LoRA
weights); pytest (tests/test_meridian.py) runs the same fixture through
the binding and asserts the identical SHA-256. Both pass.
Verified:
cargo test --features meridian --test meridian_parity -> 2/2 pass
maturin develop --features meridian + pytest tests/test_meridian.py
-> 13/13 pass
default cargo build clean, 0 train/signal/sensing-server refs in the
default dep graph (gate keeps the base wheel lean).
WHEEL-SIZE FINDING (ADR-185 section 9 / section 1.2): the libtorch risk
the ADR feared is AVOIDED -- wifi-densepose-train's `tch` dep is properly
optional (feature tch-backend, OFF), so no libtorch links. BUT train
still carries NON-optional deps: tokio (rt subset), the five ruvector-*
crates, and wifi-densepose-nn (which itself pulls `ort` / ONNX Runtime +
reqwest/hyper). So a [meridian] wheel exceeds the ADR-117 section 5.4
<=5 MB budget (though lighter than AETHER's axum/tokio server tree). The
clean fix is the same leaf-crate hoist: move the pure inference modules
(geometry, rapid_adapt, eval, hardware_norm) into a tch/tokio/ort-free
leaf crate. A required pre-release follow-up, not a functional blocker;
P2 binds real code and proves parity today.
109 lines
3.7 KiB
TOML
109 lines
3.7 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 = []
|
||
# 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
|