Knowledge Graph
Every Graspful course is a directed acyclic graph. Concepts are nodes. Edges encode two kinds of relationships: prerequisites and encompassing links. The graph drives everything — task selection, diagnostics, spaced repetition, and mastery enforcement.
What is a knowledge graph?
A knowledge graph is a directed acyclic graph (DAG) where each node represents one teachable concept — a single idea that can be tested independently. Edges between nodes express how concepts relate to each other. The graph must be acyclic: you cannot have circular dependencies where A requires B and B requires A.
The right granularity matters. A concept should be small enough to master in one sitting (10-30 minutes) but large enough to test meaningfully. "Ohm's Law" is a good concept. "All of circuit analysis" is too broad. "The letter V in V=IR" is too narrow.
Prerequisite edges
A prerequisite edge from concept A to concept B means "you must understand A before you can learn B." The adaptive engine enforces this: a student will never be assigned tasks for B until A is mastered.
Prerequisites are transitive. If A is a prerequisite of B, and B is a prerequisite of C, then A is implicitly a prerequisite of C. You should only declare direct prerequisites — the engine infers the rest. Keep it to 3-4 direct prerequisites per concept to match working memory limits.
concepts:
- id: voltage
name: Voltage
difficulty: 2
estimatedMinutes: 15
prerequisites: [] # foundational — no prerequisites
- id: ohms-law
name: Ohm's Law
difficulty: 3
estimatedMinutes: 20
prerequisites:
- voltage # must master Voltage first
- id: circuit-analysis
name: Circuit Analysis
difficulty: 5
estimatedMinutes: 30
prerequisites:
- ohms-law # only list the direct prerequisite
# voltage is inferred transitivelyEncompassing edges
An encompassing edge says "practicing concept B automatically exercises concept A." Each edge carries a weight between 0.0 and 1.0 that controls how much credit flows backward.
This is the mechanism behind implicit repetition. When a student correctly solves a circuit analysis problem, they are also exercising Ohm's Law and voltage concepts. The encompassing weight determines how much spaced-repetition credit each ancestor receives.
Weight guidelines
- - 1.0: Fully exercises the target as a subskill (rare — the child is essentially a superset)
- - 0.5 - 0.7: Substantially exercises the target (e.g., circuit analysis exercises Ohm's Law)
- - 0.2 - 0.4: Partially exercises the target (e.g., a word problem partially exercises arithmetic)
- - < 0.2: Probably not worth listing — the connection is too weak to matter
concepts:
- id: circuit-analysis
name: Circuit Analysis
difficulty: 5
estimatedMinutes: 30
prerequisites:
- ohms-law
encompassing:
- concept: ohms-law
weight: 0.8 # heavily exercises Ohm's Law
- concept: voltage
weight: 0.6 # substantially exercises Voltage
# When a student practices Circuit Analysis:
# - Ohm's Law gets 0.8× spaced-repetition credit
# - Voltage gets 0.6× spaced-repetition credit
# This means advanced students don't need to go back
# and drill basics separately — the graph handles it.The knowledge frontier
The frontier is the set of concepts a student is ready to learn right now. A concept is on the frontier when all of its prerequisites are mastered but the concept itself is not yet mastered.
The frontier is the core input to task selection. The learning engine picks from frontier concepts, weighted by priority (due reviews first, then new material). A student with no mastered concepts has a frontier containing only root nodes — concepts with zero prerequisites.
As the student masters concepts, the frontier expands. As they master everything, it shrinks. A fully mastered course has an empty frontier (until spaced repetition flags something for review).
Course graph: sections and concepts
The underlying knowledge graph is a flat DAG — no hierarchy. But humans need structure. Courses add two organizational layers on top of the graph: sections group related concepts for display, and courses bundle everything with metadata.
Sections are purely for human navigation. They do not affect the adaptive engine, task selection, or prerequisite enforcement. A concept's prerequisites can span sections freely — the graph doesn't care about section boundaries.
Sections can optionally include a sectionExam — a checkpoint exam that gates progression. See the Course Schema docs for details.
course:
id: electrical-fundamentals
name: Electrical Fundamentals
estimatedHours: 12
version: "2026.1"
sections:
- id: dc-circuits
name: DC Circuits
description: Voltage, current, resistance, and basic analysis
- id: ac-circuits
name: AC Circuits
description: Alternating current, impedance, and phasors
concepts:
# DC section — root concepts
- id: voltage
name: Voltage
section: dc-circuits
difficulty: 2
estimatedMinutes: 15
prerequisites: []
- id: current
name: Current
section: dc-circuits
difficulty: 2
estimatedMinutes: 15
prerequisites: []
# DC section — depends on roots
- id: ohms-law
name: Ohm's Law
section: dc-circuits
difficulty: 3
estimatedMinutes: 20
prerequisites: [voltage, current]
encompassing:
- concept: voltage
weight: 0.6
- concept: current
weight: 0.6
# AC section — cross-section prerequisite
- id: impedance
name: Impedance
section: ac-circuits
difficulty: 5
estimatedMinutes: 25
prerequisites: [ohms-law] # crosses section boundary — that's fine
encompassing:
- concept: ohms-law
weight: 0.7Graph validation
The importer validates several graph properties at import time. Violations are rejected before any data is written.
- - No cycles: The prerequisite graph must be a DAG. Cycles make mastery enforcement impossible.
- - All references resolve: Every concept ID in a prerequisites or encompassing array must exist in the course.
- - Weights in range: Encompassing weights must be between 0.0 and 1.0 inclusive.
- - Reachability: Every concept must be reachable from at least one root node (a concept with no prerequisites).
Run graspful validate course.yaml locally to catch graph errors before importing.