'keep going' on public data. Imported values (OCR/CSV/some FHIR) often arrive with NO
reference range, so focus/vitals couldn't classify them. New helix-refranges crate
supplies a labeled FALLBACK: 27 analyte reference intervals (2.5–97.5th percentile)
derived from NHANES 2021–2023 (~5,600–6,000 adults each) via the bio-age XPT reader
(examples/nhanes_refranges regenerates the table).
- helix-refranges: RefInterval table keyed by LOINC + lookup/reference_range_for/
position_for; honest docs (POPULATION percentiles, not lab-specific; never
overrides a lab's own range; label in UI per ADR-006). 4 tests.
- helix-wasm: population_range_json(loinc) + population_range_coverage().
- UI: fillPopRanges() fills missing ranges on import, tagged range_source:
'population' so it reads as a fallback, then vitals/focus can classify the value.
Values track clinical ranges well (creatinine 0.53–1.46, sodium 134–144, albumin
3.3–4.7); some are wider (glucose/CRP) because NHANES is a general population — noted
honestly. 183 tests; clippy/fmt clean. NHANES data public, not committed (cited).
Co-Authored-By: claude-flow <ruv@ruv.net>
'do it' track 2. examples/nhanes_validate includes a from-scratch SAS XPT reader in
Rust (IBM hex-float decode + NAMESTR parsing, no deps) and validates the bio-age
implementation against NHANES 2021–2023 (CDC, public domain) — the population PhenoAge
was derived from.
RESULT on 3,134 real adults (full 9-marker panel + age):
correlation(PhenoAge, chronological age) r = 0.922 (Levine 2018 reported ~0.94)
mean delta = -0.64 yrs · 86.1% within ±10 yrs → GATE ✅ PASS
This empirically clears the 'verify coefficients against Levine 2018' gate I'd flagged
in ADR-034: the coefficients + unit conversions (g/dL→g/L, mg/dL→µmol/L, mg/dL→mmol/L,
mg/L→mg/dL) reproduce PhenoAge on its source population. ADR-034 + the in-code gate
updated from ⚠️ to ✅. Clinical-governance sign-off for production remains separate.
NHANES data not committed (public but large; in /tmp). Example errors gracefully if
absent; cites NHANES. 179 tests; clippy/fmt clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
'do it' on public data. examples/mimic_eval ingests the OPEN MIMIC-IV demo (894 real
serial-lab series w/ reference ranges), labels each by a STATISTICALLY rigorous,
non-circular ground truth (OLS slope t-test, |t|>2 ⇒ trend — independent of the
range-fraction heuristic), and measures how well Helix's relative band agrees.
HONEST RESULT (recorded in ADR-036):
absolute band 0.01 → 55.4% agreement
adopted relative 0.08 → 54.3% (NO better here)
evolved on this data → 82.1% (frac≈0.37)
The real data revealed the adopted frac=0.08 is calibrated to my SYNTHETIC
outpatient-style trends and does not transfer to MIMIC's ICU data (short, noisy,
irregular bursts — the wrong population for Helix's outpatient target; a high frac
'wins' mainly by calling noisy series flat). Decision: RETAIN 0.08 for the outpatient
target (still 27/27 on the clinical eval), treat frac as population-dependent, and
re-calibrate on outpatient longitudinal data. mimic_eval kept as the calibration tool.
Data not committed (licensed; in /tmp). Example errors gracefully if absent. Cites MIMIC-IV.
Co-Authored-By: claude-flow <ruv@ruv.net>
Publishes the dashboard/import/evolve work + 4 new crates (helix-bioage, -focus,
-timeline, -evolve) and the changed crates (-connect, -genome, -numeric, -pipeline,
-wasm) to crates.io. Path-dep reqs stay ^0.1.0 (0.1.1 satisfies).
Iter 2 of the SOTA loop: stress-test the adopted relative band (ADR-036, frac=0.08)
on a larger, more diverse set — added creatinine, eGFR, systolic BP, ALT, platelets,
plus short-window (2pt/10d real drop) and long-window (1yr tiny noise) cases.
RESULT: the actually-adopted shipping config scores 27/27 (fitness 27.00), and
evolution finds +0.00 — the relative band GENERALIZES across 11 markers with no
further tuning win. Honest validation that iter-1's fix is robust, not overfit to
the original 4 cases. The expanded set is now a stronger regression gate.
Mobile checked: mobile.js doesn't call analyze_json, so no trend-band parity gap.
Co-Authored-By: claude-flow <ruv@ruv.net>
The Darwin eval (ADR-035) proved no single ABSOLUTE flat_band works across markers
of different scales. Fix: a reference-range-RELATIVE dead-band.
- helix-numeric::trend_direction_relative(slope, range_span, window_days, frac):
a move is a trend only if it exceeds of the reference range over the
observation window (effective band = frac*span/window). Scale-invariant.
- helix-pipeline: AnalyzeRequest.flat_band_frac opt-in; when >0 with a reference
range it supersedes the absolute band (backward compatible, 0.0 = absolute) +
window_days_of helper.
- helix-evolve: flat_band_frac added to the search space; evolve_full now finds
frac≈0.077 → 17/17 (fitness 14.20→17.00, +2.80, 4→0 wrong, over_confident 0).
- helix-wasm: AnalyzePayload/AnalyzeRequest carry flat_band_frac.
- UI ADOPTED flat_band_frac=0.08 (eval-gated, governance-reviewed per ADR-035):
catches slow clinically-important trends (prediabetic HbA1c creep, hypothyroid
TSH drift) the old 0.01 band silently called 'stable', AND stops large-scale
noise (cholesterol/vitD) being read as a trend.
Affects trend WORDING only — abstention + red-flag safety paths unchanged;
over_confident stayed 0. ADR-036 (Accepted). 179 tests; clippy/fmt/audit clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
evolve_full.rs: a 17-case, 6-marker eval set (ferritin, HbA1c, TSH, cholesterol,
vitamin D, glucose) labeled by clinical ground truth, run from Helix's REAL
shipping defaults.
RESULT — the eval exposed a genuine flaw and evolution improved it:
SHIPPING flat_band=0.01 → 13/17 correct (fitness 14.20). Misses:
- hba1c-creep: real prediabetes rise (0.0033/day) read as FLAT (band too coarse)
- tsh-drift-up: real hypothyroid drift (0.008/day) read as FLAT (band too coarse)
- chol-noise / vitd-stable: large-scale normal variation read as a trend
EVOLVED flat_band=0.0014, floor=0.625, staleness=289 → 15/17 (fitness 15.60, +1.40):
fixes the two clinically-important slow-trend MISSES; over_confident stays 0 and
the confidence floor RISES (more conservative) — safety preserved/strengthened.
KEY FINDING: the 2 remaining errors are irreducible for ANY single global band —
small-scale markers (HbA1c/TSH) need a lower band, large-scale ones (cholesterol)
need a higher one. The real fix the eval surfaced is a REFERENCE-RANGE-RELATIVE
band (band as a fraction of range over the observation window), which separates all
17. Proposed as a follow-up (governance-reviewed per ADR-035, not auto-promoted).
Co-Authored-By: claude-flow <ruv@ruv.net>
Running evolve from Helix's ACTUAL shipping defaults (flat_band=0.01, floor=0.5,
staleness=365) yields +0.00 — the defaults already score a perfect 4/4 on the eval
set; evolution finds nothing to beat. The earlier +0.70 was over a strawman
(flat_band=0.0) Helix doesn't ship, and only demonstrated the mechanism can move.
Honest takeaway: we added the evolve capability and verified (a useful negative
result) that current defaults are already well-chosen. A real tuning win requires
a larger, diverse eval set containing cases the defaults get wrong.
Co-Authored-By: claude-flow <ruv@ruv.net>
Answers 'can we use Darwin evolve to improve the system?' — yes, scoped honestly.
helix-evolve applies Darwin Mode's principle (mutate config → measure on a
held-out eval set → keep only measurable wins; model frozen, air-gapped) to
Helix's NON-SAFETY pipeline parameters (confidence_floor, staleness_window_days,
flat_band_per_day), within bounds that forbid degenerate values.
Two hard guarantees:
- SAFETY FROZEN: the red-flag escalation registry (helix-escalation) and the
SaMD boundary are passed in frozen and are NOT in the search space.
- GROUNDING-FIRST FITNESS: answering when Helix should abstain (over-confidence)
is penalized ~7x more than over-abstention, so evolution structurally CANNOT
win by making Helix less conservative.
Deterministic + air-gapped (ADR-018): seeded LCG, no clock/IO/network — same seed
+ same eval set => identical, replayable evolution. Hill-climb keeps a mutation
only if fitness strictly improves.
Demo (cargo run -p helix-evolve --example evolve_demo): from a flat_band=0.0
baseline that misreads a noisy-flat series as a trend (fitness 3.30), evolution
finds flat_band≈0.022 (fitness 4.00, +0.70) while over_confident stays 0 and the
confidence floor RISES to ~0.574 — a real accuracy gain, safety strictly preserved.
ADR-035 documents the decision (proposal-not-auto-promotion; eval-set curation as
the main open question). 3 tests incl. improvement-without-touching-safety +
determinism. 177 tests total; clippy/fmt clean; audit clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
Adds the remaining import sources the user asked for, all parsed on-device and
flowing into the live dossier:
- Apple Health export.xml (helix-connect::parse_apple_health): scans <Record>
elements, maps curated HealthKit identifiers to LOINC (heart rate, RHR, HRV,
steps, weight, BMI, SpO2, BP, resp rate, temp, glucose, VO2max), parses the
'YYYY-MM-DD HH:MM:SS ±ZZZZ' date with tz offset, skips unknown/non-numeric,
bounded to 100k records. wasm: apple_health_import_json.
- 23andMe raw genome (helix-genome::parse_23andme_raw): counts variants, surfaces
a few well-documented SINGLE-SNP findings (CYP2C19*2, CYP2C9*2/*3, MTHFR C677T,
lactase persistence) with effect-allele-copy counts + GENO-SNP records (capped
confidence) — honestly framed as NOT a full diplotype/PGx panel; raw file stays
on device. wasm: genome_raw_import_json.
- OCR visual preview (helix-visual via wasm visual_encode_json/visual_maxsim_json):
a dropped lab image gets a thumbnail + perceptual fingerprint + 'looks X% similar
to a prior image' note, then tesseract OCR -> helix-ocr safety gate -> records.
Fix: renderRecords + report vitals dereferenced record.reference_range.low without
a null guard, so device/genome/vitals records (no range) crashed the re-render
(surfaced as a misleading 'couldn't parse'). Both now null-guard the range.
Also fixed the OCR accepted-record shape: Gated is internally tagged, so an accepted
item spreads ProvRecord fields onto the object (strip status) rather than g.record.
Validated end to end in a real browser (claude-in-chrome): all 5 methods import 14
values with correct codes/badges; OCR reads a lab image and the visual fingerprint
is captured. 174 tests; clippy/fmt clean; audit clean (200 deps).
Co-Authored-By: claude-flow <ruv@ruv.net>
New 'Import' view that brings medical data in and flows it straight into the live
dossier (Dashboard / Health report / Ask all update). Nothing leaves the browser.
- FHIR / EMR: paste or drop a FHIR R4 Bundle (or a single Observation) -> parsed
by helix-connect via a new wasm fn fhir_import_json -> ProvRecords (LOINC +
UCUM unit + date + reference range); un-parseable resources counted to review.
- Lab report image/PDF: drag-drop a photo/scan -> in-browser OCR (tesseract.js)
-> analyte extraction -> the helix-ocr safety gate (ocr_ingest_json): implausible
/ unit-less / low-confidence values are HELD for review, never auto-trusted;
survivors become OcrExtraction records (capped confidence).
- CSV / paste: 'concept, code, value, unit, low, high' rows -> records.
Imported records merge into the session dossier and re-render the dashboard, so a
freshly imported HDL/TSH/B12/HbA1c immediately appears in vitals, focus, and the
score. Validated in headless Chrome (FHIR+CSV import end to end); screenshot
committed + embedded in docs/ui.
helix-wasm exposes fhir_import_json. 168 tests green; clippy/fmt clean; audit clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
helix-wasm now exposes bioage_json (ADR-034), focus_json (ADR-032), timeline_json
(ADR-031). New 'Health report' view in the console runs them all through the real
WASM pipeline:
- Biological age card: PhenoAge from a routine panel -> delta vs. calendar age
(e.g. 42.5 yrs, 7.5 younger than 50), with a non-diagnostic 'about' modal.
- Health score over time: SVG sparkline of the versioned ScorePoints with the
trend label + a dashed change-point marker.
- Vitals & key markers: latest value per concept vs. reference range (LOW/OK/HIGH).
- Focus areas: the deterministic rules (ferritin below-range+trending -> elevated;
vitamin D below-range -> watch), each non-diagnostic and cited.
- Updates & recommendations: Tier-1 grounded items from the pipeline + focus.
wasm pkg rebuilt; validated in headless Chrome (all panels render real data);
report screenshot committed + embedded in docs/ui (links to live demo #report).
clippy/fmt clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
helix-focus (ADR-032): deterministic, non-diagnostic focus-area selection from
the user's own records — rules: out-of-range, worsening-trend (severity-upgraded
when out-of-range AND moving further out), stale-critical (retest prompt). Each
item cites the records that triggered it and is framed 'worth discussing', never
a diagnosis. Ranked by severity.
helix-timeline (ADR-031): the ADR-016 composite score plotted over time —
composes each dated subsystem snapshot into a methodology-versioned ScorePoint
(visible break on methodology change, no silent retroactive rewrite), with a
deterministic overall trend + CUSUM change-point. Trend-first, confidence carried
per point.
Both deterministic (ADR-007), reusing helix-numeric/score/provenance. 10 tests
green; clippy -D warnings clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
New ADRs for the full medical dashboard the user requested:
- ADR-031 longitudinal health-score timeline (score plotted over time, trend-first,
uncertainty shown, methodology-versioned — no opaque retroactive rewrites)
- ADR-032 evidence-based 'focus areas' + vitals panel (deterministic rules:
out-of-range / worsening trajectory / red-flag / stale-critical; never a diagnosis)
- ADR-033 dashboard updates & recommendations (grounded diff, evidence-tiered,
LLM narrates under the number-guard, refuse-when-unknown, non-prescriptive)
- ADR-034 biological/medical age from routine labs
helix-bioage implements ADR-034: the Levine PhenoAge algorithm (Aging 2018) over 9
routine blood markers + age, deterministic (ADR-007). Output framed as an ESTIMATE,
never a diagnosis (ADR-010): headline is the delta vs. chronological age, capped
confidence, abstains on any missing/non-physiological marker (a g/dL albumin value
is caught as out-of-g/L-range). Coefficients documented + carry a verify-against-
Levine-2018 gate (ADR-034 sec.5). Validated by property tests: healthy 50yo ->
~42.6 (younger); worse inflammatory/glycemic markers -> older; monotonic in age.
Note: the /deep-research run for this was throttled by API rate limits and produced
no usable evidence base, so these ADRs are grounded in established literature with
honest evidence grades + clinical-governance caveats (not the failed workflow).
5 tests green; clippy -D warnings clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
helix-core is taken on crates.io; renamed the keystone grounded-answer pipeline
crate to helix-pipeline (a free, descriptive name) so the full set publishes.
Updated helix-wasm dep + use paths + doc comments. 153 tests still green.
README refreshed: documents the now-built platform (22 crates, on-device GPU AI,
ruvnet integrations, live demo) instead of spec-only.
Co-Authored-By: claude-flow <ruv@ruv.net>
crates.io rejects path-only dependencies; every intra-workspace dep now carries
{ path, version = "0.1.0" } so the crates can be packaged/published. No code
change.
The LAST directive item. Federation client for ADR-011 cohort intelligence, built
so privacy is STRUCTURALLY UNBYPASSABLE:
- the only thing that can leave the device is a helix_cohort::CohortVector (the
ADR-024 gate output: generalized + cell-suppressed + DP-noised). No API
accepts raw records / embeddings / un-noised features -> they cannot be sent.
- per-contribution expiring Consent (opt-out is the default, ADR-011)
- genomics re-excluded at the door (defense in depth on top of ADR-024)
- FedTransport trait (in-memory aggregator in tests; Ruflo Ed25519 signed
dispatch later)
- returns only aggregate CohortSignals (size + aggregate + epsilon), refused
below a min-cohort re-identification guard.
Elevates ADR-011 from privacy-primitive to client-implemented.
All 5 directive items now complete (LLM analyst, text embedder, visual encoder,
connectors, federation). 153 tests workspace-wide; clippy -D warnings clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
A learned visual encoder by composition: a GPU vision model (moondream)
constrained to LAYOUT-ONLY description -> MiniLM embedding (ADR-027). Encodes
appearance, NEVER clinical interpretation (ADR-025/010); on-device (ADR-013).
Safety:
- layout-only prompt (forbids values/findings/diagnoses)
- value-guard: a caption containing any digit is rejected (the model started
reading content) -> neutral-token fallback.
- VisionCaptioner + TextEmbedder are traits; a true in-process CLIP/ColPali
encoder (candle, GPU) drops in behind the same contract.
GPU-validated end to end over the real medical corpus. The value-guard PROVABLY
fired: moondream attempted to read lab-report values and the guard caught the
digits, forcing the neutral fallback — the ADR-028 safety property working.
Honest note: caption quality on the synthetic SVG corpus is weak (garbage on the
synthetic x-ray), so retrieval is degenerate here; CLIP is the documented quality
upgrade. Architecture + safety + GPU path are validated.
5 unit tests + 1 GPU integration test (--ignored); clippy -D warnings clean.
base64 inlined (no new dependency).
Co-Authored-By: claude-flow <ruv@ruv.net>
Replaces helix-retrieval's reference embedder with real all-MiniLM-L6-v2 (384-dim,
the ruvnet stack standard) served on the local GPU — no health text leaves the
device (ADR-013).
- TextEmbedder trait (deterministic stub in tests, GPU LocalEmbedder in prod via
the ollama embeddings endpoint; in-stack ruvLLM/ONNX-MiniLM plug in the same way).
- LearnedEmbedder adapts it to helix_retrieval::Embedder (wires the real encoder
into ADR-023), degrading to an empty vector on backend failure so one embedding
error never fails the whole answer.
- cosine + provenance-safe record_text rendering.
Embeddings drive RECALL; the grounding gate (ADR-005) keeps assertion strict.
Validated on the GPU: fatigue query -> 0.483 cosine to fatigue/ferritin text vs
0.098 to an unrelated potassium-recipe sentence (real semantic recall).
ADR-027 + COVERAGE + GPU ledger. 4 unit tests + 1 GPU integration test (--ignored);
clippy -D warnings clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
Real grounded-compose step using the local GPU (RTX 5080) — no health data leaves
the device (ADR-013). The LLM is a NARRATOR, never a reasoner: it receives the
finished grounded facts (claims + deterministic trend + citations) and restates
only those.
Anti-hallucination guards:
- strict system prompt (no added numbers/claims/diagnoses/advice)
- number-guard: every numeric token in the output must appear in the facts;
a fabricated value -> reject -> deterministic template fallback.
- backend is a trait; the Verifier (ADR-008) still gates qualitative claims.
Backend: LocalLlmBackend over any OpenAI-compatible endpoint. Default is ruvLLM
(ruvnet-native, ADR-013; v2.1.0 serving Qwen2.5-3B-Instruct on :8080); ollama is
the fallback. Both validated on the GPU.
ADR-026 + COVERAGE (013 now a real local-GPU LLM) + GPU_STATUS ledger. 6 unit
tests green + 1 GPU integration test (--ignored); clippy -D warnings clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
Every screenshot in README.md and docs/ui/README.md is now a clickable link that
opens that exact state in the live demo (https://ruvnet.github.io/helix/):
dashboard -> /ui/ · answer -> /ui/#ask · guide -> /ui/#guide ·
mobile -> /mobile/ · sensing -> /ui/#sensing · genome -> /ui/#genome
Co-Authored-By: claude-flow <ruv@ruv.net>
Brings ruvnet/rupixel (pixel-native / ColPali-style visual RAG) into Helix for
the artifacts OCR can't handle — lab reports with tables, imaging reports, ECG
strips, scanned forms, photos.
helix-visual: image -> grid of tiles -> perceptual descriptor (mean-subtracted +
L2-normalized) -> retrieval by MaxSim late interaction (ColPali). Pluggable
VisualEmbedder so a learned ColPali/MiniLM encoder (rupixel on RuVector, WASM at
the edge) drops in behind the reference descriptor.
Hard line (ADR-010/023): visual retrieval finds similar-LOOKING documents and
surfaces them for a human + the grounding gate — it never interprets or diagnoses
an image. Every match carries that note.
Benchmarked on a REAL medical-image corpus (lab-lipid, lab-cbc, trend chart,
chest X-ray, ECG strip, skin photo, rendered to PNG and committed):
- query 'lab-lipid' -> ranks lab-cbc 2nd (0.484) above xray-chest (0.281):
it groups by visual appearance on real medical images.
- embed 0.8ms (ingest-time), maxsim 1.7us, retrieve 10.5us.
ADR-025 + COVERAGE + ledger updated. 6 tests green; clippy -D warnings clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
Browser design review (headless Chrome, multi-viewport) found the sidebar broke
awkwardly below 880px (nav stacked vertically mid-header, controls scattered).
Fixes:
- Responsive sidebar -> a clean sticky horizontal top bar (brand · horizontal
nav pills · guide), scrollable; cards stack to one column. Added a <560px tier
(hide chips, center score card, smaller title).
- Gradient score ring (teal->blue) via an inline SVG <linearGradient>.
- score-trend no longer wraps ('holding steady · confidence 81%' on one line).
Re-validated at 820px and 1280px; dashboard.png refreshed.
Co-Authored-By: claude-flow <ruv@ruv.net>
Dashboard & mobile UX upgrade:
- Anatomical digital twin (ADR-015, previously N/A): a body silhouette with
organ/system dots colour-coded from the REAL subsystem scores (good/watch/
attention), tappable -> system detail modal, with a legend. Schematic and
strictly data-driven — never a fabricated scan (ADR-015 safety principle).
- 'Today' briefing is now DYNAMIC: the real grounded pipeline insight
('ferritin 28 ng/mL, trending down · Quest') with a click-through to the full
cited answer — replacing the static placeholder.
- Mirrored the twin onto the mobile PWA home screen.
Validated in headless Chrome; dashboard.png + mobile.png refreshed.
Considered ruvnet/rupixel (pixel-native visual RAG): noted as a future capability
for visual lab-document retrieval + a client-side WASM Embedder for helix-retrieval.
Co-Authored-By: claude-flow <ruv@ruv.net>
The Data Sources view now runs the real Rust integration crates through WASM —
not static cards:
- RuView (WiFi-CSI, ADR-020): tap to run a CSI reading -> contactless vitals
(breathing/HR, conf 0.5) + Escalation Guardian flags (apnea -> urgent,
possible-distress -> critical).
- rvDNA genome (ADR-021): tap to run a profile -> pharmacogenomic phenotypes
(CYP2D6 poor / CYP2C19 normal, conf 0.6) + a 'verify with your prescriber'
advisory for the non-normal gene + T2D risk (conf 0.4) + GINA privacy note.
Validated end to end in headless Chrome; screenshots (sensing-demo, genome-demo)
committed and embedded in docs/ui/README.md. Deep-link hooks #sensing/#genome.
Co-Authored-By: claude-flow <ruv@ruv.net>
Elevates ADR-011 (opt-in PII-stripped cohort intelligence) from documented-N/A
to a built, tested primitive — the hard part ADR-011 named ('anonymization must
be genuinely robust; re-identification is real', §7.4), implemented before any
federation transport.
helix-cohort turns a dossier into a contribution-safe vector or contributes
nothing: generalize -> cell-suppression (local k-anonymity proxy) -> Laplace
differential-privacy noise (epsilon budget split across features) -> refuse when
nothing safe survives. Genomic features excluded by default (ADR-021/GINA);
quasi-identifiers require a 2k cell; the DP noise source is injected (CSPRNG in
production, deterministic in tests) so the policy is pure + exhaustively testable.
ADR-024 documents the decision. COVERAGE.md: ADR-011 now has a real primitive.
119 tests green; clippy -D warnings clean; fmt clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
The retrieval contract the analyst's Retrieve step (ADR-005) builds on RuVector
HNSW/GraphRAG: direct concept-code matches + vector neighbours + one graph hop,
fused with a recency bonus (180-day half-life), deduped by record id, top_k.
The hard line: retrieval is RECALL, not grounding. It widens what the analyst may
look at; every candidate still passes the ADR-005 grounding gate before backing a
claim. Each result carries its score AND the reason it was retrieved (direct /
vector-neighbour / graph-linked) so the Retrieve step is auditable and the
Verifier (ADR-008) sees why a record is in scope. Embedder/Index are injected
(RuVector at the edge), so the policy is pure + fully testable.
Result: 'why am I tired?' surfaces ferritin + deep-sleep + vitamin-D though they
share no concept code — the cross-concept reasoning the product is for.
ADR-023 documents the decision. 112 tests green; clippy -D warnings clean; fmt clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
Unblocks the real primary lab-ingestion path (Quest/Labcorp have no consumer
APIs, ADR-012) using RuVector's on-device OCR — documents never leave the device.
helix-ocr is the most conservative ingestion route: extract -> gate -> record|queue.
The sanity gate sends a candidate to the human-review queue (never silently
coerces) when it is non-finite, unit-less, below an OCR-confidence floor, or
physiologically implausible — so a misread '28' -> '2800000' cannot fabricate a
red-flag. Survivors become OcrExtraction ProvRecords with confidence capped at
0.8 (always below a structured feed) and code=None for later ADR-004 normalization.
ADR-022 documents the decision. 107 tests green; clippy -D warnings clean; fmt clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
Reviewed ruvnet/ruvector + ruvnet/ruview for capabilities to bring into Helix.
First adopted: RuView's WiFi-CSI contactless sensing as a real backend for the
ADR-014 ambient-sensing tier.
helix-sensing maps a RuView reading (extracted on-device, Ed25519-attested) into:
- ProvRecords for vitals (breathing, heart rate) — AmbientSensing method,
RUVW-* research codes (never a clinical LOINC), capped 0.5 confidence
(the published CSI encoder is honestly 82.3% screening-grade, not clinical)
- Escalation Guardian screening flags (ADR-009): possible-distress / fall-risk
-> Critical; elderly-inactivity / apnea-screening -> Urgent; ambient context
states -> no escalation. Every message is screening, never a diagnosis (ADR-010).
Rejects unsigned/empty/non-finite readings (provenance required, ADR-005).
ADR-020 documents the decision (complementary to mmWave, on-device-only, capped
confidence). 94 tests green; clippy -D warnings clean; fmt clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
- mobile/: installable PWA (manifest + service worker + offline cache + icon)
reusing the SAME helix-wasm pipeline as the desktop console; mobile-first
layout with bottom sheet, tab bar, and the live grounded-answer screen.
- Real WASM-rendered screenshots committed (headless Chrome capture of the
running UI): dashboard, grounded answer (ferritin, -38%, cited, Tier 1),
step-by-step guide modal, and the mobile view. Embedded in README.md and
docs/ui/README.md (fixes 'no screenshot in the readme').
- SEO on ui/index.html: meta description/keywords, Open Graph + Twitter cards,
canonical, JSON-LD SoftwareApplication, og-image.png, robots.txt, sitemap.xml.
- app.js #ask/#guide deep-link hooks for shareable/captured states.
Co-Authored-By: claude-flow <ruv@ruv.net>
helix-neural ingests a ruv-neural signed session and maps its 40 Hz
gamma-entrainment / EEG metrics into Helix ProvRecords so the neuro signal lives
in the personal-health graph alongside labs and ambient sensing — strictly as a
research / screening signal:
- RUVN-* research code namespace, never a clinical LOINC (ADR-004 can't mistake
it for validated lab data)
- MeasurementMethod::AmbientSensing + capped 0.6 confidence (exploratory)
- RESEARCH_DISCLAIMER: 'not a diagnosis and not a therapeutic claim'
- rejects unsigned / empty / non-finite sessions (provenance required, ADR-005)
- neuro_orientation() 0-100 for an optional Neuro subsystem (ADR-016)
Exposed to the UI via helix-wasm: neural_session_to_records_json, neural_disclaimer.
87 tests green; clippy -D warnings clean; fmt clean; wasm pkg rebuilt.
Co-Authored-By: claude-flow <ruv@ruv.net>
A dark, modern management console (ui/) that runs the REAL Rust anti-hallucination
pipeline (helix-core + helix-score) via helix-wasm — no JS re-implementation.
Screens: dashboard (decomposable health-score ring + body-systems grid),
Ask Helix (grounded / abstain / escalate, each from analyze_json), Records,
Data sources (incl. Cognitum Seed + ruv-neural cards). Modals: score info,
score breakdown, system detail, add-record. Plus a step-by-step onboarding
guide ('Get started in 4 steps').
Validated in Chrome against live WASM:
- health score 76 = real compose_score_json weighted roll-up
- grounded ferritin answer: 3 citations + deterministic trend
'-38% vs first reading · 3 readings · crossed reference range' + Tier 1 chip
- step-by-step guide modal renders
docs/ui/README.md documents the screens and how each maps to an ADR.
Co-Authored-By: claude-flow <ruv@ruv.net>
helix-wasm wraps the crypto-free analytic core (helix-core grounded-answer
pipeline + helix-score) behind a JSON-in/JSON-out wasm-bindgen surface:
analyze_json(), compose_score_json(), redflag_registry_version(), version().
The web management UI and the mobile app will run the SAME audited Rust logic
in-browser — no JS re-implementation, one source of truth. Vault/crypto is
intentionally excluded from the wasm surface (key custody uses platform secure
storage).
- .cargo/config.toml overrides the wasm target's rustflags so the parent
workspace's mold linker flag doesn't break rust-lld.
- wasm-pack output committed at ui/pkg (helix_bg.wasm ~169KB) for static hosting.
- 3 native binding tests green.
Co-Authored-By: claude-flow <ruv@ruv.net>
Adds proptest property tests (13 properties, 1200+ generated cases) across the
trust-critical crates:
- helix-numeric: mean bounded+finite, slope finite, monotone=>nonneg slope,
pearson in [-1,1], crossings <= intervals, percent_change matches definition.
- helix-vault: seal/open round-trips for ALL keys+plaintexts; wrong key never
opens; any single-bit ciphertext tamper fails authentication; ciphertext
never contains the plaintext verbatim.
- helix-ontology: Normalized implies (>=floor AND beat runner-up by margin);
below-floor always queued; normalize() total for valid inputs.
78 tests green; clippy -D warnings clean; fmt clean; cargo audit clean (101 deps).
This closes SOTA exit criterion #4 (security/validation). All 6 exit criteria
are now met — see IMPLEMENTATION_STATUS.md.
Co-Authored-By: claude-flow <ruv@ruv.net>
- helix-score (ADR-016): transparent, decomposable 0-100 composite. The
top-line number is a weight-normalized roll-up of subsystem SubScores, each
carrying its Drivers (concept + source_record + trend) so it is never a black
box; versioned METHODOLOGY_VERSION; always-on non-diagnostic disclaimer
(ADR-010); overall_trend for the 'which way am I heading' framing. Weights are
relative (>=0, normalized), values/confidence range-validated, NaN rejected.
- Captured criterion baselines for the numeric engine (sub-us per op at
realistic series lengths) into the ledger.
- docs/COVERAGE.md: every ADR 001-019 mapped to crate / modeled-seam / N/A.
All 6 SOTA exit criteria now met (see IMPLEMENTATION_STATUS.md): ADR coverage,
65 green tests across 8 crates, clippy+fmt clean, security pass (0 unsafe,
audit clean), benchmarks with baselines, e2e pipeline integration test.
65 tests green; clippy -D warnings clean; fmt clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
helix-vault encodes the 23andMe lesson as architecture, with working crypto
(not a stub):
- XChaCha20-Poly1305 AEAD, 192-bit random nonce per seal (no nonce-reuse
footgun); SealKey zeroizes on drop and redacts its Debug output.
- seal()/open() are authenticated: a wrong key or a single flipped bit in
the ciphertext fails to open rather than returning garbage (tested).
- ADR-001 'company cannot read/sell the corpus' is a TYPE boundary, not a
promise: VaultStore holds only SealedRecord ciphertext and exposes no
plaintext accessor (serializing the whole store leaks nothing — tested);
UserKeyring is the sole capability that can decrypt, and stays on-device.
58 tests green; clippy -D warnings clean; fmt clean; zero unsafe in helix
code; cargo audit clean across 75 deps including the AEAD stack.
Co-Authored-By: claude-flow <ruv@ruv.net>
helix-verifier (ADR-008): the independent re-derivation gate that stands
between the analyst and the user.
- cross-family fusion invariant encoded in the type system: ModelFamily,
and verify() rejects any checker sharing the synthesizer's family.
- ClaimChecker trait abstracts the (different-family) verifier LLM so the
crate is pure + deterministic-testable.
- Informational claims => single supporting check; Clinical claims =>
odd quorum >= 3 with strict-majority consensus.
- dispositions: Approved / DownGraded(tier) / Rejected, so over-reaching
claims are dropped or down-tiered before they're ever shown.
Also adds .github/workflows/ci.yml (fmt + clippy-deny-warnings + test +
bench-compile + cargo-audit) so the quality gate travels with the standalone
repo.
50 tests green; clippy -D warnings clean; fmt clean; zero unsafe.
Co-Authored-By: claude-flow <ruv@ruv.net>
- helix-ontology (ADR-004): CodeSystem enum (LOINC/RxNorm/SNOMED/ICD-10/UCUM)
with FHIR system URIs and FHIR Coding round-trip; Domain->canonical-system
map; normalize() gate that returns Normalized only on a confident, unambiguous
match and otherwise Queued(LowConfidence|Ambiguous|NoCandidate) — the ADR-004
'never silently coerce; route to human review' rule, enforced.
- criterion bench 'engine' for the ADR-007 numeric hot path (slope/crossings/
change_point/pearson at n=16/256/4096).
Security/validation pass:
- zero unsafe across all crates
- cargo audit clean (54 deps, no RUSTSEC advisories)
- release profile lto=thin + codegen-units=1
44 tests green; clippy -D warnings clean; fmt clean; bench compiles.
Co-Authored-By: claude-flow <ruv@ruv.net>
helix-core::analyze() composes the four anti-hallucination primitives in the
order that makes the product safe:
abstain (ADR-006) -> escalate (ADR-009) -> deterministic numerics (ADR-007)
-> ground every claim (ADR-005) -> tiered recommendation (ADR-006),
with the recommendation suppressed entirely when a red flag fires (ADR-009).
3 end-to-end integration tests prove the three guaranteed outcomes:
- fresh falling ferritin -> grounded, cited, trended answer + range crossing
- stale data -> honest Stale GapNotice (abstain, never guess)
- critical potassium -> Critical escalation, optimization suppressed
37 tests green across 5 crates; clippy -D warnings clean; fmt clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
- helix-evidence (ADR-006): EvidenceTier 1-4 mapped to the CEBM hierarchy;
abstention gate (assess) that returns NoData/Stale/LowConfidence GapNotices
instead of guessing; default staleness windows per data kind. Abstaining is
a first-class, tested outcome.
- helix-escalation (ADR-009): versioned, governance-controlled RedFlagThreshold
registry with cited critical values (potassium, hemoglobin, glucose, SpO2,
and a screening-only Cognitum Seed respiratory-event index). evaluate()
returns level + suppress_optimization; unknown codes error rather than being
assumed safe; Seed signals use screening-not-diagnosis language.
33 tests green across the 4 crates; clippy -D warnings clean; fmt clean.
Co-Authored-By: claude-flow <ruv@ruv.net>
Scaffold standalone helix Rust workspace with the two most self-contained,
fully-testable core crates from the Helix ADRs:
- helix-provenance (ADR-005): ProvRecord schema + type-level grounding gate;
a claim cannot be constructed without resolving its cited records against
the retrieved evidence set (no-data-no-claim enforced at compile/runtime).
- helix-numeric (ADR-007): deterministic trend engine (mean/delta/%change/
OLS slope/range-crossings/Pearson/CUSUM change-point), every fn refuses to
compute below a documented minimum sample size.
18 unit tests green. Parent workspace excludes helix/ so it stays detached
and liftable as its own ruvnet repo. Loop ledger at helix/IMPLEMENTATION_STATUS.md.
Co-Authored-By: claude-flow <ruv@ruv.net>