Files
rootnode-academy/platform
ced4568 08ff5315de docs(phase2b): document admin and platform-data architecture
New docs/PHASE2B_ADMIN_AND_PLATFORM_DATA.md covers the Platform API
split, Postgres schema and migration guarantees/rollback, the session
cookie architecture (including the whoami-routing-bug fix), the admin
portal, the API/security boundary, known limitations, and Phase 3+
future work.

Updates ENGINEERING_SOP.md §8, LAB_ARCHITECTURE.md, README.md, and
platform/README.md to reflect Platform API as the sole Provisioner
caller and Postgres as authoritative for identity/progress as of
Phase 2B.
2026-08-18 12:23:17 -05:00
..

RootNode Academy — Platform

The full multi-student platform, layered on top of the unmodified Lab image at the repo root. Start here, then go to the component you need:

  • provisioner/ — Postgres-backed environment registry and lifecycle. Design: docs/LAB_ARCHITECTURE.md, docs/PHASE1_PLATFORM_FOUNDATION.md. Operational reference: provisioner/README.md.
  • api/ — the lightweight Platform API: students, cohorts, enrollments, curriculum, progress, scenario attempts, student/admin sessions, and the instructor/admin control plane. No k3s, no --privileged — this replaced Phase 2A's "identity" instance, which was a full Lab image booting an unused k3s cluster just to serve these APIs. Design: docs/PHASE2B_ADMIN_AND_PLATFORM_DATA.md. Operational reference: api/README.md.
  • gateway/ — the only student-facing path to a Lab (HTTP + WebSocket proxy, environment-aware routing derived from a server-controlled session — not a client-suppliable header/param). Design: docs/PHASE2A_GATEWAY_AND_STUDENT_FLOW.md (routing), docs/PHASE2B_ADMIN_AND_PLATFORM_DATA.md §3 (session ownership).
  • egress-proxy/ — shared allowlisting proxy every Lab's outbound traffic passes through.
  • docker-compose.dev.yml — the full stack (Postgres, egress proxy, Provisioner, Platform API, Gateway) on one machine. This is the Phase 1/2A/2B local dev exception — production is the two-VM Proxmox split described in docs/LAB_ARCHITECTURE.md §1.

Running the full stack locally

cd platform
echo "PROVISIONER_SHARED_SECRET=$(openssl rand -hex 32)" > .env
echo "ADMIN_PASSWORD=$(openssl rand -hex 12)" >> .env
docker compose -f docker-compose.dev.yml build
docker compose -f docker-compose.dev.yml up -d

No k3s boot to wait for at this layer anymore (Platform API starts instantly) — the whole platform is reachable at http://localhost:4200 (the Gateway) right away: students at /, instructors at /admin.

Tests

  • provisioner/test/run.js — fast, isolated Provisioner tests (network/container/firewall mechanics, no Gateway/Platform API involved). Run against provisioner/docker-compose.dev.yml.
  • test/e2e-phase2a.js — student-flow regression through real session cookies: roster → login → curriculum → launch → Gateway routing → cross-student rejection → progress relay → reset.
  • test/e2e-phase2b.js — the classroom acceptance workflow: instructor creates a cohort, adds students, assigns curriculum, Prepare Labs (concurrent), students complete different scenarios, instructor resets one, instructor destroys all cohort Labs after class — progress survives every step. Needs ADMIN_PASSWORD set (see platform/.env).

Both e2e suites are slow (real k3s boots) and need the full stack up. Neither substitutes for the manual real-Lab-image checks (node-pty, terminal WebSocket, kubectl, scenario validation) in docs/PHASE2A_GATEWAY_AND_STUDENT_FLOW.md §8 — those need a browser-equivalent client and aren't automated here.

Known limitations

See provisioner/README.md (Phase 1), docs/PHASE2A_GATEWAY_AND_STUDENT_FLOW.md §9 (Phase 2A), and docs/PHASE2B_ADMIN_AND_PLATFORM_DATA.md §13 (Phase 2B) for the full, honest lists — including in-memory sessions, the single shared admin credential, and exam mode's live bookkeeping staying Lab-local.