Commit 7a79b74
feat(sonic_ct): acoustic digital human workbench — Rust/WASM USCT + R3F UI (#595)
* feat(sonic_ct): acoustic digital human workbench — Rust/WASM USCT + R3F UI
Add `sonic_ct`, a research-grade Ultrasound Computed Tomography (USCT)
simulator and reconstruction workbench.
Core (crates/sonic-ct, pure Rust, zero deps, 17 tests):
- procedural z-varying torso phantom (fat/muscle/organ shells, spine, ribs,
pelvis, liver/spleen/kidneys/aorta, heart+lungs in thorax)
- circular ring acquisition with straight-ray travel-time + attenuation
- SART time-of-flight reconstruction (1 sweep == delay backprojection)
- transparent speed-band segmentation with per-cell uncertainty
- coordinate-ascent threshold training (mean Dice ~0.30 -> ~0.63)
- RuVector-style acoustic memory: NSW vector index, longitudinal drift,
warm-start, anatomical graph-coherence checks, .rvf-style serialization
- 3-D volume sweep (truth / recon / error / confidence channels)
- mock Butterfly Embedded acquisition boundary (trait, no hardware SDK)
WASM (crates/sonic-ct-wasm): raw C-ABI cdylib (no wasm-bindgen, ~39 KB)
exposing the single-slice + progressive volume pipeline.
UI (examples/sonic-ct): React Three Fiber "Sonic Chamber" — water chamber,
transducer ring(s), holographic torso with internal organ glows and
class-tinted contour slices, live HUD (acoustic paths, phantom fidelity,
path confidence, body composition), cranio-caudal scrubber. Driven entirely
by real reconstruction data.
Docs (docs/sonic-ct): 8 ADRs, SOTA research map, market brief, SPARC.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01Mx4vKMfvsq5KBQgPRSoxM7
* feat(sonic_ct ui): welcome modal + GLB body-model loader with procedural fallback
- WelcomeModal: Simulate/Reconstruct/Analyze/Validate intro, Get Started cards,
"show on startup" preference, research-only disclaimer.
- BodyModel: loads a supplied GLB anatomy model (GLB_URL) and applies a ghost
material override + per-organ tinting from organ_manifest.json; cleanly falls
back to the procedural violet ghost (torso + internal organ glows) when no
asset is supplied or it fails to load. GLB is a visual prior only — the Rust
phantom stays the physics ground truth.
- Refined holographic ghost: violet volumetric glow, class-tinted contour
slices, twin transducer rings, glowing base, internal organ volumes.
- docs/sonic-ct/BODY-MODELS.md: researched model sources (Zygote, BioDigital,
SMPL/Meshcapade, Z-Anatomy, BodyParts3D) + GLB integration pipeline.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01Mx4vKMfvsq5KBQgPRSoxM7
* feat(sonic_ct ui): load open-source CesiumMan GLB as the ghost body shell
- Ship CesiumMan (Khronos glTF Sample Assets, CC-BY 4.0) as public/models/human.glb,
loaded via useGLTF, auto-fit to the chamber, and styled with the ghost-material
override; procedural internal organ glows render inside it.
- GLB_URL now points at the bundled model; missing/broken asset still falls back
to the procedural torso shell via the error boundary.
- Attribution recorded in organ_manifest.json and docs/sonic-ct/BODY-MODELS.md.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01Mx4vKMfvsq5KBQgPRSoxM7
* feat(metabiohacker): organ-hypothesis detector, Darwin optimizer, rebrand
Rename the app to MetaBioHacker (Acoustic Digital Human Workbench · Sonic
Chamber) across HUD, welcome modal, and metadata.
Organ inference (ADR-0009/0010): new `crates/sonic-ct/src/organ.rs` detects
liver, spleen, kidneys, aorta, heart, and lungs from the reconstructed
volume using anatomical priors (zone, side, size, posterior adjacency,
slice-consistency) — never from speed alone. Each hypothesis carries a
confidence and an evidence bitmask. Exposed via WASM (sct_organ_*,
sct_quality_flag) and surfaced in a new HUD panel with per-organ confidence
bars + quality flags (bone shadowing / sparse coverage / boundary
uncertainty / gas). 18 Rust tests pass; clippy clean.
Harness optimization (examples/sonic-ct/optimize.mjs): uses
@metaharness/darwin ("freeze the model, evolve the harness") with
cheap->frontier tiering and Pareto selection over the frozen WASM engine to
evolve {elements, fan, iters}; lifts phantom fidelity ~0.53 -> ~0.59.
Documented in docs/sonic-ct/OPTIMIZATION.md.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01Mx4vKMfvsq5KBQgPRSoxM7
* feat(metabiohacker): faithful Darwin harness evolution + OpenRouter write layer
- crates/sonic-ct/src/bin/serve.rs: the frozen acoustic engine as a JSON-over-
stdio process (sonic_ct_serve) — the physics truth layer for the evolver.
- examples/sonic-ct/src/optimizer/reconstructionEvolution.ts: typed genome
(reconstruction/routing/scoring/safety), runFrozenRustEngine (spawns the real
binary), cheap->frontier routeReconstruction (augments engine output, never
rewrites anatomy), multi-objective scoreCandidate, mutateGenome, and
evolveMetaBioHarness using Darwin mapLimit + paretoFront + an archive.
- optimize.mjs: OpenRouter LLM "write layer" proposes harness mutations (cheap
gpt-4o-mini / frontier gpt-4o), gated by routing policy, bounded budget, key
read from env only; archive-based acceptance gate now PASSES (latency -92.8%,
no regression). probeDarwin.mjs verifies the export surface.
- Tests (npm test, Node type-stripping): mapLimit bounds concurrency; paretoFront
keeps accurate+cheap trade-offs and drops dominated; frontier never bypasses
the frozen engine. docs/sonic-ct/OPTIMIZATION.md updated.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01Mx4vKMfvsq5KBQgPRSoxM7
* docs(metabiohacker): ADRs 0009-0019 — organ inference, harness evolution, multimodal data + governance
Add 11 ADRs and an index covering the layers built and the medical-data
architecture roadmap:
Organ/inference layer (grounded in organ.rs / segmentation.rs / Hud.jsx):
- 0009 five acoustic classes canonical (no organ identity from speed alone)
- 0010 organ identity inferred from anatomical priors (evidence + confidence)
- 0011 organ function requires dynamic/multiparametric channels ("not measured")
- 0012 explainability mandatory (evidence bitmask surfaced in the UI)
- 0013 no disease labels — research mode only
Harness + data architecture:
- 0014 freeze the physics engine, evolve the reconstruction harness (Darwin)
- 0015 patient data as a graph of typed observations (MedicalObservation,
provenance + uncertainty + consent scope)
- 0016 adopt DICOM / FHIR / LOINC / SNOMED CT / OMOP + RuVector similarity index
- 0017 typed multimodal fusion patterns (monitoring/research, not diagnosis)
- 0018 governance & SaMD boundary (FDA GMLP/PCCP, Health Canada, Ontario PHIPA)
- 0019 a medical signal operating system, not an AI doctor
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01Mx4vKMfvsq5KBQgPRSoxM7
* feat(metabiohacker): benchmark harness on real CT data + synthetic corpus
- Real-data ingestion: Grid::from_pgm (P5 parser), Phantom::from_intensity_grid
(band a grayscale CT slice into the five acoustic classes), and
pipeline::run_with_phantom (reconstruct a supplied phantom — engine unchanged).
- sonic_ct_serve gains a phantomPgm path: reconstruct a real anatomical slice
instead of a procedural one and emit the same score schema.
- tools/fetchRealSlice.mjs: fetch a public-domain abdominal CT slice (Wikimedia
Commons) and convert to a grayscale PGM (image not committed; fetched on
demand, derived PGM gitignored).
- benchmark.mjs (npm run benchmark): baseline vs Darwin-evolved harness over 12
reproducible synthetic phantoms + 1 real CT slice; writes docs/sonic-ct/
BENCHMARK.md + benchmark.report.json. Representative: evolved harness ~157%
faster at equal Dice; real CT honestly harder (Dice ~0.27).
- New integration test exercises the PGM/real-phantom reconstruction path
(19 Rust tests pass).
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01Mx4vKMfvsq5KBQgPRSoxM7
* feat(metabiohacker): scale benchmark — 40 synthetic seeds + multiple real CT slices, 95% CI
- fetchRealSlice.mjs fetches several public-domain CT slices (abdomen, thorax,
pelvis) resiliently, skipping unavailable ones.
- benchmark.mjs now runs N synthetic seeds (default 40) + every fetched real
slice, reports mean ± 95% CI, and writes docs/sonic-ct/BENCHMARK.md.
Representative: 42 samples, evolved harness ~149% faster at equal Dice
(±0.002 CI); real CT slices honestly harder (Dice ~0.30).
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01Mx4vKMfvsq5KBQgPRSoxM7
* feat(metabiohacker): Multimodal Ingest V0 — observations, graph, fusion, ledger, ruvn evidence gate
New package packages/metabiohacker (@metabiohacker/core, TS, 14 tests pass):
- ingest/: canonical MedicalObservation + lab (CSV→LOINC), imaging (DICOM
sidecar), and pathology adapters with provenance/uncertainty/consent.
- graph/: auditable patient state graph + rule-based contradiction detection
(low-quality, ≥2x same-test disagreement, unflagged review modalities).
- fusion/: prior builder (data shapes priors, never forces conclusions),
multimodal scoring (acoustic residual passed through unchanged), contradiction
penalty, and a Darwin harness (mapLimit + paretoFront) selecting fusion policy.
- evidence/: ruvn as the evidence-intelligence layer (off the hot path) — provider
interface, A/B-or-blocked claim gate, deterministic cached provider + optional
@ruvnet/ruvn CLI adapter (never a hard dep). Claims ship only on grade A/B with
citations; pathology/biopsy/Pap/HPV/cytology force human review.
- ledger/ + output/: stable-hash reconstruction run ledger (tamper-evident,
verifiable) and the safe UI packet (uncertainty overlay, diagnosis blocked).
Benchmark: +10% stability, ~37% uncertainty drop, residual unchanged, ledger
verified, clinical-review mode forced by pathology.
Docs: ADR-0020 (canonical observation), 0021 (graph+contradictions),
0022 (run ledger), 0023 (ruvn evidence layer); ADR index updated.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01Mx4vKMfvsq5KBQgPRSoxM7
* feat(metabiohacker): real-slice calibration, domain-gap honesty gate, evidence refresh, CI gates
Attacks the synthetic→real Dice gap honestly rather than hiding it.
- Engine: sonic_ct_serve emits per-class (region) Dice on real slices.
- calibration/: region-level Dice (diceByRegion), domain-gap scoring +
honesty gate (classifyRealSliceResult: headline/researchOnly/exclude),
centroid registration-error + boundary-complexity proxies. Real CT slices are
calibration targets, not USCT.
- benchmark.mjs: 3-section report (synthetic / real region-level / governance);
headline separates speed from real fidelity. Real slices now classify as
exclude/researchOnly and stay out of headline metrics (abdomen~0.30).
- evidence:refresh (OpenRouter): grades modality evidence into docs/evidence/*.md
+ a candidate cache; promotion to the curated cache stays a reviewed step.
Live run graded acoustic USCT = C (research-only), MRI = B.
- CI gates (ciGates.test.ts + .github/workflows/metabiohacker-ci.yml): residual
invariant, pathology review forced, A/B-only claims, real-slice honesty gate.
23 metabiohacker tests + 12 Rust integration tests pass. ADR-0024 added.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01Mx4vKMfvsq5KBQgPRSoxM7
* feat(sonic_ct): method comparison vs BP/SART/Landweber on Shepp-Logan with RMSE/PSNR/SSIM
Bench reconstruction against recognised algorithms on a recognised target:
- shepp_logan.rs: standard 10-ellipse Shepp-Logan phantom -> speed map.
- reconstruction.rs: Method enum + reconstruct_speed_with; Landweber solver
(gradient descent on ‖As−t‖²) alongside backprojection (1 sweep) and SART.
- metrics.rs: standard image-quality metrics RMSE, PSNR (dB), SSIM.
- sonic_ct_methods bin -> docs/sonic-ct/METHOD-BENCHMARK.md (deterministic).
Measured: backprojection < SART < Landweber on every metric for both Shepp-Logan
and abdomen (abdomen RMSE 130→99→51 m/s, SSIM 0.22→0.60→0.92) at ~4/28/100 ms.
SART stays production default; Landweber is the higher-fidelity option. 2 new
tests; 14 integration tests pass; clippy clean. ADR-0025 added.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01Mx4vKMfvsq5KBQgPRSoxM7
* feat(metabiohacker): rigid translation registration for real-slice calibration
Replace the centroid-only proxy with registerByTranslation — finds the integer
offset that maximises predicted/target body-mask overlap Dice, returning the
offset, residual misalignment (errorPx), and aligned overlap. Gives the
domain-gap honesty gate a real registration estimate (landmark refinement is the
next step). +1 test (recovers a known offset; maximises overlap). 24 tests pass.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01Mx4vKMfvsq5KBQgPRSoxM7
* feat(sonic_ct): full-waveform inversion (FWI) — forward + adjoint-state gradient
The SOTA step beyond straight-ray TOF (ADR-0004 roadmap), as a dependency-free
2-D reference:
- fwi.rs: FDTD scalar-wave forward model (∂ₜ²p = κ∇²p + f), CFL-stable, damping
sponge; adjoint-state gradient ∂χ/∂κ = Σ_t λ ∇²p; gradient descent with
source/receiver-footprint muting, smoothing, and backtracking line search.
- Proven by the gold-standard adjoint-vs-finite-difference gradient check
(cosine > 0.85) + an inversion that cuts data misfit ≥15% and recovers a
centrally-concentrated velocity anomaly. 2 new tests; 23 Rust tests pass;
clippy clean.
- Honest scope: single-frequency, unregularised — frequency continuation,
regularisation, source encoding, and 3-D are the documented next steps; no
quantitative clinical recovery claimed. ADR-0026 added.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01Mx4vKMfvsq5KBQgPRSoxM7
* feat(sonic-ct): add FWI frequency continuation (multiscale inversion)
Add invert_multiscale + Stage to fwi.rs: chains low->high frequency FWI
stages with between-stage model smoothing to avoid cycle-skipping. Low
frequencies recover the smooth background first, keeping high-frequency
stages out of local minima.
Proven by a third FWI test: frequency continuation lowers the
inclusion-region error below single-scale FWI at matched iteration count
(deterministic). Adjoint-vs-FD gradient check and misfit-reduction tests
still pass. Updates ADR-0026.
Co-Authored-By: claude-flow <ruv@ruv.net>
Claude-Session: https://claude.ai/code/session_01Mx4vKMfvsq5KBQgPRSoxM7
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 90a1dc1 commit 7a79b74
139 files changed
Lines changed: 11839 additions & 0 deletions
File tree
- .github/workflows
- crates
- sonic-ct-wasm
- src
- sonic-ct
- src
- bin
- tests
- docs
- evidence
- sonic-ct
- adr
- screenshots
- examples/sonic-ct
- public
- models
- src
- hud
- optimizer
- scene
- test
- fixtures
- tools
- packages/metabiohacker
- src
- calibration
- evidence
- fusion
- graph
- ingest
- ledger
- output
- test
- tools
- scripts
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
| 3 | + | |
3 | 4 | | |
4 | 5 | | |
5 | 6 | | |
6 | 7 | | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
7 | 13 | | |
8 | 14 | | |
9 | 15 | | |
| |||
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
0 commit comments