- PHASE5B_SELF_PACED_ENROLLMENT.md: the full design doc. - RUNBOOK_SELF_PACED_ENROLLMENT.md: operational runbook for /admin -> Programs. - WEBSITE_ENROLLMENT_INTEGRATION.md: the complete contract for the separate website team — endpoint, auth, request/response schema, idempotency/retry rules, student matching, minor/ no-email behavior, error responses, what not to send, local testing, production-secret handling. Written to be usable without reading the Platform API source. - REMOTE_AND_SELF_PACED_ARCHITECTURE.md: closes the self-registration/curriculum-assignment/ delivery-mode/enrollment-model gaps this doc previously flagged as Phase 5+ scope. - ENGINEERING_SOP.md: new §15. LAB_ARCHITECTURE.md, PRODUCTION_VALIDATION_CHECKLIST.md, README.md, platform/README.md: cross-references and a Phase 5B production-validation section.
6.1 KiB
Remote & Self-Paced Delivery Architecture
Phase 4.1 §12. This is an architecture review, not a new product — no self-registration, payments, or public enrollment is built here (explicit non-goal). The question this document answers: does the infrastructure and application assume "an instructor always provisions the Lab," and if so, where, and what would need to change for self-paced delivery to work.
The short answer: less of that assumption exists than expected
RootNode Academy's Lab lifecycle was built student-driven from Phase 1 — POST /api/environment/launch is called by the STUDENT'S OWN session, not by an instructor action.
"Prepare Labs" (POST /api/admin/cohorts/:id/prepare-labs) is a classroom convenience that
front-loads several students' launches at once before a synchronous class session, not the only
path to a running Lab. This was true before Phase 4.1 and confirmed still true by this phase's
own regression suites (platform/test/e2e-phase2a.js roster's two students with cohort_id: null and takes them through login → curriculum → launch → scenario work with zero cohort
involvement) and by two new Phase 4.1 drills built specifically to exercise the remote/returning
-student narrative:
infra/scripts/drills/test-lab-host-loss.js— student launches, makes progress, their Lab is destroyed out from under them (standing in for an idle-reaper destroy), Platform stays up, progress is untouched, they launch again unprompted and continue.infra/scripts/drills/test-fake-cohort-rehearsal.js— the same "returns later, fresh Lab, curriculum continues" narrative as part of a fuller classroom rehearsal.
Both pass today, with zero application code changes needed for the self-paced-relevant parts of this flow specifically — see the Phase 4.1 report for the full run results.
What already works, unmodified
- Student-initiated provisioning — no instructor step is required between "student wants to
work" and "Lab exists." (
platform/api/src/server.js's/api/environment/launch.) - Cohort-less students —
cohort_idis nullable on student creation (POST /api/admin/students); a student with no cohort logs in, sees the curriculum, launches Labs, and makes progress identically to a cohorted one. Confirmed by inspection AND by the existing regression suite, not just by schema reading. - Idle reaper → academic state survives → return → continue — the exact lifecycle this section describes as the target self-paced experience is what Phase 1's reaper + Phase 2B's Postgres-backed academic data (separate from the disposable Lab) were already designed to produce. Phase 4.1 proved it end-to-end, twice (see above).
- Curriculum content itself is not cohort-gated —
GET /api/curriculum/pathreads the one curriculum path file directly (curriculum.loadCurriculumPath()); it never checkscurriculum_assignmentsor cohort membership at all. A self-paced student sees the full curriculum with no instructor action required to "unlock" it.
What's genuinely missing for a real self-paced product (Phase 5, not built here)
-
No self-registration / public enrollment surface. Still true, still deliberate — Phase 5B built the boundary a separate public website will call (
POST /api/integrations/enrollments, seedocs/PHASE5B_SELF_PACED_ENROLLMENT.md§11 anddocs/WEBSITE_ENROLLMENT_INTEGRATION.md) rather than a public sign-up form here. A student row can now be created automatically by a trusted server-to-server enrollment event, but there is still no browser-facing "sign up" page anywhere in this codebase — that's the website's job. -
No real student authentication.Closed in Phase 5A. Students now have real credentials (email+password or login-identifier+password,password_hash/scryptreusinginstructors' exactsrc/auth/password.js), a first-login/reset token flow, and Postgres- backed rate-limited/CSRF-protected sessions on the samesessionstable instructors use — seedocs/PHASE5A_STUDENT_IDENTITY_REMOTE_CLASSROOM.md. The old bare-student_idPOST /api/loginstill works for not-yet-converted pilot rows only; it's rejected (409) the moment an account has real credentials or a pending activation token. -
Addressed differently in Phase 5B.curriculum_assignments.student_idis schema-ready but unwired.curriculum_assignmentsitself remains unwired, unchanged — but the real problem it was meant to eventually solve (which curriculum a given student sees) is now solved at the enrollment layer instead:enrollments.curriculum_pathsnapshotsprograms.curriculum_pathper enrollment.curriculum_assignmentsis still available for a future direct per-student assignment need outside the program/enrollment model — it wasn't removed, just not the mechanism Phase 5B ended up using. Seedocs/PHASE5B_SELF_PACED_ENROLLMENT.md§4. -
No delivery-mode concept anywhere.Closed in Phase 5B.programs.delivery_mode/enrollments.delivery_mode(self_paced/cohort/hybrid) is now a real, snapshotted field. Capacity planning, the reaper, and Lab lifecycle mechanics still behave identically regardless of delivery mode — this only affects how enrollment/entitlement is modeled, not infrastructure. -
No self-paced enrollment/entitlement model.
Closed in Phase 5B— seedocs/PHASE5B_SELF_PACED_ENROLLMENT.mdforprograms/enrollments, server-enforced entitlement (pending/future/expired/cancelled), server-derived completion, and the resulting self-paced student dashboard.
What Phase 4.1 deliberately did NOT do here
No signup flow, no student password/email auth implementation, no per-student curriculum
assignment route, no payments, no public course catalog, no held/premium scenario content. All
explicit non-goals per this phase's authorization. Student authentication (Phase 5A) and the
self-paced enrollment/entitlement model (Phase 5B) have both since been built; a public
self-registration page, real payment processing, and a Parent/Guardian portal remain
deliberately out of scope — see docs/PHASE5B_SELF_PACED_ENROLLMENT.md §12.