Teaching

A classroom of robots

Here is a workshop worth wanting: thirty seats, ninety minutes, hands on keyboards. Everyone builds a small workflow, trains a tiny model on it, and leaves holding something that still works next week. Now here is the uncomfortable question that comes with it. Before you ask thirty real people for ninety minutes of their attention, how do you know the room will hold — not hope, know?

The answer this platform is building toward is thirty students who do not exist. Not a metaphor: synthetic actors driving real browsers against the real system, so the ninety minutes can fail in private before they are allowed to fail in public. This post is the design of that classroom — what it rests on, and what a rehearsal would have to prove.

What is built, and what is not

Everything the classroom design rests on is built and verified: the CPU path for a device without a GPU, login-free identity, fork lineage, collaboration that is additive rather than load-bearing, and committed snapshot links. The rehearsal harness itself — the simulation surface described below — is specified end to end and being built now, so no workshop has been rehearsed and none has been taught (where things stand). Read this as the design argued through, with its numbers derived rather than measured.

Thirty students who do not exist#

The simulation surface is built on one principle: synthetic inputs, real system. A mock is a synthetic input, never a parallel implementation. Thirty actors are minted through the real sign-in path, so each is a real identity with a session and a handle (and a synthetic e-mail address ending in .invalid — even people who do not exist get privacy hygiene). The thirty laptops are real headless browser contexts that join the session through the real coordinator, fetch content over the real sync path, and run workflows through the real engine. Every row a robot creates is stamped as simulated so it can be swept away afterwards — and no runtime code path is allowed to branch on that stamp. The system cannot quietly behave better for robots; whatever they experience is exactly what people will get.

One root seed threads the whole thing: actor 17 of seed 40712 has the same handle, the same invented e-mail, the same scripted behavior on every run. Replay the scenario and you replay the ninety minutes. For a rehearsal, that determinism is the entire value: change one thing, run again, and any difference you observe is the thing you changed.

Note

The simulation surface is development tooling: it exists in development and staging builds and is structurally absent from production. A classroom gets the product that was rehearsed — never the robots.

The script for ninety minutes#

A rehearsal is a file. Scenarios are declarative: a seed; fixtures (how many actors, which browsers, which datasets); a timeline of who does what, when; and assertions that must hold at the end. Because every capability in Scellis is an API command — the interface is just one client of the same surface — the script's vocabulary is the platform's own command set plus browser actions. Nobody has to build a workshop-simulation feature; the grammar is already the product.

yaml
seed: 40712
fixtures:
  actors: 30
  browsers: { webgpu: 20, wasm_only: 10 }
  datasets: [workshop/tabular-10k]
timeline:
  - { at: 0m,  actor: instructor,     action: doc.open }
  - { at: 2m,  actor: "seats[1..30]", action: join.session }
  - { at: 12m, actor: "seats[1..30]", action: doc.fork }
  - { at: 14m, actor: "seats[1..30]", action: run.start }
  - { at: 38m, actor: "seats[1..30]", action: doc.commit }
faults:
  - { at: 20m, kind: peer_churn,       seats: "12..17", rejoin: +2m }
  - { at: 30m, kind: coordinator_loss, duration: 3m }
assertions:
  - run.completed: { every: seat, within: lab_window }
  - commit.exists: { every: seat }
  - diagnostics: { silent_failures: none }

The shape of the class: the instructor presents for twelve minutes on a shared canvas while thirty cursors watch; then every seat forks the workflow and runs the exercise on its own device; everyone commits before the wrap-up. Even the boring first line earns its place: thirty cold tabs open the same link and pull the exercise's working set — workflow, dataset, blocks — from the database into each seat's local catalog. Thirty simultaneous first loads is exactly the kind of event you want to have watched happen before it happens to you.

The machine in your head is not the machine in the room#

Ten of the thirty browsers in that fixture list have no WebGPU at all. That is not pessimism, it is the honest shape of a room: roughly one device in seven lacks it out in the world, and teaching rooms skew worse — managed laptops, locked-down browsers, hardware that was mid-range when it was new, a while ago.

What a seat without WebGPU gets is a designed state, not a blank screen: the whole workflow runs on the CPU reference path, behind a loud, persistent banner that says exactly that — running on CPU, slower. Nothing about the lesson changes. Except time. And a lesson plan is nothing but time.

So do the arithmetic before you write the exercise, not after. A CPU path is slower than a GPU by a large factor, not a small one — call it one to two orders of magnitude for work of this shape. Take a model of about 170,000 parameters on 40,000 rows: comfortably under a minute on a laptop GPU, and therefore somewhere north of half an hour on the slowest seat in the room. Longer than the entire lab window. The exercise that survives that multiplication is humbler: sixteen features into two hidden layers, just under eleven thousand parameters, ten thousand rows — roughly two orders of magnitude less arithmetic, which is exactly what it takes to bring the worst seat inside the window while the best seat finishes in seconds. The rule belongs at the top of the lesson plan: size the exercise for the slowest seat, and let the GPU make it comfortable — never possible.

Thirty cursors are a demo, not a lab#

The second thing the rehearsal is for is social, not computational. One live document with thirty cursors on it is wonderful — until it has to be a lab. Script two seats to keep editing during the presentation (every real classroom has those two) and the platform handles it correctly: edits validated, undo strictly per person — the instructor's Cmd+Z never touches a student's work. But handled correctly is not pedagogically right. Thirty people editing one graph is a crowd, not a class.

The format that works separates the two modes: collaborate for the demo, isolate for the exercise. Each seat forks the workflow — its own copy, with lineage recorded — so when the work is collected later, whose fork is this and where did it come from answers itself.

At minute twenty the script closes six laptop lids mid-run and reopens them two minutes later. Rejoining is undramatic: edits rebase, nothing is lost, and a seat that joins late receives the full session state and the whole metric curve from t = 0. A student who arrives late is behind — not lost.

At minute thirty the script kills the session coordinator for three minutes — the classic classroom Wi-Fi death. The session suspends; the cursors vanish. And the thirty runs do not care, because every run is local compute on the seat's own device; the server was carrying presence, never computation. The demo dies with the Wi-Fi. The lab work survives it. Collaboration on this platform is strictly additive, and in a classroom that is not a footnote — it is the difference between a hiccup and a lost session.

No account at minute zero, a URL at minute ninety#

None of the thirty seats has an account. That is not a compromise; it is the point. A sign-up wall at minute zero costs ten minutes and a third of the room's goodwill. A login-free visitor joins the session as a stable, attributable handle, forks, authors, and runs — computation is never tier-gated, including for people with no account at all. Their work stays on their own device under that anonymous identity until they decide it is worth keeping; claiming it with an account later is a single gesture that carries everything over and loses nothing.

And the hand-in is a URL, not a file. Each seat commits its fork and mints a snapshot link: frozen, content-addressed, openable without a login. Next week's question — where did my work go? — has an answer that is a link, and the link still resolves. The same property that makes results citable makes homework durable.

What a classroom actually needs#

  • No installs. The room's software is a URL; version skew across thirty machines stops being your problem at minute one. The traditional first act of a hands-on workshop — toolchain triage — simply does not exist.
  • No accounts to start. Identity can wait until there is something worth keeping.
  • Assume the worst machine. Size every exercise for the CPU path; the GPU is a bonus, never a dependency.
  • Collaborate for the demo, isolate for the exercise. The fork is the doorway between the two.
  • End with URLs. Committed, content-addressed work outlives the session, the Wi-Fi, and the semester.

What thirty robots could never tell you is whether the workshop is any good. They do not get bored; they never ask wait, why? at the exact moment the why matters; they mistype only when scripted to. A green rehearsal is evidence that the room holds — thirty seats, the slowest machine, the mid-lab Wi-Fi death — not a verdict on the teaching. That part needs people. And when the real thirty show up, things will go wrong that no seed ever produced. But they will be the interesting kind of wrong — the kind about teaching, not about infrastructure. That is all anyone should want from a rehearsal: a classroom where the only surprises left are the human ones.

  • teaching
  • simulation
  • collaboration
  • local-first

← All posts