About

We built the boring one
on purpose

There is no shortage of AI tutors that will answer anything. The interesting problem was building one that refuses.

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.

Three constraints,
never negotiated

01

Grounded

Every factual claim originates in a retrieval result. The only extension permitted is a connection between documents that were both retrieved.

02

Invisible

Students should never see the machinery. No "according to the context provided" — in English or in Ukrainian.

03

Isolated

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.

what it runs on
LayerChoiceWhy this one
APINestJS 11 · TypeScript 5.7Structure the isolation rules can be enforced inside, not bolted onto
InterfaceReact 19Fast to iterate on where students actually meet the product
StoragePostgreSQL 15 + VectorChordVectors and relational data in one transaction, so deletes cannot half-happen
AgentLangGraph JSA state graph compiled per request, so the retry loop is explicit rather than implied
Jobs8 BullMQ queuesIngestion, topic mapping, summaries and analytics, each with its tenant passed in
ModelsAnthropic ClaudeHaiku, Sonnet or Opus per course; changing model is a dropdown, not a deploy

Who is behind it

Taras Kornichuk

Founder

Based inChernivtsi, Ukraine
Also runsWarmDevs
Educated atKyiv Polytechnic Institute
LanguagesUkrainian · English · Russian

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.

Contact

Tell us what you teach

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.

  • Procurement and security reviews — we will fill in your questionnaire and say plainly what we have not finished.
  • Pilot a single module before committing a department. That is the honest way to evaluate this.
what to send us
We run 6 modules, ~1,400 students, material in EN and UK. Can courses share nothing?
That is exactly the Institution shape — six tenants under one account, per-course model budgets, and nothing shared between them. Send the module list and we will map it out with you.
◈ a real reply, usually same day

Take control of your course

Upload your material, pick a model, share the link. Most courses are answering questions the same afternoon.