Skip to content

Add Instructor-run live classroom management - #314

Merged
MajorIncident merged 79 commits into
mainfrom
feature/classroom-live-management
Oct 6, 2026
Merged

MajorIncident merged 79 commits into
mainfrom
feature/classroom-live-management

Conversation

@MajorIncident

@MajorIncident MajorIncident commented Oct 6, 2026 •

Copy link
Copy Markdown
Owner

Issue

Goal

Move Classroom from capability-oriented setup to an Instructor-run live class:

Start class
  -> one human Student join code
  -> waiting / late roster
  -> Instructor creates teams
  -> assign / reassign / unassign Students live
  -> Student reconnects automatically to the authorized team Intake
  -> Instructor observes/coaches from one dashboard

Tranche 1 — architecture/server contract

Checkpoint: 0c6bf97d1939437bd63e7f3107995b811cf3a7cd.

This PR currently changes documentation/governance only. No schema/runtime behavior has changed yet.

Canonical design: docs/classroom-live-management.md.

Decisions:

  • normal Instructor path becomes Start a class;
  • Student uses one human-friendly join code + display name;
  • join code is an admission locator, not a privileged bearer capability;
  • admission mints a stable high-entropy Student class-session capability;
  • Students may wait unassigned, including late joiners;
  • Student class-session authority can read only that participant's assignment state and cannot edit collaboration directly;
  • workspace edit capabilities remain assignment-specific classroom-student aliases;
  • assign/reassign/unassign revokes old workspace edit authority before destination access is issued;
  • never retarget one active workspace edit token from Team A to Team B;
  • reassignment does not merge Intake snapshots; destination team state is authoritative;
  • coaching remains attached to the workspace it reviewed;
  • legacy two-code admission remains supported during the additive migration.

Tranche 2 — additive persistence + repository primitives

Checkpoint implementation head: df3633d008bb7e352509e15c1964b7d27ebf441f.
Documentation checkpoint: 8eed407c19f9f0034b518fead649bc6dbbf8f917.

Implemented:

  • normalized human join-code contract;
  • additive student_join_code persistence;
  • additive classroom_participants waiting/unassigned participant model;
  • independent Student class-session vs workspace-access capability hashes;
  • class-session lookup and Instructor-scoped participant listing primitives;
  • re-admission session rotation without forced assignment;
  • deterministic in-memory parity and focused tests;
  • no Student UI cutover and no removal/change to legacy two-code admission.

Validation on implementation head:

  • repository quality: 241 tests / 1 intentional skip;
  • required Browser E2E: 22 passed / 6 intentional skips / 0 failed;
  • CodeQL, Dependency Review, Template Manifest Guard: green.

Exact next tranche: HTTP admission/status/access APIs around these primitives, before assignment/reassignment UI.

Tranche 3 — live HTTP admission/status/access

Implementation checkpoint: 04f95f24dd63d2ce75260034d75c9c514d07e84e.
Documentation checkpoint: 6e1a023fb2e9e2a504f85b4d236856d25efc4722.

Implemented:

  • Start Class returns one formatted human Student join code while preserving the legacy high-entropy join token;
  • POST /api/classes/admit creates/rotates a waiting Student class session;
  • GET /api/classes/participants is Instructor-only;
  • GET /api/classes/student returns only the represented Student's own assignment state;
  • POST /api/classes/student/access issues assignment-specific edit authority only while assigned;
  • live workspace-access rotation revokes prior edit authority;
  • the Student class-session token itself cannot edit collaboration;
  • live access tokens resolve through existing Student coaching/protected-resource authorization;
  • current Student UI is still unchanged.

Validation:

  • repository quality: 244 tests / 243 pass / 0 fail / 1 intentional skip;
  • required Browser E2E: 22 passed / 6 intentional skips / 0 failed;
  • CodeQL, Dependency Review, Template Manifest Guard: green.

Exact next tranche: Instructor assign/reassign/unassign server semantics and old-team authority cutoff before any live management UI.

Tranche 4 — Instructor assignment authority

Implementation checkpoint: 7bfd662e2dcbe5511a4065b7b19222129485d08a.
Documentation checkpoint: 27e9df7af70c21a1f02553d8241077821409c5e0.

Implemented:

  • Instructor-only assign/reassign/unassign through PATCH /api/classes/participants;
  • assignment revision increments only on real assignment changes;
  • same-assignment PATCH is idempotent;
  • old assignment-specific workspace authority is revoked before assignment mutation;
  • stale presence is removed by internal workspace ID after revocation;
  • Student workspace-access hash clears on move/unassign;
  • destination access is obtained later by the Student, never minted by the Instructor action;
  • cross-class destinations are rejected without assignment change;
  • individual workspace single-participant enforcement;
  • leaving an individual workspace releases its claim;
  • no snapshot read/copy/merge during assignment;
  • live Student coaching/resource authorization now also proves the stored access hash is an active, unrevoked classroom-student alias.

Validation:

  • repository quality: 246 tests / 245 pass / 0 fail / 1 intentional skip;
  • required Browser E2E: 22 passed / 6 intentional skips / 0 failed;
  • CodeQL, Dependency Review, Template Manifest Guard: green.

Exact next tranche: Instructor live-management UI + deterministic browser fixture + real-browser Instructor journey. Student one-code/reassignment UI remains deferred.

Tranche 5 — Instructor live-management client

Implementation checkpoint: d3e2a397cd76fc75e62516ed63ad76231bb4812c.
Documentation checkpoint: d88a763293df3e5484c22a151fb64d9dd737a5c3.

Implemented:

  • Start a class is the primary Instructor path; existing Instructor capability entry remains an advanced/recovery disclosure;
  • same-device Instructor resume persists Instructor authority + public class/join-code context only;
  • human Student join code display/copy;
  • live participant polling with Waiting/Unassigned state;
  • Team/Individual workspace creation;
  • accessible per-Student assign/reassign/unassign selectors;
  • live participants count toward workspace membership totals;
  • existing read-only observer/coaching navigation remains integrated;
  • Instructor client ignores legacy workspace assignment tokens returned for compatibility;
  • deterministic browser fixture supports live class creation/roster/workspace/assignment;
  • real-browser journey covers Start Class -> Waiting -> create Team -> assign -> observe -> reload/resume.

The first browser run correctly exposed only a stale test assumption: older Instructor journeys needed to open the now-collapsed existing-class recovery disclosure. Those tests were updated; no product rollback was needed.

Validation:

  • repository quality: 248 tests / 247 pass / 0 fail / 1 intentional skip;
  • required Browser E2E: 23 passed / 7 intentional skips / 0 failed;
  • CI, CodeQL, Dependency Review, Template Manifest Guard: green.

Exact next tranche: additive Student live-class client — one-code admission, Waiting, own assignment-status polling, assignment-specific access exchange, automatic safe reassign/unassign, and same-device class-session resume. Keep the legacy two-code Student path available during migration.

Tranche 6 — Student live-class client

Implementation checkpoint: 0c8692c7486ecb50c730d0757c41426b81830250.
Documentation checkpoint: 738712799d46dd1c710d121c49e6be24cfb1aa6e.

Implemented:

  • normal Student path is display name + one human class code;
  • legacy two-code access remains an explicit recovery/compatibility disclosure;
  • one-code admission creates a stable Student class-session capability;
  • Waiting has no collaboration edit authority and polls only the represented Student's assignment;
  • assignment-specific workspace capability is memory-only and never persisted in the live resume envelope;
  • reload/move reacquires fresh current-workspace access;
  • reassignment disconnects old collaboration before destination access and destination Intake wins without merge;
  • unassign returns the Student to Waiting while preserving the class session;
  • terminal class-session failure restores pre-class local recovery where available;
  • existing Student coaching/protected-resource integrations receive only the active assignment workspace token.

Browser/security coverage:

  • desktop + mobile one-code -> Waiting -> Team Alpha -> edit -> reload/resume Alpha -> Team Beta -> Waiting;
  • stale Alpha token returns 404 after move;
  • stale Beta token returns 404 after unassign;
  • Team Beta loads its own canonical snapshot rather than Team Alpha's work;
  • legacy authorization/coaching/protected-case/team-collaboration journeys remain green through the explicit two-code recovery path;
  • axe caught and drove a Waiting-state contrast repair.

Validation on implementation head:

  • repository quality: 252 tests / 251 pass / 0 fail / 1 intentional skip;
  • required Browser E2E: 25 passed / 7 intentional skips / 0 failed;
  • CI, CodeQL, Dependency Review, Template Manifest Guard: green.

Tranche 7 — integrated live-class acceptance

Implementation checkpoint: 9315210dd15ed583cfbd3201302699d025ded3a1.
Documentation checkpoint: 01c20b731c1002a54c62f28de00a82a785b9f575.

Implemented:

  • parallel-safe integrated browser fixture with its own Instructor capability, displayed human join code, workspace IDs, participant roster, and shared workspace state;
  • one Instructor + three live Student browser contexts share the same class instance;
  • two Waiting Students assigned to Team Alpha synchronize one Intake;
  • a late Student joins after work begins and is assigned to isolated Team Beta;
  • Instructor read-only observer sees the real Team Alpha Student snapshot;
  • Instructor field-level coaching reaches a Team Alpha Student read-only;
  • Student A moves Team Alpha -> Team Beta and lands on Team Beta's existing Intake without snapshot merge;
  • Student B remains on Team Alpha unchanged;
  • stale Team Alpha authority returns 404 after reassignment;
  • unassign returns Student A to Waiting and stale Team Beta authority returns 404;
  • accessible non-drag assignment selectors remain the canonical grouping path;
  • Classroom follow-on: Instructor-orchestrated case simulation and staged debrief #313 staged case/simulation state remains outside this PR.

Validation:

  • repository quality: 252 tests / 251 pass / 0 fail / 1 intentional skip;
  • required Browser E2E: 26 passed / 8 intentional skips / 0 failed;
  • CI, CodeQL, Dependency Review, Template Manifest Guard: green.

Exact next tranche: final #312 docs/security/merge-readiness review. Reconcile API/architecture docs with the implemented lifecycle, inspect the full main -> #314 diff and unresolved review/security state, verify rollback and legacy compatibility language, and move the PR out of draft only if the final documented head remains green.

Tranche 8 — final documentation / security / merge readiness

Final readiness head: d6a2f27b95639340ad46f6e596368f064671a08f.

Final audit:

Final validation:

  • repository quality: 252 tests / 251 pass / 0 fail / 1 intentional skip;
  • required Browser E2E: 26 passed / 8 intentional skips / 0 failed;
  • CI, CodeQL, Dependency Review, Template Manifest Guard: green.

Merge boundary: #314 is ready to leave draft and merge into main. After merge, #313 must branch from the resulting merge commit rather than stacking on the old feature branch.

Planned implementation tranches

  1. Architecture/server contract — this checkpoint.
  2. Additive persistence + repository methods — join code + live participant/session/assignment model, with unit/API tests; no Student UI cutover.
  3. Admission/status/access APIs — waiting Student + assignment-specific workspace access, preserving legacy join.
  4. Instructor class-start / roster / team-management client.
  5. Student one-code admission / waiting / automatic reassignment client.
  6. Browser E2E + accessibility — late join, team assignment, reassignment, old-authority cutoff, isolation.
  7. Docs/security/final gates.

Security / rollback

  • Raw high-entropy capabilities remain hash-only server-side.
  • Human join code cannot enumerate or edit class data.
  • Student cannot enumerate classmates/workspaces.
  • Instructor observation remains read-only.
  • Existing collaboration snapshot/revision engine remains authoritative.
  • First server migration is additive; legacy /api/classes/join and classroom_memberships remain working until explicit later removal.
  • The new UI will not cut over until server/API tests prove safe reassignment and browser fixture coverage exists.

Cold restart

Read:

Exact next action: merge #314 at d6a2f27...; then start #313 from the resulting main merge commit with an architecture/server-contract tranche for exercise lifecycle, stage authorization, staged protected content, checkpoint/debrief semantics, late join, and reassignment resilience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant