← back to work
case study · service design

The Human platform: scheduling, classrooms, records, and billing for four kinds of people.

Designed for my own tutoring practice, built from March 2026, live with families since mid-June.

A student’s board, with one assignment opened.
Client Human, the bilingual tutoring practice I founded and run · its families and teachers
Sector Education, tutoring services
My Role Founder; service designer; sole builder-operator
Team Solo, built and operated
Duration March 2026–present; live since mid-June 2026
Methods Service blueprinting, role-based access design, self-hosted systems architecture, AI-assisted workflow with a human approval gate, adversarial security audit
Outputs A live self-hosted platform: four role surfaces, AI-drafted lesson records under teacher approval
Permissions My own practice, soft-launched to real families · live at forhuman.ca

Classes ran on Whereby; parents were on three different chat apps.

Six disconnected apps, billing reconciled by hand, records about minors on third-party clouds.

Human is the small tutoring practice I run, and it existed long before its platform did, running the way small practices do: on whatever is closest to hand. Nothing connected, and nothing was bilingual by design, though most of these parents think in Mandarin.

The six services the practice ran on before the platform, and what each one cost
what it didwhere it livedwhat it cost
the class itselfWherebyA lesson could end and leave no record anywhere.
schedulingGoogle CalendarA reschedule meant renegotiating across whichever threads were open.
filesGoogle DriveRecords about minors on a third-party cloud chosen for convenience.
talking to parentsWeChat · WhatsApp · iMessageEvery family on a different app, and nothing bilingual by design.
getting paide-Transfer · WeChat PayMe at month end, matching payments against a calendar by hand.
knowing how a student is doingmemoryAn answer composed from recall, in English, in whatever thread was open.
Before The right-hand column is the actual brief: not that six apps are untidy, but six specific failures a family could feel.

Underneath sat a harder constraint. I wanted AI in this service, because the clerical load on a solo teacher is exactly what a machine should carry, and I was not willing to let a machine speak to a child unsupervised. In March 2026 I stopped patching and started designing.

My role

I founded Human, I teach in it, and I designed and built the platform, so whoever specified the teacher gate also works behind it on a Tuesday night.

A parent and a teacher sign into the same address and land in different rooms.

One sign-on, four roles, and load-bearing walls between the rooms.

The service model starts from who is asking, and a parent's version is the shortest: is my kid okay, and what am I paying for. A student never sees billing, a parent never sees another family, a teacher sees their own students and no one else’s, and those boundaries are checked on every request rather than drawn in the interface.

Each account keeps its own way of reading, remembered per person on every device: text scale, high contrast, reduced motion, a dyslexia-friendly typeface. The family surfaces target WCAG 2.2 AA.

admin
Admin dashboard: student, teacher and session counts, an empty day, a needs-attention panel holding one overdue task, recent enrolments, and the full practice navigation down the side.
teacher
Teacher dashboard: today's date and one session scheduled, a list of calendar additions a family has sent in, a session to review, a student picker beside an open-classroom button, and the day's class card with its join link.
student
Student dashboard: a greeting, a level band naming the writer they are becoming, the next class time, an open-classroom button, and to-do and in-progress panels; no billing anywhere.
parent
Parent dashboard: a greeting, a row of section tabs, the next class time with a reschedule request, and their own child's grade-level band and counts; one child only.
Four rooms Every dashboard is scoped to its role, and everyone pictured here is fictional.
The parent room, full width 1 screen
The parent's skills view: six named English skills split into four at or above grade level and two approaching it, each with a band and a progress dot row, above a growth line reading moving toward grade level.
The answer to it Named skills against grade level, and a line with a direction. The dots place a skill in its band; a parent sees no score and no ranking.

Follow one family from the welcome message to the day everything is erased.

A family's whole arc, welcome message to erasure, fits on one blueprint.

Onboarding is eight steps that run as one, in order, the same way every time.

1 & 2

Accounts created for every member of the household, and the calendar feed wired up.

3 & 4

The rate and the session pack set; the recurring schedule seeded from them.

5 & 6

The family’s file folder and workspace opened.

7 & 8

A welcome sent, in both languages, in the same breath.

the admin’s part

Checking the details, then pressing start. The order never varies, which is the point.

Eight steps, one action The admin here is also the teacher, and an evening spent copying names between systems is not spent on a lesson.

From there the rhythm is weekly. The schedule recurs on an open calendar standard, so lessons appear in whatever calendar app a household trusts, and a reschedule is a request with an approval queue rather than a negotiation across three chat threads. On class day the student knocks at a lobby, and there is no other way into a live classroom.

And when a family leaves, the platform is built to forget them. One erasure request cascades through every stack that ever held their data. PIPEDA grants families that right; this service draws it as a step on the blueprint like any other. I have run the cascade live and checked what it left behind.

a person acts the system carries it the teacher decides
onboardingeight steps, one run
schedulingthe weekly rhythm
live classlobby, knock, admit
lesson recordsa teacher signs off
billingday 28 of the cycle
leavingthe right to be forgotten
student
sets a password, has a look around
sees the week’s lessons
lands in the lobby and knocks
finds new steps on their board
parent
fills in the family’s details
asks to move a lesson
gets the invoice, pays it
asks the service to forget them
teacher
lets the student in and teaches
approves, edits, or throws out the draft
line of visibility
admin
checks the details, starts the eight steps
sets the recurring schedule, approves changes
checks the numbers, records the payment
runs the erasure, checks what is left
system
accounts, calendar, folders; a welcome in both languages
updates calendars and notices on its own
holds the lobby; records the lesson
turns the recording into a transcript and a draft
builds the invoice from the month’s lessons
the cascade clears every stack, invoices included

→ scroll the lifecycle sideways on a narrow screen

Lifecycle Four lanes of people and one of systems, onboarding through erasure. Departure is on the blueprint because it is part of the service.

Between the AI and the student, there is always a teacher.

A local model drafts the next steps; a teacher approves, edits or rejects each one. Nothing reaches a family unread.

Every lesson ends with the same question: what should this student work on before next time? Here a machine answers first. The recording becomes a transcript, a local model reads it, and out come drafted action items.

The student sees none of this. A draft exists in exactly one place, the teacher’s review queue, where the teacher signs off on it or it does not go out. Approval is the only door. An edit keeps the AI’s original wording beside the final version, so the gap between what the machine heard and what the teacher meant stays on the record. A rejection leaves no trace the student can see.

The rule is that strict because the practice sells a teaching relationship: someone who knows this student and catches what a transcript flattens. The AI makes the record cheap to produce. The teacher makes it true.

AI draftsa local model reads the transcript
teacher reviewsapprove, edit, or reject
if rejected, the student never sees it
student’s boardonly approved items land
The teacher's homework-drafts queue: one student with two pending items, each dated to the session it came from, tagged AI draft, and waiting to be approved, edited, or rejected.
The gate Dashed strokes are the machine’s draft, solid the teacher’s decision. In the queue a draft becomes a lesson record or quietly stops existing.
Where AI enters, and the six refusals 1 map, 1 table
the machine, acting on its own a person has to say yes
inputs
what the ai does
the record
the gate
where it lands
self-hosted: the models on one machine, the record on the other. no third-party service, no api key, no training on student data.
A classroom recordingone track per person, or one for the room if that fails
A transcript, then what happened in classskills, works, tasks, a recapwhisper large-v3, then qwen3.5:4b
written down and marked pending; a family sees none of it
a teacher approves, edits, or throws it out
the student’s agenda and the parent’s feed
Live room audiowhile the class is happening
Live captionsas the words are saidwhisper small.en, on the cpu
never written down
never waits; there is nothing drafted to approve
the classroom, live
An uploaded documenthomework, a worksheet, a report card
What this document isa summary and the factsqwen3.5:4b vision
held against the class, pending
a teacher approves it
the teacher’s agenda
A teacher’s voice noteheld down and dictated after class
The note, written downnever waits for the gpuwhisper small, on the cpu
held against the class, pending
the teacher who dictated it
their own agenda
The last approved classand the student’s skills, goals and open tasks
A plan for the next classit never supersedes a plan a teacher wroteqwen3.5:4b
pending, beside the plan it does not replace
a teacher approves it
the teacher’s agenda, pre-drafted
A recap a teacher acceptedin English, already through the gate
The recap in Chinesetraditional; simplified derived from itqwen3.5:4b
held with the English it came from
approved before translation, or never translated
the parent’s feed

→ scroll the map sideways on a narrow screen

the full board, with the trigger weights and the connectors this grid straightens out ↓
How AI is used in the Human platform A five-column data-flow map. Inputs on the left feed six AI jobs running on self-hosted hardware; their output is written to a single record, passes through a teacher-review gate, and only then reaches a parent, a student or a teacher. Live captions are the one output that bypasses the gate. current state AI in the Human platform: what the models are given, what they produce, and where a person has to say yes human, an education collective · 1:1 and small-group tutoring · sourced to the running system: human-pipeline, human-mcp, human-dashboard trigger automatic: an event fires it a teacher or the operator asks waits for a teacher to approve compute + NAS, self-hosted: the models on one machine, the record on the other. no third-party ai service, no api key, no training on student data two engines: faster-whisper (speech → text) · qwen3.5:4b (everything else). they share one 8 GB gpu, one job at a time; the small whispers run on cpu inputs what the ai does the record the gate where it lands Classroom recording one track per person, or one for the room if that fails Live room audio while the class is happening An uploaded document homework · worksheet · report card A teacher’s voice note held down and dictated after class The student’s history past classes · skills · goals · open tasks An approved recap english a teacher has already accepted Live captions whisper small.en · cpu · live, while it’s said The transcript whisper large-v3 · gpu · who said what, when What happened in class qwen3.5:4b · from the transcript above → skills, works, tasks, a recap What this document is qwen3.5:4b vision · a summary and the facts The voice note, written down whisper small · cpu · never waits for the gpu A plan for the next class qwen3.5:4b · from the last approved class A progress account qwen3.5:4b · a term of classes, for a parent The recap in Chinese qwen3.5:4b · traditional; simplified derived The record human-mcp · postgres · every class, skill, task and plan. a family sees none of it until the status flips to approved Off the record private windows are cut from the parent’s copy; the teacher’s keeps everything Teacher review nothing reaches a family until a person accepts it The classroom, live captions, as they are spoken The parent’s feed a recap, in english or chinese The student’s agenda today’s plan · checklist · tasks The teacher’s agenda the next class, pre-drafted cut for the parent everything, still pending never waits for approval note: the student’s history is read back out of the record itself, and that loop is omitted here for focus, as is the link from the transcript into what happened in class (stated in the node instead). the plan for the next class has three triggers rather than the one drawn: an approval, a teacher’s request, and a nightly sweep. this board maps only the ai that touches student data.
Where the AI is, and is not Six jobs, all on hardware in the building. Live captions are the one output with no teacher between, because speech as it happens has nothing to approve.
What the platform’s AI never does, and what stops it
the refusalwhere it is enforced
Never reads a journalA student’s journal never enters a model’s input, and a parent cannot read one either. Both walls live in the query layer, so neither is a setting anybody can change. not one reference in any prompt or input builder
Never transcribes a guestAnonymous visitors are skipped, because nobody asked them to consent. Only signed-in participants are transcribed. should_transcribe_identity(), in the live agent and the recorder both
Never sends what a teacher has not approvedThe translator refuses a session a teacher has not accepted. Rendering unapproved words in a language a parent cannot proofread is worse than sending nothing. processing_status must read approved before a word is sent
Never overwrites a teacherA plan a teacher approved, or wrote by hand, is never superseded by a drafted one. Not by the nightly sweep, and not by the teacher’s own request. should_generate_plan(), plan_freshness.py
Never reaches a vendorNo third-party AI service ever sees a student, and no student data leaves for training. both engines local; there is no model api key to leak
Never decidesThe models propose; a person accepts, edits, or throws it away. Nothing here runs to a conclusion on its own. every output lands as a draft, marked pending
Six refusals A refusal in a policy document is a preference. The same refusal in a query layer is a property of the service.

Parents read this platform in the language they worry in.

Chinese sits beside English in the data model, so every notice to a parent arrives in both scripts.

Before the platform, everything official arrived in English anyway, and the nuance travelled by chat app when it travelled at all. Now Chinese fields sit beside the English ones in the data model, written together at the source, so a reschedule, an invoice or a welcome says itself in both scripts. Staff surfaces stay in English.

The difference is small and weekly. A schedule change reads the way the household speaks, and an invoice explains itself without a translation app.

parent · English
The parent view in English: the next class with reschedule and all-classes links, the mastery band with its stage labels, and the term counts.
parent · 繁體中文
The same parent view in Traditional Chinese: the next class, the mastery band with its stage labels, and the term counts, all translated, with the layout unchanged field for field.
Two scripts Both are written into the record at the source, and a Simplified conversion is generated from the Traditional.

The whole service runs on two machines I can point at.

About 14 self-hosted stacks on two machines for roughly $30 a month, the AI included.

Underneath the service sits a deliberately small build: ~14 self-hosted stacks, 30+ containers, two machines, one sign-on. Each job runs as its own stack, which keeps failures local.

Self-hosting was a privacy decision before it was a cost decision. A child’s voice never travels to a third-party API to become a lesson note. The cost argument holds too: it all runs for about $30 a month, where per-seat tools would have attached a fee to every student, per product, forever.

And it is operated by the same person who designed it, so any operational shortcut I take reaches my own students within days.

a person acts the system carries it
one tunnel, one sign-on*.forhuman.ca

the NAS

identity
single sign-on auth.
classroom
role dashboards class. live classroom meet.
records
the student record internal site analytics analytics.
files
files & recordings cloud. reading library library. shared workspace work. nightly backups
billing
invoices & payments billing.

the GPU workstation

AI
records the lesson turns speech into text drafts the next steps reads documents & whiteboards
Two machines The ~14 stacks grouped by job, identity through billing.

Three reversals were big enough to change the build, and all three are still on the page.

Every finding stayed on file, and the one bug that mattered traced to a single root cause.

A platform for other people’s children should not run on its author’s confidence, so the method was audit-first. Findings land in a docs folder, and the docs are amended rather than rewritten, so the first version of a finding stays visible under the fix.

An audit trail that only ever says everything is fine is decoration.

Decisions reversed during the build, both eras still on file
what I builtwhat replaced iton file
the original video stackReplaced mid-build, once the live-class requirements were clear.both eras
a separate task toolRetired when the platform’s own boards covered the job.both eras
a contract-signature serviceRemoved entirely, once a simpler local wizard made it redundant.both eras
The reversals Both eras of each decision stay on file, which is what makes the record worth having.

Two audits shaped the launch, and what they taught was about counting.

the launch audits, in order
June triage 40 findings ranked, about 30 closed overnight
two customer-blocking failures both traced to a single date-handling regression
the fix patched that night, and a guard now runs in CI
adversarial audit, three days later 78 findings confirmed, 2 critical, all fixed
backup restore a full restore, performed and verified
One root cause The rest of the table is what audit-first catches before it reaches a family.

A few families, the full loop, no projections.

Soft-launched mid-June 2026, and still small.

A small number of families use it, and I am not going to dress that up. The whole loop runs in production: classes scheduled, taught, recorded into lesson notes a teacher approved, and billed, with no glue work in a chat thread at midnight.

Class day The student’s board, then one card opened to its sub-cards: two ticked, the rest due. Recorded on production.

I built the service before I built the ground it stood on.

Ransomware made that argument in April 2026.

Mallox encrypted the NAS after three months of root Telnet access through a port the DMZ had left open. No family lost anything, and only because there were no families yet: the launch came after the rebuild. Infrastructure first, next time.