Dars
درسprivate repo2026 — nowOrenda Project · Taleemabad
A FastAPI service over Supabase Postgres, fronted by two published npm packages — @dars/client for the API and @dars/react for the components. Consuming teams integrate against an org API key rather than forking the codebase, which is the whole reason it exists as infrastructure instead of an app. Deployed on Railway; the image ships the Claude Agent SDK and the Claude Code CLI because the chapter planner invokes an agent at request time, not at build time.
Decisions
─ The planner was reverted before it was rebuilt
An LLM planner went in, came straight back out in favour of a deterministic placeholder, and was only then rebuilt properly as a standalone Chapter Planning Engine with explicit planning principles in the prompt. Shipping the intelligent version early would have meant debugging generation quality and scheduling logic at the same time.
─ Holidays and exams are inputs, not exceptions
Class paths are buffer-budgeted and re-plannable, so a two-week exam period changes the plan instead of invalidating it. Modelling lost time as a first-class input is what makes the plan survive a real school calendar.
─ Generation is per-slot and on demand
Lesson plans and formative assessments are generated for the slot a teacher is actually looking at, rather than batch-generating a term nobody reads. Cheaper, and it means a re-plan doesn't invalidate a pile of finished work.
─ Tenancy is an org API key, and that cut both ways
Per-org keys keep regional teams isolated, but a stale key surviving signup/login leaked across tenants until it was explicitly cleared on both paths.
What broke
- ✗uuid/text type mismatch at the DB boundary returning 500s on generate-lp
- ✗int grade codes reaching a parser that expected strings — another 500
- ✗NULL book_chapter_id meaning is_generated/status silently skipped slots
- ✗hydration race in the teacher-app auth gate: a hard refresh dropped the session
- ✗chapters marked broken-down as soon as they were dated, conflating dated with generated
FastAPISupabasePostgresTypeScriptReactRailwayPlaywrightBruno
Orenda Project × National Institute of Education
A Node service on the WhatsApp Cloud API: interactive list messages for navigation, WhatsApp Flows for multi-select quiz questions, and a web portal sharing the same session model. Media sits in Cloudflare R2 and is presigned inline so training videos play inside the thread instead of bouncing users to a browser. An Android wrapper handles Play distribution for the portal.
Decisions
─ One source of truth for training rules
Levels, attempt ceilings, pass marks and cooldowns resolve from a single place rather than being restated in the bot, the portal and the dashboard. Three copies of a pass mark is three chances to disagree with itself in front of a teacher.
─ A chat thread has to behave like a gradebook
Attempts, terminal states and cooldowns need to be strict even though the interface is a conversation. A level with no exam still needs a terminal state, or a teacher gets stuck in a lesson that never ends.
─ Certificates are minted on demand
PDFs are generated the moment they're earned and delivered in-thread, rather than pre-generated or emailed later. The reward has to land inside the same conversation that produced it.
─ Questions are pooled and varied per attempt
Fewer questions served per attempt, drawn varied from a pool — so a retake isn't a memory test of the first attempt.
What broke
- ✗/menu falling back to Meta's plain-text list instead of the interactive one
- ✗sessions lost on an Android force-close until state survived the lifecycle
- ✗"/" starting a fresh session instead of honouring the existing one
- ✗slash commands failing to end a reflective coaching conversation
- ✗exam captions counting the whole question pool rather than the served paper
- ✗R2 media 403ing in the dashboard until presigning moved inline
Node.jsWhatsApp Cloud APIWhatsApp FlowsCloudflare R2PostgresAndroid
Agent skill packs
private repo2026Orenda Project · Taleemabad
A skill pack that gives each team's coding agent real Slack and Notion access — per-team tokens, no shared credentials, roughly ten minutes from clone to working. Built on MCP and the Claude Agent SDK.
Decisions
─ Route point lookups instead of iterating
slack-search was rewritten so a direct lookup goes straight to the message rather than walking search results. About 20% fewer tool hops at equal correctness — the win came from removing a reason to guess, not from adding capability.
─ Per-team tokens over a central credential
Every team holds its own token. Slower to set up once, but it removes the shared secret and the person who owns it from the critical path.
─ Label placement is a solvable problem
The worldmap skill de-collides overlapping labels and picks label contrast per region automatically, so output is legible without a human nudging text boxes.
What broke
- ✗labels colliding into illegible stacks before de-collision existed
- ✗fixed label colours disappearing against dark regions
Claude Agent SDKMCPPythonSlack APINotion API
EasyDost data platform
private repo2023EFT
The data side of a customer-messaging product: a scheduled DynamoDB → RDS ETL, a serverless function extracting parts-of-speech and named entities from message text, a Jupyter-based analysis layer over the result, and a serverless websocket endpoint feeding realtime WhatsApp into a support inbox.
Decisions
─ Extraction as a separate serverless function
POS and NER ran as their own endpoint rather than inside the pipeline, so language-model work could fail, retry and be redeployed without touching the ETL.
─ Websockets for the inbox, not polling
Support agents needed messages to arrive, not to be fetched. A serverless websocket endpoint kept that realtime without a server to babysit.
What broke
- ✗idempotency: reruns double-writing into RDS before the pipeline was made safe to repeat
PythonDynamoDBRDSspaCyWebSocketsJupyter
Orchestration harness
private repo2026A Slack + Notion + GitHub harness that runs my own projects. It provisions its own Notion database schema on setup, then reconciles issues, agent runs and status back to a single board. Slack is the control surface, GitHub is the record.
Decisions
─ Provision the schema, don't document it
Setup creates the full Notion database schema itself. A README describing the columns you're supposed to add by hand is a README that goes stale in a week.
ShellNotion APISlack APIGitHub API