An investigational, phone-first tuberculosis triage prototype that combines a guided cough recording with supported clinical inputs to help prioritize follow-up urgency — no X-ray machine, lab, or radiologist required.
Product Brief · Architecture · Design · Agent Guide
Jaga is a research prototype documented for symptomatic adults aged 18+, matching the available CODA TB evidence base. A community health worker captures a guided cough recording and supported clinical inputs. The system returns a research estimate and model-inspection artifacts.
The estimate may prioritize follow-up urgency, but it does not decide whether a symptomatic person receives testing. Every symptomatic participant is directed to confirmatory evaluation. Jaga does not diagnose or rule out tuberculosis.
Jaga is Indonesian for “to watch over / to guard.”
Tuberculosis remains the world's leading infectious-disease killer. WHO estimated 10.7 million incident cases in 2024 and 8.3 million notified diagnoses, leaving a gap of about 2.4 million people caused by both underdiagnosis and underreporting. Indonesia accounted for approximately 10% of global incident cases. Sources and permitted wording are maintained in the evidence register.
Jaga explores whether cough acoustics plus routinely available clinical information can support accessible research into TB triage. It does not replace microbiological confirmation, clinical judgment, or an approved screening programme.
Two co-equal, never-fused signals:
- Gema (cough + clinical): the browser records one guided cough. The Go gateway cleans the audio (DC-offset removal, 80 Hz high-pass, silence trim, peak-normalize), then a Rust pipeline resamples to 16 kHz mono and a Rust YAMNet (ONNX) service gates that the clip really is a cough — extracting just the detected cough segment (start/end) so only that slice is embedded, keeping compute cheap. A local WavLM Large (dynamic-int8 ONNX, runs in-process in Rust) produces the embedding on-device, with graceful degradation to the Fireworks embedding API if the local model is missing, errors, or exceeds the timeout. The embedding plus 12 demographic features feed a Rust XGBoost (ONNX Runtime) service, and the calibrated-model probability comes back with a relative urgency band. Gemma (Fireworks chat) writes the mandatory-next-step guidance around that number — it never invents or alters the probability, and every failure path falls back to deterministic bilingual copy.
- Prisma (digital CXR, separate): a Python worker reconstructs the
local_claheDenseNet121 checkpoint, runs CLAHE preprocessing, and reports its own estimate with its own metrics plus an optional Grad-CAM heatmap for model inspection, alongside a PennyLane quantum-kernel-SVM evaluation (4-qubitlightning.qubit, 98.3% accuracy / 1.00 ROC-AUC on PCA-4 DenseNet embeddings). Gema and Prisma scores are never combined.
| Capability | Behavior |
|---|---|
| Guided capture | Record a guided cough; the YAMNet gate rejects non-cough audio before inference |
| Clinical inputs | Collect only variables supported by the approved model contract |
| Research estimate | Gema returns the model probability and relative urgency band |
| Mandatory next step | Direct every symptomatic participant to confirmatory evaluation |
| Assistant | Gemma-backed guidance chat; deterministic copy on any model failure |
| Privacy | Process inputs transiently without request-body logging or patient-data persistence |
| Digital CXR (Prisma) | Separate estimate with separate metrics; never fused with Gema |
Six layers, real-time processing, powered by multimodal AI and AMD accelerated computing.
| Layer | Technology |
|---|---|
| Frontend | Next.js 15 · React 19 · TypeScript · Tailwind CSS 4 · shadcn/ui · Zustand · TanStack Query (PWA, served behind NGINX) |
| Backend & gateway | Go (API gateway) · Rust + Axum (model microservices) · Python + FastAPI (CXR worker) · NGINX (reverse proxy) |
| Audio DSP pipeline | Go DSP (DC-offset, 80 Hz high-pass, silence trim, peak-normalize) → Rust + hound (mono downmix, 16 kHz resample) |
| AI / ML | PyTorch (training) · ONNX Runtime (serving) · YAMNet (cough gate) · WavLM Large int8 (local embeddings, Fireworks fallback) · XGBoost (Gema) · DenseNet121 + CLAHE + PennyLane quantum-kernel SVM (Prisma) · Gemma via Fireworks/Featherless (guidance chat) |
| Data & storage | PostgreSQL · Redis · MinIO |
| Infra & quality | Docker Swarm (HA orchestration) · Vitest · Playwright · Zod |
| Training accelerator | AMD Instinct MI300X via AMD Developer Cloud (ROCm PyTorch) — see below |
- Training — AMD Instinct MI300X (AMD Developer Cloud). Both models were trained on the AMD Developer Cloud Jupyter environment (8-hour/day MI300X sessions) with ROCm PyTorch: the Gema cough detector/classifier (
GemmaTraining/— YAMNet-gated WavLM embeddings + XGBoost on CODA TB data) and the Prisma CXR model (PrismaTraining/— DenseNet121 + CLAHE, plus the PennyLane quantum-kernel-SVM evaluation). The trained artifacts ship in this repo and are what the services load at inference time. - Inference — local-first, with graceful degradation. YAMNet, WavLM int8, and XGBoost run locally in Rust/ONNX Runtime; DenseNet121 runs locally in Python. With the WavLM model in place, embeddings are produced entirely on-device; if it is missing, errors, or times out, the service degrades gracefully to a Fireworks embedding deployment so triage still works (the response reports which path ran via
embedding_source). Fireworks/Featherless also serves the Gemma guidance/orchestration chat that wraps the model output. Gemma on Fireworks is on-demand-deployment only — our hackathon-credit deployment was retired when the $50 allowance ran out, so the live demo currently serves the same Gemma family via Featherless (LLM_PROVIDER=featherless); the Fireworks code path is intact and works with any account's own deployment.
jaga/
├── AGENT.md # Agent entry point / doc router (start here)
├── README.md # This file
├── .agent/ # Agent-facing specification documents
│ ├── product-brief.md # Product vision, market, business model
│ ├── product-requirements.md # PRD: roles, features, acceptance, safety
│ ├── project-architecture.md # System architecture, data flow, diagram
│ ├── design-guidelines.md # Brand, color, type, motion, components
│ ├── data-evaluation-plan.md # Dataset, splits, metrics, evidence gates
│ ├── evidence-register.md # Single source of truth for all cited facts
│ └── context-dump.md # Full decision history and rationale
├── frontend/ # Next.js 15 PWA (React 19, TypeScript)
│ └── src/
│ ├── app/ # Route views: clinical, coughs, review, result, cxr, chat
│ ├── components/ # UI, layout, and common components
│ ├── features/ # Feature modules (capture, triage, assistant)
│ ├── services/ · store/ · hooks/ # API clients, Zustand stores, hooks
│ ├── locales/ # Bilingual (EN/ID) copy
│ └── styles/ # Design tokens, global CSS
├── backend/
│ ├── backendHandlers/ # Go API gateway
│ │ ├── cmd/server/ # Entry point
│ │ └── internal/ # audioPreprocess, triage, cxr, demographics,
│ │ # assistant, llm, spectrogram, server (router)
│ └── modelServerandTraining/
│ ├── GemmaServer/ # Gema serving (cough + clinical)
│ │ ├── rust/ # yamnetService · xgboostService · jagaAudio (Axum + ONNX)
│ │ └── models/ # YAMNet + XGBoost ONNX (WavLM downloaded, see below)
│ ├── GemmaTraining/ # Cough-model training (notebooks, data prep)
│ ├── PrismaServer/ # Python CXR worker (FastAPI)
│ │ └── app/ # main.py, model.py, gradcam.py, quantum.py
│ └── PrismaTraining/ # PyTorch CXR research framework (ROCm/MI300X)
├── contracts/openapi/ # OpenAPI contract (jaga-v1.yaml)
├── infra/ # Docker Swarm stack, NGINX, scripts (.sh + .ps1)
│ ├── docker-stack.yml # Service topology
│ ├── scripts/ # build · deploy · logs · remove · scale
│ └── healthcheck/ # Manual health probes
├── docs/ # Backend integration map, submission assets
└── run.ps1 # Windows one-shot: build + deploy + frontend dev
Model weights ship in the repository (all under GitHub's file-size limit): GemmaServer/models/ (YAMNet + XGBoost ONNX) and PrismaServer/app/models/local_clahe/checkpoints/best.pt (DenseNet121, 83 MB). The one exception is the WavLM int8 embedder (356 MB, over GitHub's 100 MB limit) — download it from Google Drive into GemmaServer/models/wavlm/wavlm_large_int8.onnx (see below) so embeddings run fully on-device. Without it, the service degrades to the Fireworks embedding fallback (requires FIREWORKS_API_KEY + FIREWORKS_MODEL).
-
Docker with Swarm available (Docker Desktop on macOS/Windows, Docker Engine on Linux). The deploy script runs
docker swarm initfor you on first use. -
WavLM weights (recommended — the local, on-device embedder; skip it only if you'll rely on the Fireworks embedding fallback). Download
wavlm_large_int8.onnx(356 MB) from Google Drive intobackend/modelServerandTraining/GemmaServer/models/wavlm/. Because the file is large, usegdown(handles Drive's confirmation page that plaincurlcannot):pip install gdown gdown 1O4uoKIUKnGPzNopkYlcqvO08TeS71-_h \ -O backend/modelServerandTraining/GemmaServer/models/wavlm/wavlm_large_int8.onnx
-
API key in
infra/.env(for the Gemma guidance chat only — models run locally):FEATHERLESS_API_KEY— the zero-deploy path for the assistant (Gemma chat,LLM_PROVIDER=featherless).FIREWORKS_API_KEY— optional: Gemma chat via your own on-demand Fireworks deployment (LLM_PROVIDER=fireworks), and/or the WavLM embedding fallback (also setFIREWORKS_MODEL) if you skip the local model download above.
-
Everything else (YAMNet, XGBoost, DenseNet121 weights) is already in the repo.
cd infra
cp .env.example .env # then fill in the API keys above
./scripts/build.sh # build all images locally
./scripts/deploy.sh # deploy the Swarm stack
docker stack services jaga # confirm all services report REPLICAS 1/1
./scripts/logs.sh # tail logs (or ./scripts/logs.sh go-api)
./scripts/remove.sh # tear down when doneEvery infra/scripts/*.sh has a .ps1 twin — no WSL required:
Set-Location infra
Copy-Item .env.example .env # then fill in the API keys above
.\scripts\build.ps1
.\scripts\deploy.ps1
docker stack services jaga
.\scripts\logs.ps1
.\scripts\remove.ps1Or use the one-shot script from the repo root, which creates .env, builds, deploys, and starts the frontend dev server:
.\run.ps1Use PowerShell 7 (pwsh) if available; Windows PowerShell 5.1 works but is less forgiving about redirected stderr from Docker.
curl http://127.0.0.1/health # gateway health via NGINX
./healthcheck/api.sh # manual probes (from infra/)
./healthcheck/prisma.sh http://127.0.0.1:8000/healthThe app is served at http://127.0.0.1/ (port configurable via NGINX_PUBLISHED_PORT).
| Method | Path | Purpose |
|---|---|---|
| GET | /health |
Gateway health |
| POST | /api/v1/demographics |
Validate clinical/demographic inputs |
| POST | /api/v1/audio/preprocess |
Audio cleanup (DC offset, high-pass, trim) |
| POST | /api/v1/triage |
Gema cough + clinical triage |
| POST | /api/v1/assistant/messages |
Gemma guidance chat |
| POST | /api/v1/cxr |
Prisma digital-CXR estimate (proxied) |
infra/README.md documents the full stack topology, scaling, health checks, and routing.
Segment, target, position. Jaga serves hospitals, primary-care clinics, and high-risk symptomatic individuals in resource-limited settings. The buyers are hospital administrators looking to optimize scarce testing resources, and the reach extends to impoverished or geographically isolated people who need a free, instant risk assessment. Jaga is positioned to reach symptomatic people early and prioritize who to send for confirmatory TB testing first — not as a definitive diagnostic tool.
Market sizing.
| Tier | Size | Definition |
|---|---|---|
| TAM | $22B | Global funding target for TB prevention, diagnosis, and treatment |
| SAM | $5.9B | Available TB funding in low- and middle-income countries (LMICs) |
| SOM | $590M | Indonesia B2B/B2C screening market — 3-year target |
Business model.
| Tier | Price | For |
|---|---|---|
| Public Screening | Free (ad-supported) | Individuals doing self-screening |
| Clinic License | $99–$199 / month | Clinics — unlimited triage |
| API & Enterprise | Roadmap | Programs, integrations, national deployments |
![]() Paulus Billy Design Engineer |
![]() Daffa Tarigan AI & Infrastructure |
![]() Keisha Putri Theanny Front-End |
![]() Mohammad Ezzeddin Pratama Back-End |
Kevin Fransisco Product Manager |
Released under the MIT License.
Jaga is an investigational research prototype, not a diagnostic device, cleared medical device, or substitute for confirmatory testing and clinical judgment. Do not use it to make real patient-care decisions.



