docs(phase6d): document the ROOT Foundations milestone
Adds PHASE6D_ROOT_FOUNDATIONS.md (the phase's own record: the generic-scenario-engine finding, the tested container-runtime decision, what was authored, the bugs found and fixed, and honest test/regression/rehearsal results) and ROOT_FOUNDATIONS_PILOT_READINESS.md (module-by-module READY/DEFERRED classification for ROOT 01-04 against the unchanged Phase 6C readiness standard — ROOT 01 READY, ROOT 02-04 DEFERRED by design). Adds ROOT_PROGRAM_DURATION_MODEL.md — real per-course instructional-hour totals computed from actual estimated_duration_minutes values (2,931 minutes / 48.9 hours across all authored content), not invented, with an explicit note on why instructor-led timing isn't a separate summable field yet. Updates ROOT_PROGRAM_ARCHITECTURE.md (ROOT 01's new READY status and the real 01-04 prerequisite chain), ROOT_PILOT_CURRICULUM.md (ROOT 01 added to the pilot, module-level detail), and ROOT_CURRICULUM_COVERAGE_MATRIX.md (updated module/scenario totals) to reflect what Phase 6D actually built, without restating Phase 6C's own Kubernetes-scenario tables. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
# Phase 6D — ROOT_ Systems Foundations
|
||||
|
||||
Phase 6D's mission: build the foundational half of ROOT_ (ROOT 01-04) so a student reaches
|
||||
ROOT 05 already fluent in Linux/networking/Git and understanding why Kubernetes exists, using
|
||||
the existing course/module/activity model throughout.
|
||||
|
||||
## Baseline verification
|
||||
|
||||
Confirmed at start: branch `main`, clean tree, HEAD = `origin/main` =
|
||||
`bd0a10fbfb31b05a6264d083f27d85a6f7d5d50c` (the Phase 6C milestone).
|
||||
|
||||
## The central architectural finding (Section 6/7)
|
||||
|
||||
`backend/server.js`'s scenario engine (`runCommand()`) executes an arbitrary shell command
|
||||
string from a scenario's `setup_commands`/`validation.commands` and checks its output — nothing
|
||||
about it is Kubernetes-specific. This means the existing `lab` activity type and
|
||||
`scenarios/data/*.json` format already fully support Linux and Git exercises with real,
|
||||
deterministic validation. **No `shell_lab`/`git_lab`/`container_lab` activity type was built —
|
||||
the speculative multi-type model the authorization raised as a possibility was unnecessary.**
|
||||
See `docs/ROOT_FOUNDATIONS_LAB_STRATEGY.md`.
|
||||
|
||||
## Container runtime decision, tested not assumed (Section 10)
|
||||
|
||||
Installed Docker Engine (`docker.io` + a static `docker-compose` v2 binary) inside the same
|
||||
already-`Privileged: true` Lab container, alongside k3s. This does not weaken the security
|
||||
boundary — the Lab Host's own Docker socket is never touched; the nested daemon has its own
|
||||
socket inside the guest. Verified empirically against the real production resource caps (2
|
||||
vCPU, 4096MB, 512 PIDs): k3s + dockerd + a running `nginx:alpine` container + a real image
|
||||
build together used 884MB/4096MB and 160/512 PIDs, comfortable headroom in all dimensions.
|
||||
`Dockerfile` and `scripts/entrypoint.sh` updated accordingly (dockerd starts non-blockingly
|
||||
alongside k3s; a Docker daemon failure never breaks Kubernetes-only Labs).
|
||||
|
||||
## ROOT 01 — Computing & Linux Foundations: fully authored, READY
|
||||
|
||||
6 modules, 35 activities, 29 new content files, 6 new hands-on scenario files
|
||||
(`linux-inspect-hardware`, `linux-shell-basics`, `linux-filesystem-navigation`,
|
||||
`linux-files-and-text`, `linux-process-management`, `linux-permissions-foundations`) plus 2 MCQ
|
||||
scenarios, all using the existing generic scenario/validation engine — no new mechanism. Every
|
||||
lab was tested end-to-end via the real scenario API (setup → solve → validate), including
|
||||
negative tests confirming they correctly FAIL when not actually solved. A new
|
||||
`rootnode-linux-foundations-assessment` (2 required + 4 random-draw scenarios) uses the existing
|
||||
Phase 3B engine.
|
||||
|
||||
## ROOT 02-04: architecture designed, content deferred
|
||||
|
||||
`docs/ROOT_FOUNDATIONS_ARCHITECTURE.md` designs all remaining 20 modules (6+6+8) in full —
|
||||
outcomes, activities, and Real Ops connections for each. Given realistic effort constraints,
|
||||
authoring, testing, and verifying ROOT 01 to genuine READY depth was prioritized over shallow
|
||||
architecture-only coverage across all four courses (see
|
||||
`docs/ROOT_FOUNDATIONS_PILOT_READINESS.md` for the full reasoning). ROOT 02-04 remain honestly
|
||||
`status = 'planned'` with zero modules — not padded to look further along than they are.
|
||||
|
||||
## Course prerequisite chain (Section 19)
|
||||
|
||||
`courses.prerequisites` now encodes ROOT 01→02→03→04→05 server-side, verified live: a fresh
|
||||
student sees ROOT 02 correctly LOCKED (ROOT 01 is real, non-empty content) while ROOT 03/04/05
|
||||
stay unlocked (vacuously satisfied — their own prerequisite courses are still empty). Completing
|
||||
ROOT 01 unlocks ROOT 02 for that student. ROOT 06+ and the Capstone are completely unaffected
|
||||
(re-confirmed via regression). No UI-only hiding — this is a real `courses` table constraint the
|
||||
existing `prerequisitesSatisfied()` engine already enforced correctly before this phase; Phase
|
||||
6D only populated real data into it.
|
||||
|
||||
## Extension point for placement/override (Section 20)
|
||||
|
||||
Documented, not built: `courses.prerequisites` is a plain array a future placement assessment or
|
||||
instructor override could satisfy without a schema change. No bypass button implemented.
|
||||
|
||||
## Frontend (Sections 21-23)
|
||||
|
||||
No frontend change was needed or made. `CourseView.jsx` and `CurriculumView.jsx` already
|
||||
generalized correctly to ROOT 01's activity/status shapes (lesson/demonstration/knowledge_check/
|
||||
guided_exercise/lab/reflection/assessment, `ready`/`planned` status, `is_required`,
|
||||
`instructor_notes`) — the same generic rendering already proven for ROOT 05-12 in Phase 6C.
|
||||
Verified by inspection and by the real API responses `e2e-phase6d.js` and the rehearsal exercise.
|
||||
|
||||
## New application/platform code and why necessary
|
||||
|
||||
- `Dockerfile` + `scripts/entrypoint.sh`: the nested Docker Engine described above — a genuine
|
||||
platform gap (ROOT 04's course design needs it) that the existing content model couldn't
|
||||
satisfy on its own, tested and justified in `docs/ROOT_FOUNDATIONS_LAB_STRATEGY.md`.
|
||||
- No other application code. Every ROOT 01 requirement was satisfiable with the existing
|
||||
`course_modules`/`module_activities`/`assessment_definitions`/scenario-engine model.
|
||||
|
||||
## Bugs found and fixed
|
||||
|
||||
- An early draft of the real-Lab rehearsal's hardware-report step used a triple-nested
|
||||
JS-template/shell/heredoc string that silently produced a malformed file. Caught by actually
|
||||
running the rehearsal against a real Lab (not assumed to work); fixed by writing the script to
|
||||
a file and `docker cp`-ing it in rather than an inline heredoc.
|
||||
- Phase 6D's own content changes made two hardcoded assumptions in `e2e-phase6a.js`/
|
||||
`e2e-phase6b.js` stale: both suites asserted `resume` pointed at ROOT 05's gold module as "the
|
||||
first real content," which was true before this phase and is now ROOT 01. Both suites fixed
|
||||
and re-verified green against a fresh stack.
|
||||
|
||||
## Testing (Section 26)
|
||||
|
||||
`platform/test/e2e-phase6d.js` — 20/20 passing (fresh stack): ROOT 01 hierarchy, ROOT 02-04
|
||||
honestly empty, activity ordering, lab-cannot-be-manually-completed, full course completion via
|
||||
lesson/lab/assessment, prerequisite chain (both the locked and unlocked directions, on two
|
||||
separate students), existing ROOT 05+ and Capstone state unaffected, is_required rule
|
||||
unaffected, self-paced no-instructor-deferral check, instructor-notes exclusion, RBAC, logout/
|
||||
login persistence, cross-student isolation, version-bump stability, and content validation.
|
||||
|
||||
## Real-Lab rehearsal (Section 27)
|
||||
|
||||
`infra/scripts/drills/test-phase6d-foundations-rehearsal.js` — 11/11 passing against a real
|
||||
disposable Lab container (no mocking): login → enroll → resume → lesson/guided-exercise →
|
||||
real Lab launch → real bash hardware inspection (`nproc`/`free`/`df`, written to a real file) →
|
||||
real validation → real permission-denial-then-fix (`su - labuser`, genuinely denied, then
|
||||
genuinely allowed after `chmod 644`) → remaining modules → assessment → course completion →
|
||||
ROOT 02 unlock → logout/login persistence → instructor visibility of the resulting state.
|
||||
|
||||
## Regression (Section 30)
|
||||
|
||||
Re-ran 6A (21/21), 6B (24/24), 6C (17/17) fresh, each against its own freshly-reset stack per
|
||||
the established isolation convention — all green after the two resume-point staleness fixes
|
||||
above. 2A/2B/3A/3B/5A/5B/5C were not re-run: `git diff` for this phase shows no changes to
|
||||
`platform/api/src/`, gateway, or provisioner code (only the Lab image/entrypoint, migrations,
|
||||
content, scenarios, tests, and docs), so their surface area was untouched. Frontend build: clean
|
||||
(`vite build`, unchanged this phase). Lab image: rebuilt and standalone-smoke-tested directly
|
||||
(see the container runtime section above) in addition to the full-stack rehearsal.
|
||||
|
||||
## Content validation
|
||||
|
||||
`infra/scripts/validate-course-content.js` — 0 errors against 17 courses/modules with real
|
||||
content, 201 activities, 106 scenario files (98 + 8 new this phase).
|
||||
|
||||
## Known limitations / intentionally deferred
|
||||
|
||||
- ROOT 02, 03, 04 course content — architecture designed, not authored.
|
||||
- ROOT 04's Docker/Compose hands-on labs specifically — platform extension done and verified,
|
||||
course content not yet written against it.
|
||||
- Instructor-led vs. self-paced timing is not a separate database field (see
|
||||
`docs/ROOT_PROGRAM_DURATION_MODEL.md`).
|
||||
- No placement testing or instructor-override UI (explicitly out of scope this phase).
|
||||
|
||||
## Recommended Phase 6E scope
|
||||
|
||||
Author ROOT 02 (prioritize the "critical" Networking Mental Model module), then ROOT 03 (Git,
|
||||
using the already-verified local-repo strategy), then ROOT 04 (content only — the runtime is
|
||||
already built and tested).
|
||||
Reference in New Issue
Block a user