Grounded
Every factual claim originates in a retrieval result. The only extension permitted is a connection between documents that were both retrieved.
A lecturer we know put her course notes into a general chatbot and asked it a question from her own week 4. It gave a confident, fluent, well-structured answer that contradicted the thing she had spent an hour teaching. Not wrongly, exactly — it was a defensible position from somewhere else in the literature. It just was not her course.
That is the failure that matters in education. A student cannot tell the difference between what you taught and what sounds like something you might have taught. And once they cannot tell, the assistant is worse than nothing, because it is confidently undoing the work.
So the constraint came first and the product was built around it: a factual claim must originate in a passage retrieved from material the instructor uploaded. Not "should prefer". Must. Everything else here — the retry loop, the topic mapping, the tenant isolation, the blocklist of phrases that leak the plumbing — exists to make that one rule survive contact with real students.
Every factual claim originates in a retrieval result. The only extension permitted is a connection between documents that were both retrieved.
Students should never see the machinery. No "according to the context provided" — in English or in Ukrainian.
Every read, write, job and log is scoped to one course. A leak is a critical defect, and we treat it as one.
These are numbered because they are ranked. When two of them pull against each other, the lower number wins.
| Layer | Choice | Why this one |
|---|---|---|
| API | NestJS 11 · TypeScript 5.7 | Structure the isolation rules can be enforced inside, not bolted onto |
| Interface | React 19 | Fast to iterate on where students actually meet the product |
| Storage | PostgreSQL 15 + VectorChord | Vectors and relational data in one transaction, so deletes cannot half-happen |
| Agent | LangGraph JS | A state graph compiled per request, so the retry loop is explicit rather than implied |
| Jobs | 8 BullMQ queues | Ingestion, topic mapping, summaries and analytics, each with its tenant passed in |
| Models | Anthropic Claude | Haiku, Sonnet or Opus per course; changing model is a dropdown, not a deploy |
Taras Kornichuk
Founder
Taras has spent his career building for the web — a decade of design and front-end work, most recently leading Webflow builds for product companies including ClickCease, MindBody, IndieFlow, QC Immigration and Panax. Handy Partners came out of that same instinct: take something people are doing badly by hand and make the machine do the boring part properly.
He works from Chernivtsi and also runs WarmDevs. He writes publicly about development practice, hiring, and what AI-assisted building actually changes about the work — which is roughly the argument this product makes in software form.
If you are weighing this for a faculty, or you have a security question that the security page did not answer, write to us. A person replies.
Upload your material, pick a model, share the link. Most courses are answering questions the same afternoon.