0
stars
2,371
commits
Python
primary language
Sep 8, 2026
updated
Active release baseline — verified 2026-08-12. The supported frontend gate is
npm run build; source lint is expected to have zero errors;npm audit --omit=devmust be clean. See the release evidence pack for the complete safety, documentation, and privileged-integration checklist. Historical counts elsewhere in this document are architectural context, not live service assertions.
An AI-powered spiritual guide rooted in the teachings of Sri Preethaji & Sri Krishnaji. Built with a 12-layer RAG pipeline, dual-level LightRAG knowledge graph, second-brain memory vault, real-time guardrails, and cross-platform native mobile & web UI.
Developer Navigation:
- Architecture & Developer Guide: docs/DEVELOPER_GUIDE.md & docs/COMPLETE_BACKEND_ARCHITECTURE.md
- Prioritized Backlog & System Status: docs/PRODUCT_OPPORTUNITIES.md (roadmap merged in as the "Roadmap — Execution Strategy" section)
- Operational Runbooks: docs/runbooks/ (
BENCHMARK_RUNBOOK.md,CREDENTIALS_GUIDE.md,STREAM_PROTOCOL.md)- Lessons Learned & Invariants: lessons.md & AGENTS.md
| Component | Technology | Port / Scope |
|---|---|---|
| Frontend | Vite React 18 + TailwindCSS + shadcn/ui + HashRouter | 80 (Docker) / 8080 (Local) |
| Mobile App | Capacitor 8 (com.askmukthiguru.app) iOS & Android | Native WebView |
| Backend | FastAPI (Async Python 3.12, 12-Layer RAG Pipeline) | 8000 |
| Vector DB | Qdrant (spiritual_wisdom: 89,053 points, second_brain_vault) | 6333 |
| Knowledge Graph | Neo4j 5.17 (LightRAG 7,601 concept & transformation arc nodes) | 7474 (HTTP) / 7687 (Bolt) |
| Caching & Memory | Redis 7 Alpine (Sliding TTL session cache & response cache) | 6379 |
| Auth & Database | Supabase Postgres (RLS enabled) + Supabase Auth (OAuth/Email) | Cloud / Local |
| Observability | OpenTelemetry + Jaeger Distributed Tracing | 16686 |
spiritual_wisdom): Ingested 89,053 items covering books, 450+ YouTube discourses, meditations, and lectures.scripts/ingest_lightrag_data.py directly scrolls Qdrant payloads with asyncio worker pools, fast LLM timeouts, and atomic .tmp -> .json checkpointing (data/lightrag_checkpoint.json).spiritual_wisdom_contextual.second_brain_vault): Multi-tenant collection in Qdrant indexed with user_id keyword filters. User notes live encrypted in Postgres (user_brain_nodes), vectors in Qdrant.classify_user_familiarity dynamically adapts response tone across 3 tiers:
EPHEMERAL_TTL = 900).scripts/ops/cleanup_inactive_user_data.py.DELETE /api/memory/reflections and POST /api/memory/forget.bge-reranker-v2-m3 (GPU/MPS) or mmarco-mMiniLMv2-L12-H384-v1 (CPU)./knowledge-graph for all visitors.com.askmukthiguru.app).HashRouter inside Capacitor WebView (https://localhost/) for seamless client-side routing.@capacitor/push-notifications -> FCM & APNs).com.askmukthiguru.app://auth-callback).| Command | Description |
|---|---|
make dev | Start local backend (start_local.sh) and frontend dev servers |
make test | Run backend unit and integration test suite |
make lint | Run Ruff linter on backend |
make format | Format code with Ruff |
make docker-up | Build and start full Docker stack |
make docker-rebuild-web | Rebuild and restart stateless frontend & backend services |
make docker-down | Stop all running Docker services |
make flush-cache | Clear Redis response cache and semantic caches |
Ensure Docker Desktop is running on macOS, then execute:
# Set Docker binary PATH and run docker compose via safe script (bypasses keychain issues)
cd backend && bash ../scripts/docker-safe.sh docker compose up -d --build
Access local endpoints:
To run services locally on host machine:
# 1. Start core infrastructure containers only (Qdrant, Neo4j, Redis)
cd backend && bash ../scripts/docker-safe.sh docker compose up -d qdrant neo4j redis
# 2. Run backend FastAPI server (in terminal 1)
cd backend
.venv/bin/uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
# 3. Run frontend Vite server (in terminal 2)
npm install
npm run dev
Note: backend/app/config.py automatically normalizes container hostnames (http://qdrant:6333 -> http://localhost:6333) when executing directly on host Python outside Docker.
To resume or execute full LightRAG knowledge graph ingestion directly from Qdrant:
CONCURRENCY_WORKERS=8 backend/.venv/bin/python scripts/ingest_lightrag_data.py
data/lightrag_checkpoint.json.data/lightrag_ingestion.log.To purge inactive user data (>365 days inactive):
backend/.venv/bin/python backend/scripts/ops/cleanup_inactive_user_data.py --days 365
askmukthiguru/
├── backend/ # FastAPI Python application
│ ├── app/ # Routes, config, dependencies, middleware
│ ├── rag/ # 12-layer RAG nodes, prompts, graph strategies
│ ├── services/ # Qdrant, Neo4j, LightRAG, Second Brain services
│ ├── scripts/ops/ # Automated maintenance & TTL cleanup scripts
│ └── tests/ # Pytest suite (edge cases, quality gate, nodes)
├── src/ # React 18 Frontend Application
│ ├── components/ # UI components (Chat, KG visualizer, Admin)
│ ├── pages/ # App page views
│ └── lib/ # API clients, backend URL resolvers
├── docs/ # Comprehensive Documentation
│ ├── runbooks/ # Operational runbooks (Benchmark, Credentials, AB Test)
│ ├── archive/ # Historical audit reports & completed plans
│ ├── COMPLETE_BACKEND_ARCHITECTURE.md
│ ├── DEVELOPER_GUIDE.md
│ └── PRODUCT_OPPORTUNITIES.md # UX/hardcoding audit + merged roadmap
├── scripts/ # High-level data ingestion & eval scripts
│ └── ingest_lightrag_data.py # High-throughput LightRAG Qdrant scroll script
├── handoff.md # Latest session status & operational handoff
├── lessons.md # Lessons learned & architectural invariants
└── Makefile # Developer command orchestrator
Populate key environment variables in backend/.env:
| Variable | Description | Example / Default |
|---|---|---|
LLM_PROVIDER | Active LLM provider (sarvam_cloud, openrouter, nim, ollama) | nim / sarvam_cloud |
OPENROUTER_API_KEY | Key for OpenRouter inference & LightRAG graph extraction | sk-or-v1-... |
OPENROUTER_PROVIDER_SORT | Optional server-side provider ordering (latency, throughput, or price); empty preserves normal OpenRouter load balancing | empty |
OPENROUTER_PREFERRED_MAX_LATENCY_P90 | Optional soft provider preference for p90 latency in seconds; requires provider sorting | 0 (disabled) |
OPENROUTER_PREFERRED_MIN_THROUGHPUT_P90 | Optional soft provider preference for p90 throughput in tokens/second; requires provider sorting | 0 (disabled) |
SARVAM_API_KEY | Key for Sarvam 30B Indian multilingual LLM & STT | sarvam-... |
FORWARDED_ALLOW_IPS | Non-wildcard proxy allowlist for Railway's start_railway.py (uvicorn forwarded_allow_ips; startup fails when missing or *). Not needed for docker compose (plain uvicorn). | 10.0.0.0/8 (Railway) |
NIM_API_KEY | Key for Nvidia NIM API catalog (low latency) | nvapi-... |
SUPABASE_URL | Supabase project URL | https://your-project.supabase.co |
SUPABASE_KEY | Supabase service-role key | eyJ... |
QDRANT_URL | Vector database endpoint | http://localhost:6333 |
NEO4J_URI | Neo4j Bolt protocol URI | bolt://localhost:7687 |
REDIS_URL | Redis cache URI | redis://localhost:6379/0 |
REDIS_CACHE_MAX_KEYS | Maximum new exact-query cache keys in the mukthiguru:cache:* namespace; 0 disables the ceiling | 10000 |
REDIS_CACHE_TELEMETRY_INTERVAL_SECONDS | Minimum interval between namespace cardinality/TTL scans | 60 (minimum 5) |
CELERY_QUEUES | Comma-separated allowlisted queues for a worker profile; use a maintenance-only profile only after queue/SLA measurement | ingestion,embedding,indexing,okf,memory |
CELERY_CONCURRENCY | Celery worker process concurrency, validated from 1 to 32 | 2 |
WEB_SEARCH_TIMEOUT_SECONDS | Maximum time for one live-search provider call before fail-open fallback | 12 (maximum 30) |
RAG_USE_HYDE | Global hypothetical-document generation switch; adds a provider round trip on eligible complex requests | true (runtime-compatible default) |
RAG_INDIC_USE_HYDE | Opt-in HyDE for non-English/Indic requests; keep off until held-out quality evidence justifies the added tail | false |
RAG_MAX_REWRITES | Global CRAG rewrite retry cap | 2 (runtime-compatible default) |
RAG_INDIC_MAX_REWRITES | Independent CRAG retry cap for non-English/Indic requests | 1 |
LATENCY_BENCHMARK_CACHE_DISABLED | Local-only benchmark switch that bypasses all application cache reads and writes; use only when measuring uncached latency | false |
RAG_RETRIEVAL_EXPANSION_SOFT_WAIT_SECONDS | Maximum post-primary-retrieval wait for optional LLM query expansion; slow planner work is cancelled and primary retrieval remains authoritative | 0.35 (maximum 5) |
The chat composer accepts text and office documents (.txt, Markdown, CSV/TSV, JSON, XML, HTML, YAML, DOCX, PPTX, XLSX), PDFs, images, audio, and video. Each selected file is sent to POST /api/chat/upload, where the backend applies a 10 MB per-file cap and 50 MB combined cap, extracts bounded evidence using PDF/OOXML text extraction, OCR, or local Whisper transcription, and returns an attachment_context value for the next chat turn. Upload bytes are not persisted or indexed automatically. The subsequent /api/chat or /api/chat/stream request carries that context separately from user_message; the RAG generation prompt marks it as untrusted evidence and shared caches/coalescing are bypassed or scoped by an attachment digest.
The upload path is intentionally an extraction MVP, not a corpus-ingestion shortcut. Durable indexing, page/frame citations, malware scanning, resumable uploads, and asynchronous job status remain separate production hardening work and require explicit design before enabling persistence.
Developed by Harshodai Kolluru. Built with AI pair-programming assistance (Anthropic Claude, Google Gemini, GitHub Copilot, and Lovable). All rights reserved.
useRequireAuth / useAdminGuard call supabase.auth.mfa.getAuthenticatorAssuranceLevel() on every session load and redirect to /auth/mfa when aal2 is required. MFAChallengePage falls back to verified TOTP factors from the session.require_aal2 dependency (backend/services/auth_service.py) + probe route GET /api/health/mfa (tested by backend/tests/test_aal2_dependency.py, 12 tests). Test auth backdoor honors X-Test-Aal header.supabase/migrations/20260728103548_85070891-f7bf-4835-94db-4246463b3813.sql (UPDATE WITH CHECK) + idempotent 20260730000000_verify_rls_with_check.sql.backend/scripts/verify_rls_policies.py (ephemeral Alice/Bob via Admin API, 12 probes) — runs nightly against prod via .github/workflows/nightly-rls.yml (set repo secrets SUPABASE_URL/SUPABASE_SERVICE_ROLE_KEY first).tests/e2e/rls-cross-user.spec.ts (UI deep-link isolation + REST probe).backend/scripts/verify_leaked_password_protection.py.backend/app/schemas/metrics.py (pydantic) ↔ src/lib/metricsSchema.ts (zod), parity tested by src/test/metricsSchema.test.ts.GET /api/metrics (auth, RLS-scoped client, anonymous → zeroed payload) consumed by src/hooks/useMetrics.ts (60s TTL cache, refetch on conversation:updated).backend/services/healing_course_service.py: assigns a healing course only on distress streaks — ≥2 consecutive turns, ≥3-of-5 frequency, escalating severity, or same SufferingSignal ≥2× in 24h; never duplicates an active course (user_course_progress).POST /api/healing-course/assign, POST /api/healing-course/progress.src/components/chat/HealingPathCard.tsx shows the card with dismissal and assignment.langhanam_voice_enabled=false by default; GURU_VOICE_MODE=prompt|adapter selects variant; benchmark backend/benchmarks/guru_voice_benchmark.py gates flipping the flag at ≥4.0/5.0 (needs a live LLM run). Reference voice: backend/services/guru_voice_langhanam.py (Langhanam transcript excerpt).1,198 commits
1,168 commits
3 commits
1 commits
Python
74.3%
TypeScript
19.8%
HTML
1.7%
PLpgSQL
1.3%
Shell
1.2%
0
stars
2,371
commits
Python
primary language
Sep 8, 2026
updated
Active release baseline — verified 2026-08-12. The supported frontend gate is
npm run build; source lint is expected to have zero errors;npm audit --omit=devmust be clean. See the release evidence pack for the complete safety, documentation, and privileged-integration checklist. Historical counts elsewhere in this document are architectural context, not live service assertions.
An AI-powered spiritual guide rooted in the teachings of Sri Preethaji & Sri Krishnaji. Built with a 12-layer RAG pipeline, dual-level LightRAG knowledge graph, second-brain memory vault, real-time guardrails, and cross-platform native mobile & web UI.
Developer Navigation:
- Architecture & Developer Guide: docs/DEVELOPER_GUIDE.md & docs/COMPLETE_BACKEND_ARCHITECTURE.md
- Prioritized Backlog & System Status: docs/PRODUCT_OPPORTUNITIES.md (roadmap merged in as the "Roadmap — Execution Strategy" section)
- Operational Runbooks: docs/runbooks/ (
BENCHMARK_RUNBOOK.md,CREDENTIALS_GUIDE.md,STREAM_PROTOCOL.md)- Lessons Learned & Invariants: lessons.md & AGENTS.md
| Component | Technology | Port / Scope |
|---|---|---|
| Frontend | Vite React 18 + TailwindCSS + shadcn/ui + HashRouter | 80 (Docker) / 8080 (Local) |
| Mobile App | Capacitor 8 (com.askmukthiguru.app) iOS & Android | Native WebView |
| Backend | FastAPI (Async Python 3.12, 12-Layer RAG Pipeline) | 8000 |
| Vector DB | Qdrant (spiritual_wisdom: 89,053 points, second_brain_vault) | 6333 |
| Knowledge Graph | Neo4j 5.17 (LightRAG 7,601 concept & transformation arc nodes) | 7474 (HTTP) / 7687 (Bolt) |
| Caching & Memory | Redis 7 Alpine (Sliding TTL session cache & response cache) | 6379 |
| Auth & Database | Supabase Postgres (RLS enabled) + Supabase Auth (OAuth/Email) | Cloud / Local |
| Observability | OpenTelemetry + Jaeger Distributed Tracing | 16686 |
spiritual_wisdom): Ingested 89,053 items covering books, 450+ YouTube discourses, meditations, and lectures.scripts/ingest_lightrag_data.py directly scrolls Qdrant payloads with asyncio worker pools, fast LLM timeouts, and atomic .tmp -> .json checkpointing (data/lightrag_checkpoint.json).spiritual_wisdom_contextual.second_brain_vault): Multi-tenant collection in Qdrant indexed with user_id keyword filters. User notes live encrypted in Postgres (user_brain_nodes), vectors in Qdrant.classify_user_familiarity dynamically adapts response tone across 3 tiers:
EPHEMERAL_TTL = 900).scripts/ops/cleanup_inactive_user_data.py.DELETE /api/memory/reflections and POST /api/memory/forget.bge-reranker-v2-m3 (GPU/MPS) or mmarco-mMiniLMv2-L12-H384-v1 (CPU)./knowledge-graph for all visitors.com.askmukthiguru.app).HashRouter inside Capacitor WebView (https://localhost/) for seamless client-side routing.@capacitor/push-notifications -> FCM & APNs).com.askmukthiguru.app://auth-callback).| Command | Description |
|---|---|
make dev | Start local backend (start_local.sh) and frontend dev servers |
make test | Run backend unit and integration test suite |
make lint | Run Ruff linter on backend |
make format | Format code with Ruff |
make docker-up | Build and start full Docker stack |
make docker-rebuild-web | Rebuild and restart stateless frontend & backend services |
make docker-down | Stop all running Docker services |
make flush-cache | Clear Redis response cache and semantic caches |
Ensure Docker Desktop is running on macOS, then execute:
# Set Docker binary PATH and run docker compose via safe script (bypasses keychain issues)
cd backend && bash ../scripts/docker-safe.sh docker compose up -d --build
Access local endpoints:
To run services locally on host machine:
# 1. Start core infrastructure containers only (Qdrant, Neo4j, Redis)
cd backend && bash ../scripts/docker-safe.sh docker compose up -d qdrant neo4j redis
# 2. Run backend FastAPI server (in terminal 1)
cd backend
.venv/bin/uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
# 3. Run frontend Vite server (in terminal 2)
npm install
npm run dev
Note: backend/app/config.py automatically normalizes container hostnames (http://qdrant:6333 -> http://localhost:6333) when executing directly on host Python outside Docker.
To resume or execute full LightRAG knowledge graph ingestion directly from Qdrant:
CONCURRENCY_WORKERS=8 backend/.venv/bin/python scripts/ingest_lightrag_data.py
data/lightrag_checkpoint.json.data/lightrag_ingestion.log.To purge inactive user data (>365 days inactive):
backend/.venv/bin/python backend/scripts/ops/cleanup_inactive_user_data.py --days 365
askmukthiguru/
├── backend/ # FastAPI Python application
│ ├── app/ # Routes, config, dependencies, middleware
│ ├── rag/ # 12-layer RAG nodes, prompts, graph strategies
│ ├── services/ # Qdrant, Neo4j, LightRAG, Second Brain services
│ ├── scripts/ops/ # Automated maintenance & TTL cleanup scripts
│ └── tests/ # Pytest suite (edge cases, quality gate, nodes)
├── src/ # React 18 Frontend Application
│ ├── components/ # UI components (Chat, KG visualizer, Admin)
│ ├── pages/ # App page views
│ └── lib/ # API clients, backend URL resolvers
├── docs/ # Comprehensive Documentation
│ ├── runbooks/ # Operational runbooks (Benchmark, Credentials, AB Test)
│ ├── archive/ # Historical audit reports & completed plans
│ ├── COMPLETE_BACKEND_ARCHITECTURE.md
│ ├── DEVELOPER_GUIDE.md
│ └── PRODUCT_OPPORTUNITIES.md # UX/hardcoding audit + merged roadmap
├── scripts/ # High-level data ingestion & eval scripts
│ └── ingest_lightrag_data.py # High-throughput LightRAG Qdrant scroll script
├── handoff.md # Latest session status & operational handoff
├── lessons.md # Lessons learned & architectural invariants
└── Makefile # Developer command orchestrator
Populate key environment variables in backend/.env:
| Variable | Description | Example / Default |
|---|---|---|
LLM_PROVIDER | Active LLM provider (sarvam_cloud, openrouter, nim, ollama) | nim / sarvam_cloud |
OPENROUTER_API_KEY | Key for OpenRouter inference & LightRAG graph extraction | sk-or-v1-... |
OPENROUTER_PROVIDER_SORT | Optional server-side provider ordering (latency, throughput, or price); empty preserves normal OpenRouter load balancing | empty |
OPENROUTER_PREFERRED_MAX_LATENCY_P90 | Optional soft provider preference for p90 latency in seconds; requires provider sorting | 0 (disabled) |
OPENROUTER_PREFERRED_MIN_THROUGHPUT_P90 | Optional soft provider preference for p90 throughput in tokens/second; requires provider sorting | 0 (disabled) |
SARVAM_API_KEY | Key for Sarvam 30B Indian multilingual LLM & STT | sarvam-... |
FORWARDED_ALLOW_IPS | Non-wildcard proxy allowlist for Railway's start_railway.py (uvicorn forwarded_allow_ips; startup fails when missing or *). Not needed for docker compose (plain uvicorn). | 10.0.0.0/8 (Railway) |
NIM_API_KEY | Key for Nvidia NIM API catalog (low latency) | nvapi-... |
SUPABASE_URL | Supabase project URL | https://your-project.supabase.co |
SUPABASE_KEY | Supabase service-role key | eyJ... |
QDRANT_URL | Vector database endpoint | http://localhost:6333 |
NEO4J_URI | Neo4j Bolt protocol URI | bolt://localhost:7687 |
REDIS_URL | Redis cache URI | redis://localhost:6379/0 |
REDIS_CACHE_MAX_KEYS | Maximum new exact-query cache keys in the mukthiguru:cache:* namespace; 0 disables the ceiling | 10000 |
REDIS_CACHE_TELEMETRY_INTERVAL_SECONDS | Minimum interval between namespace cardinality/TTL scans | 60 (minimum 5) |
CELERY_QUEUES | Comma-separated allowlisted queues for a worker profile; use a maintenance-only profile only after queue/SLA measurement | ingestion,embedding,indexing,okf,memory |
CELERY_CONCURRENCY | Celery worker process concurrency, validated from 1 to 32 | 2 |
WEB_SEARCH_TIMEOUT_SECONDS | Maximum time for one live-search provider call before fail-open fallback | 12 (maximum 30) |
RAG_USE_HYDE | Global hypothetical-document generation switch; adds a provider round trip on eligible complex requests | true (runtime-compatible default) |
RAG_INDIC_USE_HYDE | Opt-in HyDE for non-English/Indic requests; keep off until held-out quality evidence justifies the added tail | false |
RAG_MAX_REWRITES | Global CRAG rewrite retry cap | 2 (runtime-compatible default) |
RAG_INDIC_MAX_REWRITES | Independent CRAG retry cap for non-English/Indic requests | 1 |
LATENCY_BENCHMARK_CACHE_DISABLED | Local-only benchmark switch that bypasses all application cache reads and writes; use only when measuring uncached latency | false |
RAG_RETRIEVAL_EXPANSION_SOFT_WAIT_SECONDS | Maximum post-primary-retrieval wait for optional LLM query expansion; slow planner work is cancelled and primary retrieval remains authoritative | 0.35 (maximum 5) |
The chat composer accepts text and office documents (.txt, Markdown, CSV/TSV, JSON, XML, HTML, YAML, DOCX, PPTX, XLSX), PDFs, images, audio, and video. Each selected file is sent to POST /api/chat/upload, where the backend applies a 10 MB per-file cap and 50 MB combined cap, extracts bounded evidence using PDF/OOXML text extraction, OCR, or local Whisper transcription, and returns an attachment_context value for the next chat turn. Upload bytes are not persisted or indexed automatically. The subsequent /api/chat or /api/chat/stream request carries that context separately from user_message; the RAG generation prompt marks it as untrusted evidence and shared caches/coalescing are bypassed or scoped by an attachment digest.
The upload path is intentionally an extraction MVP, not a corpus-ingestion shortcut. Durable indexing, page/frame citations, malware scanning, resumable uploads, and asynchronous job status remain separate production hardening work and require explicit design before enabling persistence.
Developed by Harshodai Kolluru. Built with AI pair-programming assistance (Anthropic Claude, Google Gemini, GitHub Copilot, and Lovable). All rights reserved.
useRequireAuth / useAdminGuard call supabase.auth.mfa.getAuthenticatorAssuranceLevel() on every session load and redirect to /auth/mfa when aal2 is required. MFAChallengePage falls back to verified TOTP factors from the session.require_aal2 dependency (backend/services/auth_service.py) + probe route GET /api/health/mfa (tested by backend/tests/test_aal2_dependency.py, 12 tests). Test auth backdoor honors X-Test-Aal header.supabase/migrations/20260728103548_85070891-f7bf-4835-94db-4246463b3813.sql (UPDATE WITH CHECK) + idempotent 20260730000000_verify_rls_with_check.sql.backend/scripts/verify_rls_policies.py (ephemeral Alice/Bob via Admin API, 12 probes) — runs nightly against prod via .github/workflows/nightly-rls.yml (set repo secrets SUPABASE_URL/SUPABASE_SERVICE_ROLE_KEY first).tests/e2e/rls-cross-user.spec.ts (UI deep-link isolation + REST probe).backend/scripts/verify_leaked_password_protection.py.backend/app/schemas/metrics.py (pydantic) ↔ src/lib/metricsSchema.ts (zod), parity tested by src/test/metricsSchema.test.ts.GET /api/metrics (auth, RLS-scoped client, anonymous → zeroed payload) consumed by src/hooks/useMetrics.ts (60s TTL cache, refetch on conversation:updated).backend/services/healing_course_service.py: assigns a healing course only on distress streaks — ≥2 consecutive turns, ≥3-of-5 frequency, escalating severity, or same SufferingSignal ≥2× in 24h; never duplicates an active course (user_course_progress).POST /api/healing-course/assign, POST /api/healing-course/progress.src/components/chat/HealingPathCard.tsx shows the card with dismissal and assignment.langhanam_voice_enabled=false by default; GURU_VOICE_MODE=prompt|adapter selects variant; benchmark backend/benchmarks/guru_voice_benchmark.py gates flipping the flag at ≥4.0/5.0 (needs a live LLM run). Reference voice: backend/services/guru_voice_langhanam.py (Langhanam transcript excerpt).1,198 commits
1,168 commits
3 commits
1 commits
Python
74.3%
TypeScript
19.8%
HTML
1.7%
PLpgSQL
1.3%
Shell
1.2%