Built in 24 hours at the ** Hackathon** by a team of 4, orchestrated with Claude.
Live demo: https://artha-eta.vercel.app Demo personas: Riya · Mr. Sharma · Arjun & Priya
Every existing app — Groww, Tickertape, INDmoney — shows beginners data. Artha shows them reasoning. Every recommendation is traceable to a deterministic engine, every assumption is on screen, every 20-year outcome is Monte-Carlo simulated before you commit a rupee.
We are not SEBI-registered, do not execute trades, and do not collect money. Same posture as Zerodha Varsity: planning + education, period.
A direct-talk landing page. No "10x your money" — just the thesis.
Eleven structured profile signals + at least one goal, extracted from a free-form conversation. Right pane fills in real time as the LLM emits structured tool calls. No questionnaires.
Goal → Profile → Asset sleeves → Concrete instruments, laid out on a @xyflow/react
canvas. Each node is the output of a deterministic engine — click any edge to
see the inputs that produced it.
Public page documenting the deterministic core ↔ narrative shell split, ranking weights, and the four "transfer patterns" (insurance, credit, wealth, regulatory) the same architecture extends to.
-
Deterministic core, narrative shell. Every financial number is computed by pure TypeScript in
src/lib/engine/*. The LLM only translates pre-computed numbers into language. It is never asked to calculate, decide, or invent fund names, returns, or percentages. -
Glass box, not black box. Every recommendation surfaces its full reasoning chain on click. Every fund card includes a "Why NOT this fund" counter-section and a TER-vs-regular commission disclosure.
-
Simulate before commit. 10,000-iteration block-bootstrap Monte Carlo against real AMFI NAV history, running in a Web Worker so the UI never blocks. The simulation is the product.
| Layer | Choice | Why |
|---|---|---|
| Framework | Next.js 16 (App Router, Turbopack) | RSC + streaming + edge-deployable |
| Language | TypeScript strict | No any, no exceptions |
| UI | Tailwind v4 + shadcn/ui + Framer Motion | Minimal, dark-first |
| Spatial canvas | @xyflow/react | Goal → instrument graph, dagre layout |
| Charts | Recharts + D3 (Monte Carlo only) | Boring works |
| LLM | Vercel AI SDK (provider-agnostic) | Default OpenAI GPT-4o, switchable to Claude/Gemini via env |
| DB | Supabase Postgres + pgvector | NAV history, sessions, chat memory |
| Sim engine | Web Worker + seeded mulberry32 RNG | 10k iterations off the main thread, reproducible |
| @react-pdf/renderer | 8-page Investment Policy Statement | |
| Region | Vercel bom1 (Mumbai) |
Latency for Indian users |
src/
├── lib/engine/ # DETERMINISTIC core. Pure TS. NO LLM imports allowed.
│ ├── profile.ts # Risk capacity vs tolerance scoring
│ ├── allocation.ts # Asset sleeve weights from profile + goals
│ ├── inflation.ts # Future-value goal targets
│ ├── selector.ts # AMFI fund picker, TER-aware
│ ├── ranking.ts # Weighted score with @no-llm-imports header
│ └── simulator.ts # Block-bootstrap Monte Carlo
├── lib/llm/ # Provider-agnostic LLM wrappers (always go through index.ts)
├── app/api/ # Route handlers — streaming where it matters
│ ├── onboarding/chat/ # Goal Archaeology agent
│ ├── plan/create/ # Onboarding → DB pipeline (this turns the chat into a session_id)
│ ├── portfolio/build/ # Profile + goals → allocation + instruments
│ ├── simulation/run/ # 10k Monte Carlo, persists to Supabase
│ ├── explain/ # Streamed natural-language reasoning
│ ├── ips/generate/ # Investment Policy Statement PDF
│ ├── firewall/upload/ # Behavior Firewall video → Supabase Storage
│ └── copilot/chat/ # pgvector-backed Q&A
├── workers/ # Web Workers (simulator off main thread)
└── app/{landing,onboarding,plan,architecture}/
public/
├── personas/ # 3 demo personas (riya, sharma, arjun-priya)
└── cache/ # Pre-baked PlanData JSON — stage demo fallback
supabase/migrations/ # 0001..0005 — atomic, reversible
scripts/
├── ingest-amfi.ts # AMFI scheme master loader
├── ingest-nav-history.ts
├── cache-personas.ts # Builds public/cache/{persona}.json + persists DB
└── deploy-vercel.sh # One-shot prod deploy helper
- Risk Capacity vs Risk Tolerance — two different scores. Capacity = how much loss your situation can absorb. Tolerance = how much your psychology can. The gap is the dangerous zone where beginners get hurt.
- Goal Archaeology — conversational onboarding that extracts structured goal data from unstructured life narrative. No multiple-choice forms.
- Glass-Box Recommendation — every fund card includes (1) reasoning chain, (2) "why not" counter-section, (3) TER vs regular-plan commission disclosure.
- Block Bootstrap Monte Carlo — samples blocks of historical monthly returns rather than assuming Geometric Brownian Motion. Honest under fat tails.
- SEBI Mode — UI toggle that re-renders any plan in SEBI-RIA compliance document format. Demonstrates regulatory awareness without claiming the licence.
- Behavior Firewall — user records a video to their future self at onboarding. Replayed before any "sell" action during a market drawdown. Ulysses contract pattern.
- Investment Policy Statement (IPS) — legal-grade PDF that real SEBI-RIAs charge ₹15,000 to produce. We generate it in 90 seconds.
pnpm install
cp .env.example .env.local # fill OPENAI_API_KEY + Supabase keys
pnpm ingest:amfi # one-time AMFI scheme master
pnpm ingest:nav # one-time NAV history (~30 min)
pnpm cache:personas # bake demo fallback JSON
pnpm dev # http://localhost:3000bash scripts/deploy-vercel.shProduction targets bom1 (Mumbai). Per-route maxDuration is configured in
vercel.json (60s for simulation + IPS, 30s for chat routes).
Logged in CLAUDE.md under Post-Hackathon Ideas:
- Signed URLs for private firewall-video bucket
- Real pgvector kNN RPC for chat memory (currently recency-fallback)
- Inngest drawdown trigger → behavior firewall replay
- Auto-regenerate Supabase types via
supabase gen types - Worker progress events for true % bar (currently start/end only)
- LLM-narrated cache for 0-latency stage demo





