diff --git a/README.md b/README.md index 95de313..a378667 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ See `docs/classroom-api.md` for the endpoint/capability matrix and `SECURITY.md` The public `/api/classes/**` URL contract is preserved while Vercel packaging is consolidated: `vercel.json` rewrites those paths into the single `api/classroom.js` Serverless Function, which delegates through `api/_classroomRouter.js` to the same class/coaching/protected-case/exercise handlers. The rewrite marker is routing only and grants no authority. Do not restore one Vercel function file per Classroom endpoint; `npm run verify:vercel-functions` protects the deployment budget. -#313 staged simulation is implemented end-to-end on the active classroom branch. Protected Case Studies may carry an explicit server-only `simulation` definition; additive Neon tables persist class exercise lifecycle, optional releases, workspace readiness, and immutable debrief checkpoints. Running exercises pin the staged-definition version plus a definition fingerprint and inherit the owning class expiry. Instructor APIs/UI support staged selection, Start/Pause/Resume, controlled evidence release, debrief, explicit edit freeze/unfreeze, checkpoint inspection, Advance, and Complete. Student staged reads use the stable class-session capability, expose only current/cumulative Student-safe material, support Ready/Resume Working, and project frozen debrief Intake read-only while the server enforces writes with HTTP 423. These tables and clients do **not** duplicate live Intake state: collaboration workspaces remain the only live snapshot/revision source of truth, checkpoint snapshots are historical read-only evidence, and Classroom exercise/session state stays outside Intake persistence/export/summary. Production official Case Study stage content remains intentionally unauthored until authoritative material is supplied. +#313 staged simulation is implemented end-to-end and production-published. Protected Case Studies may carry an explicit server-only `simulation` definition; additive Neon tables persist class exercise lifecycle, optional releases, workspace readiness, and immutable debrief checkpoints. Running exercises pin the staged-definition version plus a definition fingerprint and inherit the owning class expiry. Instructor APIs/UI support staged selection, Start/Pause/Resume, controlled evidence release, debrief, explicit edit freeze/unfreeze, checkpoint inspection, Advance, and Complete. Student staged reads use the stable class-session capability, expose only current/cumulative Student-safe material, support Ready/Resume Working, and project frozen debrief Intake read-only while the server enforces writes with HTTP 423. These tables and clients do **not** duplicate live Intake state: collaboration workspaces remain the only live snapshot/revision source of truth, checkpoint snapshots are historical read-only evidence, and Classroom exercise/session state stays outside Intake persistence/export/summary. Production official Case Study stage content remains intentionally unauthored until authoritative material is supplied. ### Conflict recovery and two-window testing diff --git a/docs/classroom-roadmap.md b/docs/classroom-roadmap.md index 898d0da..71b8d74 100644 --- a/docs/classroom-roadmap.md +++ b/docs/classroom-roadmap.md @@ -223,24 +223,23 @@ The eight-slice #288 program establishes the secure Classroom foundation; it doe #312 is complete and merged as PR #314 at `b141d55050207e4cf7ce842a4452a220a5268968`: Start Class, one human Student join code, Waiting/late roster, stable Student class sessions, accessible team creation/assignment, safe reassignment/unassign with stale-authority cutoff, observer/coaching integration, and integrated multi-browser acceptance are the live substrate. -#313 is implementation-complete on `feature/classroom-staged-simulation`, based directly on the #312 merge. Its canonical contract is `docs/classroom-staged-simulation.md`. Tranches 1–10 are complete: server-only staged authoring schema, additive exercise persistence, Instructor/Student APIs, server-enforced Student freeze, Instructor orchestration console, Student case reference/readiness, immutable checkpoint inspection, integrated browser/security/mobile/accessibility acceptance, and final security/documentation audit. PR #315 is the publish/merge vehicle. +#313 is complete and merged as PR #315. Its canonical contract is `docs/classroom-staged-simulation.md`. Tranches 1–10 are complete: server-only staged authoring schema, additive exercise persistence, Instructor/Student APIs, server-enforced Student freeze, Instructor orchestration console, Student case reference/readiness, immutable checkpoint inspection, integrated browser/security/mobile/accessibility acceptance, and final security/documentation audit. ## Next production-Classroom roadmap The secure classroom/orchestration engine is complete, but a **real production KT simulation is not yet runnable from source-faithful case material**. The remaining roadmap is now product/content enablement rather than another exercise-engine tranche. -### Publish recovery — #321 / PR #322 +### Publish recovery — #321 / PR #322 — complete -#312 and #313 were both green in GitHub, but their first `main` deployments exceeded the Vercel Hobby limit of 12 Serverless Functions. Production therefore remained on the older #308 baseline even after PR #315 merged. +#312 and #313 initially exceeded the Vercel Hobby limit of 12 Serverless Functions after merge. #321 / PR #322 consolidated every public `/api/classes/**` route behind one deployment entrypoint without changing URLs or authorization behavior. -#321 resolves the deployment packaging without changing public API or authorization semantics: -- keep every public `/api/classes/**` URL; -- rewrite those paths to one `api/classroom.js` Vercel function; -- delegate through `api/_classroomRouter.js` to the existing tested handlers; -- keep collaboration workspace functions separate; -- enforce the <=12 budget in `npm run quality` and in the Vercel build. +Production recovery is verified: +- conservative deployment function count: **5/12**; +- exact merged-main SHA `21bff1d1c5a70caff0aa94aadd58abcb0644f397`; +- production deployment `dpl_VZoSoWJsDs6Eb727EN5hmrFSgAcA`: **READY**; +- post-deploy runtime-error scan: **clean**. -**Roadmap gate:** do not begin #316 as production work until #321/#322 has a READY Vercel deployment from the exact merged `main` SHA. Once that publish recovery is verified, #316 is the next implementation issue. +#316 is now unblocked and is the immediate next implementation issue. ### P0 — production case material delivery @@ -288,7 +287,7 @@ Add QR/share-link convenience around the human join code without putting bearer #320 join/mobile polish (can proceed in parallel after #315) ``` -The first next implementation action after #315 merges is **#316**, not authoring an official case prematurely. #317 may prepare source mapping in parallel, but must not ship production staged content until #316 provides the secure rich-content path. +The immediate next implementation action is **#316**, not authoring an official case prematurely. #317 may prepare source mapping in parallel, but must not ship production staged content until #316 provides the secure rich-content path. #318 and #320 can proceed in parallel; #319 should preferably build on #318's stable target identity. ## Stacked PR rules diff --git a/docs/classroom-workstream.md b/docs/classroom-workstream.md index 9780773..c41945f 100644 --- a/docs/classroom-workstream.md +++ b/docs/classroom-workstream.md @@ -6,22 +6,32 @@ This is the live restart document for the Classroom Experience program (#288). ## Current phase -#294 is merged and production READY. #295 Protected Case Study delivery is active on `feature/classroom-protected-cases`. +The secure Classroom foundation (#288), live-class management (#312), and staged-simulation engine (#313) are **merged and production-published**. The Vercel function-budget blocker #321 was resolved by PR #322; exact merged-main SHA `21bff1d1c5a70caff0aa94aadd58abcb0644f397` reached production **READY** with a clean runtime-error scan. + +The immediate next implementation issue is **#316 — protected staged case assets and rich Student case rendering**. Do not author the first production staged KT Case Study (#317) until #316 provides the secure rich-content path. ## Program issues | Slice | Issue | Status | PR / branch | Notes | | --- | --- | --- | --- | --- | -| Program | #288 | Open | #297 merged | Architecture/governance foundation is now on `main` | -| Experience role | #289 | Complete | PR #298 / `feature/classroom-experience-roles` | Runtime/tests/docs complete; canonical CI, dependency review, template guard, and CodeQL green | -| Templates / Case Studies | #290 | Complete | PR #299 / `feature/classroom-resource-split` | 171 tests: 170 pass, 0 fail, 1 skip; CI/CodeQL/dependency/template guard green | -| Class domain/API | #291 | Complete | PR #300 / `feature/classroom-domain-api` | Combined #290+#291 head: 183 tests, 182 pass, 0 fail, 1 skip; CI/CodeQL/dependency/template guard green | -| Student join/resume | #292 | Complete | PR #302 / `feature/classroom-student-experience` | 194 tests: 193 pass, 0 fail, 1 skip; CI/CodeQL/dependency/template guard green | -| Instructor observer | #293 | Complete | PR #305 merged | 208 tests: 207 pass, 0 fail, 1 skip; repository gates green | -| Coaching | #294 | Complete | PR #306 merged | 224 tests: 223 pass, 0 fail, 1 skip; all repository gates green; production deployment READY | -| Protected cases | #295 | Complete | PR #307 merged | Protected catalog/payload delivery, minimal `dist/` public boundary, deployment controls, and production verification complete | -| Browser E2E/CI | #296 | In progress — final stabilization | draft PR #308 / `feature/classroom-browser-e2e` | Critical Standalone/Student/Instructor/security journeys complete; Playwright now runs inside required `tests` CI gate | -| Browser test foundation | #279 | In progress — final stabilization via #296 | draft PR #308 | Deterministic local HTTP + Playwright/axe complete; focused Browser E2E workflow retained as manual diagnostic | +| Program | #288 | Complete | PR #297 merged | Foundation program closed; follow-ons tracked separately | +| Experience role | #289 | Complete | PR #298 merged | Runtime/tests/docs complete | +| Templates / Case Studies | #290 | Complete | PR #299 merged | Resource semantics complete | +| Class domain/API | #291 | Complete | PR #300 merged | Class/workspace authorization complete | +| Student join/resume | #292 | Complete | PR #302 merged | Student admission/resume complete | +| Instructor observer | #293 | Complete | PR #305 merged | Server-enforced read-only observation complete | +| Coaching | #294 | Complete | PR #306 merged | Separate coaching persistence/UI complete | +| Protected cases | #295 | Complete | PR #307 merged | Protected catalog/payload + minimal public `dist/` boundary complete | +| Browser E2E/CI | #296 | Complete | PR #308 merged | Required Playwright/axe regression is inside CI | +| Browser test foundation | #279 | Complete | PR #308 merged | Deterministic browser fixture and accessibility foundation complete | +| Live class management | #312 | Complete / published | PR #314 merged | Start Class, one-code admission, Waiting/late join, teams, reassignment, observer/coaching | +| Staged simulation | #313 | Complete / published | PR #315 merged | Staged release, Ready/debrief/freeze/checkpoints/advance/complete | +| Publish recovery | #321 | Complete | PR #322 merged | Vercel function count consolidated to 5/12; exact-main production READY | +| Rich staged assets | #316 | **Next** | Open | Secure protected image/table/document-page delivery + Student rendering | +| First production staged case | #317 | Blocked by #316 | Open | Source-faithful official case authoring/rehearsal | +| Stage-linked Intake guidance | #318 | Open | Open | Runtime `intakeTargetIds` + dynamic Possible Cause coaching identity | +| Class debrief comparison | #319 | Open | Open | Cross-team checkpoint/live comparison; benefits from #318 target identity | +| Join/mobile polish | #320 | Open | Open | QR/share convenience + compact Notes/Class/Case mobile chrome | ## Current architecture decisions @@ -38,7 +48,7 @@ See `docs/classroom-architecture.md` for the full contract. ## Cold restart checklist -1. Inspect current `main` HEAD and all open PRs/issues matching #288–#296 and #279. +1. Inspect current `main` HEAD and open Classroom follow-on issues #316–#320. Also inspect any newer Classroom/deployment blocker before creating work. 2. Read: - root `AGENTS.md`; - `docs/classroom-architecture.md`; @@ -56,28 +66,46 @@ See `docs/classroom-architecture.md` for the full contract. ## Active work -#297–#306 are merged to `main`. #295 is active in draft PR #307 on `feature/classroom-protected-cases`. #296 / #279 is active in stacked draft PR #308 on `feature/classroom-browser-e2e`. +There is no unfinished #288/#312/#313 implementation branch. #321 is closed and production is current through `21bff1d1c5a70caff0aa94aadd58abcb0644f397`. + +**Next implementation:** #316. ## Last completed action -Completed the #295 implementation/security/documentation slices through root cold-start and repository-operations guidance. Latest durable docs checkpoint before this update is `47ffd1bf11c813e69f8d7956659902c041c8e908`, followed by README/onboarding/roadmap/commenting/storage/operations synchronization. The public/server manifest split, authorized API/client flow, raw authored-JSON Vercel exclusion, and protected-resource verifier are implemented. +PR #322 merged and restored production publishing after #314/#315 exceeded the Vercel Hobby Serverless Function limit. The recovery preserves every public `/api/classes/**` URL through rewrites into one `api/classroom.js` function and keeps authorization inside the existing handlers. + +Deployment evidence: +- exact PR-head verification `9094a3fa2a56c8720e9c149278ef03165ecd0b17` -> Vercel preview `dpl_87aJLUvqaSc3wQ45gecTiGVMdCVq` -> **READY**; +- Vercel build guard: **5/12** conservative Serverless Function candidates; +- protected authored `templates/*.json` excluded and protected/public manifest boundary re-verified; +- PR #322 squash-merged as `21bff1d1c5a70caff0aa94aadd58abcb0644f397`; +- exact merged-main production deployment `dpl_VZoSoWJsDs6Eb727EN5hmrFSgAcA` -> **READY**; +- post-deploy Vercel runtime-error scan -> **clean**. + +#312 and #313 are therefore both merged **and production-published**. ## Next recommended action -Continue #295 on draft PR #307 from the current branch head. - -1. Protected Case Study runtime/security implementation is complete: public/server manifest split, Classroom authorization, role-aware client delivery, static/runtime leak guards, and deterministic API/client coverage. -2. A second-order production exposure was discovered during deployed verification: with the old `outputDirectory: "."`, production returned internal repository files such as `/docs/classroom-workstream.md` and `/scripts/build-templates-manifest.mjs` with HTTP 200. -3. #307 now builds a minimal public `dist/` surface via `scripts/build-vercel-public.mjs`. It copies only `index.html`, `main.js`, `styles.css`, and browser JavaScript under `src/` + `components/`; it rejects internal file types and protected Case Study identifiers. -4. `vercel.json` now uses `outputDirectory: "dist"` and `npm run verify:protected-cases && npm run build:vercel-public`. The verifier rejects any return to repository-root static output. -5. Exact GitHub CI evidence on `7f998f96b92a6760d5437a8fd8ffc36ea0a97f4c`: - - `[verify:protected-cases] Protected 4 Case Study payload(s); public manifest/runtime and Vercel deployment boundary verified.` - - `[build:vercel-public] Built 45 public file(s) in dist/ with no internal docs or protected Case Study identifiers.` - - CI, CodeQL, Dependency Review, and Template Manifest Guard all green. -6. Vercel Git deployment policy remains repository-owned: ordinary branches create no Vercel deployment; `main` and `verify/**` are the only allowed classes, and repo `ignoreCommand` explicitly continues those branches. -7. A deliberate preview of the new `dist/` head was requested through `verify/protected-cases-preview`, but Vercel returned `upgradeToPro=build-rate-limit` before creating the deployment. This remains tracked in #304. -8. The earlier guarded preview `dpl_Ep2q8Y3BMUWGEV7fzZQHnvdwPumA` reached READY and returned HTTP 404 for the formerly public Microcomputer Cabinets authored JSON path, proving the protected authoring-source boundary before the `dist/` broadening. -9. Exact next action: finish PR/issue/diff synchronization on the latest documented head, then obtain one deliberate `verify/**` preview when Vercel capacity permits and confirm `/docs/classroom-workstream.md`, `/scripts/build-templates-manifest.mjs`, and protected `/templates/*.json` paths return 404. The deployed protected API matrix still requires an approved preview-auth bypass path; deterministic server tests are already green. Keep #307 draft and do not merge without explicit authorization. +Start **#316 — Protected staged case assets and rich Student case rendering** from current `main`. + +Why #316 is first: +1. #313 deliberately supports rich staged block kinds (`image`, `table`, `document-page`) in the protected authoring schema. +2. The Student runtime still projects/renders released staged material primarily as `id/kind/title/body`; it cannot yet faithfully present protected pages, images, or structured tables. +3. #317 must not flatten, guess, or publish official case material around that missing secure rendering layer. + +#316 must preserve: +- protected assets remain server-gated and absent from public `dist/`; +- Student receives only currently authorized/released assets; +- future-stage, Instructor-only, exemplar/model, and full protected source material remain withheld; +- stable Student class-session authority remains separate from assignment/workspace edit authority; +- asset or exercise state must not enter `kt-intake-full-v2`, file exports, summaries, or URLs; +- deterministic API/client/browser tests must prove unauthorized/non-released asset denial and accessible rich rendering. + +Parallel work that is safe: +- #318 can proceed independently on stable Intake target identity / `intakeTargetIds`, provided it does not depend on guessed official case stages. +- #320 can proceed independently as join/mobile polish. +- #317 may inventory/map authoritative source material, but must not ship production-selectable staged content until #316 is complete. +- #319 should preferably consume #318's stable target identity rather than invent a second comparison-target model. ## Completed #300 implementation