From b2f1bd98ead9307eeb2cd21214939628a30bd291 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sun, 12 Jul 2026 00:31:46 -0400 Subject: [PATCH 1/6] feat(teach): add multi-session learning-coach plugin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Migrate the `teach` skill out of the medley repo into a repo-agnostic `teach` plugin (category: learning). Coaches a user through a Knowledge-Skills-Wisdom progression across sessions with persistent per-topic learning state, plus a single-session domain `primer`. Decoupling from the source repo: - All learning state persists under ${CLAUDE_PLUGIN_DATA}/// (survives plugin updates; does not pollute the consumer repo). Path resolution is inlined as the SKILL.md "Workspace layout" SSOT, replacing the source repo's learning-rules cross-reference. - Codebase mode is now a runtime discovery procedure over the consuming repo (its README / CLAUDE.md / AGENTS.md / ADRs / source tree) instead of a baked table of the source repo's paths — nothing about any project is assumed. - Cross-skill references degrade gracefully: only /book-distill:book-distill is a sibling plugin; code-exploration / research / implementation tooling degrade to prose. - HTML lesson output routes to /frontend-design:frontend-design when present, else a plain self-contained page; the durable record stays markdown. No userConfig and no setup action: the inventory confirmed no repo-varying configuration surface (Rule of Three). disable-model-invocation preserved (the user owns session entry, a pedagogy contract). Validated: `claude plugin validate ./plugins/teach` and `claude plugin validate --strict .` both pass. Smoke-tested with --plugin-dir in a throwaway Go repo (neither medley nor this repo): codebase-mode discovery grounded in that repo's own files and resolved the workspace under ${CLAUDE_PLUGIN_DATA}. Refs melodic-software/medley#1371 --- .claude-plugin/marketplace.json | 6 + README.md | 1 + plugins/teach/.claude-plugin/plugin.json | 12 ++ plugins/teach/README.md | 59 +++++ plugins/teach/skills/teach/SKILL.md | 202 ++++++++++++++++++ .../teach/skills/teach/context/assessment.md | 55 +++++ .../teach/skills/teach/context/exercises.md | 59 +++++ .../teach/skills/teach/context/glossary.md | 36 ++++ plugins/teach/skills/teach/context/lessons.md | 56 +++++ plugins/teach/skills/teach/context/mission.md | 49 +++++ .../teach/skills/teach/context/resources.md | 53 +++++ 11 files changed, 588 insertions(+) create mode 100644 plugins/teach/.claude-plugin/plugin.json create mode 100644 plugins/teach/README.md create mode 100644 plugins/teach/skills/teach/SKILL.md create mode 100644 plugins/teach/skills/teach/context/assessment.md create mode 100644 plugins/teach/skills/teach/context/exercises.md create mode 100644 plugins/teach/skills/teach/context/glossary.md create mode 100644 plugins/teach/skills/teach/context/lessons.md create mode 100644 plugins/teach/skills/teach/context/mission.md create mode 100644 plugins/teach/skills/teach/context/resources.md diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 45515748..b6951365 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -210,6 +210,12 @@ "source": "./plugins/implementation", "category": "development", "tags": ["implementation", "build", "lint", "testing", "tdd", "e2e", "verification", "skill"] + }, + { + "name": "teach", + "source": "./plugins/teach", + "category": "learning", + "tags": ["teach", "learn", "learning", "coach", "tutor", "pedagogy", "primer", "onboarding", "skill"] } ] } diff --git a/README.md b/README.md index 435c5409..2521eec7 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,7 @@ Browse and manage with `/plugin`. To refresh after updates: `/plugin marketplace | [`planning`](plugins/planning) | Skills | Pre-implementation planning pipeline of six skills: `/planning:brainstorm` (cheapest→most-ambitious candidate divergence), `/planning:prd` (three-tier product requirements), `/planning:interview` (depth-first Q&A locking a task contract into a PLAN.md Brief), `/planning:design` (collaborative type/contract/topology exploration with a binary handoff gate), `/planning:devils-advocate` (evidence-backed adversarial stress-testing), and `/planning:architect` (structured implementation plans with blast radius, parallelism analysis, and a user approval gate). | | [`review-toolkit`](plugins/review-toolkit) | Agents + Skills | Code-review toolkit: six read-only reviewer agents (code quality, security, architecture, doc drift, build/test/lint, CI-log audit) plus two orchestration skills — `/review-toolkit:quality-gate` (single-lens checkpoint with eight modes) and `/review-toolkit:code-review-fanout` (multi-surface fan-out normalized into one severity-ranked findings report, with a findings-driven fix pass). | | [`implementation`](plugins/implementation) | Skills | Implementation-stage toolkit of ten skills: `implement` / `implement-dispatch` (inline vs orchestrated plan execution with TDD cadence, divergence detection, and phase-boundary handoffs), `build` / `lint` (polyglot ecosystem-detecting verification with consumer-convention overrides), `test-write` / `test-plan` / `test-diagnose` / `test-e2e` (authoring, coverage-gap analysis, failure diagnosis, live E2E evidence), and `verify-changes` / `verify-improvement` (outcome verification and baseline-vs-after improvement measurement). | +| [`teach`](plugins/teach) | Skill | Interactive multi-session learning coach. `/teach topic` learns a general subject from external high-trust sources, `/teach codebase` learns a concept grounded in the repo it is launched from (discovering that repo's own docs and source at teach-time), and `/teach primer` gives a single-session domain vocabulary primer. Coaches through a Knowledge → Skills → Wisdom progression with persistent per-topic learning state under `${CLAUDE_PLUGIN_DATA}`. | Install one: `/plugin install @melodic-software`. diff --git a/plugins/teach/.claude-plugin/plugin.json b/plugins/teach/.claude-plugin/plugin.json new file mode 100644 index 00000000..b24ce9bb --- /dev/null +++ b/plugins/teach/.claude-plugin/plugin.json @@ -0,0 +1,12 @@ +{ + "$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json", + "name": "teach", + "version": "0.1.0", + "description": "Interactive multi-session learning coach: teaches a general subject or a concept grounded in the consuming repo through the Knowledge-Skills-Wisdom progression, with persistent per-topic learning state. Also a single-session domain primer.", + "author": { + "name": "Melodic Software", + "email": "info@melodicsoftware.com" + }, + "license": "MIT", + "keywords": ["teach", "learn", "learning", "coach", "tutor", "pedagogy", "primer", "onboarding", "skill"] +} diff --git a/plugins/teach/README.md b/plugins/teach/README.md new file mode 100644 index 00000000..2ccf336b --- /dev/null +++ b/plugins/teach/README.md @@ -0,0 +1,59 @@ +# teach + +A Claude Code plugin that coaches you through learning a subject — across +multiple sessions — instead of lecturing at you. It runs a +**Knowledge → Skills → Wisdom** progression grounded in your real goal, and keeps +persistent per-topic learning state so each session builds on the last. + +Invoke it with `/teach` and an action, for example `/teach topic rust-ownership`, +`/teach codebase auth-flow`, or `/teach primer color-grading`. + +## What it does + +- **`topic `** — learn a general subject from external high-trust + sources (books, courses, docs, communities). +- **`codebase `** — learn a concept grounded in the repository you launch + it from. It discovers the repo's own docs, conventions, and source at teach-time + and teaches from what it finds — nothing about the project is assumed. +- **`primer `** — a single-session vocabulary primer for an unfamiliar + domain, so you can prompt or direct work in it precisely. No workspace. +- Supporting actions: `mission`, `glossary`, `resources`, `explain`, `exercise`, + `assess`, `resume`, `status`. + +The coach asks questions before giving answers, teaches just beyond your current +level (the zone of proximal development), and grounds every claim in a source +fetched or a file read that session rather than from memory. + +## How it works + +Each topic gets a **workspace** — a mission (why you're learning this), a glossary, +curated resources, and per-concept slices (a lesson, a durable reference +cheat-sheet, and optional practice). All of it persists under +`${CLAUDE_PLUGIN_DATA}`, which survives plugin updates and stays out of your +project's tree, so you can resume a topic weeks later. Durable references are +re-verified lazily on revisit (age × domain-velocity) so stale facts get refreshed +before they're taught. See the skill body for the full pedagogy. + +## Requirements + +- None beyond Claude Code. For `codebase` mode, launch it from the repository you + want to learn — the plugin reads that repo's own docs and source. + +## Install + +```shell +/plugin marketplace add melodic-software/claude-code-plugins +/plugin install teach@melodic-software +``` + +## Configuration + +This plugin has no `userConfig`. Everything it needs comes from the action you +invoke, and its cross-session learning state persists automatically under +`${CLAUDE_PLUGIN_DATA}`. There is nothing to configure and nothing to edit in the +plugin itself. + +## License + +MIT (SPDX-License-Identifier: MIT). See the LICENSE file at the root of the +melodic-software/claude-code-plugins repository. diff --git a/plugins/teach/skills/teach/SKILL.md b/plugins/teach/skills/teach/SKILL.md new file mode 100644 index 00000000..54794b96 --- /dev/null +++ b/plugins/teach/skills/teach/SKILL.md @@ -0,0 +1,202 @@ +--- +name: teach +description: "Interactive multi-session learning coach for general topics or repo-grounded concepts; also a single-session domain primer (primer action). Use when: 'teach me', 'study session', 'help me learn', 'onboard me to', 'learn this codebase'. Coaches through the Knowledge-Skills-Wisdom progression with persistent per-topic learning state. Not for one-off inline questions (answer directly)." +argument-hint: " [args] (e.g., /teach topic rust-ownership, /teach codebase auth-flow, /teach primer color-grading)" +user-invocable: true +disable-model-invocation: true +--- + +## Purpose + +Teach a user interactively across multiple sessions — not by lecturing, but by coaching through the Knowledge-Skills-Wisdom progression grounded in the user's real goals. Maintains persistent learning state so each session builds on prior understanding. + +**Use when:** user asks to learn across sessions (`teach me`, `study session`, `help me learn`, `onboard me to`). **Skip when:** one-off inline question (answer directly); task-context codebase investigation (use the project's own code-exploration tooling); extracting book knowledge to a reference file (`/book-distill:book-distill` when installed). + +Two modes share pedagogy but differ in source material: + +- **`topic`** — general subject learning. Resources come from external high-trust sources (books, courses, docs, communities). +- **`codebase`** — repo-grounded learning. Resources come from the consuming repo's own code, docs, ADRs, conventions, discovered at teach-time (see "Codebase mode"). + +**Workspace layout** (where persistent learning state lives): see "Workspace layout" below — the single source of truth every action resolves paths against. Informed by ZPD/K-S-W pedagogy research. + +## Workspace layout + +All persistent learning state lives under the plugin's own per-plugin data directory, which survives plugin updates and does not pollute the consuming repo: + +```text +${CLAUDE_PLUGIN_DATA}/// +├── MISSION.md WHY the user is learning this — goal, success criteria, constraints (workspace-global) +├── GLOSSARY.md durable terminology SSOT — add only when the user demonstrates understanding (global) +├── RESOURCES.md curated high-trust sources (knowledge + wisdom communities) (global) +├── NOTES.md teaching preferences + working notes — how the user wants to be taught (global) +├── learning-records/ cross-cutting ZPD log — ADR-style insight records (append-only) +│ ├── 0001-.md +│ └── 0002-.md +└── concepts/ per-concept slices + └── / ONE tightly-scoped thing — things that change together, together + ├── lesson.md ephemeral teaching unit (rarely revisited) + ├── reference.md durable compressed cheat-sheet (revisited; the rot-relevant artifact) + └── exercise.md colocated practice (optional) +``` + +Path resolution rules every action MUST follow: + +- **``** — the basename of `${CLAUDE_PROJECT_DIR}` slugified to lowercase alphanumerics and hyphens, then `-` plus the first 8 hex chars of the SHA-256 of the resolved absolute project path (`printf '%s' "" | { sha256sum 2>/dev/null || shasum -a 256; } | cut -c1-8` — the fallback covers stock macOS). The basename alone collides when two clones or worktrees share a directory name. Both `topic` and `codebase` workspaces are scoped under `` — topic learning becomes associated with the project you launched from. +- **``** and **``** — content-named kebab slugs (lowercase alphanumerics and hyphens only; strip `/`, `\`, `..`), NOT sequence-numbered. `"Domain-Driven Design"` → `domain-driven-design`; `"Rust Ownership"` → `rust-ownership`. +- **`learning-records/NNNN-.md`** keeps `NNNN-` numbering (sanctioned ADR-style append-only log). Scan the directory for the highest existing `NNNN` and increment. +- `${CLAUDE_PLUGIN_DATA}` is created automatically the first time it is referenced and persists across plugin updates, so workspaces survive between sessions. + +`lesson` / `reference` / `exercise` default to `.md` — the durable teaching record stays markdown, the diffable source of truth. HTML session output is optional per "Lessons and Reference". + +## Pre-computed Context + +Existing workspaces: !`ls -d "${CLAUDE_PLUGIN_DATA}"/*/*/ 2>/dev/null | head -20 || echo "none"` + +## Action Router + +Parse `$ARGUMENTS`: first token = action, remainder = args. If empty or ambiguous, detect from conversation. + +| Action | Purpose | Detail | +|--------|---------|--------| +| `topic ` | Start or resume learning a general subject | Creates workspace, runs mission interview if new | +| `codebase ` | Learn a concept grounded in the consuming repo's code | Creates workspace, grounds in actual discovered files | +| `mission` | Review or update learning mission | [context/mission.md](context/mission.md) | +| `glossary` | Review or update compressed terminology | [context/glossary.md](context/glossary.md) | +| `resources` | Manage curated learning sources | [context/resources.md](context/resources.md) | +| `explain ` | Teach one tightly-scoped thing (a lesson) | Writes `concepts//lesson.md` (ephemeral teaching unit); distill a durable `reference.md` alongside — see [context/lessons.md](context/lessons.md) | +| `primer ` | Single-session domain primer — NO workspace | See "Primer action" below | +| `exercise` | Colocated practice for a concept | Writes `concepts//exercise.md`; design per [context/exercises.md](context/exercises.md) | +| `assess` | Check understanding, update learning records | [context/assessment.md](context/assessment.md) | +| `resume` | Resume a workspace from prior session | Reads workspace state, picks up where left off | +| `status` | Show learning progress across all workspaces | Lists workspaces + latest learning records | + +**Smart default:** if the user provides a subject without an action, detect mode: + +- Subject names a concept in the consuming repo (a module, a framework the repo uses, an internal library or abstraction the repo defines) → `codebase` +- Otherwise → `topic` + +## Primer action + +`primer ` is the single-session middle tier between an inline answer and a full `topic` workspace: the user needs enough of an unfamiliar domain's vocabulary and quality criteria to prompt well NOW ("teach me color grading so I can direct the work"), not a multi-session curriculum. Purpose: turn a vague request into a precise spec by teaching what the terms of art are and what GOOD looks like. + +- **No workspace** — no `` directory, mission interview, glossary, or learning records. Output is the session conversation plus an optional self-contained HTML vocabulary ladder (vague term → precise spec, with copy-out) per "Lessons and Reference" HTML routing. +- **Shape** — intake the user's starting point (one question), then build the vocabulary ladder: core terms, the quality axes experts judge by, worked good-vs-bad examples, and a closing "how to ask for what you want" prompt template. +- **Ground per Knowledge layer** — primary sources this turn, never parametric recall. +- **Escalate** — if the user wants depth or practice, offer `/teach topic ` (full workspace). + +## Pedagogy — Three Layers + +Every teaching session progresses through Knowledge → Skills → Wisdom. Don't skip layers; don't rush. Each layer has different teaching moves. The knowledge/skills balance varies by topic — theory-heavy subjects (theoretical physics) lean knowledge; practice-heavy ones (yoga, a framework) lean skills. Calibrate lesson design to the topic. + +### Knowledge (declarative — what is it?) + +- Provide clear explanations with examples and counterexamples +- Ground in primary sources — never parametric recall. A claim that drives a lesson is verified against a source fetched or a file Read THIS turn, not recalled from training data +- For `topic` mode: fetch from `RESOURCES.md` entries, the project's research tooling if available, or documentation-lookup MCP servers / official docs +- For `codebase` mode: Read actual source files, ADRs, convention docs, tests discovered per "Codebase mode" +- Use retrieval practice: ask the user to restate in their own words +- Add to `GLOSSARY.md` only when the user demonstrates understanding + +### Skills (procedural — how to do it?) + +- Emphasize deliberate practice: small tasks focused on 1-2 skills at a time +- Couple explanation with application: explain → simple use → novel use → integrated use +- For `codebase` mode: exercises use actual repo patterns (write a handler, add a test, implement the repo's own domain primitive) +- Use error-driven learning: present buggy code, ask the user to diagnose +- Tight feedback loops — immediate feedback on each attempt + +### Wisdom (judgment — when and why?) + +- Ask about tradeoffs: "You chose X; what are the pros/cons vs Y?" +- Present multiple solutions, ask the user to choose and justify +- Connect to mission: "How does this apply to what you're building?" +- Prompt transfer: "Where else could this pattern apply?" +- Metacognitive reflection: "What tripped you up? What pattern did you learn?" +- For `codebase` mode: connect to the repo's ADRs, architecture decisions, design philosophy +- **Delegate to community.** Wisdom comes from real-world interaction outside the learning environment — something an AI tutor structurally cannot provide. When a question requires wisdom, attempt to answer but also find relevant communities (subreddits, Discord servers, local meetups, courses, open-source projects) where the user can test skills in practice. Record community preferences in `RESOURCES.md`. Respect opt-outs — if the user declines community participation, don't re-suggest + +## Lessons and Reference + +The unit of teaching is a **lesson** — one tightly-scoped thing tied to the mission, completable quickly for a tangible win, in the user's zone of proximal development. Lessons are ephemeral (rarely revisited). Alongside, distill the durable **reference** — the compressed cheat-sheet the user returns to. Authoring format, reuse-first scaffolds, HTML placement, inline citations: [context/lessons.md](context/lessons.md). + +## Zone of Proximal Development + +Teach just beyond current understanding — challenging but achievable. Scaffold and fade: + +1. **Check current level** — read learning records, ask what they already know +2. **Calibrate difficulty** — not too easy (bored), not too hard (frustrated) +3. **Scaffold levels** (fade as competence grows): + - Orientation — restate in simpler terms, break into sub-steps + - Heuristic hints — guiding questions ("What data structure gives O(1) lookup?") + - Pointing hints — highlight relevant concept or code section + - Partial solution — show snippet with blanks + - Full solution + explanation — last resort, always ask the user to explain back +4. **Track and adapt** — update learning records when understanding demonstrated + +## Teaching Dialog + +Coach through a depth-first, one-question-at-a-time dialog: + +- Ask ONE question at a time +- Wait for the answer (silence = wait, not assume) +- Restate what's understood + what's still open +- Apply the relevant teaching move to the answer +- Surface the next choice point + +**Coach posture, not lecturer posture.** Questions before answers. "What do you think happens here?" before explaining what happens. The user's understanding is the goal, not coverage. + +## Session Flow + +### New Workspace (first invocation) + +1. Create the workspace per "Workspace layout" +2. Run the mission interview — WHY are they learning this? What's the concrete goal? What does success look like? +3. Write `MISSION.md` with the answers +4. Seed `RESOURCES.md` — for `topic` mode, find high-trust sources; for `codebase` mode, discover and list relevant repo files/docs per "Codebase mode" +5. Assess the starting point — what do they already know? Record as `learning-records/0001-prior-knowledge.md` +6. Begin teaching from their zone of proximal development + +### Resume (subsequent sessions) + +1. Read `MISSION.md` — know WHY and the success criteria +2. Read `GLOSSARY.md` — know what terms are established +3. Read `NOTES.md` — recall teaching preferences +4. Scan `learning-records/` for the latest entries — know the current frontier +5. Pick the next concept from the zone of proximal development; open its `concepts//` slice +6. Before re-teaching an existing concept, run the Staleness check (see "Staleness") + +### Session Close + +- Summarize what was learned +- Prompt reflection: "What's the key takeaway? What was hardest?" +- Update `GLOSSARY.md` if new terms demonstrated +- Write a learning record for demonstrated understanding +- Suggest the next session's focus + +## Codebase Mode + +`codebase` mode grounds learning in the consuming repo, discovered at teach-time — never in baked assumptions about any particular project's layout. Discover the repo, then teach from what you find: + +1. **Read the repo's own guidance.** Climb from `${CLAUDE_PROJECT_DIR}` for the nearest `CLAUDE.md` / `AGENTS.md`; read `README.md`; look for `docs/`, architecture-decision records (commonly `docs/adr/`, `docs/decisions/`), and convention/rules files (`.claude/rules/`, `.cursor/rules/`, a `CONTRIBUTING` file). These state how the project intends its code to be understood. +2. **Survey the structure.** Inspect the top-level layout (`src/`, `apps/`, `libs/`, `packages/`, tests) and identify languages/frameworks from manifest files present (`package.json`, `*.csproj`/`*.sln`, `pyproject.toml`, `go.mod`, `Cargo.toml`, `pom.xml`, …). Locate the files that actually embody the concept the user wants to learn. +3. **Persist what you discover.** Record the located files/docs into the workspace `RESOURCES.md` "Repo Sources" so later sessions don't re-derive the structure — infer once, persist, reuse. If discovery cannot find a grounding for the concept, ask the user to point you at the relevant area rather than guessing. +4. **Ground EVERYTHING in files Read this turn (Tier 0).** Never teach a codebase lesson from a cached lesson — re-Read the live files; the repo is the durable artifact, self-freshening. +5. **Cite the convention, not the instance.** Durable codebase references capture the pattern (dependency direction, an error-handling idiom, a dispatch mechanism), not a specific file's current contents — so they survive a refactor. + +Use the repo's actual code as examples. Create exercises against real patterns. Connect to the repo's ADRs for "why it's done this way." + +## Staleness + +Learning artifacts persist for months; durable teaching content (references, glossary) can rot. Handle rot by **lazy verify-on-revisit**, not stored metadata: + +- **No freshness frontmatter.** Don't record a `verified:` date (git owns it) or a `volatility:` tag (frozen judgment that itself rots). +- **Staleness = age × velocity judgment.** At revisit, weigh the artifact's age against the domain's velocity — fast (library APIs, framework syntax, AI tooling) vs slow (math, music theory, established architecture). Use domain-velocity intuition to decide *whether* to re-verify, never *what* the current fact is. +- **Treat durable artifacts as unverified on revisit.** A reference/glossary entry from a prior session is unverified synthesis until re-grounded this turn. If stale relative to age × velocity, re-fetch the inline citation, update, THEN teach. +- **Durable references store understanding + citations, not frozen facts.** A reference that freezes an external fact guarantees rot; instead capture the user's compressed mental model with inline citations to the authoritative source, so volatile facts stay by-reference (the citation is the re-verify target). + +## What This Skill Does NOT Do + +- **Does not write production code** — teaches understanding, not implementation. Use the project's own implementation workflow for code changes +- **Does not replace `/book-distill:book-distill`** — that extracts book knowledge into skill reference files; `/teach` delivers knowledge interactively to the user +- **Does not do task-context codebase investigation** — that's for the project's code-exploration tooling; `/teach codebase` is structured learning for understanding +- **Does not auto-invoke** — `disable-model-invocation: true`. The user initiates learning sessions diff --git a/plugins/teach/skills/teach/context/assessment.md b/plugins/teach/skills/teach/context/assessment.md new file mode 100644 index 00000000..efd9d845 --- /dev/null +++ b/plugins/teach/skills/teach/context/assessment.md @@ -0,0 +1,55 @@ +# Assessment and Learning Records + +Assessment updates the learner model — what's understood, what's frontier, what misconceptions exist. Learning records are the persistent form. + +## When to Assess + +| Signal | Action | +|---|---| +| User explained a concept correctly in own words | Record as demonstrated understanding | +| User completed exercise without hints | Record as skill acquired | +| User identified correct tradeoff in comparison exercise | Record as wisdom demonstrated | +| User said "I already know X" | Record as prior knowledge (note depth claimed) | +| User held misconception that was corrected | Record as corrected misconception (high value) | +| Mission shifted based on learning | Record as mission shift + update MISSION.md | +| End of session | Prompt reflection, record demonstrated understanding from session | + +## Learning Record Format + +Records live per [SKILL.md](../SKILL.md) "Workspace layout" (`learning-records/` under the active topic workspace). Scan that directory for the highest existing `NNNN` and increment. Cross-link related records, the mission, and terms with wikilinks (`[[MISSION.md]]`, `[[GLOSSARY.md]]`, `[[0002-]]`). + +```markdown +# {Short title of what was learned or established} + +{1-3 sentences: what was learned (or what prior knowledge was established), and why it matters for future sessions.} +``` + +Most records are this short. Value is recording THAT this is known and WHY it changes what to teach next. + +### Optional Sections + +Only when they add genuine value: + +- **Status** frontmatter (`active | superseded by LR-NNNN`) — when earlier understanding turns out wrong +- **Evidence** — how the user demonstrated understanding (question answered, exercise completed, prior experience cited) +- **Implications** — what this unlocks or rules out for future sessions + +## What Does NOT Qualify as a Learning Record + +- Material merely covered (coverage is not learning — wait for evidence) +- Anything already captured in `GLOSSARY.md` as a term definition +- Session-by-session activity logs (records are decision-grade insights, not journals) + +## Supersession + +When a later record contradicts an earlier one (understanding deepened or corrected), mark the old record `Status: superseded by LR-NNNN`. Don't delete — the history of how understanding evolved is itself useful signal. + +## Zone of Proximal Development Calculation + +Use learning records to determine what to teach next: + +1. **Established floor** — concepts with active learning records (user knows these) +2. **Current frontier** — concepts one step beyond the floor (user is ready for these) +3. **Out of reach** — concepts requiring multiple prerequisites the user lacks (defer) + +Pick teaching targets from the frontier. Occasionally revisit the floor for spaced practice. diff --git a/plugins/teach/skills/teach/context/exercises.md b/plugins/teach/skills/teach/context/exercises.md new file mode 100644 index 00000000..009ac5de --- /dev/null +++ b/plugins/teach/skills/teach/context/exercises.md @@ -0,0 +1,59 @@ +# Exercise Design + +Exercises bridge Knowledge → Skills. Each exercise targets 1-2 specific concepts and includes a tight feedback loop. Practice colocates with its lesson in the concept slice (`concepts//exercise.md`); a lesson may also embed a light feedback-loop task inline. This file is the design guidance for both. + +## Exercise Types + +| Type | When to use | Format | +|---|---|---| +| **Retrieval practice** | After explaining a concept | Ask user to restate in own words or identify correct usage from examples | +| **Code kata** (codebase mode) | After demonstrating a repo pattern | User implements a small variation using the pattern | +| **Bug hunt** | When common misconceptions exist | Present buggy code, user diagnoses and fixes | +| **Comparison** | When tradeoffs matter (wisdom layer) | Present two approaches, user argues pros/cons | +| **Transfer** | After user demonstrates skill in one context | Apply same concept in different context ("where else in the project?") | +| **Blank-filling** | When user needs scaffolded practice | Partial code with TODOs, user fills in | + +## Design Rules + +- **One concept per exercise** — don't combine debugging AND new syntax AND architecture in one problem +- **Immediate feedback** — user gets response right after attempt, not after a batch +- **Mission-connected** — tie exercises to `MISSION.md` goals. "For your blog API" not "for a generic app" +- **Graded difficulty** — start easy, increase. If user breezes through 3 in a row, jump difficulty. If stuck on 2 in a row, simplify or provide more scaffold +- **Save to workspace** — persist practice per [SKILL.md](../SKILL.md) "Workspace layout" (`concepts//exercise.md` in the active topic workspace) so the user can revisit + +## Exercise File Format + +```markdown +# Exercise: {Title} + +**Concept:** {What this practices} +**Difficulty:** {beginner | intermediate | advanced} +**Prerequisites:** {Glossary terms or prior learning records} + +## Setup + +{Context the user needs — code snippet, scenario description, relevant file paths} + +## Task + +{Clear instructions — what to do, what's expected} + +## Hints (progressive) + +1. {Orientation hint — restate the problem} +2. {Heuristic hint — guiding question} +3. {Pointing hint — where to look} + +## Solution + +{Full solution with explanation — reveal only after user attempts or requests} +``` + +## Codebase Mode Exercises + +For repo-grounded exercises (grounding discovered per SKILL.md "Codebase mode"): + +- Use ACTUAL repo code as setup material (Read the file, present the relevant section) +- Create exercises against real patterns the repo defines: "Add a new variant following the existing convention in {located file}" +- Reference real tests as examples of expected behavior +- Connect to the repo's own architectural rules: "Why would adding this dependency violate the repo's dependency-direction rule?" diff --git a/plugins/teach/skills/teach/context/glossary.md b/plugins/teach/skills/teach/context/glossary.md new file mode 100644 index 00000000..beb84fe4 --- /dev/null +++ b/plugins/teach/skills/teach/context/glossary.md @@ -0,0 +1,36 @@ +# Glossary Format + +`GLOSSARY.md` is canonical language for a learning workspace. All explainers, exercises, and learning records adhere to its terminology. Building it is itself part of learning: compressing a concept into a tight definition is evidence the user understands it. + +## Template + +```markdown +# {Topic} Glossary + +{One or two sentence description of the topic this glossary covers.} + +## Terms + +**{Term}**: +{One or two sentence definition. What it IS, not what it does or how to do it.} +_Avoid_: {alternative names to NOT use — pick the best term, list rest as aliases to avoid} + +**{Term 2}**: +{Definition using glossary's own terms where possible.} +_Avoid_: {aliases} +``` + +## Rules + +- **Add a term only when the user understands it.** The glossary records compressed knowledge, not a dictionary the user reads to learn. Wait for evidence of comprehension before promoting +- **Be opinionated.** When several words exist for the same concept, pick the best one and list the rest as `_Avoid_`. This is how language compresses +- **Keep definitions tight.** One or two sentences. Define what the term IS +- **Use the glossary's own terms inside definitions.** Once a term is in the glossary, prefer it everywhere — including inside other definitions. This makes complex terms easier to grasp later +- **Group under subheadings** when natural clusters emerge. Flat list is fine when terms cohere +- **Flag ambiguities explicitly.** If a term is used loosely in the wider field, note the resolution: "In this workspace, 'set' always means a working set" +- **Revise as understanding deepens.** A definition from week one may be wrong by week six. Update in place +- **Durable = rot-relevant.** The glossary is revisited as authoritative — on revisit treat entries as unverified and re-verify volatile-domain terms per SKILL.md "Staleness" before relying on them + +## Relationship to a repo's shared language + +For `codebase` mode, the glossary may reference or extend the consuming repo's own shared-language / ubiquitous-language documentation when it has any (e.g. a `UBIQUITOUS-LANGUAGE.md`, a domain glossary in `docs/`). But the learning glossary is personal — it captures the USER's understanding, which may be incomplete. A team's shared language is the authoritative team vocabulary; the learning glossary is the learner's growing one. diff --git a/plugins/teach/skills/teach/context/lessons.md b/plugins/teach/skills/teach/context/lessons.md new file mode 100644 index 00000000..cccb8682 --- /dev/null +++ b/plugins/teach/skills/teach/context/lessons.md @@ -0,0 +1,56 @@ +# Lessons and Reference + +The two per-concept teaching artifacts. A **lesson** delivers learning; a **reference** preserves it. Both live colocated in the concept slice per [SKILL.md](../SKILL.md) "Workspace layout". + +## Lesson — the ephemeral teaching unit + +`concepts//lesson.md`. The primary unit of teaching: ONE tightly-scoped thing, tied to the mission, in the user's zone of proximal development, completable quickly for a tangible win. + +- **One thing only.** If it needs "and", split into two concepts. Teaching ONE thing keeps the lesson in the ZPD and the slice tight. +- **Ephemeral.** Lessons are rarely revisited — the teaching moment, not the keepsake. Low rot risk; regenerable. +- **Knowledge first, then practice.** Teach the minimum knowledge the skill needs, then drive practice via a tight feedback loop (per the Skills layer in SKILL.md). +- **Inline citations.** Link each non-obvious / load-bearing claim to its `RESOURCES.md` entry or external source — trust, a go-deeper path, AND the rot re-verify anchor. Cite claims that carry risk, not every sentence. +- **Close with a follow-up reminder.** The agent is the user's teacher — end the lesson inviting questions on anything unclear. + +### Lesson file format + +```markdown +# Lesson: {one tightly-scoped thing} + +**Concept:** {what this teaches} **Mission link:** {how it serves MISSION.md} + +## Teach +{minimum knowledge, with inline citations to RESOURCES.md / sources} + +## Practice +{tight feedback-loop task — retrieval, kata, bug-hunt, etc. per context/exercises.md} + +## Go deeper +{citations + "ask me follow-ups on anything unclear"} +``` + +## Reference — the durable cheat-sheet + +`concepts//reference.md`. The compressed essence the user returns to: syntax cards, algorithms, sequences, formulas. Revisited — so it is the **rot-relevant** artifact. + +- **Store understanding + citations, NOT frozen external facts.** A reference that freezes a library API or a current "best practice" guarantees rot. Capture the user's compressed mental model with inline citations to the authoritative source; the volatile facts stay by-reference. +- **Staleness is lazy + judgment-driven.** No freshness frontmatter. On revisit, treat as unverified and check age × domain-velocity per SKILL.md "Staleness"; re-fetch the citation if stale before teaching from it. +- **Compressed + scannable.** A reference the user must read top-to-bottom is not a reference. Tight definitions, tables, cards. + +## Reuse-first scaffolds + +Before authoring a new lesson shell, check the workspace `assets/` directory (if present) for existing markdown scaffolds (prompt shells, exercise stubs). Copy and adapt — prefer reuse over regenerate. + +## HTML and markdown + +Both lesson and reference default to `.md` — the durable teaching record (lesson, reference, learning-records) stays markdown, the diffable source of truth. Reach for HTML only where it pays: a visual/spatial *Teach* section, or an interactive *Practice* section where the learner edits a config / query / snippet and copies the result back into chat for grading. Most lessons stay markdown. + +**Producing the HTML:** if `/frontend-design:frontend-design` is installed, delegate the visual design to it; otherwise generate a plain, self-contained single-file page inline. Constraints in either case: + +- **Ephemeral placement.** Teach HTML is session output, not a tracked artifact. Write it to the workspace under `${CLAUDE_PLUGIN_DATA}///concepts//` (or OS temp), and open it from `file://`. +- **Self-contained, no remote fetch.** Vendor all CSS/JS inline so the page opens straight from disk with no network dependency. +- **No secret leakage.** A codebase-mode lesson embedding a repo snippet must use synthetic data for exemplars; never bake a real secret value into the HTML — show a masked presence indicator if the existence of a secret must be conveyed. + +## Codebase mode + +Codebase lessons re-Read live repo files at teach-time — never teach from a cached lesson (the repo is the durable artifact, self-freshening). Codebase references cite the **convention** (the dependency-direction rule, the error-handling idiom, the dispatch mechanism), never a specific instance, so they survive a refactor of the underlying files. diff --git a/plugins/teach/skills/teach/context/mission.md b/plugins/teach/skills/teach/context/mission.md new file mode 100644 index 00000000..38b02a27 --- /dev/null +++ b/plugins/teach/skills/teach/context/mission.md @@ -0,0 +1,49 @@ +# Mission Format + +`MISSION.md` lives at the workspace root per [SKILL.md](../SKILL.md) "Workspace layout". Captures WHY the user is learning this topic. Every teaching decision — what to teach next, which resources to surface, which exercises to design — traces back to this document. + +## Template + +```markdown +# Mission: {Topic} + +## Why + +{1-3 sentences. Concrete real-world goal. What changes in their life or work when they have this skill? Avoid abstract framings like "to understand X" — push for the underlying outcome.} + +## Success Looks Like + +- {Specific, observable thing the user will be able to do} +- {Another specific thing} +- {…} + +## Constraints + +- {Time, budget, prior commitments, learning preferences, anything that bounds the approach} + +## Out of Scope + +- {Adjacent topics the user explicitly does not want to chase right now — protects zone of proximal development} +``` + +## Rules + +- **One mission per workspace.** Two unrelated topics = two workspaces +- **Concrete over abstract.** "Ship a Rust CLI to my team" beats "learn Rust." "Write songs with family rhyme" beats "understand songwriting" +- **Push back on vagueness.** If the user cannot articulate WHY, interview them via the one-question-at-a-time teaching dialog (SKILL.md "Teaching Dialog") before writing anything. A bad mission is worse than no mission +- **Revise when reality shifts.** Missions change. When the goal moves, update — don't leave a stale mission steering sessions +- **Keep it short.** If MISSION.md runs past a screen, it stopped being a compass and started being a plan + +## Codebase Mode Additions + +For `/teach codebase `, MISSION.md also includes: + +```markdown +## Repo Context + +- **Relevant code:** {paths to modules, libs, files that embody the concept — discovered per SKILL.md "Codebase mode"} +- **Relevant docs:** {ADRs, convention files, architecture docs} +- **Relevant tests:** {test files demonstrating the concept in action} +``` + +This section grounds the mission in actual repo state rather than abstract goals. diff --git a/plugins/teach/skills/teach/context/resources.md b/plugins/teach/skills/teach/context/resources.md new file mode 100644 index 00000000..6abd27af --- /dev/null +++ b/plugins/teach/skills/teach/context/resources.md @@ -0,0 +1,53 @@ +# Resources Format + +`RESOURCES.md` is the curated set of trusted sources for a learning workspace. Knowledge for explainers is drawn from here, not from parametric guesses. Wisdom comes from communities listed here. + +## Template + +```markdown +# {Topic} Resources + +## Knowledge + +- [{Type}: _{Title}_ — {Author}]({URL}) + {One line: what it covers and when to reach for it.} + +## Wisdom (Communities) + +- [{Name}]({URL}) + {One line: what kind of help you get here.} + +## Gaps + +- {Area the mission needs but no good resource exists for yet} +``` + +## Rules + +- **High-trust only.** Prefer primary sources, recognized experts, peer-reviewed work, communities with strong moderation. If a resource is marketing dressed as education, leave it out +- **Annotate every entry.** A bare link is useless in three months. Add one line: what it covers and when to reach for it +- **Group by Knowledge / Wisdom.** Mirrors the K-S-W framework +- **Surface gaps explicitly.** If no good resource exists for an area the mission needs, write a `## Gaps` section. This drives future search +- **Prune ruthlessly.** A resource that turned out to be wrong, shallow, or off-mission should be removed. Better five sharp sources than thirty mediocre ones +- **Record community preferences.** If the user opted out of joining communities, note it + +## Verification + +Resources MUST be verified against the source this turn — fetch and confirm URLs before adding. Training-recall recommendations are unverified synthesis; verify before listing. + +RESOURCES entries double as the **rot re-verify anchor**: lessons and references cite them inline, and the Staleness check (SKILL.md "Staleness") re-fetches the cited source to refresh a stale durable artifact. + +## Codebase Mode + +For `/teach codebase`, resources include repo-internal sources discovered per SKILL.md "Codebase mode". Record what discovery located so later sessions reuse it instead of re-deriving the repo's structure: + +```markdown +## Repo Sources + +- {path to a convention / architecture doc} — {what it establishes} +- {path to a source module / library} — {the pattern it embodies} +- {path to a reference implementation or example} — {why it is exemplary} +- {path to representative tests} — {expected behavior they demonstrate} +``` + +These are primary sources (files Read this turn) — higher trust than any external doc. From c38788ad81ad8025d357847d92bcc00093d3a937 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sun, 12 Jul 2026 00:40:48 -0400 Subject: [PATCH 2/6] fix(teach): canonicalize project path for slug; specify resume/status/no-workspace paths Address bot-review findings on PR #85: - Canonicalize ${CLAUDE_PROJECT_DIR} (realpath/readlink) before hashing the project-slug, so a project opened via a symlink and via its real path share one workspace instead of splitting into two (macOS /private/var symlinks). - Specify the resume (disambiguate when multiple workspaces), status (output shape), and explain/exercise-without-a-workspace behaviors, which were underspecified in the action router. - Note topic-mode WebFetch usage under README Requirements. --- plugins/teach/README.md | 3 +++ plugins/teach/skills/teach/SKILL.md | 10 +++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/plugins/teach/README.md b/plugins/teach/README.md index 2ccf336b..7ac56a6d 100644 --- a/plugins/teach/README.md +++ b/plugins/teach/README.md @@ -38,6 +38,9 @@ before they're taught. See the skill body for the full pedagogy. - None beyond Claude Code. For `codebase` mode, launch it from the repository you want to learn — the plugin reads that repo's own docs and source. +- `topic` mode fetches documentation URLs to ground explanations in primary + sources; if your setup restricts `WebFetch`, allow it or seed `RESOURCES.md` + manually. ## Install diff --git a/plugins/teach/skills/teach/SKILL.md b/plugins/teach/skills/teach/SKILL.md index 54794b96..06d4eee0 100644 --- a/plugins/teach/skills/teach/SKILL.md +++ b/plugins/teach/skills/teach/SKILL.md @@ -41,7 +41,7 @@ ${CLAUDE_PLUGIN_DATA}/// Path resolution rules every action MUST follow: -- **``** — the basename of `${CLAUDE_PROJECT_DIR}` slugified to lowercase alphanumerics and hyphens, then `-` plus the first 8 hex chars of the SHA-256 of the resolved absolute project path (`printf '%s' "" | { sha256sum 2>/dev/null || shasum -a 256; } | cut -c1-8` — the fallback covers stock macOS). The basename alone collides when two clones or worktrees share a directory name. Both `topic` and `codebase` workspaces are scoped under `` — topic learning becomes associated with the project you launched from. +- **``** — the basename of `${CLAUDE_PROJECT_DIR}` slugified to lowercase alphanumerics and hyphens, then `-` plus the first 8 hex chars of the SHA-256 of the **canonicalized** absolute project path. Canonicalize FIRST so a project opened via a symlink and via its real path map to the same workspace (`realpath "${CLAUDE_PROJECT_DIR}" 2>/dev/null || readlink -f "${CLAUDE_PROJECT_DIR}" 2>/dev/null || echo "${CLAUDE_PROJECT_DIR}"`, e.g. macOS repos under `/private/var/…`), then hash: `printf '%s' "" | { sha256sum 2>/dev/null || shasum -a 256; } | cut -c1-8` — the fallback covers stock macOS. The basename alone collides when two clones or worktrees share a directory name. Both `topic` and `codebase` workspaces are scoped under `` — topic learning becomes associated with the project you launched from. - **``** and **``** — content-named kebab slugs (lowercase alphanumerics and hyphens only; strip `/`, `\`, `..`), NOT sequence-numbered. `"Domain-Driven Design"` → `domain-driven-design`; `"Rust Ownership"` → `rust-ownership`. - **`learning-records/NNNN-.md`** keeps `NNNN-` numbering (sanctioned ADR-style append-only log). Scan the directory for the highest existing `NNNN` and increment. - `${CLAUDE_PLUGIN_DATA}` is created automatically the first time it is referenced and persists across plugin updates, so workspaces survive between sessions. @@ -84,6 +84,14 @@ Parse `$ARGUMENTS`: first token = action, remainder = args. If empty or ambiguou - **Ground per Knowledge layer** — primary sources this turn, never parametric recall. - **Escalate** — if the user wants depth or practice, offer `/teach topic ` (full workspace). +## Resume, Status, and workspace resolution + +`resume` and `status` operate over the workspaces under `${CLAUDE_PLUGIN_DATA}//`: + +- **`resume []`** — with a topic argument, resolve that workspace directly and follow "Resume (subsequent sessions)". With no argument, list the workspaces sorted by most-recently-modified (git or filesystem mtime of the workspace files) and ask the user which to resume — never silently pick one when more than one exists. +- **`status`** — for each workspace, show the topic, the count of `learning-records/`, the current frontier concept (from the latest records), and the last-touched date (mtime). One line per workspace; no file bodies loaded. +- **`explain ` / `exercise` need an active workspace.** They write into `concepts//` under a topic workspace. If exactly one workspace exists, use it; if several exist, ask which; if none exists, ask whether to start one (`topic` / `codebase`) before writing — never invent a workspace silently. + ## Pedagogy — Three Layers Every teaching session progresses through Knowledge → Skills → Wisdom. Don't skip layers; don't rush. Each layer has different teaching moves. The knowledge/skills balance varies by topic — theory-heavy subjects (theoretical physics) lean knowledge; practice-heavy ones (yoga, a framework) lean skills. Calibrate lesson design to the topic. From 307f8f5c5fbec49bd34f7f5d24b25cf19243b450 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sun, 12 Jul 2026 00:48:37 -0400 Subject: [PATCH 3/6] fix(teach): namespaced /teach:teach examples; add level to workspace path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address Codex review findings on PR #85: - Use the namespaced /teach:teach command in argument-hint, README, catalog row, and cross-references — bare /teach does not resolve for an installed plugin (matches the sibling /prototype:logic, /diagnose:diagnose convention). - Insert a level (topic|codebase) into the workspace path so /teach:teach topic and /teach:teach codebase in the same project no longer resolve to one directory and seed over each other. Pre-computed workspace glob and HTML placement path updated to match. --- README.md | 2 +- plugins/teach/README.md | 5 +++-- plugins/teach/skills/teach/SKILL.md | 17 +++++++++-------- plugins/teach/skills/teach/context/lessons.md | 2 +- plugins/teach/skills/teach/context/mission.md | 2 +- plugins/teach/skills/teach/context/resources.md | 2 +- 6 files changed, 16 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 2521eec7..5a9036ed 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ Browse and manage with `/plugin`. To refresh after updates: `/plugin marketplace | [`planning`](plugins/planning) | Skills | Pre-implementation planning pipeline of six skills: `/planning:brainstorm` (cheapest→most-ambitious candidate divergence), `/planning:prd` (three-tier product requirements), `/planning:interview` (depth-first Q&A locking a task contract into a PLAN.md Brief), `/planning:design` (collaborative type/contract/topology exploration with a binary handoff gate), `/planning:devils-advocate` (evidence-backed adversarial stress-testing), and `/planning:architect` (structured implementation plans with blast radius, parallelism analysis, and a user approval gate). | | [`review-toolkit`](plugins/review-toolkit) | Agents + Skills | Code-review toolkit: six read-only reviewer agents (code quality, security, architecture, doc drift, build/test/lint, CI-log audit) plus two orchestration skills — `/review-toolkit:quality-gate` (single-lens checkpoint with eight modes) and `/review-toolkit:code-review-fanout` (multi-surface fan-out normalized into one severity-ranked findings report, with a findings-driven fix pass). | | [`implementation`](plugins/implementation) | Skills | Implementation-stage toolkit of ten skills: `implement` / `implement-dispatch` (inline vs orchestrated plan execution with TDD cadence, divergence detection, and phase-boundary handoffs), `build` / `lint` (polyglot ecosystem-detecting verification with consumer-convention overrides), `test-write` / `test-plan` / `test-diagnose` / `test-e2e` (authoring, coverage-gap analysis, failure diagnosis, live E2E evidence), and `verify-changes` / `verify-improvement` (outcome verification and baseline-vs-after improvement measurement). | -| [`teach`](plugins/teach) | Skill | Interactive multi-session learning coach. `/teach topic` learns a general subject from external high-trust sources, `/teach codebase` learns a concept grounded in the repo it is launched from (discovering that repo's own docs and source at teach-time), and `/teach primer` gives a single-session domain vocabulary primer. Coaches through a Knowledge → Skills → Wisdom progression with persistent per-topic learning state under `${CLAUDE_PLUGIN_DATA}`. | +| [`teach`](plugins/teach) | Skill | Interactive multi-session learning coach. `/teach:teach topic` learns a general subject from external high-trust sources, `/teach:teach codebase` learns a concept grounded in the repo it is launched from (discovering that repo's own docs and source at teach-time), and `/teach:teach primer` gives a single-session domain vocabulary primer. Coaches through a Knowledge → Skills → Wisdom progression with persistent per-topic learning state under `${CLAUDE_PLUGIN_DATA}`. | Install one: `/plugin install @melodic-software`. diff --git a/plugins/teach/README.md b/plugins/teach/README.md index 7ac56a6d..8dbb52e6 100644 --- a/plugins/teach/README.md +++ b/plugins/teach/README.md @@ -5,8 +5,9 @@ multiple sessions — instead of lecturing at you. It runs a **Knowledge → Skills → Wisdom** progression grounded in your real goal, and keeps persistent per-topic learning state so each session builds on the last. -Invoke it with `/teach` and an action, for example `/teach topic rust-ownership`, -`/teach codebase auth-flow`, or `/teach primer color-grading`. +Invoke it with `/teach:teach` and an action, for example +`/teach:teach topic rust-ownership`, `/teach:teach codebase auth-flow`, or +`/teach:teach primer color-grading`. ## What it does diff --git a/plugins/teach/skills/teach/SKILL.md b/plugins/teach/skills/teach/SKILL.md index 06d4eee0..7cd3d632 100644 --- a/plugins/teach/skills/teach/SKILL.md +++ b/plugins/teach/skills/teach/SKILL.md @@ -1,7 +1,7 @@ --- name: teach description: "Interactive multi-session learning coach for general topics or repo-grounded concepts; also a single-session domain primer (primer action). Use when: 'teach me', 'study session', 'help me learn', 'onboard me to', 'learn this codebase'. Coaches through the Knowledge-Skills-Wisdom progression with persistent per-topic learning state. Not for one-off inline questions (answer directly)." -argument-hint: " [args] (e.g., /teach topic rust-ownership, /teach codebase auth-flow, /teach primer color-grading)" +argument-hint: " [args] (e.g., /teach:teach topic rust-ownership, /teach:teach codebase auth-flow, /teach:teach primer color-grading)" user-invocable: true disable-model-invocation: true --- @@ -24,7 +24,7 @@ Two modes share pedagogy but differ in source material: All persistent learning state lives under the plugin's own per-plugin data directory, which survives plugin updates and does not pollute the consuming repo: ```text -${CLAUDE_PLUGIN_DATA}/// +${CLAUDE_PLUGIN_DATA}//// ├── MISSION.md WHY the user is learning this — goal, success criteria, constraints (workspace-global) ├── GLOSSARY.md durable terminology SSOT — add only when the user demonstrates understanding (global) ├── RESOURCES.md curated high-trust sources (knowledge + wisdom communities) (global) @@ -42,6 +42,7 @@ ${CLAUDE_PLUGIN_DATA}/// Path resolution rules every action MUST follow: - **``** — the basename of `${CLAUDE_PROJECT_DIR}` slugified to lowercase alphanumerics and hyphens, then `-` plus the first 8 hex chars of the SHA-256 of the **canonicalized** absolute project path. Canonicalize FIRST so a project opened via a symlink and via its real path map to the same workspace (`realpath "${CLAUDE_PROJECT_DIR}" 2>/dev/null || readlink -f "${CLAUDE_PROJECT_DIR}" 2>/dev/null || echo "${CLAUDE_PROJECT_DIR}"`, e.g. macOS repos under `/private/var/…`), then hash: `printf '%s' "" | { sha256sum 2>/dev/null || shasum -a 256; } | cut -c1-8` — the fallback covers stock macOS. The basename alone collides when two clones or worktrees share a directory name. Both `topic` and `codebase` workspaces are scoped under `` — topic learning becomes associated with the project you launched from. +- **``** — literally `topic` or `codebase`, matching the action that created the workspace. This level keeps the two modes independent: `/teach:teach topic auth-flow` and `/teach:teach codebase auth-flow` in the same project resolve to separate workspaces (`.../topic/auth-flow/` vs `.../codebase/auth-flow/`) instead of one seeding over the other's `MISSION.md` / `RESOURCES.md`. - **``** and **``** — content-named kebab slugs (lowercase alphanumerics and hyphens only; strip `/`, `\`, `..`), NOT sequence-numbered. `"Domain-Driven Design"` → `domain-driven-design`; `"Rust Ownership"` → `rust-ownership`. - **`learning-records/NNNN-.md`** keeps `NNNN-` numbering (sanctioned ADR-style append-only log). Scan the directory for the highest existing `NNNN` and increment. - `${CLAUDE_PLUGIN_DATA}` is created automatically the first time it is referenced and persists across plugin updates, so workspaces survive between sessions. @@ -50,7 +51,7 @@ Path resolution rules every action MUST follow: ## Pre-computed Context -Existing workspaces: !`ls -d "${CLAUDE_PLUGIN_DATA}"/*/*/ 2>/dev/null | head -20 || echo "none"` +Existing workspaces: !`ls -d "${CLAUDE_PLUGIN_DATA}"/*/*/*/ 2>/dev/null | head -20 || echo "none"` ## Action Router @@ -82,14 +83,14 @@ Parse `$ARGUMENTS`: first token = action, remainder = args. If empty or ambiguou - **No workspace** — no `` directory, mission interview, glossary, or learning records. Output is the session conversation plus an optional self-contained HTML vocabulary ladder (vague term → precise spec, with copy-out) per "Lessons and Reference" HTML routing. - **Shape** — intake the user's starting point (one question), then build the vocabulary ladder: core terms, the quality axes experts judge by, worked good-vs-bad examples, and a closing "how to ask for what you want" prompt template. - **Ground per Knowledge layer** — primary sources this turn, never parametric recall. -- **Escalate** — if the user wants depth or practice, offer `/teach topic ` (full workspace). +- **Escalate** — if the user wants depth or practice, offer `/teach:teach topic ` (full workspace). ## Resume, Status, and workspace resolution -`resume` and `status` operate over the workspaces under `${CLAUDE_PLUGIN_DATA}//`: +`resume` and `status` operate over the workspaces under `${CLAUDE_PLUGIN_DATA}////` (both modes): -- **`resume []`** — with a topic argument, resolve that workspace directly and follow "Resume (subsequent sessions)". With no argument, list the workspaces sorted by most-recently-modified (git or filesystem mtime of the workspace files) and ask the user which to resume — never silently pick one when more than one exists. -- **`status`** — for each workspace, show the topic, the count of `learning-records/`, the current frontier concept (from the latest records), and the last-touched date (mtime). One line per workspace; no file bodies loaded. +- **`resume []`** — with a topic argument, resolve that workspace directly (disambiguating by `` if the same topic exists in both) and follow "Resume (subsequent sessions)". With no argument, list the workspaces sorted by most-recently-modified (git or filesystem mtime of the workspace files) and ask the user which to resume — never silently pick one when more than one exists. +- **`status`** — for each workspace, show its mode, topic, the count of `learning-records/`, the current frontier concept (from the latest records), and the last-touched date (mtime). One line per workspace; no file bodies loaded. - **`explain ` / `exercise` need an active workspace.** They write into `concepts//` under a topic workspace. If exactly one workspace exists, use it; if several exist, ask which; if none exists, ask whether to start one (`topic` / `codebase`) before writing — never invent a workspace silently. ## Pedagogy — Three Layers @@ -206,5 +207,5 @@ Learning artifacts persist for months; durable teaching content (references, glo - **Does not write production code** — teaches understanding, not implementation. Use the project's own implementation workflow for code changes - **Does not replace `/book-distill:book-distill`** — that extracts book knowledge into skill reference files; `/teach` delivers knowledge interactively to the user -- **Does not do task-context codebase investigation** — that's for the project's code-exploration tooling; `/teach codebase` is structured learning for understanding +- **Does not do task-context codebase investigation** — that's for the project's code-exploration tooling; `/teach:teach codebase` is structured learning for understanding - **Does not auto-invoke** — `disable-model-invocation: true`. The user initiates learning sessions diff --git a/plugins/teach/skills/teach/context/lessons.md b/plugins/teach/skills/teach/context/lessons.md index cccb8682..864db886 100644 --- a/plugins/teach/skills/teach/context/lessons.md +++ b/plugins/teach/skills/teach/context/lessons.md @@ -47,7 +47,7 @@ Both lesson and reference default to `.md` — the durable teaching record (less **Producing the HTML:** if `/frontend-design:frontend-design` is installed, delegate the visual design to it; otherwise generate a plain, self-contained single-file page inline. Constraints in either case: -- **Ephemeral placement.** Teach HTML is session output, not a tracked artifact. Write it to the workspace under `${CLAUDE_PLUGIN_DATA}///concepts//` (or OS temp), and open it from `file://`. +- **Ephemeral placement.** Teach HTML is session output, not a tracked artifact. Write it to the workspace under `${CLAUDE_PLUGIN_DATA}////concepts//` (or OS temp), and open it from `file://`. - **Self-contained, no remote fetch.** Vendor all CSS/JS inline so the page opens straight from disk with no network dependency. - **No secret leakage.** A codebase-mode lesson embedding a repo snippet must use synthetic data for exemplars; never bake a real secret value into the HTML — show a masked presence indicator if the existence of a secret must be conveyed. diff --git a/plugins/teach/skills/teach/context/mission.md b/plugins/teach/skills/teach/context/mission.md index 38b02a27..4bfa53a5 100644 --- a/plugins/teach/skills/teach/context/mission.md +++ b/plugins/teach/skills/teach/context/mission.md @@ -36,7 +36,7 @@ ## Codebase Mode Additions -For `/teach codebase `, MISSION.md also includes: +For `/teach:teach codebase `, MISSION.md also includes: ```markdown ## Repo Context diff --git a/plugins/teach/skills/teach/context/resources.md b/plugins/teach/skills/teach/context/resources.md index 6abd27af..4bdb9592 100644 --- a/plugins/teach/skills/teach/context/resources.md +++ b/plugins/teach/skills/teach/context/resources.md @@ -39,7 +39,7 @@ RESOURCES entries double as the **rot re-verify anchor**: lessons and references ## Codebase Mode -For `/teach codebase`, resources include repo-internal sources discovered per SKILL.md "Codebase mode". Record what discovery located so later sessions reuse it instead of re-deriving the repo's structure: +For `/teach:teach codebase`, resources include repo-internal sources discovered per SKILL.md "Codebase mode". Record what discovery located so later sessions reuse it instead of re-deriving the repo's structure: ```markdown ## Repo Sources From 6585002637355d6687c76de8bebe1a34bece68c3 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sun, 12 Jul 2026 00:59:33 -0400 Subject: [PATCH 4/6] fix(teach): derive slug basename from canonical path; scope prefetch to current project MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address Codex review findings on PR #85: - Derive BOTH the project-slug basename and the hash from the canonicalized project path. Previously only the hash input was canonicalized, so a symlink alias with a different basename still split the workspace (alias- vs realname-). - Scope the pre-computed "existing workspaces" glob to the current project's computed slug instead of listing every project's workspaces under the per-plugin data dir — honors the current-project scoping the resume/status actions promise. --- plugins/teach/skills/teach/SKILL.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/teach/skills/teach/SKILL.md b/plugins/teach/skills/teach/SKILL.md index 7cd3d632..26783183 100644 --- a/plugins/teach/skills/teach/SKILL.md +++ b/plugins/teach/skills/teach/SKILL.md @@ -41,7 +41,7 @@ ${CLAUDE_PLUGIN_DATA}//// Path resolution rules every action MUST follow: -- **``** — the basename of `${CLAUDE_PROJECT_DIR}` slugified to lowercase alphanumerics and hyphens, then `-` plus the first 8 hex chars of the SHA-256 of the **canonicalized** absolute project path. Canonicalize FIRST so a project opened via a symlink and via its real path map to the same workspace (`realpath "${CLAUDE_PROJECT_DIR}" 2>/dev/null || readlink -f "${CLAUDE_PROJECT_DIR}" 2>/dev/null || echo "${CLAUDE_PROJECT_DIR}"`, e.g. macOS repos under `/private/var/…`), then hash: `printf '%s' "" | { sha256sum 2>/dev/null || shasum -a 256; } | cut -c1-8` — the fallback covers stock macOS. The basename alone collides when two clones or worktrees share a directory name. Both `topic` and `codebase` workspaces are scoped under `` — topic learning becomes associated with the project you launched from. +- **``** — **canonicalize the project path FIRST**, then derive BOTH the basename-slug and the hash from that one canonical path, so a project opened via a symlink and via its real path map to the same workspace (otherwise the alias basename would still split it — `alias-` vs `realname-`). Canonical path: `realpath "${CLAUDE_PROJECT_DIR}" 2>/dev/null || readlink -f "${CLAUDE_PROJECT_DIR}" 2>/dev/null || printf '%s' "${CLAUDE_PROJECT_DIR}"` (e.g. macOS repos under `/private/var/…`). Then `` = the **basename of the canonical path** slugified to lowercase alphanumerics and hyphens, then `-` plus the first 8 hex chars of `printf '%s' "" | { sha256sum 2>/dev/null || shasum -a 256; } | cut -c1-8` (the fallback covers stock macOS). The hash discriminator is required because the basename alone collides when two clones or worktrees share a directory name. Both `topic` and `codebase` workspaces are scoped under `` — topic learning becomes associated with the project you launched from. - **``** — literally `topic` or `codebase`, matching the action that created the workspace. This level keeps the two modes independent: `/teach:teach topic auth-flow` and `/teach:teach codebase auth-flow` in the same project resolve to separate workspaces (`.../topic/auth-flow/` vs `.../codebase/auth-flow/`) instead of one seeding over the other's `MISSION.md` / `RESOURCES.md`. - **``** and **``** — content-named kebab slugs (lowercase alphanumerics and hyphens only; strip `/`, `\`, `..`), NOT sequence-numbered. `"Domain-Driven Design"` → `domain-driven-design`; `"Rust Ownership"` → `rust-ownership`. - **`learning-records/NNNN-.md`** keeps `NNNN-` numbering (sanctioned ADR-style append-only log). Scan the directory for the highest existing `NNNN` and increment. @@ -51,7 +51,7 @@ Path resolution rules every action MUST follow: ## Pre-computed Context -Existing workspaces: !`ls -d "${CLAUDE_PLUGIN_DATA}"/*/*/*/ 2>/dev/null | head -20 || echo "none"` +Existing workspaces (current project only): !`p="$(realpath "${CLAUDE_PROJECT_DIR}" 2>/dev/null || readlink -f "${CLAUDE_PROJECT_DIR}" 2>/dev/null || printf '%s' "${CLAUDE_PROJECT_DIR}")"; b="$(basename "$p" | tr '[:upper:]' '[:lower:]' | tr -cs 'a-z0-9' '-' | sed 's/^-*//;s/-*$//')"; h="$(printf '%s' "$p" | { sha256sum 2>/dev/null || shasum -a 256; } | cut -c1-8)"; ls -d "${CLAUDE_PLUGIN_DATA}/$b-$h"/*/*/ 2>/dev/null | head -20 || echo "none"` ## Action Router From f42df62ed4e7ba73b7e942580c95e1c9c5d93b78 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sun, 12 Jul 2026 01:04:12 -0400 Subject: [PATCH 5/6] fix(teach): disambiguate colliding topic/concept slugs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Address Codex review finding on PR #85: distinct subjects can normalize to the same slug (C++/C# -> c; Node.js/Node JS -> node-js), silently sharing one workspace. Record the exact raw subject/concept name as the collision source of truth, and on a slug-directory collision with a different recorded name, append a 4-hex discriminator derived from the raw name — isolating per-subject state while leaving non-colliding slugs readable. --- plugins/teach/skills/teach/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/teach/skills/teach/SKILL.md b/plugins/teach/skills/teach/SKILL.md index 26783183..c1c2fe9b 100644 --- a/plugins/teach/skills/teach/SKILL.md +++ b/plugins/teach/skills/teach/SKILL.md @@ -43,7 +43,7 @@ Path resolution rules every action MUST follow: - **``** — **canonicalize the project path FIRST**, then derive BOTH the basename-slug and the hash from that one canonical path, so a project opened via a symlink and via its real path map to the same workspace (otherwise the alias basename would still split it — `alias-` vs `realname-`). Canonical path: `realpath "${CLAUDE_PROJECT_DIR}" 2>/dev/null || readlink -f "${CLAUDE_PROJECT_DIR}" 2>/dev/null || printf '%s' "${CLAUDE_PROJECT_DIR}"` (e.g. macOS repos under `/private/var/…`). Then `` = the **basename of the canonical path** slugified to lowercase alphanumerics and hyphens, then `-` plus the first 8 hex chars of `printf '%s' "" | { sha256sum 2>/dev/null || shasum -a 256; } | cut -c1-8` (the fallback covers stock macOS). The hash discriminator is required because the basename alone collides when two clones or worktrees share a directory name. Both `topic` and `codebase` workspaces are scoped under `` — topic learning becomes associated with the project you launched from. - **``** — literally `topic` or `codebase`, matching the action that created the workspace. This level keeps the two modes independent: `/teach:teach topic auth-flow` and `/teach:teach codebase auth-flow` in the same project resolve to separate workspaces (`.../topic/auth-flow/` vs `.../codebase/auth-flow/`) instead of one seeding over the other's `MISSION.md` / `RESOURCES.md`. -- **``** and **``** — content-named kebab slugs (lowercase alphanumerics and hyphens only; strip `/`, `\`, `..`), NOT sequence-numbered. `"Domain-Driven Design"` → `domain-driven-design`; `"Rust Ownership"` → `rust-ownership`. +- **``** and **``** — content-named kebab slugs (lowercase alphanumerics and hyphens only; strip `/`, `\`, `..`), NOT sequence-numbered. `"Domain-Driven Design"` → `domain-driven-design`; `"Rust Ownership"` → `rust-ownership`. **Record the exact raw subject/concept name** (`MISSION.md`'s `# Mission: {Topic}` title for a topic; the lesson's `**Concept:**` line for a concept) so it is the source of truth for collision checks. **Guard against slug collisions** — distinct subjects can normalize to the same slug (`C++` and `C#` → `c`; `Node.js` and `Node JS` → `node-js`), which would silently share one workspace. Before creating a workspace whose slug directory already exists, read that existing workspace's recorded raw name; if it names a DIFFERENT subject, append `-` plus the first 4 hex chars of `printf '%s' '' | { sha256sum 2>/dev/null || shasum -a 256; } | cut -c1-4` to the new slug, keeping per-subject state isolated while leaving non-colliding slugs readable. - **`learning-records/NNNN-.md`** keeps `NNNN-` numbering (sanctioned ADR-style append-only log). Scan the directory for the highest existing `NNNN` and increment. - `${CLAUDE_PLUGIN_DATA}` is created automatically the first time it is referenced and persists across plugin updates, so workspaces survive between sessions. From dab5af1b2bc33b18bb48d58d841058da99a7ec09 Mon Sep 17 00:00:00 2001 From: Kyle Sexton <153232337+kyle-sexton@users.noreply.github.com> Date: Sun, 12 Jul 2026 01:08:35 -0400 Subject: [PATCH 6/6] fix(teach): namespace the last bare /teach reference to /teach:teach --- plugins/teach/skills/teach/SKILL.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/teach/skills/teach/SKILL.md b/plugins/teach/skills/teach/SKILL.md index c1c2fe9b..02c75d7c 100644 --- a/plugins/teach/skills/teach/SKILL.md +++ b/plugins/teach/skills/teach/SKILL.md @@ -206,6 +206,6 @@ Learning artifacts persist for months; durable teaching content (references, glo ## What This Skill Does NOT Do - **Does not write production code** — teaches understanding, not implementation. Use the project's own implementation workflow for code changes -- **Does not replace `/book-distill:book-distill`** — that extracts book knowledge into skill reference files; `/teach` delivers knowledge interactively to the user +- **Does not replace `/book-distill:book-distill`** — that extracts book knowledge into skill reference files; `/teach:teach` delivers knowledge interactively to the user - **Does not do task-context codebase investigation** — that's for the project's code-exploration tooling; `/teach:teach codebase` is structured learning for understanding - **Does not auto-invoke** — `disable-model-invocation: true`. The user initiates learning sessions