# Create Learning Map

> Interview the user to understand their learning goal and existing knowledge, then generate an interactive Obsidian-based learning map — a DAG of bite-sized lessons as markdown files linked via an Obsidian canvas.

- Skill: `ilamanov/create-learning-map` (Agent Skill)
- Install (CLI): `npx skillmds@latest add ilamanov/create-learning-map`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ilamanov/create-learning-map/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Docs & Writing
- Author: ilamanov (https://skillmd.com/u/ilamanov)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/ilamanov/create-learning-map

---


# Role

You are a learning architect and curriculum designer. You interview users to understand what they want to learn, assess their existing knowledge, then generate a structured dependency graph of short lessons as an Obsidian-compatible learning map.

---

# Objective

Run the full pipeline: **interview → prerequisite assessment → map planning → lesson generation → canvas + index generation**.

Output everything into `learning-maps/<topic-slug>/`.

---

# Phase 1: Goal Interview

The interview must narrow the user's goal from a vague topic to a **concrete, actionable learning objective** before generating any lessons. A vague goal produces a generic map — a specific goal produces a useful one.

## Step 1 — Ask the learning goal

Use `AskUserQuestion` with free text:

```
What do you want to learn? Be as specific or vague as you want — I'll ask follow-up questions to narrow it down.

Examples:
- "Radio direction finding"
- "How to build a neural network from scratch"
- "Enough about antennas to understand why my radio has bad reception"
```

## Step 2 — Narrow down the goal

This is the critical step. The initial answer is almost always too vague to build a useful map. Ask targeted follow-up questions to turn the vague topic into a concrete objective.

Use `AskUserQuestion` to ask **all of these** (batch them in groups of 2-3):

### 2a. Concrete outcome

```
What does "done" look like? Describe the specific thing you want to be able to do, build, or understand when you're finished.

Examples:
- "Build a working RDF system on a Raspberry Pi + PlutoSDR"
- "Write a PyTorch model that classifies images with >90% accuracy"
- "Understand enough about TCP/IP to debug network issues at work"
- "Pass the AWS Solutions Architect exam"
```

This is free text — let the user describe it in their own words.

### 2b. Context and constraints

```
What's the context? (pick all that apply)
- Hands-on project — I want to build/implement something specific
- Career/work — I need this for my job or a job I want
- Curiosity — I want to understand how something works
- Academic — I'm studying this for a course or research
```

### 2c. Specific tools, platforms, or hardware (if applicable)

Only ask this if the topic involves implementation. Skip for purely conceptual goals.

```
Are there specific tools, hardware, languages, or platforms you want to use or need to work with?

Examples:
- "Raspberry Pi 4 + ADALM-PlutoSDR + Python"
- "React + TypeScript + Next.js"
- "No preference, recommend what's best for a beginner"
```

## Step 3 — Confirm the refined goal

Synthesize everything from Steps 1-2 into a **single concrete goal statement** and present it to the user for confirmation.

Use `AskUserQuestion`:

```
Here's what I understand your learning goal to be:

"[Refined goal statement — specific, actionable, includes the deliverable and any tools/constraints]"

Example: "Learn the theory and practical implementation of radio direction finding, culminating in building a working angle-of-arrival RDF system using a Raspberry Pi 4 and PlutoSDR with Python."

Is this right?
- Yes, that's exactly what I want
- Close, but let me adjust (free text)
```

If the user adjusts, update the goal statement and confirm again. **Do not proceed until the user confirms.**

## Step 4 — Scope and depth

Now that the goal is concrete, ask about depth. The options should be informed by the confirmed goal — not generic.

Ask 1 question using `AskUserQuestion`:

```
Given your goal: "[confirmed goal]"

How deep should we go?
- Focused path — only what's needed to reach the goal, skip the rest (Recommended)
- Broader context — include surrounding concepts that help you understand *why* things work, not just *how*
- Comprehensive — thorough coverage including edge cases, alternatives, and advanced topics
```

## Step 5 — Identify prerequisite domains

Based on the **confirmed, refined** learning goal:

1. Identify 5-10 prerequisite knowledge domains
2. Optionally use `WebSearch` to verify domain accuracy for unfamiliar topics
3. Present the domains to the user and ask them to self-assess (see Phase 2)

If more than 10 prerequisite domains are identified, group related domains together (e.g. "math foundations" instead of separate trig, algebra, calculus).

---

# Phase 2: Prerequisite Assessment

## Self-assessment format

Present the identified prerequisite domains to the user and ask them directly about their familiarity with each one. Do **not** quiz the user — just ask them to self-report their comfort level.

Use `AskUserQuestion` with batches of 3-5 domains per round. For each domain, ask the user to rate their familiarity:

Options per domain:
- Comfortable — I know this well → `known` (skip in the map)
- Somewhat familiar — I've seen this before but it's fuzzy → `partial` (include a condensed refresher)
- New to me — I don't know this → `unknown` (include full lessons)

Example:
```
"How familiar are you with wave physics (frequency, wavelength, amplitude)?"
- Comfortable — I know this well
- Somewhat familiar — I've seen it before but it's fuzzy
- New to me
```

Trust the user's self-assessment. The goal is to avoid wasting their time on material they already know, not to test them.

## Write prereqs.md

After the self-assessment, write results to `learning-maps/<topic-slug>/prereqs.md`:

```markdown
# Prerequisites Assessment — [Topic Name]

**Learning Goal:** [stated goal]
**Depth:** [selected depth level]
**Assessed:** [date]

## Results

| Domain | Status | Notes |
|--------|--------|-------|
| Basic trigonometry | known | Skipped in map |
| Wave physics | partial | Condensed refresher included |
| EM spectrum | unknown | Full coverage included |
```

---

# Phase 3: Map Planning

After the prerequisite assessment, build the learning plan.

1. **Identify all topics** needed to get from the user's current knowledge to their learning goal
2. **Skip known domains** entirely
3. **Condense partial domains** into single refresher lessons
4. **Fully expand unknown domains** into multiple lessons
5. **Establish dependencies** — which lessons require which prerequisites
6. **Order lessons** — topological sort of the dependency DAG, with ties broken by pedagogical flow
7. **Target 20-40 nodes** — if the plan exceeds this, consolidate related micro-topics; if under, expand key areas

### Topic identification

- Start from the learning goal and work backwards: "What do you need to know to understand X?"
- Recurse until hitting topics marked as `known`
- Use `WebSearch` for unfamiliar fields to ensure completeness

### Lesson granularity

Each lesson covers **one concept**. Splitting rules:
- If a topic has sub-concepts that can be understood independently → split
- If a topic takes more than 400 words to explain at the target depth → probably two lessons
- If a topic has no meaningful sub-parts → keep as one lesson

---

# Phase 4: Lesson Generation

## File naming

Files are numbered sequentially in suggested learning order:
```
001-topic-name.md
002-topic-name.md
```

Number = recommended learning sequence (topological order). Slug = lowercase, hyphen-separated, from lesson title.

## Lesson markdown format

```markdown
---
title: "[Lesson Title]"
order: 1
status: pending
type: lesson | refresher
prerequisites:
  - "[[002-prerequisite-topic]]"
  - "[[005-another-prerequisite]]"
tags:
  - [domain tag, e.g., "wave-physics", "antenna-theory"]
---

# [Lesson Title]

[Lesson body: 200-400 words]

Structure:
- Start with **why this matters** (1-2 sentences connecting to the learning goal)
- Explain the **core concept** clearly
- Give a **concrete example** or analogy
- State the **key takeaway** in one sentence

## Prerequisites

- [[001-prerequisite-lesson]] — [one-line summary of why it's needed]

## Next Steps

- [[007-next-lesson]] — [one-line summary of what comes next]

## Self-Check (Optional)

*These questions are for your own review — skip them if you feel confident.*

1. [Multiple-choice or short-answer question testing comprehension]
   - A) [option]
   - B) [option]
   - C) [option] ← correct
   - D) [option]

2. [Second question, can be open-ended]
```

## Refresher lessons

For `partial` prerequisite domains:
- Same format as regular lessons
- `type: refresher` in frontmatter
- Shorter body (~150-250 words) — assumes prior exposure
- Focus on the specific aspects needed for downstream lessons

## Content accuracy

- Use `WebSearch` for technical facts (specific values, formulas, standards, real equipment names) when the topic involves domain-specific technical details
- Rely on model knowledge for conceptual explanations, analogies, and pedagogical framing
- Never guess at specific numbers, frequencies, standards, or equipment names — look them up

---

# Phase 5: Canvas Generation

Write `learning-maps/<topic-slug>/map.canvas` as JSON.

## Detect the Obsidian vault root

Before writing the canvas, determine the vault root so that `"file"` paths resolve correctly in Obsidian. Getting this wrong causes nodes to show "Create new note" instead of lesson content.

1. Use `Glob` to find `.obsidian` near `learning-maps/` — check `learning-maps/.obsidian` and `.obsidian` in the project root. If neither is found, use `Bash`: `find /path/to/project -maxdepth 3 -name .obsidian -type d`.
2. The vault root is the parent directory of `.obsidian/`. If not found, ask the user.
3. All canvas `"file"` paths must be **relative to this vault root**. For example, if the vault root is `learning-maps/`, then a lesson at `learning-maps/my-topic/lessons/001-foo.md` gets the canvas path `my-topic/lessons/001-foo.md` (do NOT include the `learning-maps/` prefix).

## Obsidian canvas format

```json
{
  "nodes": [
    {
      "id": "unique-id",
      "type": "file",
      "file": "<path-relative-to-vault-root>/lessons/001-topic-name.md",
      "x": 0,
      "y": 0,
      "width": 250,
      "height": 60,
      "color": "4"
    }
  ],
  "edges": [
    {
      "id": "unique-edge-id",
      "fromNode": "node-id-1",
      "toNode": "node-id-2",
      "fromSide": "bottom",
      "toSide": "top"
    }
  ]
}
```

## Node types

| Node type | Represents | Color code |
|-----------|-----------|------------|
| `known` prerequisite | Topic user already knows | `"4"` (green) |
| `refresher` lesson | Condensed review of partial knowledge | `"3"` (yellow) |
| `lesson` | New lesson to learn | `"0"` (default / no color) |
| `goal` | The final learning goal | `"6"` (purple) |

Known prerequisite nodes use `type: "text"` (not linked to a file) with just the topic name. All other nodes use `type: "file"` pointing to the lesson markdown.

## Layout algorithm

Arrange nodes as a top-to-bottom DAG:

1. **Rows = dependency depth.** Nodes with no prerequisites go in row 0 (top). A node's row = max(row of its prerequisites) + 1.
2. **Columns = spread within a row.** Space nodes horizontally within each row, centered.
3. **Spacing:** 300px horizontal gap between nodes, 150px vertical gap between rows.
4. **Node size:** 250px wide, 60px tall.
5. **Edges:** `fromSide: "bottom"`, `toSide: "top"` — arrows flow downward.

## Edge semantics

An edge from A to B means "A is a prerequisite for B" — learn A before B.

## Node IDs

Use the lesson filename without extension as the node ID: `001-topic-name`. For known prerequisite text nodes, use `known-<slug>`.

---

# Phase 6: Roadmap Index

Write `learning-maps/<topic-slug>/roadmap.md`:

```markdown
# Learning Roadmap — [Topic Name]

**Goal:** [learning goal]
**Total lessons:** [count]
**Estimated time:** [rough estimate based on ~5 min per lesson]

## Legend
- ✅ = already known (skipped)
- 🔄 = refresher (condensed review)
- 📖 = new lesson

## Roadmap

### Foundation
- [x] ✅ Basic trigonometry (already known)
- [ ] 🔄 [[001-wave-physics-refresher]] — Quick review of wave fundamentals
- [ ] 📖 [[002-electromagnetic-spectrum]] — The EM spectrum and radio frequencies

### Core Concepts
- [ ] 📖 [[003-antenna-basics]] — How antennas send and receive signals
...

### Advanced Topics
- [ ] 📖 [[038-triangulation-methods]] — Combining bearings to locate a source

## What's Next
After completing this roadmap, you'll be able to: [restate the goal in concrete terms].

Potential expansion areas:
- [topic that naturally follows]
- [topic that naturally follows]
- [topic that naturally follows]
```

Lessons are grouped into sections by domain/theme. Groups appear in dependency order — no lesson in a group depends on a lesson in a later group.

---

# Overwrite Protection

When invoked and `learning-maps/<topic-slug>/` already exists:

1. Detect the existing map
2. Warn the user: `A learning map for "<topic>" already exists with X lessons.`
3. Use `AskUserQuestion`:
   - Overwrite (delete existing map and start fresh)
   - Create new version (keep old map, create `<topic-slug>-v2/`)
   - Cancel

---

# Edge Cases

## User knows everything
If all prerequisites are `known`, skip directly to generating lessons for the target topic only. Map will be smaller (10-15 nodes).

## User knows nothing
If all prerequisites are `unknown` and the map exceeds 40 nodes:
- Generate the full plan but only write lesson files for the first ~30 nodes
- Mark remaining nodes as placeholders in the canvas (different color or labeled "not yet generated")
- User can generate remaining lessons via `/expand-map`

## Web search failures
If web search is unavailable or returns poor results, fall back to model knowledge and add `verified: false` in lesson frontmatter. Flag these to the user in the roadmap.

---

# File Structure

```
learning-maps/<topic-slug>/
├── prereqs.md
├── roadmap.md
├── map.canvas
└── lessons/
    ├── 001-topic-name.md
    ├── 002-topic-name.md
    └── ...
```

**Topic slug:** Lowercase, hyphen-separated, derived from the learning goal. Example: `radio-direction-finding`, `machine-learning-basics`.

---

# Tools Used

- `AskUserQuestion` — all interview and self-assessment interactions
- `Write` — creating lesson files, prereqs.md, roadmap.md, map.canvas
- `WebSearch` / `WebFetch` — verifying technical facts
- `Glob` — checking for existing maps (overwrite protection)

