11 Commits
Author SHA1 Message Date
ced4568andClaude Sonnet 5 ce6abfe6c7 feat(platform): relay scenario progress from ephemeral labs to identity backend
Real architectural gap found and fixed during Phase 2A testing, not part of
the original plan: scenario validate/answer requests proxied through
/lab/<token>/api/scenarios/:id/{validate,answer} were writing progress into
that ephemeral Lab container's own SQLite — which is destroyed on every
reset/reap. Confirmed by testing: solving a scenario never showed up on the
dashboard's curriculum view, and would have been silently lost on lab
recreate, directly contradicting "academic progress must survive lab
reset/recreate."

Root tension: scenario validation must run against the student's own live
cluster (only exists inside their Lab container) — it can't be re-run
anywhere else. But the canonical progress record needs to live on the
persistent identity instance, which never has the student's actual cluster
state applied to it.

Fix: this endpoint (POST /api/progress/record) records an outcome WITHOUT
re-running validation — it exists purely so the Gateway can relay a
validate/answer result it already obtained from the real Lab. The Gateway
forwards the real request to the Lab, returns that real response to the
browser unchanged, and separately calls this endpoint with the outcome. See
platform/gateway/src/server.js's relayScenarioOutcome().

Verified end-to-end: a scenario solved through a student's Lab shows up in
their curriculum immediately, survives their lab being destroyed and reset,
and is correctly attributed only to that student (not visible to a second
student's own curriculum view).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-18 11:16:08 -05:00
ced4568andClaude Sonnet 5 60fbf0c385 feat(curriculum): add RootNode learning path, student roster, and scenario isolation metadata
Pre-Phase-1 platform work, approved and tested earlier but not yet committed:

- Terminal banner: "RootNode Academy Lab — node: k8s-lab", upstream KubeKosh
  attribution left untouched in footer/README/LICENSE.
- RootNode curriculum mode: scenarios/rootnode-path.json (Foundation -> Workloads
  -> Networking -> Configuration -> Troubleshooting -> Real Ops -> Capstone),
  built from existing scenario content grouped by category, no new scenarios
  invented. New GET /api/curriculum/path endpoint.
- Student roster + per-student progress: instructor-roster, pick-your-name login
  (no password), students/environments-adjacent progress table migrated to a
  (student_id, scenario_id) composite key so practice progress and exam sessions
  are isolated per student instead of one global bucket. New /api/roster,
  /api/login endpoints.
- scenarios/data/*.json: added isolation_type metadata (shared_namespace vs
  ephemeral_cluster) from an audit of which scenarios execute cluster-scoped or
  node-level commands. This was Tier-1-isolation groundwork that got superseded
  same-day by the full-ephemeral-per-student architecture (see
  docs/LAB_ARCHITECTURE.md) — the field is kept as descriptive metadata only,
  per the note now in scenarios/SCHEMA.md. Not wasted: it's an accurate audit of
  which scenarios touch cluster-scoped resources, useful independent of isolation
  model.
- .gitignore added (node_modules/, frontend/dist/, *.db, /data/, .env) — none
  existed before; without it, npm installs during testing would have landed in
  a commit.

Known limitation still open: no frontend UI for any of this yet (login screen,
roster-add form, curriculum view) — API-only. No auth on the roster-add endpoint.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-18 01:21:16 -05:00
Abhinav Sinha 09bd1b20da refactor(exam): flat sidebar list, weight badges, UI cleanup
Signed-off-by: Abhinav Sinha <[email protected]>
2026-06-18 01:11:19 +05:30
Abhinav Sinha 4acdb0df40 feat(exam): log time spent per scenario in exam report
Signed-off-by: Abhinav Sinha <[email protected]>
2026-06-16 16:29:50 +05:30
Abhinav Sinha 6766d772d1 feat(exam): add exam history and improve scenario timer
Signed-off-by: Abhinav Sinha <[email protected]>
2026-06-16 16:03:08 +05:30
Abhinav Sinha 5720b59a5f feat(exam): add timer for each scenario in exam mode
Signed-off-by: Abhinav Sinha <[email protected]>
2026-06-16 10:53:14 +05:30
Abhinav Sinha ab2403e914 feat: implement scenario caching and hot-reloading
Signed-off-by: Abhinav Sinha <[email protected]>
2026-06-15 15:28:53 +05:30
Abhinav Sinha 8489544981 refactor(server): replace execSync with execAsync
Signed-off-by: Abhinav Sinha <[email protected]>
2026-06-15 11:02:28 +05:30
Abhinav Sinha 124e5276d4 refactor(scenarios): split monolithic configuration into individual files
- Split `scenarios/scenarios.json` into individual JSON files under `scenarios/data/` named `<scenario-id>.json`
- Split `scenarios/bundles.json` into individual JSON files under `scenarios/bundles/` named `<bundle-id>.json`
- Updated `backend/server.js` to dynamically load scenario and bundle files from their respective directories
- Updated documentation in `scenarios/SCHEMA.md` and `README.md` to reflect the new repository layout and contributor workflow

Signed-off-by: Abhinav Sinha <[email protected]>
2026-06-15 07:52:47 +05:30
Abhinav Sinha 356d4ee326 feat: Add 10 new scenarios
Added new scenarios:

1. Kubernetes Basics:
  - [TASK] Annotating Kubernetes Resources
  - [TASK] Pod with Init Container
  - [MCQ] Pod Restart Policies
  - [MCQ] kubectl Output Formats

2. Kubernetes Administrator (CKA):
  - [TASK] Configure a PodDisruptionBudget
  - [TASK] Pod Priority and PriorityClass

3. Kubernetes Security (CKS):
  - [TASK] RuntimeClass for Sandboxed Workloads
  - [TASK] Write a Kubernetes Audit Policy
  - [TASK] Restrict Egress to Namespace
  - [TASK] Enforce Non-Root Container

Signed-off-by: Abhinav Sinha <[email protected]>
2026-05-31 04:20:10 +05:30
Abhinav SinhaandGitHub c26c0122ce Initial commit 2026-05-26 20:18:08 +05:30