Ed-tech platform for deep CS fundamentals — 8 courses, React 18 + FastAPI rewrite,
RAG-powered AI assistant with hybrid retrieval. Razorpay payments, Firebase video streaming.
All 8 courses, tracks, and pricing live in a local JS file (tracks.js). Browsing triggers zero network calls — instant page loads, deployable to any CDN. API is only called at purchase or AI chat. This makes the browse experience feel native.
tracks.jsTanStack QueryCDN-deployable
Payments Security
Razorpay secret never leaves FastAPI
Order creation happens server-side only — FastAPI receives the amount, creates the Razorpay order, returns only the order_id and public key_id to the browser. The secret key never touches the client. Prices are stored in paise (integer) to avoid float precision issues.
FastAPIRazorpaypaise integers
RAG Design
pgvector with HNSW indexing
Vectors stored in PostgreSQL via pgvector extension with HNSW index — O(log N) approximate nearest neighbour search. Hybrid retrieval combines HNSW semantic search with BM25 lexical scoring. Score gate at 0.15 — below threshold the LLM is never called, preventing hallucination and saving cost.
pure Pythoncosine similarityFAISS-ready
RAG Quality
Hybrid re-ranking: semantic + Jaccard lexical
After cosine search returns top 8, _rank_matches() re-scores each with both semantic similarity (weight 1.0) and Jaccard lexical overlap (stop-word filtered). Per-chunk score is max(semantic, lexical) — ensures exact keyword matches surface even when embeddings drift.
Jaccardstop-word filtertop 5 after rerank
AI Safety
Gate at 0.15 — no LLM call below threshold
If no chunk scores ≥ 0.15, the system returns a canned "I don't have enough context" message without touching GPT-4.1-mini. This prevents hallucination on out-of-domain questions, saves API cost, and keeps the assistant honest about what it knows.
threshold gateretrieval-gatedcost control
Scalability Path
localStorage → Firestore production path
hasCourse(id) checks localStorage in the MVP — instant, no network call. The production path is Firestore arrayUnion per uid on successful payment. This swap is isolated to a single hook. Firebase Auth Google Sign-In replaces the current localStorage session at the same boundary.
localStorage MVPFirestoreFirebase Auth
Sovereign AI Layer — Hermes + GEPA + RAGAS
Agent Runtime
Hermes — sovereign tutor agent
The tutor runs on Hermes v0.18.2: SOUL.md identity (hashed into every audit row), ReAct agent loop, HindSight session-spanning memory, MCP tools (search_course_content, generate_notes). Sovereign inference on Ollama/vLLM — generation never leaves the machine. Production routes all traffic through the Hermes agent loop.
Hermes v0.18.2SOUL.mdHindSightMCP
Self-Evolution
GEPA — reflective prompt evolution
Offline loop: eval current SOUL on test set → LLM reflects on 3 weakest cases → proposes improved SOUL → re-eval candidate → Pareto gate (avg improves AND no case regresses below 2) → human approves via API → apply with .bak rollback. Every evolved SOUL is SHA-fingerprinted in the audit log — tamper-evident self-improvement under human oversight. Never runs during a live chat.
GEPAPareto gateHITL approveaudit hash
RAG Evaluation
RAGAS — sovereign quality measurement
RAGAS 0.2.14 scores the tutor on faithfulness (are the answer's claims supported by retrieved context?) and LLM context precision (were retrieved chunks useful?). The judge is pointed at the local model — no external calls. Feeds the same grounding signal GEPA optimises. Runs serially on the local model (parallel judge calls would saturate one GPU).
Design rule: agent when the AI decides its next move; workflow when every step is known in advance. Hermes handles the open-ended tutor (ReAct loop). LangGraph handles QuizMe and artifact generation (plan → HITL interrupt → generate → loop → summarize, with MemorySaver checkpointer for durable suspend/resume). No single framework forced on everything.
HermesLangGraph 1.2.9MemorySaverinterrupt
Governance
EU-AI-Act audit + GDPR erasure
Audit row written before every inference: student, question, model, provider, SOUL hash. The hash makes the agent's identity tamper-evident — you can prove which SOUL answered. GDPR: GET /api/hermes/memory/{id} shows what's stored; DELETE erases it. Grounding is enforced in code — below threshold 0.45 the model is never called (deterministic, not model-trust).
EU-AI-Act auditSOUL hashGDPRthreshold 0.45
Sovereign Inference
Ollama (dev) → vLLM on GPU (prod)
Both are OpenAI-compatible endpoints — dev→prod is a base_url change. Dev model: qwen2.5:3b. Generation is 100% local. The one remaining external call: retrieval embeddings still use OpenAI text-embedding-3-small (the question leaves as an embedding vector). Closing this is a one-file swap to a local embedder (e.g. nomic-embed-text).