Content is a hierarchy plus a graph: worlds → topics → boxes, with each box naming the boxes it builds on. Validation guarantees the graph has no cycles.
flowchart TB
W[World: Graphs] --> T1[Topic: Traversal]
W --> T2[Topic: Shortest paths]
T1 --> B1[BFS]
T1 --> B2[DFS]
T2 --> B3[Dijkstra]
T2 --> B4[Bellman-Ford]
B1 -. builds on .-> B3
B3 -. builds on .-> B4
Illustrative example of the structure.
A topic map lays out a topic's boxes by depth in the build-on graph, coloured by the learner's progress: not opened yet, started or done, with markers for kept boxes and boxes due for review. A world map shows its topics with mastery. Maps are drawn on the device from the cached taxonomy and local history, so they work offline and update live as the learner keeps or reviews boxes.
| Signal | Source |
|---|---|
| Not opened · started · done | seen (deepest layer reached) |
| Kept | keeps |
| Due for review | replayed cards |
Opening a box whose prerequisites aren't met shows a "This builds on" sheet once, as the box opens (never mid-read), linking the earlier box with an option to read on anyway.
search_quality and content_requests so missing content shows up in analytics.world_waitlist, which helps decide what to write next.Onboarding asks for a few interests. The behaviour-interests job adds interests learned from behaviour, and the planner uses both, with stated interests weighted higher at first.
${sch.nav()}