docs(phase6e): document the ROOT Foundations Completion milestone

Adds PHASE6E_ROOT_FOUNDATIONS_COMPLETION.md (the phase's own record: what was authored, the
dash-vs-bash scenario bug found and fixed, the pre-existing lock-enforcement gap found and
fixed, the regression fallout that fix revealed in earlier suites and why each was a stale test
assumption rather than a platform bug, and honest test/rehearsal/regression results).

Updates ROOT_FOUNDATIONS_PILOT_READINESS.md (full re-audit: all 4 ROOT Foundations courses now
READY, not inherited blindly from Phase 6D), ROOT_PROGRAM_DURATION_MODEL.md (real ROOT 02-04
duration data: 24.7 combined hours, landing inside Phase 6D's own estimated range; 67.9 hours
across the full authored program), ROOT_PILOT_CURRICULUM.md (ROOT 02-04 move from NOT IN PILOT
to IN PILOT with full module-level detail; the pilot is now genuinely self-paced-capable for the
entire foundational half, not just instructor-led), ROOT_PROGRAM_ARCHITECTURE.md and
ROOT_CURRICULUM_COVERAGE_MATRIX.md (course/module/scenario totals), and
ROOT_FOUNDATIONS_ARCHITECTURE.md (marked as-built, not just as-designed).

Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
2026-08-26 17:09:02 -05:00
co-authored by Claude Sonnet 5
parent 59edceea1f
commit 87ad1251ce
7 changed files with 357 additions and 110 deletions
+171
View File
@@ -0,0 +1,171 @@
# Phase 6E — ROOT Foundations Completion
Phase 6E's mission: finish what Phase 6D deliberately left for a future phase — ROOT 02 (Linux
Administration & Networking), ROOT 03 (Git & Collaborative Development), and ROOT 04
(Containers & Docker) — completing the real ROOT 01→02→03→04→05 foundational path.
## Baseline verification
Confirmed at start: branch `main`, clean tree, HEAD = `origin/main` = Phase 6D's
`b6516a74db2d5a5d53d2f1f76c5f2d74e4ed35eb`.
## ROOT 02, 03, 04 — architecture, content, labs
All three courses were authored to the exact same gold-module standard already proven in ROOT
01: real lessons/demonstrations/knowledge-checks/guided-exercises/reflections, real hands-on labs
using the existing generic scenario/validation engine, and a wired course assessment. See
`docs/ROOT_FOUNDATIONS_PILOT_READINESS.md` for the full module-by-module evidence and
`docs/ROOT_PILOT_CURRICULUM.md` for the pilot manifest detail.
**ROOT 02** (6 modules, 37 activities): the Networking Mental Model module (M3) received
deliberately extra depth per its "critical module" designation — no lab by design (conceptual
mastery via knowledge check and guided exercise), with every later module building on it
explicitly. Real Labs: a nginx-inspection task that never touches the platform's own reverse
proxy, a controllable start/stop service lifecycle, disk-usage forensics, `ip`/`ss`/`getent`
diagnostics, and a genuine DNS-resolves-but-port-is-wrong diagnose-and-fix.
**ROOT 03** (6 modules, 31 activities): uses only real LOCAL Git repositories — a real merge
conflict caused on purpose and resolved by the student, and a real local bare repository
standing in for a remote (clone/commit/push, verified independently on the "remote" side). No
Gitea account, no network access, no RootNode credential of any kind ever reaches a student Lab.
**ROOT 04** (8 modules, 43 activities): uses the nested Docker Engine Phase 6D built and tested.
Real Labs: `docker run`/`exec`/`inspect` fluency, a genuine "works internally, unreachable from
host" port-publishing diagnosis and fix, a real destroy/recreate volume-persistence proof, a
real Dockerfile build, and a real two-service Compose application.
## The central architectural finding, confirmed again
Every new scenario this phase (Linux, Git, Docker) uses the exact same generic scenario/
validation engine ROOT 01 proved — `runCommand()` executes an arbitrary shell command and checks
its output, nothing Kubernetes-specific. No new activity type, no new mechanism.
## A real, reproducible dash-vs-bash bug, found and fixed
`&>file` (bash's combined-redirect shorthand) silently misparses under `/bin/sh` (dash, this
image's actual shell, confirmed via `readlink -f /bin/sh`), which is what
`backend/server.js`'s `runCommand()` uses — a scenario's `setup_commands` using `&>` captured
the WRONG process's PID via `$!`, breaking a later `kill $(cat pid)` step with "No such
process." Found while testing `linux-service-lifecycle` and `linux-dns-http-diagnosis` against
the real API (not assumed). Fixed by using the POSIX-portable `>file 2>&1` form in both affected
scenarios' `setup_commands`/hints.
## A real, pre-existing security gap, found and fixed
Testing the real ROOT 01→02→03→04→05 chain via direct API (Step 11's explicit requirement)
revealed that `POST /api/student/activities/:activityId/complete`
(`platform/api/src/course-routes.js`) checked only that the activity exists and the student
holds an active PROGRAM enrollment — **never** whether the activity's own course/module was
actually unlocked for that student. A direct POST could mark any `manual_marker` activity
complete regardless of the prerequisite chain. This is the exact class of gap Phase 6B already
fixed once for the capstone's own start route, just never closed for this more general route.
**Proven to predate Phase 6E**, not introduced by it: reproduced against an unrelated ROOT 05/06
pair before touching any Phase 6E content, confirming the gap was real and pre-existing, just
never triggered before because ROOT 01-04 (and therefore any REAL prerequisite gate before ROOT
05) didn't exist with real content until this phase and Phase 6D.
**Fix**: the route now calls the same `buildCourseTree()`/lock computation every other route
already trusts, resolves the activity's own course and module within that tree, and returns
`403 { error: 'locked' }` if either is locked — reusing the exact mechanism, not a second,
duplicated check. Verified live: both a ROOT 02 bypass attempt (behind the new chain) and a
ROOT 06 bypass attempt (a completely unrelated, pre-existing course pair) are now correctly
rejected, while legitimate unlocked completions still succeed.
## Regression fallout from a genuine, correct fix — and what it revealed
Enforcing this lock for real broke several EARLIER e2e suites' own historical shortcuts: tests
written under the old (buggy) permissive behavior had accumulated small ordering gaps —
completing a course's modules out of the order its own real prerequisite chain requires, or
skipping a scenario the ALL_STAGES/FOUNDATION lists never included because the corresponding
activity was added in a later phase. None of these were platform bugs; each was a stale test
assumption the missing enforcement had been silently covering for. Found and fixed, with the
underlying scenario gap named explicitly in each case:
- `e2e-phase6a.js`/`e2e-phase6b.js`/`e2e-phase6c.js`/`e2e-phase6d.js`: needed the real ROOT
01-04 completion sequence injected before touching ROOT 05+ content, since ROOT 05's real
prerequisite (ROOT 04) is no longer vacuously satisfied. Extracted into a new shared
`platform/test/foundations-helper.js` (`completeRootFoundations01Through04`,
`completeThroughRoot06`, `completeThroughRoot10`) rather than duplicating ~30-80 lines four
times.
- `e2e-phase6b.js`'s `bypass` student flow: needed `deployment-rollback`, `job-task`,
`cronjob-task`, and `container-logging-mcq` scenarios completed explicitly — all four exist in
the real curriculum but were added in phases after the original `ALL_STAGES` list was written,
so completing "every stage scenario" via that stale list never actually finished
`root-06`/`root-10` the COURSE, only their originally-scoped subset.
- `e2e-phase6a.js`'s and `e2e-phase6d.js`'s own ROOT 01/05 completion tests needed each module
completed fully (lesson→demo→kc→guided→**lab→reflection**) before moving to the next, since
ROOT 01's (and ROOT 05's) own modules carry real intra-course prerequisites — completing every
module's front half first and circling back for labs/reflections later is exactly the ordering
the newly-enforced lock now correctly rejects.
- Two now-obsolete Phase-6D-era assertions in `e2e-phase6d.js` ("ROOT 02-04 stay PLANNED," "ROOT
03-05 stay vacuously unlocked") were updated to assert the opposite, with a comment explaining
Phase 6E intentionally changed that fact.
## Testing
`platform/test/e2e-phase6e.js` — 23/23 passing (fresh stack): full ROOT 02/03/04 hierarchy,
content, and assessment-pool verification; the complete ROOT 01→02→03→04→05 chain proven on one
student (each course's completion unlocking exactly the next, nothing further); the direct-API
lock bypass proven blocked on both a Phase 6E course pair and a pre-existing, unrelated pair;
existing ROOT 06+/Capstone/`is_required` behavior confirmed unaffected; self-paced no-instructor-
deferral scan; instructor-notes exclusion and RBAC; logout/login persistence; cross-student
isolation; content-version stability; content validation.
## Real-Lab rehearsal
`infra/scripts/drills/test-phase6e-foundations-rehearsal.js` — 13/13 passing against a real,
freshly-built stack: real Platform API/Gateway/Provisioner/disposable Lab, real shell, real
nested Docker, real Git, real k3s (left completely untouched, still healthy at the end). Walks
one genuinely representative real-Lab task per new course (a real nginx-inspection Lab for ROOT
02, a real merge-conflict resolution for ROOT 03, a real container-networking diagnose-and-fix
for ROOT 04) plus the full ROOT 01-04 chain to a genuine ROOT 05 unlock, with an instructor
narrative confirming the resulting learning state is visible.
## Regression
Full fresh-stack reruns after every fix: 6A (23/23), 6B (26/26), 6C (17/17), 6D (20/20), 6E
(23/23) — all green. 2A/2B/3A/3B/5A/5B/5C not re-run: `git diff` for this phase touches only
`platform/api/src/course-routes.js` (the one real application-code change) plus content/
migrations/tests/docs — confirmed by grep that none of those earlier suites reference the
`/api/student/activities/:id/complete` route this phase's fix touched.
## Frontend, Lab image, nested Docker, k3s
No frontend change was needed — `CourseView.jsx`/`CurriculumView.jsx` already generalize
correctly to every ROOT 02-04 activity/status shape (proven by the rehearsal and e2e suite, not
assumed). Frontend build: clean, unchanged this phase. Lab image: rebuilt with the dash-fix and
new scenario files, standalone-smoke-tested and exercised extensively via the rehearsal (real
nested Docker + real k3s side by side, k3s health reconfirmed untouched at the rehearsal's end).
## New application code and why necessary
`platform/api/src/course-routes.js` — the lock-enforcement fix described above. This is the
ONLY application code changed this phase; every course/content requirement was satisfiable with
the existing `course_modules`/`module_activities`/`assessment_definitions`/scenario-engine
model.
## Content validation
`infra/scripts/validate-course-content.js` — 0 errors, all courses/modules with real content,
the full activity/scenario set including this phase's 17 new scenario files (6 Linux task
scenarios, 2 Linux MCQs, 3 Git task scenarios, 2 Git MCQs, 5 Docker task scenarios, 2 Docker
MCQs — see the migrations for the exact counts per course).
## Known limitations
- Instructor-led vs. self-paced timing remains prose in Instructor Notes, not a separate
database field (unchanged from Phase 6D).
- Three practice-bank modules from earlier phases (root-06-m01, root-07-m01, root-10-m02) remain
instructor-led-only this pilot — unrelated to Phase 6E's own scope, unchanged.
- No placement testing or instructor-override UI (explicitly out of scope, as in every prior
phase) — the extension point (`courses.prerequisites` as a plain array) remains documented in
`docs/ROOT_FOUNDATIONS_ARCHITECTURE.md`.
## Recommended Phase 6F scope
With the entire ROOT_ foundational-to-capstone path now genuinely READY, natural next
directions: author ROOT 08 (Storage & Scheduling) to close the last PARTIAL Kubernetes course;
build the future lab infrastructure ROOT 11 modules 2-7 need (a Git+ArgoCD environment for
GitOps, a CI runner for CI/CD) and author that content; or invest in self-paced teaching layers
for the three remaining instructor-led-only practice-bank modules.
+19 -3
View File
@@ -14,9 +14,25 @@ new hands-on Linux scenarios plus 2 MCQs, all READY. This is the program's first
the Kubernetes/CKS content this matrix was originally scoped to, so it is documented separately the Kubernetes/CKS content this matrix was originally scoped to, so it is documented separately
in `docs/ROOT_FOUNDATIONS_ARCHITECTURE.md` and `docs/PHASE6D_ROOT_FOUNDATIONS.md` rather than in `docs/ROOT_FOUNDATIONS_ARCHITECTURE.md` and `docs/PHASE6D_ROOT_FOUNDATIONS.md` rather than
folded into the tables below, which remain the ROOT 05+ (Kubernetes) scenario-coverage record. folded into the tables below, which remain the ROOT 05+ (Kubernetes) scenario-coverage record.
Post-Phase-6D totals: **28 modules total across all courses with any content — 22 READY, 6 Post-Phase-6D totals: 28 modules total across all courses with any content — 22 READY, 6
PARTIAL** (Phase 6C's 22 modules — 16 READY, 6 PARTIAL — plus 6 new ROOT 01 modules, all READY). PARTIAL (Phase 6C's 22 modules — 16 READY, 6 PARTIAL — plus 6 new ROOT 01 modules, all READY).
**106 scenario files** (98 + 8 new). 106 scenario files (98 + 8 new).
## Phase 6E addition
Phase 6E authored ROOT 02 (Linux Administration & Networking, 6 modules, 37 activities), ROOT 03
(Git & Collaborative Development, 6 modules, 31 activities), and ROOT 04 (Containers & Docker, 8
modules, 43 activities) in full — completing the entire ROOT_ Foundations sequence
(ROOT 01-04). See `docs/PHASE6E_ROOT_FOUNDATIONS_COMPLETION.md` and
`docs/ROOT_FOUNDATIONS_PILOT_READINESS.md`. 20 new hands-on/MCQ scenarios (6 Linux task + 2
Linux MCQ, 3 Git task + 2 Git MCQ, 5 Docker task + 2 Docker MCQ).
**Post-Phase-6E totals: 48 modules total across all courses with any content — 42 READY, 6
PARTIAL** (unchanged PARTIAL set: root-06-m01, root-07-m01, root-08-m01, root-08-m02,
root-10-m02, root-11-m01 — none touched by this phase). **126 scenario files** (106 + 20 new).
The entire ROOT_ program now has a complete, READY, real path from Computing & Linux
Foundations through the Capstone, excluding only the explicitly-deferred ROOT 08 and ROOT 11
modules 2-7 — see `docs/ROOT_PILOT_CURRICULUM.md`.
## Phase 6C verification (superseding Phase 6B's own self-reported counts) ## Phase 6C verification (superseding Phase 6B's own self-reported counts)
+6
View File
@@ -7,6 +7,12 @@ activity type or content model was needed. Every course below is a row that alre
`courses` (`status='planned'`, seeded by Phase 6A's `022_course_content.sql`) — this phase adds `courses` (`status='planned'`, seeded by Phase 6A's `022_course_content.sql`) — this phase adds
their modules and activities, and updates their `status`/`objectives`/`prerequisites`. their modules and activities, and updates their `status`/`objectives`/`prerequisites`.
**Status as of Phase 6E:** this document was written as a DESIGN in Phase 6D, when only ROOT 01
was actually authored. As of Phase 6E, all four courses below (ROOT 01-04) are fully authored
and READY exactly as designed here — see `docs/PHASE6E_ROOT_FOUNDATIONS_COMPLETION.md` and
`docs/ROOT_FOUNDATIONS_PILOT_READINESS.md` for the built/verified state. The module tables below
remain accurate as the as-built architecture, not just the original plan.
## Course sequence and prerequisite chain ## Course sequence and prerequisite chain
``` ```
+56 -45
View File
@@ -1,65 +1,76 @@
# ROOT Foundations Pilot Readiness — ROOT 01-04 # ROOT Foundations Pilot Readiness — ROOT 01-04
Phase 6D §24 — the honest READY/PARTIAL/DEFERRED classification for ROOT 01-04, using the same Phase 6E §27 — the honest, re-audited READY/PARTIAL/DEFERRED classification for ROOT 01-04,
bar `docs/ROOT_PILOT_READINESS_STANDARD.md` established in Phase 6C. The standard is not using the same bar `docs/ROOT_PILOT_READINESS_STANDARD.md` established in Phase 6C. Phase 6D's
lowered because these courses are new. ROOT 01 classification is not inherited blindly — it is revalidated here against the same
standard, using the same evidence discipline (real API verification, not assumption).
## ROOT 01 — Computing & Linux Foundations: READY ## ROOT 01 — Computing & Linux Foundations: READY (revalidated)
All 6 modules re-confirmed READY this phase — no ROOT 01 content itself changed, but its real
prerequisite gate to ROOT 02 was verified for real (previously it could only be vacuously
satisfied, since ROOT 02 didn't exist). `e2e-phase6d.js` and `e2e-phase6e.js` both independently
re-prove ROOT 01's full lesson→lab→assessment→completion path end to end, fresh, this phase.
## ROOT 02 — Linux Administration & Networking: READY
All 6 modules meet the 8-point standard: All 6 modules meet the 8-point standard:
| Module | Status | Evidence | | Module | Status | Evidence |
|---|---|---| |---|---|---|
| M1 How Computers Run Software | READY | Lesson, guided exercise, real hands-on lab (`linux-inspect-hardware`), reflection. Verified via `e2e-phase6d.js` and the real-Lab rehearsal (`infra/scripts/drills/test-phase6d-foundations-rehearsal.js`). | | M1 Linux System Administration | READY | Lesson/demo/kc/guided + 2 real labs (`linux-service-inspection` — inspects the platform's own real nginx without touching it; `linux-service-lifecycle` — start/verify/stop a real service) + reflection. Both labs tested end-to-end via the real scenario-validation API, including negative tests. |
| M2 Linux and the Shell | READY | Full gold pattern (lesson/demo/kc/guided/lab/reflection). Lab (`linux-shell-basics`) tested end-to-end via the real scenario-validation API, including a negative test (fails when unsolved). | | M2 Storage & Filesystems | READY | Full gold pattern. `linux-storage-inspection` tested end-to-end, negative-tested. |
| M3 Navigating the Filesystem | READY | Full gold pattern. Lab (`linux-filesystem-navigation`) tested end-to-end. | | M3 Networking Mental Model | READY | The course's "critical module," given extra lesson depth. No lab by design (conceptual mastery via knowledge check + guided exercise), matching `root-05-m00`'s precedent. |
| M4 Files and Text | READY | Full gold pattern. Lab (`linux-files-and-text`) tested end-to-end. | | M4 Linux Network Inspection | READY | Full gold pattern. `linux-network-inspection` tested end-to-end. |
| M5 Processes | READY | Full gold pattern. Lab (`linux-process-management`) tested end-to-end, including a negative test (fails while the process is still running). | | M5 DNS & HTTP | READY | Full gold pattern. `linux-dns-http-diagnosis` (a genuine port-mismatch diagnose-and-fix) tested end-to-end, negative-tested. |
| M6 Users & Permissions Foundations | READY | Full gold pattern. Lab (`linux-permissions-foundations`) tested end-to-end via the real-Lab rehearsal, including a REAL permission denial (a second Linux user genuinely denied read access) before the fix. | | M6 Linux Troubleshooting | READY | Full gold pattern. `linux-troubleshooting-framework` (a real missing-config-file failure, diagnosed via the RootNode framework) tested end-to-end, negative-tested. |
**Self-paced readiness:** confirmed programmatically — `infra/scripts/validate-course-content.js`'s **Assessment:** `rootnode-linux-networking-assessment` wired and verified live (2 required + 4
deferral-phrase check and `e2e-phase6d.js`'s equivalent live check both scan every ROOT 01 random scenarios, 6 total).
activity's student-visible content for "ask your instructor" or equivalent and found none.
**Instructor-led readiness:** every lesson/demonstration/guided_exercise/reflection activity has ## ROOT 03 — Git & Collaborative Development: READY
a real Instructor Notes section (timing, misconceptions, discussion questions), verified hidden
from students both statically and via a live API check.
**Assessment:** `rootnode-linux-foundations-assessment` wired and verified live (real draw: 2 | Module | Status | Evidence |
required hands-on tasks + 2 random hands-on tasks + 2 random MCQs, 6 scenarios total). |---|---|---|
| M1 Why Version Control Exists | READY | Conceptual opener (lesson/kc/reflection) — no lab needed, motivational content. |
| M2 Git Mental Model | READY | Full teaching pattern, no lab by design (model before commands, matching ROOT 02 M3's precedent). |
| M3 Everyday Git | READY | `git-everyday-basics` — a REAL local Git repository, init/add/commit, validated by inspecting actual `git log`/`git show` state, not just command output strings. Tested end-to-end, negative-tested. |
| M4 Branching & Merging | READY | `git-branching-and-merge` — a REAL merge conflict, caused on purpose (two branches editing the same line), resolved by the student, validated by inspecting the real merge commit and confirming conflict markers are gone. Tested end-to-end (including via the real-Lab rehearsal), negative-tested. |
| M5 Remote Repositories | READY | `git-remote-clone-push` — a REAL local bare repository standing in for a remote; clone/commit/push validated by inspecting the REMOTE side directly, not just the student's clone. No account, no network, no RootNode credential ever used. Tested end-to-end. |
| M6 Engineering Git Workflow | READY | Conceptual closer bridging to CI/CD/GitOps — no lab by design. |
## ROOT 02 — Linux Administration & Networking: DEFERRED **Assessment:** `rootnode-git-fundamentals-assessment` wired and verified live (2 required + 3
random scenarios, 5 total). All state-validated via real `git` commands against real
repositories, not string-matched command output alone (Step 6's explicit requirement).
Architecture fully designed in `docs/ROOT_FOUNDATIONS_ARCHITECTURE.md` (6 modules, including the ## ROOT 04 — Containers & Docker: READY
explicitly "critical" Networking Mental Model module). Zero modules authored this phase — course
remains `status = 'planned'`, honestly, with a real (not fabricated) `prerequisites` gate to
ROOT 01 already in place so the sequence is correct once it IS authored.
## ROOT 03 — Git & Collaborative Development: DEFERRED | Module | Status | Evidence |
|---|---|---|
| M1 Why Containers Exist | READY | Conceptual opener, no lab by design. |
| M2 Images & Containers | READY | The image/container distinction, no lab by design (model before commands). |
| M3 Docker CLI | READY | `docker-cli-basics` — real `docker run`/`exec`/`inspect` against the nested Docker Engine, validated by inspecting real container state. Tested end-to-end, negative-tested. |
| M4 Container Networking | READY | `docker-container-networking` — a REAL "works internally, unreachable from host" failure (no port published), diagnosed and fixed by recreating the container with `-p`. Tested end-to-end via the real-Lab rehearsal AND negative-tested. |
| M5 Container Storage | READY | `docker-container-storage` — a REAL destroy/recreate cycle proving named-volume persistence, not just described. Tested end-to-end. |
| M6 Dockerfile & Image Build | READY | `docker-build-image` — a real Dockerfile, a real build, a real custom image run. Tested end-to-end. |
| M7 Docker Compose | READY | `docker-compose-multiservice` — a real two-service Compose application, real `docker compose up`, validated via real service state and a real published port. Tested end-to-end. |
| M8 Containers → Kubernetes | READY | The explicit bridge module — no lab by design (honest: the course's job is naming what Kubernetes adds, not re-teaching Kubernetes itself). |
Architecture designed (6 modules, local-repository-only strategy documented in **Assessment:** `rootnode-containers-assessment` wired and verified live (2 required + 4 random
`docs/ROOT_FOUNDATIONS_LAB_STRATEGY.md` §4). Zero modules authored this phase. scenarios, 6 total).
## ROOT 04 — Containers & Docker: DEFERRED (content) / PLATFORM EXTENSION DONE ## The real ROOT 01→02→03→04→05 chain
Architecture designed (8 modules). **The platform extension ROOT 04 needs — a nested Docker Verified live, repeatedly, this phase: a fresh student sees ROOT 02 genuinely LOCKED (not
Engine inside the Lab — was built and verified this phase** (`docs/ROOT_FOUNDATIONS_LAB_STRATEGY.md` vacuously satisfied — ROOT 01 has real content now) until ROOT 01 completes; the same holds at
§3: real `docker run`, `docker build`, and `docker compose` all tested working inside the actual every subsequent boundary through ROOT 05. Direct API attempts to bypass this were tested and
`rootnode-academy:test` image under production resource constraints). No course content was (after a real bug was found and fixed — see `docs/PHASE6E_ROOT_FOUNDATIONS_COMPLETION.md`)
authored against it yet — that's a real, substantial content-authoring effort left for a future correctly rejected with `403 locked`.
phase, now unblocked by this phase's platform work.
## Why ROOT 02-04 were not authored this phase
Given realistic effort constraints in a single phase, authoring, testing, and verifying ROOT 01
to the same rigor as every ROOT 05+ module (real scenarios, live end-to-end verification, a
real-Lab rehearsal, an assessment) was prioritized over shallow architecture-only coverage
across all four courses. This mirrors Phase 6C's own precedent: some content built to a genuine
READY bar, the rest explicitly and honestly DEFERRED with a real reason, rather than every
course padded to look further along than it is (`e2e-phase6d.js`'s own first test explicitly
asserts ROOT 02-04 have zero modules, catching any future accidental over-claim).
## Honest totals ## Honest totals
**READY: 1 course (ROOT 01), 6 modules. DEFERRED: 3 courses (ROOT 02-04), 0 modules — by **READY: 4 of 4 courses (ROOT 01, 02, 03, 04), 26 of 26 modules.** Every module in the ROOT
design, not oversight.** Foundations sequence meets the same readiness bar — self-paced sufficient (verified: no
"ask your instructor" language anywhere in student-visible content), instructor-notes covered,
real hands-on labs with real state validation where hands-on work is the right teaching tool,
and honest conceptual-only modules where the subject genuinely doesn't need one.
+54 -18
View File
@@ -7,24 +7,26 @@ marketed as more finished than it is. See
means and [`docs/ROOT11_DEVOPS_PLATFORM_SCOPE.md`](ROOT11_DEVOPS_PLATFORM_SCOPE.md) for the means and [`docs/ROOT11_DEVOPS_PLATFORM_SCOPE.md`](ROOT11_DEVOPS_PLATFORM_SCOPE.md) for the
ROOT 11 scope decision referenced below. ROOT 11 scope decision referenced below.
## Pilot delivery mode: instructor-led (cohort-based) ## Pilot delivery mode: instructor-led (cohort-based), with a fully self-paced foundation
The first pilot is scoped as **instructor-led**, not fully self-paced. Every module below that The first pilot is scoped as **instructor-led** as its recommended default, not because most of
is marked READY meets the self-paced bar (no "your instructor will explain this" gaps). A the curriculum requires it — as of Phase 6E, ROOT 01-04 (the entire foundational half) and every
smaller set of modules — flagged explicitly — are READY for instructor-led delivery only, Kubernetes/security/troubleshooting/real-ops/capstone module EXCEPT three specific practice-bank
because they are dense hands-on practice banks whose sibling module in the same course already modules meet the full self-paced bar (no "your instructor will explain this" gaps, verified
carries the taught concept; running them live lets an instructor supply framing a self-paced programmatically). Those three flagged modules — dense hands-on practice banks whose sibling
student wouldn't get. Fully self-paced delivery of those specific modules is deferred to a module in the same course already carries the taught concept — are READY for instructor-led
future phase pending an authored teaching layer for each. See Section 16 discussion below. delivery only; running them live lets an instructor supply framing a self-paced student wouldn't
get. Fully self-paced delivery of those specific modules is deferred to a future phase pending an
authored teaching layer for each. See Section 16 discussion below.
## Program: ROOT_ (root-kubernetes-foundations) ## Program: ROOT_ (root-kubernetes-foundations)
| Course | Pilot status | Notes | | Course | Pilot status | Notes |
|---|---|---| |---|---|---|
| ROOT 01 Computing & Linux Foundations | **IN PILOT** (added Phase 6D) | Fully authored, READY — 6 modules, real hands-on Linux Labs, a wired assessment. See `docs/PHASE6D_ROOT_FOUNDATIONS.md`. | | ROOT 01 Computing & Linux Foundations | **IN PILOT** (added Phase 6D) | Fully authored, READY — 6 modules, real hands-on Linux Labs, a wired assessment. See `docs/PHASE6D_ROOT_FOUNDATIONS.md`. |
| ROOT 02 Linux Administration & Networking | **NOT IN PILOT** | Architecture designed (`docs/ROOT_FOUNDATIONS_ARCHITECTURE.md`), content not yet authored. | | ROOT 02 Linux Administration & Networking | **IN PILOT** (added Phase 6E) | Fully authored, READY — 6 modules, real hands-on Linux/networking Labs, a wired assessment. See `docs/PHASE6E_ROOT_FOUNDATIONS_COMPLETION.md`. |
| ROOT 03 Git & Collaborative Development | **NOT IN PILOT** | Architecture designed, content not yet authored. | | ROOT 03 Git & Collaborative Development | **IN PILOT** (added Phase 6E) | Fully authored, READY — 6 modules, real local-Git Labs (including a real merge conflict and a real local-bare-remote push), a wired assessment. |
| ROOT 04 Containers & Docker | **NOT IN PILOT** | Architecture designed; its platform extension (nested Docker Engine) is built and tested, content not yet authored. | | ROOT 04 Containers & Docker | **IN PILOT** (added Phase 6E) | Fully authored, READY — 8 modules using the nested Docker Engine (built Phase 6D), real hands-on container Labs, a wired assessment. |
| ROOT 05 Kubernetes Foundations | **IN PILOT** | See modules below. | | ROOT 05 Kubernetes Foundations | **IN PILOT** | See modules below. |
| ROOT 06 Kubernetes Application Workloads | **IN PILOT** | See modules below. | | ROOT 06 Kubernetes Application Workloads | **IN PILOT** | See modules below. |
| ROOT 07 Kubernetes Networking & Configuration | **IN PILOT** | See modules below. | | ROOT 07 Kubernetes Networking & Configuration | **IN PILOT** | See modules below. |
@@ -47,6 +49,38 @@ future phase pending an authored teaching layer for each. See Section 16 discuss
| root-01-m05-processes | READY | m04 | Inspect and correctly terminate a real process | Self-paced or instructor-led | 6 required | 1 lab | | root-01-m05-processes | READY | m04 | Inspect and correctly terminate a real process | Self-paced or instructor-led | 6 required | 1 lab |
| root-01-m06-users-and-permissions-foundations | READY | m05 | Apply rwx permissions and the least-privilege principle | Self-paced or instructor-led | 7 required | 1 lab + **ROOT 01 Linux Foundations Assessment** (6-scenario timed exam) | | root-01-m06-users-and-permissions-foundations | READY | m05 | Apply rwx permissions and the least-privilege principle | Self-paced or instructor-led | 7 required | 1 lab + **ROOT 01 Linux Foundations Assessment** (6-scenario timed exam) |
### ROOT 02 — Linux Administration & Networking (added Phase 6E)
| Module | Status | Prerequisite | Outcome | Delivery | Required/Optional | Labs/Assessment |
|---|---|---|---|---|---|---|
| root-02-m01-linux-system-administration | READY | ROOT 01 | Answer the five-question service checklist for a real service | Self-paced or instructor-led | 7 required | 2 labs |
| root-02-m02-storage-and-filesystems | READY | m01 | Distinguish df from du; find real disk usage | Self-paced or instructor-led | 6 required | 1 lab |
| root-02-m03-networking-mental-model | READY | m02 | The critical networking model — no lab by design | Self-paced or instructor-led | 5 required | none (conceptual) |
| root-02-m04-linux-network-inspection | READY | m03 | Use ip/ss/getent/curl to answer specific diagnostic questions | Self-paced or instructor-led | 6 required | 1 lab |
| root-02-m05-dns-and-http | READY | m04 | Categorize a failure as DNS/routing/TCP/application | Self-paced or instructor-led | 6 required | 1 lab |
| root-02-m06-linux-troubleshooting | READY | m05 | Apply the RootNode framework to a real Linux failure | Self-paced or instructor-led | 7 required | 1 lab + **ROOT 02 Linux Administration & Networking Assessment** (6-scenario timed exam) |
### ROOT 03 — Git & Collaborative Development (added Phase 6E)
| Module | Status | Prerequisite | Outcome | Delivery | Required/Optional | Labs/Assessment |
|---|---|---|---|---|---|---|
| root-03-m01-why-version-control-exists | READY | ROOT 02 | Explain what version control gives you beyond copying files | Self-paced or instructor-led | 3 required | none (conceptual) |
| root-03-m02-git-mental-model | READY | m01 | The working-tree/staging/repository model — no lab by design | Self-paced or instructor-led | 5 required | none (conceptual) |
| root-03-m03-everyday-git | READY | m02 | init/status/add/commit/log/diff fluently | Self-paced or instructor-led | 6 required | 1 lab (real repository state) |
| root-03-m04-branching-and-merging | READY | m03 | Cause and resolve a real merge conflict | Self-paced or instructor-led | 6 required | 1 lab (real conflict) |
| root-03-m05-remote-repositories | READY | m04 | Clone/commit/push to a real local-bare remote | Self-paced or instructor-led | 6 required | 1 lab |
| root-03-m06-engineering-git-workflow | READY | m05 | Small-commit/review/protect-main discipline; bridge to CI/CD/GitOps | Self-paced or instructor-led | 4 required | none (conceptual) + **ROOT 03 Git & Collaborative Development Assessment** (5-scenario timed exam) |
### ROOT 04 — Containers & Docker (added Phase 6E)
| Module | Status | Prerequisite | Outcome | Delivery | Required/Optional | Labs/Assessment |
|---|---|---|---|---|---|---|
| root-04-m01-why-containers-exist | READY | ROOT 03 | The dependency-inconsistency problem; VM vs. container | Self-paced or instructor-led | 4 required | none (conceptual) |
| root-04-m02-images-and-containers | READY | m01 | The image/container distinction precisely | Self-paced or instructor-led | 5 required | none (conceptual) |
| root-04-m03-docker-cli | READY | m02 | run/exec/ps/logs/inspect/stop/rm fluently | Self-paced or instructor-led | 6 required | 1 lab |
| root-04-m04-container-networking | READY | m03 | Diagnose and fix a real "unreachable from host" failure | Self-paced or instructor-led | 6 required | 1 lab |
| root-04-m05-container-storage | READY | m04 | Prove volume persistence with a real destroy/recreate cycle | Self-paced or instructor-led | 6 required | 1 lab |
| root-04-m06-dockerfile-and-image-build | READY | m05 | Write a real Dockerfile; build a real image | Self-paced or instructor-led | 6 required | 1 lab |
| root-04-m07-docker-compose | READY | m06 | Run a real multi-service application declaratively | Self-paced or instructor-led | 6 required | 1 lab |
| root-04-m08-containers-to-kubernetes | READY | m07 | Explain what Kubernetes adds beyond Docker — the explicit bridge to ROOT 05 | Self-paced or instructor-led | 3 required | none (conceptual) + **ROOT 04 Containers & Docker Assessment** (6-scenario timed exam) |
### ROOT 05 — Kubernetes Foundations ### ROOT 05 — Kubernetes Foundations
| Module | Status | Prerequisite | Outcome | Delivery | Required/Optional | Labs/Assessment | | Module | Status | Prerequisite | Outcome | Delivery | Required/Optional | Labs/Assessment |
|---|---|---|---|---|---|---| |---|---|---|---|---|---|---|
@@ -109,8 +143,6 @@ instructor-only prep material was created outside the per-activity Instructor No
## What is intentionally NOT in the first pilot ## What is intentionally NOT in the first pilot
- ROOT 02-04 (architecture designed in Phase 6D, content not yet authored — ROOT 01 IS now in
the pilot, added Phase 6D).
- ROOT 08 Kubernetes Storage & Scheduling (non-capstone-gating; both modules remain PARTIAL). - ROOT 08 Kubernetes Storage & Scheduling (non-capstone-gating; both modules remain PARTIAL).
- ROOT 11 modules 2-7 (GitOps, CI/CD, IaC, hands-on Observability, hands-on Reliability) — see - ROOT 11 modules 2-7 (GitOps, CI/CD, IaC, hands-on Observability, hands-on Reliability) — see
scope doc. scope doc.
@@ -123,8 +155,12 @@ instructor-only prep material was created outside the per-activity Instructor No
## Bottom line ## Bottom line
Every module the pilot's required completion path depends on (ROOT 01, 05-07, 09-10, 12, The ROOT_ pilot now runs a complete, beginning-to-advanced path: ROOT 01-04 (Linux → networking
Capstone) meets the READY bar for instructor-led delivery, and ROOT 01's self-paced readiness → Git → containers), ROOT 05-07/09-10 (Kubernetes), ROOT 12 (Real Ops), and the Capstone — every
was verified explicitly (see `docs/PHASE6D_ROOT_FOUNDATIONS.md`). Three specific modules run module in that path meets the READY bar, and ROOT 01-04's self-paced readiness was verified
instructor-led only this pilot. ROOT 02-04, ROOT 08, and most of ROOT 11 are explicitly out of explicitly this phase (real API tests, a real-Lab rehearsal covering real Linux/Docker/Git
the required path. Given that scope, the pilot curriculum, delivered instructor-led, is ready. actions, and a programmatic scan for instructor-deferral language across every module). Three
specific practice-bank modules (root-06-m01, root-07-m01, root-10-m02) run instructor-led only
this pilot. ROOT 08 and most of ROOT 11 are explicitly out of the required path. Given that
scope, the pilot curriculum — genuinely self-paced-capable end to end, with instructor-led as
the recommended default for a first cohort — is ready.
+15 -10
View File
@@ -26,9 +26,9 @@ prerequisite chain (01→02→03→04→05) enforced server-side.
| # | Course | Status | Why | | # | Course | Status | Why |
|---|---|---|---| |---|---|---|---|
| 1 | Computing & Linux Foundations | **READY** | Phase 6D: 6 modules, real Linux/shell scenarios using the existing generic scenario engine, a wired assessment — see `docs/PHASE6D_ROOT_FOUNDATIONS.md`. | | 1 | Computing & Linux Foundations | **READY** | Phase 6D: 6 modules, real Linux/shell scenarios using the existing generic scenario engine, a wired assessment — see `docs/PHASE6D_ROOT_FOUNDATIONS.md`. |
| 2 | Linux Administration & Networking | **PLANNED** | Architecture designed (`docs/ROOT_FOUNDATIONS_ARCHITECTURE.md`); content not yet authored. Real prerequisite: ROOT 01 complete. | | 2 | Linux Administration & Networking | **READY** | Phase 6E: 6 modules, real Linux/networking scenarios, a wired assessment — see `docs/PHASE6E_ROOT_FOUNDATIONS_COMPLETION.md`. Real prerequisite: ROOT 01 complete. |
| 3 | Git & Collaborative Development | **PLANNED** | Architecture designed; content not yet authored. Real prerequisite: ROOT 02 complete. | | 3 | Git & Collaborative Development | **READY** | Phase 6E: 6 modules, real local-Git scenarios (including a real merge conflict and a real local-bare-remote push), a wired assessment. Real prerequisite: ROOT 02 complete. |
| 4 | Containers & Docker | **PLANNED** | Architecture designed; the nested-Docker-Engine platform extension it needs was built and verified this phase (`docs/ROOT_FOUNDATIONS_LAB_STRATEGY.md` §3), course content not yet authored. Real prerequisite: ROOT 03 complete. | | 4 | Containers & Docker | **READY** | Phase 6E: 8 modules using the nested Docker Engine (built and verified Phase 6D, `docs/ROOT_FOUNDATIONS_LAB_STRATEGY.md` §3), real container scenarios, a wired assessment. Real prerequisite: ROOT 03 complete. |
| 5 | Kubernetes Foundations | **PARTIAL** | Phase 6B added a READY front-door module (`root-05-m00-kubernetes-mental-model` — full lesson/demo/knowledge-check/guided-exercise/lab/reflection) sequenced before the existing 20-scenario bare-lab bank (`root-05-m01`), which now sits behind it. | | 5 | Kubernetes Foundations | **PARTIAL** | Phase 6B added a READY front-door module (`root-05-m00-kubernetes-mental-model` — full lesson/demo/knowledge-check/guided-exercise/lab/reflection) sequenced before the existing 20-scenario bare-lab bank (`root-05-m01`), which now sits behind it. |
| 6 | Kubernetes Application Workloads | **PARTIAL** | Phase 6B added a READY `root-06-m02-deployments-scaling-updates` and a PARTIAL `root-06-m03-jobs-cronjobs-daemonsets`, both in front of the existing bare-lab bank. | | 6 | Kubernetes Application Workloads | **PARTIAL** | Phase 6B added a READY `root-06-m02-deployments-scaling-updates` and a PARTIAL `root-06-m03-jobs-cronjobs-daemonsets`, both in front of the existing bare-lab bank. |
| 7 | Kubernetes Networking & Configuration | **PARTIAL** | Phase 6B added a READY `root-07-m03-services-and-service-discovery` and a PARTIAL `root-07-m04-ingress-networkpolicy-foundations`. The existing configuration bank (`root-07-m02`) still has no authored teaching content — an honest, documented gap. | | 7 | Kubernetes Networking & Configuration | **PARTIAL** | Phase 6B added a READY `root-07-m03-services-and-service-discovery` and a PARTIAL `root-07-m04-ingress-networkpolicy-foundations`. The existing configuration bank (`root-07-m02`) still has no authored teaching content — an honest, documented gap. |
@@ -67,13 +67,18 @@ one complete module (the gold standard) as the authoring template, not a finishe
CAPSTONE — Operate & Recover CAPSTONE — Operate & Recover
``` ```
**Updated for Phase 6D:** 01→02→03→04→05 is now a real, server-side prerequisite chain **Updated for Phase 6D:** 01→02→03→04→05 became a real, server-side prerequisite chain
(`courses.prerequisites`). Since ROOT 01 is now real content and 02-04 remain PLANNED, ROOT 02 (`courses.prerequisites`). At that point ROOT 01 was real content and 02-04 remained PLANNED, so
is the first course this chain actually locks (behind ROOT 01); 03/04/05 stay vacuously ROOT 02 was the only course the chain actually locked; 03/04/05 stayed vacuously satisfied
satisfied until their own prerequisite course is authored — see until their own prerequisite course was authored — see `docs/COURSE_CONTENT_MODEL.md`'s
`docs/COURSE_CONTENT_MODEL.md`'s "prerequisite/locking rule" for why a PLANNED/content-free "prerequisite/locking rule" for why a PLANNED/content-free prerequisite never actually blocks
prerequisite never actually blocks anything, and `docs/PHASE6D_ROOT_FOUNDATIONS.md` for the live anything.
verification of this behavior on both a completed and a fresh student.
**Updated for Phase 6E** (`docs/PHASE6E_ROOT_FOUNDATIONS_COMPLETION.md`): ROOT 02, 03, and 04 are
now real, authored, READY courses — the ENTIRE 01→02→03→04→05 chain now genuinely gates for a
real student, verified live on both a fully-completed student and a fresh one. A pre-existing
gap in the direct-API completion route (found while proving this chain, unrelated to any single
phase's own content) is also fixed this phase — see that document for detail.
## Deviations from the spec's suggested sequence, and why ## Deviations from the spec's suggested sequence, and why
+36 -34
View File
@@ -1,18 +1,17 @@
# ROOT_ Program Duration Model # ROOT_ Program Duration Model
Phase 6D §25 — the actual instructional-hour estimate, computed by summing real Phase 6E §28 — recalculated from actual authored activities in the live database. Run:
`module_activities.estimated_duration_minutes` values from the live database, not invented or `SELECT c.course_id, SUM(a.estimated_duration_minutes) ... GROUP BY c.course_id` against the
marketed backward from a target number. Run: `SELECT c.course_id, SUM(a.estimated_duration_minutes) ... current schema, same method as Phase 6D's original version of this document.
GROUP BY c.course_id` against the current schema.
## Per-course totals (self-paced estimate) ## Per-course totals (self-paced estimate)
| Course | Activities | Minutes | Hours | | Course | Activities | Minutes | Hours |
|---|---|---|---| |---|---|---|---|
| ROOT 01 Computing & Linux Foundations | 35 | 338 | 5.6 | | ROOT 01 Computing & Linux Foundations | 35 | 338 | 5.6 |
| ROOT 02 Linux Administration & Networking | 0 | 0 | 0 (not yet authored) | | ROOT 02 Linux Administration & Networking | 37 | 388 | 6.5 |
| ROOT 03 Git & Collaborative Development | 0 | 0 | 0 (not yet authored) | | ROOT 03 Git & Collaborative Development | 31 | 312 | 5.2 |
| ROOT 04 Containers & Docker | 0 | 0 | 0 (not yet authored) | | ROOT 04 Containers & Docker | 43 | 444 | 7.4 |
| ROOT 05 Kubernetes Foundations | 28 | 403 | 6.7 | | ROOT 05 Kubernetes Foundations | 28 | 403 | 6.7 |
| ROOT 06 Kubernetes Application Workloads | 22 | 295 | 4.9 | | ROOT 06 Kubernetes Application Workloads | 22 | 295 | 4.9 |
| ROOT 07 Kubernetes Networking & Configuration | 27 | 353 | 5.9 | | ROOT 07 Kubernetes Networking & Configuration | 27 | 353 | 5.9 |
@@ -22,39 +21,42 @@ GROUP BY c.course_id` against the current schema.
| ROOT 11 DevOps & Platform Engineering | 3 | 35 | 0.6 | | ROOT 11 DevOps & Platform Engineering | 3 | 35 | 0.6 |
| ROOT 12 Real Ops | 6 | 115 | 1.9 | | ROOT 12 Real Ops | 6 | 115 | 1.9 |
| ROOT Capstone | 5 | 120 | 2.0 | | ROOT Capstone | 5 | 120 | 2.0 |
| **Total (all authored content)** | **201** | **2,931** | **48.9** | | **Total (all authored content)** | **312** | **4,075** | **67.9** |
**ROOT Foundations (01-04) subtotal: 146 activities, 1,482 minutes, 24.7 hours.** This is now
real, measured data — Phase 6D's own version of this document correctly flagged the eventual
"20-25 hour" range as a planning ESTIMATE pending real authorship; the actual total (24.7 hours)
landed inside that estimated range.
## Self-paced vs. instructor-led ## Self-paced vs. instructor-led
The figures above are self-paced estimates — the sum of each activity's own As in Phase 6D's version of this document: the figures above are self-paced estimates (the sum
`estimated_duration_minutes`, which is how long a student working alone is expected to need for of each activity's own `estimated_duration_minutes`). Instructor-led classroom time is still not
that specific lesson/lab/reflection. This is the one number this phase can honestly derive a separate summable database field — every Instructor Notes section documents approximate live-
programmatically. facilitation timing in prose (e.g. ROOT 02 Module 3's "25 minutes read; 15-20 minutes live with
discussion — longer than a typical lesson, deliberately"), but this remains per-activity
**Instructor-led classroom time is NOT separately tracked as a distinct database field** — every guidance embedded in Markdown, not a column a query can sum. A future phase could add a distinct
Instructor Notes section already documents approximate live-facilitation timing in prose (e.g.
"10 minutes live discussion; 8 minutes self-paced writing"), but these are per-activity
estimates embedded in Markdown, not a summable column. A future phase could add a distinct
`estimated_duration_minutes_instructor_led` column if precise classroom scheduling becomes a `estimated_duration_minutes_instructor_led` column if precise classroom scheduling becomes a
real, measured need — this phase does not invent that precision now. As a conservative real, measured need.
approximation: instructor-led delivery of the currently-authored curriculum runs roughly the
same total or somewhat longer than the self-paced figure above, once live discussion and As a conservative approximation, instructor-led delivery of the full 67.9-hour curriculum should
demonstration time (documented per-activity) is added — do not treat 48.9 hours as a hard be expected to run somewhat longer once live discussion and demonstration time is added —
classroom-scheduling number without reading the relevant Instructor Notes first. consult the relevant Instructor Notes before scheduling a live cohort session, don't treat the
self-paced total as a classroom-time promise.
## What this is NOT ## What this is NOT
Not a marketing duration, not a promise, not a certification-hours figure. `estimated_duration_minutes` Not a marketing duration, not a promise, not a certification-hours figure.
values were themselves authored as honest guesses (see `docs/COURSE_AUTHORING_STANDARD.md` §4) `estimated_duration_minutes` values were authored as honest guesses (see
— this total will get more accurate as real completion-time data accumulates from actual `docs/COURSE_AUTHORING_STANDARD.md` §4) — this total will get more accurate as real completion-
students, not before. time data accumulates from actual students, not before.
## Once ROOT 02-04 are authored ## Program completeness
The foundational half of ROOT_ (01-04) is planned at ~6 modules each (see With ROOT 01-04 now authored, the ROOT_ program's structured curriculum (excluding ROOT 08,
`docs/ROOT_FOUNDATIONS_ARCHITECTURE.md`) — ROOT 01's actual authored total (5.6 hours across 6 deliberately deferred as non-capstone-gating, and ROOT 11 modules 2-7, deferred pending future
modules) is the only real data point so far; ROOT 02-04 should be expected to land in a similar lab infrastructure — see `docs/ROOT_PILOT_CURRICULUM.md`) now runs a complete, measured
5-7 hour range each once authored, giving a rough eventual ROOT 01-04 total near 20-25 hours, beginning-to-advanced path: Linux fundamentals → Linux administration/networking → Git →
and a full ROOT_ program total near 65-75 hours — stated here as a planning estimate, explicitly containers → Kubernetes → security → troubleshooting → real operations → capstone. This is the
not yet real data, and should be replaced with the real computed total once those three courses first phase where the FULL foundational-to-capstone path has real, authored content and a real
are actually built. measured duration at every step, not a partial curriculum starting mid-stack.