Files
ruvnet--RuView/v2/crates/ruview-gamma
Claude 46b4d63dad feat(ruview-gamma): centralize claim-gate invariant + add HIL acceptance contract
Two of the "what to optimize next" items, as enforced code:

1. Hard claim gate: extract the release rule into a single
   acceptance::claim_allowed(entrainment, safety, adherence, repeatability)
   = strict AND of all four, used by every path. A test proves every 3-of-4
   subset is denied, so no path can silently weaken the gate to an OR/subset.

2. Hardware-in-the-loop contract (new hil module): verify_hil grades a
   captured actuator bench measurement against fixed targets — LED frequency
   +/-0.1 Hz, audio-visual sync < 5 ms, stop-signal -> actuator-off < 100 ms,
   session-hash reproducibility 100%, EEG entrainment lift >= 20% over fixed
   40 Hz. Every failure mode fails closed (missing/NaN stop measurement, no
   replay, any hash mismatch). The crate stays a deterministic leaf: firmware
   records the measurements, this module grades them.

README: benchmark table (safety tick ~8 ns, recommend ~15 us, cohort kNN/500
~15 us, calibration ~115 us, acceptance grading ~425 us enrollment-only) and
the positioning line — "a governed personalization engine that refuses to
overpromise."

9 new tests; crate now 97 + 1 doctest; pinned witness 13cb164c... preserved.
Workspace gate: 2,898 passed / 0 failed.

https://claude.ai/code/session_01MjBucx95K4BuUxZi8NWwRH
2026-06-10 04:31:28 +00:00
..

ruview-gamma — Adaptive Sensory Neuromodulation (ADR-250)

The most valuable thing here is not 40 Hz. It is a governed personalization engine that refuses to overpromise.

The control brain for an adaptive light-and-sound neuromodulation device. The device plays stimulation; RuView reads the body as feedback; RuVector learns the personal response map; RuFlo governs the safety, audit trail, and claim boundary. The breakthrough is not speed alone — it is safe adaptive personalization with proof discipline.

It starts from 40 Hz as the research prior, then learns whether a person responds better at 38.5, 40, 41.2, or another safe setting — watching breathing, stillness, restlessness, adherence, and sensor confidence. If something goes wrong, the session locks. If a program has not proven entrainment, safety, adherence, and repeatability, it cannot advertise a benefit — it returns research use only.

Benchmarks (this container — indicative)

Path Current Role
Safety tick ~8 ns real-time stop path
Recommendation ~15 µs per-session decision
Cohort kNN (500 profiles) ~15 µs warm-start matching
Calibration sweep ~115 µs setup and tuning
Full acceptance grading ~425 µs enrollment-only (offline)

The per-session control loop is microseconds; the heavier acceptance grading is enrollment-time work, not on the loop. No regression across the optimization passes.

The hard claim gate

A program's benefit claim is releasable through exactly one invariant (acceptance::claim_allowed), used everywhere:

claim_allowed = entrainment_pass AND safety_pass
             AND adherence_pass  AND repeatability_pass

Anything short of all four returns research use only — … no claim (acceptance::NO_CLAIM). The marketing claim is unreadable except through the gate.

Next milestone — hardware in the loop (hil)

The software core is proven against a deterministic simulator; the next acceptance bar is a real LED + speaker actuator (e.g. ESP32-driven) plus the stop path. hil::verify_hil grades a captured bench measurement against fixed targets:

Test Target
LED frequency accuracy ±0.1 Hz
Audio-visual sync drift < 5 ms
Stop signal → actuator off < 100 ms
Session-hash reproducibility 100%
EEG entrainment lift vs fixed 40 Hz ≥ 20%

Governed, deterministic, safety-constrained personalization of 40 Hz-prior multisensory (light + sound) stimulation. Treats 40 Hz as the evidence-based starting prior, then learns each person's safe entrainment response curve using passive RuView sensing, optional EEG, a constrained optimizer, and auditable RuFlo workflows.

Not medical advice / not a medical device. This crate is a research and engineering platform. The only claim it makes is "personalized entrainment optimization" (ruview_gamma::PRODUCT_CLAIM) — never Alzheimer's treatment, amyloid clearance, or any clinical outcome (ADR-250 §19). It performs no hardware actuation: real stimulus delivery, RF sensing, and EEG arrive through external adapters behind feature flags after this governed software core ships (ADR-250 §21, Milestones 24).

Why it exists

The field mostly treats 40 Hz as a fixed protocol. But individual brains differ by baseline gamma, arousal, sleep, sensory acuity, medication, age, and comfort (the 2025 PLOS One 3644 Hz re-evaluation). Fixed 40 Hz (1) assumes one frequency fits all, (2) never verifies entrainment, (3) ignores physiological state, and (4) cannot safely optimize over time. This crate closes that loop.

The safety invariant

No recommendation, calibration step, bandit arm, or closed-loop nudge can ever emit a StimulusParameters outside the SafetyEnvelope. Every emitting path clamps to the envelope and is asserted against SafetyEnvelope::contains in tests. The optimizer never widens the envelope — only an operator constructs a wider one deliberately (ADR-250 §12). Non-finite (NaN/∞) inputs clamp toward the conservative floor, never the cap.

Module map

Module Role (ADR-250 §) Highlights
stimulus §5, §12 StimulusParameters, SafetyEnvelope (validate / clamp / grids)
safety §12 exclusion screen, latched SafetyMonitor, hard-stop reasons
response §6, §9, §10 RuViewState, optional EegMeasurement, 20-field PersonResponseVector (RuVector memory) with sticky adverse flag
objective §7 safe-entrainment score; safety is a hard gate, not a weight; RF-only proxy when EEG absent
simulator §21 M1 deterministic ChaCha20 frequency_response_curve(person, state, stimulus)
optimizer §8 Phase-1 calibration sweep, Phase-2 GP + Expected-Improvement, Phase-4 closed-loop control
bandit §8 P3 LinUCB contextual bandit over envelope-safe arms
ruvector §10 items 36 anonymized ProfileStore (one-way hashed tags), deterministic kNN, cohort warm-start priors (down-weighted pseudo-observations), DriftDetector over the physiological sub-vector, deterministic k-means clustering
program §23 NeuroProgram catalog (7 use cases) — per-program envelope, prior, objective, state-gating, evidence level, and gated claim
acceptance §18/§23.1 AcceptanceHarness + ClaimGate + the claim_allowed invariant — entrainment/safety/adherence/repeatability gate; a program's claim is unreadable until all four pass
hil §17/§21 M2 hardware-in-the-loop contract: verify_hil grades a captured actuator measurement (LED ±0.1 Hz, A/V sync < 5 ms, stop < 100 ms, hash 100%, EEG lift ≥ 20%)
session §11, §13 hashable SessionRecord, reproducible session_hash (SHA-256, quantized canonical form)
ruflo §11 consent → exclusion → envelope → run → monitor → score → update → witnessed audit; trial/sham mode; clinician export; claim discipline
proof deterministic bundle witness (mirrors nvsim / verify.py)
math dependency-light numerics (erf, normal CDF/PDF, Cholesky, RBF)

Quick start

use ruview_gamma::{
    ruflo::{Consent, RufloGovernor},
    response::RuViewState,
    simulator::{LatentPerson, ResponseSimulator},
    stimulus::{SafetyEnvelope, StimulusParameters},
};

let envelope = SafetyEnvelope::conservative();
let mut gov = RufloGovernor::enroll("subject-001", envelope, &[], Consent::Granted)
    .expect("cleared to participate");

// Milestone 1: drive the governed loop with the deterministic simulator.
let sim = ResponseSimulator::new(42);
let latent = LatentPerson::from_id("subject-001");
let state = RuViewState::calm_baseline();
gov.run_calibration(&sim, &latent, &state, 5.0, 0).unwrap();

let rec = gov.recommend(&StimulusParameters::prior());
assert!(envelope.contains(&rec.stimulus)); // always inside the envelope

Test / validate / benchmark

cargo test  -p ruview-gamma --no-default-features    # 64 unit/integration + 1 doctest
cargo bench -p ruview-gamma --no-default-features     # criterion micro-benchmarks

Determinism is proven, not assumed: proof::Proof::reference_witness() runs a fixed reference participant through the full governed pipeline and pins the bundle SHA-256 (Proof::EXPECTED_WITNESS); the test fails on any silent drift in the optimizer, simulator, response update, or session hashing.

Measured (this container, indicative — not a regression gate)

Bench Median Note
gamma_safety_tick ~9.3 ns vs ADR-250 §17 < 500 ms hard-stop latency bound
gamma_bandit_select ~74 ns LinUCB decision
gamma_bayesian_recommend ~19 µs GP + EI over the 0.1 Hz envelope grid (was ~105 µs: the GP is now factorized once per recommend, not once per grid candidate — 81%, bit-identical)
gamma_calibration_sweep ~135 µs full 9-session enroll → simulate → score → update → witness (was ~486 µs, 71%)
gamma_cohort_knn_500 ~15 µs exact kNN over 500 anonymized profiles
gamma_cohort_warm_start_500 ~16 µs full cohort prior construction (runs once per enrollment)
gamma_acceptance_grade_program ~425 µs full 3-repeat program acceptance grading (offline gate)

Adaptive sensory neuromodulation platform (ADR-250 §23)

40 Hz is one prior in one program — the engine is a general personal neural-rhythm optimization platform. NeuroProgram::catalog() ships seven use cases (Alzheimer's research, post-stroke cognition, sleep optimization, attention/working-memory, mood/arousal, home wellness, drug+device trial infrastructure), each with its own safety envelope, prior, objective weighting, physiological-state gating (the sleep program permits Asleep and caps brightness near-dark; attention requires wakefulness), evidence level, and a single non-disease claim. RufloGovernor::enroll_program wires it all in; enroll stays the bare Alzheimer's-defaults path (so the pinned witness holds).

Claim discipline is executable. A program's claim can only be read through the acceptance gate:

use ruview_gamma::acceptance::{AcceptanceHarness, AcceptanceCriteria};
use ruview_gamma::program::NeuroProgram;
# use ruview_gamma::simulator::LatentPerson;
# use ruview_gamma::response::RuViewState;

let harness = AcceptanceHarness::new(42, AcceptanceCriteria::default());
let report = harness.evaluate(
    &NeuroProgram::sleep_optimization(),
    &LatentPerson::from_id("subject"),
    &RuViewState::calm_baseline(),
);
// Returns the program claim ONLY if entrainment + safety + adherence +
// repeatability all pass; otherwise the research-only NO_CLAIM string.
let _claim = report.claim_gate().claim();

Self-learning across people (ADR-250 §10)

RufloGovernor::export_anonymized_profile() publishes a participant's 20-field vector + per-frequency scores from safe sessions only under a one-way hashed tag; seed_from_cohort(&store, k) warm-starts a new person's optimizer from the k nearest responders as down-weighted pseudo-observations (observe_prior, ≥25× the real-observation noise). Priors shape where the optimizer looks first but never count as measured data — they are excluded from the EI incumbent, the audit log, and the clinician report. Per-session drift_status() (Welford centroid over the physiological sub-vector — stimulus inputs masked out) flags when recalibration is warranted.

Roadmap (ADR-250 §21)

M1 simulator · M2 device harness (envelope + e-stop contract) · M3 RuView state contract · M4 optional EEG input · M5 adaptive optimizer (BO + bandit

  • closed-loop) · M6 trial mode (sham/blinding + clinician export) · §10 RuVector self-learning (cohort warm-start, drift detection, clustering) . Hardware actuation, real RF sensing, and real EEG land behind feature-flagged adapters. An HNSW backend (the ruvector crates) drops in for ProfileStore once cohorts grow past ~10⁵ profiles.