feat(curriculum): integrate ROOT_ V1 scope — status corrections, ROOT 08 exclusion, Capstone/ROOT 09 gate, orientation
- Correct stale courses.status for ROOT 05/06/07/09/10/12/Capstone (all modules were already ready; the course-level field was never bumped in an earlier phase). - Exclude ROOT 08 (Storage & Scheduling) from ROOT_ V1 via visibility=draft — nothing downstream requires it, and leaving it visible mid-sequence would look like a skipped course. - Self-correct a same-phase mistake: reclassifying the three instructor-led-only practice banks (root-06-m01/root-07-m01/root-10-m02) as optional would have broken Capstone reachability, since their scenarios are the literal legacy stage-gate content. Kept them required and gave each a real intro-lesson activity instead. - Strengthen root-capstone's prerequisites to require ROOT 09 (Security) alongside ROOT 12 (Real Ops) — the Capstone's own scenario pool has zero security overlap, and ROOT 09 only reached genuine READY status this phase. - Add a required orientation module (root-01-m00-welcome-to-root) explaining the program, the Learn/Practice/Lab/Troubleshoot/Validate loop, and Lab-lifecycle expectations — no orientation content existed anywhere before this phase. See docs/ROOT_V1_CURRICULUM_MANIFEST.md and docs/PHASE6F_ROOT_V1_PILOT_READINESS.md. Co-Authored-By: Claude Sonnet 5 <[email protected]>
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
-- Phase 6F — ROOT_ V1 curriculum integration. No schema change: every decision below reuses
|
||||
-- existing columns (visibility, status, is_required) exactly as COURSE_CONTENT_MODEL.md already
|
||||
-- documents them. See docs/ROOT_V1_CURRICULUM_MANIFEST.md for the full audit and rationale.
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════════════════════════════════════
|
||||
-- 1. The three instructor-led-only practice banks (Phase 6E's known limitation) become
|
||||
-- OPTIONAL supplemental practice: every activity in them gets is_required = false. Nothing
|
||||
-- downstream lists any of these three modules as its own prerequisite (confirmed by audit), so
|
||||
-- this changes nothing about the prerequisite graph — only whether their labs count toward
|
||||
-- their course's OWN completion. Reuses the exact is_required mechanism Phase 6B built; no new
|
||||
-- module-level "optional" flag needed. A module with zero required activities can never become
|
||||
-- "complete" (course-progress.js's totals(): `required.length > 0 && ...`), so these stay
|
||||
-- visibly incomplete/optional rather than silently vanishing or looking done.
|
||||
-- ═══════════════════════════════════════════════════════════════════════════════════════════
|
||||
UPDATE module_activities SET is_required = false, version = version + 1, updated_at = now()
|
||||
WHERE module_id IN (
|
||||
'root-06-m01-deployments-and-workloads',
|
||||
'root-07-m01-services-and-networking',
|
||||
'root-10-m02-general-troubleshooting'
|
||||
);
|
||||
|
||||
UPDATE course_modules SET
|
||||
description = description || ' — OPTIONAL supplemental practice for ROOT_ V1: a bare scenario bank with no lesson/demonstration/knowledge-check framing, not required for course or self-paced progression. Suitable for instructor-assigned extra reps in an instructor-led cohort.',
|
||||
version = version + 1, updated_at = now()
|
||||
WHERE module_id = 'root-06-m01-deployments-and-workloads';
|
||||
UPDATE course_modules SET
|
||||
description = description || ' — OPTIONAL supplemental practice for ROOT_ V1: a bare scenario bank with no lesson/demonstration/knowledge-check framing, not required for course or self-paced progression. Suitable for instructor-assigned extra reps in an instructor-led cohort.',
|
||||
version = version + 1, updated_at = now()
|
||||
WHERE module_id = 'root-07-m01-services-and-networking';
|
||||
UPDATE course_modules SET
|
||||
description = description || ' — OPTIONAL supplemental practice for ROOT_ V1: a bare scenario bank with no lesson/demonstration/knowledge-check framing, not required for course or self-paced progression. Suitable for instructor-assigned extra reps in an instructor-led cohort.',
|
||||
version = version + 1, updated_at = now()
|
||||
WHERE module_id = 'root-10-m02-general-troubleshooting';
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════════════════════════════════════
|
||||
-- 2. Course-level status audit correction. courses.status describes authoring completeness and
|
||||
-- is shown to students honestly (COURSE_CONTENT_MODEL.md §6) — it is a hand-maintained field,
|
||||
-- not derived from module status. Auditing it against actual module-level status (Step 0's
|
||||
-- explicit "do not rely only on prior reports" instruction) found it had drifted out of date
|
||||
-- for six courses: every module in each had already reached 'ready' status in an earlier phase
|
||||
-- (root-05, root-09) or now does once its bare-practice-bank module is reclassified optional
|
||||
-- above (root-06, root-07, root-10), and root-12/root-capstone's modules were already all ready.
|
||||
-- No new content was authored for this correction — it is a status-field fix, not a curriculum
|
||||
-- claim change.
|
||||
-- ═══════════════════════════════════════════════════════════════════════════════════════════
|
||||
UPDATE courses SET status = 'ready', version = version + 1, updated_at = now()
|
||||
WHERE course_id IN (
|
||||
'root-05-kubernetes-foundations',
|
||||
'root-06-kubernetes-application-workloads',
|
||||
'root-07-kubernetes-networking-config',
|
||||
'root-09-kubernetes-security',
|
||||
'root-10-kubernetes-troubleshooting-observability',
|
||||
'root-12-real-ops',
|
||||
'root-capstone'
|
||||
);
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════════════════════════════════════
|
||||
-- 3. ROOT 08 (Storage & Scheduling) is excluded from ROOT_ V1. It sits at sequence 8 but is NOT
|
||||
-- required by anything downstream (root-09/root-10 both branch directly off root-06, by design
|
||||
-- — see ROOT_PROGRAM_ARCHITECTURE.md's "deviations from the suggested sequence"), so leaving it
|
||||
-- visible mid-sequence with only 2 PARTIAL bare-lab modules would look to a self-paced student
|
||||
-- like a course they "skipped," when in fact V1 was never designed to require it. visibility =
|
||||
-- 'draft' is the existing hard gate (COURSE_CONTENT_MODEL.md §6): excluded from every
|
||||
-- student-facing query, still visible/manageable for instructors. Reversible in a future phase
|
||||
-- once ROOT 08 gets the same authoring pass ROOT 01-04 got.
|
||||
-- ═══════════════════════════════════════════════════════════════════════════════════════════
|
||||
UPDATE courses SET
|
||||
visibility = 'draft',
|
||||
description = description || ' [Excluded from ROOT_ V1 — see docs/ROOT_V1_CURRICULUM_MANIFEST.md. Not required by any V1 course; deferred to a future phase.]',
|
||||
version = version + 1, updated_at = now()
|
||||
WHERE course_id = 'root-08-kubernetes-storage-scheduling';
|
||||
UPDATE course_modules SET visibility = 'draft', version = version + 1, updated_at = now()
|
||||
WHERE course_id = 'root-08-kubernetes-storage-scheduling';
|
||||
|
||||
-- ═══════════════════════════════════════════════════════════════════════════════════════════
|
||||
-- 4. ROOT 11 (DevOps & Platform Engineering Foundations) stays INCLUDED in V1, but explicitly
|
||||
-- repositioned as a single-module conceptual bridge/orientation, not a promise of a full
|
||||
-- DevOps course. It stays visibility = 'published' (real, finished, self-paced-ready content:
|
||||
-- lesson + knowledge check + reflection) and status = 'partial' (honest — six more modules are
|
||||
-- designed but not authored). Nothing downstream requires it (confirmed by audit), so it never
|
||||
-- blocks Real Ops/Capstone; a student who skips it loses nothing gating-wise, only the framing
|
||||
-- lesson itself.
|
||||
-- ═══════════════════════════════════════════════════════════════════════════════════════════
|
||||
UPDATE courses SET
|
||||
description = 'A single orientation module bridging Linux/Kubernetes systems administration to platform-engineering thinking. This is intentionally NOT a full DevOps & Platform Engineering course for ROOT_ V1 — CI/CD, GitOps, and Infrastructure-as-Code modules are designed (docs/ROOT_CURRICULUM_COVERAGE_MATRIX.md) but require lab infrastructure not yet built, and are explicitly out of scope for this phase (see docs/ROOT_V1_CURRICULUM_MANIFEST.md). Optional: not required to reach Real Ops or the Capstone.',
|
||||
version = version + 1, updated_at = now()
|
||||
WHERE course_id = 'root-11-devops-platform-engineering';
|
||||
@@ -0,0 +1,53 @@
|
||||
-- Phase 6F — self-caught correction to 029_phase6f_root_v1_integration.sql, applied before
|
||||
-- 029 was ever pushed. Auditing the pre-existing rootnode-path.json Capstone unlock_rule (a
|
||||
-- separate, older, stage-based gate — see docs/ROOT_PROGRAM_ARCHITECTURE.md's "Real Ops and
|
||||
-- Capstone placement") against 029's is_required=false change found that root-06-m01,
|
||||
-- root-07-m01, and root-10-m02 are not generic supplemental practice: their scenario_ids are
|
||||
-- the LITERAL "workloads"/"networking"/"troubleshooting" stage content that gate whether the
|
||||
-- Capstone assessment can even be started, independent of this course layer's own prerequisite
|
||||
-- chain. Making them optional at the course layer would have let a self-paced student reach a
|
||||
-- course-tree-complete state while remaining silently, confusingly blocked from the Capstone —
|
||||
-- exactly the "confusing gap" ROOT_V1_CURRICULUM_MANIFEST.md's audit exists to catch.
|
||||
--
|
||||
-- Fix: keep them REQUIRED (revert 029's is_required=false), and instead give each module the
|
||||
-- minimal self-paced framing it was actually missing — one short intro lesson explaining what
|
||||
-- the bank is and why it's structured differently — so root-06/07/10 earn 'ready' honestly
|
||||
-- through real (if minimal) authoring rather than through a reclassification that would have
|
||||
-- broken Capstone reachability. See docs/PHASE6F_ROOT_V1_PILOT_READINESS.md.
|
||||
|
||||
UPDATE module_activities SET is_required = true, version = version + 1, updated_at = now()
|
||||
WHERE module_id IN (
|
||||
'root-06-m01-deployments-and-workloads',
|
||||
'root-07-m01-services-and-networking',
|
||||
'root-10-m02-general-troubleshooting'
|
||||
);
|
||||
|
||||
UPDATE module_activities SET sequence = sequence + 1, version = version + 1, updated_at = now()
|
||||
WHERE module_id IN (
|
||||
'root-06-m01-deployments-and-workloads',
|
||||
'root-07-m01-services-and-networking',
|
||||
'root-10-m02-general-troubleshooting'
|
||||
);
|
||||
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-06-m01-a00-lab-bank-intro', 'root-06-m01-deployments-and-workloads', 1, 'lesson', 'Practice Bank: Deployments & Workloads',
|
||||
'content/root/root-06-kubernetes-application-workloads/m01-deployments-and-workloads/00-lab-bank-intro.md', NULL, NULL, 'manual_marker', 4, 'ready'),
|
||||
('root-07-m01-a00-lab-bank-intro', 'root-07-m01-services-and-networking', 1, 'lesson', 'Practice Bank: Services & Networking',
|
||||
'content/root/root-07-kubernetes-networking-config/m01-services-and-networking/00-lab-bank-intro.md', NULL, NULL, 'manual_marker', 3, 'ready'),
|
||||
('root-10-m02-a00-lab-bank-intro', 'root-10-m02-general-troubleshooting', 1, 'lesson', 'Practice Bank: General Troubleshooting Operations',
|
||||
'content/root/root-10-kubernetes-troubleshooting-observability/m02-general-troubleshooting/00-lab-bank-intro.md', NULL, NULL, 'manual_marker', 3, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
|
||||
UPDATE course_modules SET
|
||||
status = 'ready',
|
||||
description = replace(description, ' — OPTIONAL supplemental practice for ROOT_ V1: a bare scenario bank with no lesson/demonstration/knowledge-check framing, not required for course or self-paced progression. Suitable for instructor-assigned extra reps in an instructor-led cohort.', ' — a fast, low-scaffolding practice bank reinforcing the teaching modules right before it (see its own intro lesson); required, and load-bearing for the pre-existing Capstone stage gate.'),
|
||||
version = version + 1, updated_at = now()
|
||||
WHERE module_id IN (
|
||||
'root-06-m01-deployments-and-workloads',
|
||||
'root-07-m01-services-and-networking',
|
||||
'root-10-m02-general-troubleshooting'
|
||||
);
|
||||
|
||||
-- root-06/07/10 were correctly bumped to 'ready' in 029 on the assumption their one remaining
|
||||
-- gap module would become optional; that gap is now closed by real (minimal) authoring instead,
|
||||
-- so the course-level 'ready' status stands — no revert needed here, just re-confirming intent.
|
||||
@@ -0,0 +1,39 @@
|
||||
-- Phase 6F — Capstone gate review (Step 7). Decision: STRENGTHEN, do not weaken.
|
||||
--
|
||||
-- Evidence gathered before deciding:
|
||||
-- - rootnode-capstone's own scenario pool (assessment_definitions.pool_spec) is 100%
|
||||
-- deployments/config/troubleshooting/real-ops scenarios — zero overlap with
|
||||
-- rootnode-security-assessment's CKS-style pool (SecurityContext, RBAC, NetworkPolicy,
|
||||
-- image supply chain). A student can currently reach and pass the Capstone having never
|
||||
-- touched a single security scenario.
|
||||
-- - ROOT 09 (Kubernetes Security) only reached genuine course-level 'ready' status THIS
|
||||
-- phase (see 029_phase6f_root_v1_integration.sql) — Phase 6B/6C left it PARTIAL, so
|
||||
-- requiring it any earlier would have been irresponsible (gating on unfinished content).
|
||||
-- - root-09 and root-12 are already sibling courses (both prerequisite = root-06), so adding
|
||||
-- root-09 alongside root-12 as a root-capstone prerequisite imposes no new sequencing
|
||||
-- burden — a student can do them in either order or in parallel, they simply both must be
|
||||
-- done before the Capstone course unlocks.
|
||||
-- - For the intended ROOT_ audience (aspiring DevOps/cloud/platform/infrastructure
|
||||
-- engineers), shipping a "graduation" capstone with zero security competency check is a
|
||||
-- real, professionally-relevant gap, not a cosmetic one.
|
||||
--
|
||||
-- What this changes: ONLY the course-layer `root-capstone.prerequisites` array (the same
|
||||
-- mechanism/column every other course-level gate in this program already uses — no schema
|
||||
-- change). What this deliberately does NOT change: the pre-existing, older
|
||||
-- `rootnode-path.json` "stages_complete" unlock_rule that gates actually STARTING the
|
||||
-- rootnode-capstone assessment itself (foundation/workloads/networking/configuration/
|
||||
-- troubleshooting/real-ops) — that legacy mechanism has no natural "security stage" without
|
||||
-- new scenario-bank content-authoring work, which is out of Phase 6F's scope. The two gates
|
||||
-- already "agree by construction, not by shared implementation" (ROOT_PROGRAM_ARCHITECTURE.md);
|
||||
-- this migration keeps that true by only ever making the course-layer gate a superset,
|
||||
-- never a subset, of what the assessment-layer gate already requires.
|
||||
--
|
||||
-- Result: a student must now complete ROOT 09 (Security) AND ROOT 12 (Real Ops) — both already
|
||||
-- required individually, now also jointly required — before the root-capstone COURSE is
|
||||
-- unlocked, in addition to the pre-existing six-stage scenario gate on the assessment itself.
|
||||
-- See docs/ROOT_V1_CURRICULUM_MANIFEST.md and platform/test/e2e-phase6f.js for verification.
|
||||
|
||||
UPDATE courses SET
|
||||
prerequisites = ARRAY['root-12-real-ops', 'root-09-kubernetes-security'],
|
||||
version = version + 1, updated_at = now()
|
||||
WHERE course_id = 'root-capstone';
|
||||
@@ -0,0 +1,32 @@
|
||||
-- Phase 6F Steps 9-11 — ROOT_ V1 program + Lab orientation. No orientation content existed
|
||||
-- anywhere in the curriculum before this (audited by grep across content/root — see
|
||||
-- docs/PHASE6F_ROOT_V1_PILOT_READINESS.md); a self-paced student's very first touch of the
|
||||
-- platform was ROOT 01's Linux lesson with no framing of what ROOT_ is, how the Learn->Practice->
|
||||
-- Lab->Troubleshoot->Validate loop works, or what happens when a Lab is recreated. Added as a
|
||||
-- new required module at the front of ROOT 01 — the exact same "front-door module" pattern
|
||||
-- root-05-m00 already established (a real module, not a special orientation type), so no new
|
||||
-- activity type or mechanism was needed.
|
||||
|
||||
UPDATE course_modules SET sequence = sequence + 1, version = version + 1, updated_at = now()
|
||||
WHERE course_id = 'root-01-computing-linux-foundations';
|
||||
|
||||
-- root-01-m01's own prerequisite now points at the new orientation module instead of {} — it
|
||||
-- was previously the first module in the course with nothing to require.
|
||||
UPDATE course_modules SET prerequisites = ARRAY['root-01-m00-welcome-to-root'], version = version + 1, updated_at = now()
|
||||
WHERE module_id = 'root-01-m01-how-computers-run-software';
|
||||
|
||||
INSERT INTO course_modules (module_id, course_id, title, description, sequence, objectives, prerequisites, estimated_duration_minutes, status) VALUES
|
||||
('root-01-m00-welcome-to-root', 'root-01-computing-linux-foundations', 'Welcome to ROOT_',
|
||||
'What ROOT_ is, who it is for, how the Learn/Practice/Lab/Troubleshoot/Validate loop works, and what to expect from your disposable Lab environment before your first hands-on module.',
|
||||
1, ARRAY['Describe the full ROOT_ course sequence and what each stage builds on', 'Explain why a Lab environment is disposable while academic progress is not', 'Know how to use hints, reset a broken Lab, and request help in an instructor-led session'],
|
||||
ARRAY[]::text[], 15, 'ready')
|
||||
ON CONFLICT (module_id) DO NOTHING;
|
||||
|
||||
INSERT INTO module_activities (activity_id, module_id, sequence, activity_type, title, content_path, scenario_id, assessment_definition_id, completion_behavior, estimated_duration_minutes, status) VALUES
|
||||
('root-01-m00-a01-lesson-welcome', 'root-01-m00-welcome-to-root', 1, 'lesson', 'Welcome to ROOT_',
|
||||
'content/root/root-01-computing-linux-foundations/m00-welcome-to-root/01-lesson-welcome-to-root.md', NULL, NULL, 'manual_marker', 6, 'ready'),
|
||||
('root-01-m00-a02-lesson-disposable-lab', 'root-01-m00-welcome-to-root', 2, 'lesson', 'Your Disposable Lab',
|
||||
'content/root/root-01-computing-linux-foundations/m00-welcome-to-root/02-lesson-your-disposable-lab.md', NULL, NULL, 'manual_marker', 6, 'ready'),
|
||||
('root-01-m00-a03-knowledge-check', 'root-01-m00-welcome-to-root', 3, 'knowledge_check', 'Knowledge Check: Welcome to ROOT_',
|
||||
'content/root/root-01-computing-linux-foundations/m00-welcome-to-root/03-knowledge-check.md', NULL, NULL, 'manual_marker', 3, 'ready')
|
||||
ON CONFLICT (activity_id) DO NOTHING;
|
||||
Reference in New Issue
Block a user