diff --git a/.STATUS b/.STATUS
index 52334964..0a28ab35 100644
--- a/.STATUS
+++ b/.STATUS
@@ -1,9 +1,9 @@
status: Active
progress: 100
-next: Post-v2.18.1 — rich-exam v1 grading-line gap (backlog #13); rich-exam v2 examark QTI (backlog #11)
-target: v2.18.1 — Maintenance (dep CVE patch→0 vulns, ESLint gate+cleanup, \printanswers short-answer fix, timing de-flake)
-milestone: v2.18.1 release via PR (dev→main) 2026-06-12 | 33 commands | 38 tutorials | 3,405 tests (3,268 Jest + 137 node:test) | 143 suites
-last_session: 2026-06-12 - spec-status cleanup + PR #107 review/merge + v2.18.1 release pipeline (Session 92)
+next: Homebrew tap auto-update VALIDATED (App 2874502 + HOMEBREW_TAP_APP_ID/PRIVATE_KEY secrets set; workflow_dispatch smoke test green, App-authored tap PR #118 merged) — only residual: confirm de750f5 forwarding rides dev→main on the NEXT real release (release events run from main's copy); then rich-exam v1 grading-line gap (backlog #13); rich-exam v2 examark QTI (backlog #11)
+target: v2.19.0 — scaffolded-math-tutorial teaching skill (18th) + skills surfaced in the hub (/scholar:hub skills, discoverSkills) + skill_count macro + df-conflation closure-audit guardrail; Missing-Effect adversarial-review release (#2)
+milestone: v2.19.0 release via PR (dev→main) 2026-06-13 | 33 commands | 18 skills | 38 tutorials | 3,411 tests (3,268 Jest + 143 node:test) | 144 suites
+last_session: 2026-06-12 (Session 94) - Homebrew tap-auth ACTIVATED + validated end-to-end: created GitHub App "Data-Wise Homebrew Automation" (ID 2874502), set HOMEBREW_TAP_APP_ID + HOMEBREW_TAP_APP_PRIVATE_KEY secrets, proved via workflow_dispatch smoke test (App-authored tap PR #118 merged — also fixed stale manifest.json scholar 2.17.0→2.18.1). Debug gotcha: "JWT could not be decoded" = wrong/revoked private key (secret had old 2026-05-12 .pem; valid was 2026-06-12) — isolated with a local openssl+curl /app test. Also: root-caused `brew upgrade scholar` block to upstream Homebrew 6.0.1-28 build-sandbox regression (commit 080ffb3d1b "deny all of $HOME"), shipped tap bin.mkpath fix (PR #117, all 8 source-built formulae) + scholar upgraded to 2.18.1 via brew (pin-to-6.0.1 workaround, then unpinned). Prior: Session 93 post-v2.18.1 cleanup (de750f5, 4dd2afc, spec v5)
complexity: Low
risk_level: Low
dependencies: Claude API, js-yaml, ajv, ajv-keywords, ajv-formats, Quarto, flow-cli, R/Rscript (runtime), examark (Canvas QTI), jstat (F-distribution)
diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json
index 6d9496f4..b5fd18aa 100644
--- a/.claude-plugin/plugin.json
+++ b/.claude-plugin/plugin.json
@@ -1,6 +1,6 @@
{
"name": "scholar",
- "version": "2.18.1",
+ "version": "2.19.0",
"description": "Academic workflows for research and teaching - literature management, manuscript writing, simulation design, and course material generation",
"author": {
"name": "Data-Wise"
diff --git a/.github/markdown-link-check-config.json b/.github/markdown-link-check-config.json
index ac89e1c2..77f552b1 100644
--- a/.github/markdown-link-check-config.json
+++ b/.github/markdown-link-check-config.json
@@ -114,6 +114,12 @@
{
"pattern": "^https://aspredicted.org"
},
+ {
+ "pattern": "^https://www.imsglobal.org"
+ },
+ {
+ "pattern": "^https://opensource.org/licenses"
+ },
{
"pattern": "%7B%7B"
},
diff --git a/.github/workflows/homebrew-release.yml b/.github/workflows/homebrew-release.yml
index a4f05e1b..d35679e0 100644
--- a/.github/workflows/homebrew-release.yml
+++ b/.github/workflows/homebrew-release.yml
@@ -76,4 +76,10 @@ jobs:
command_count: '33'
skill_count: '17'
secrets:
+ # Preferred: GitHub App token (no expiry). The reusable workflow uses the
+ # App path when both app_id and app_private_key are non-empty, else falls
+ # back to tap_token (a PAT, which expires). Add HOMEBREW_TAP_APP_ID and
+ # HOMEBREW_TAP_APP_PRIVATE_KEY repo secrets to activate the App path.
+ app_id: ${{ secrets.HOMEBREW_TAP_APP_ID }}
+ app_private_key: ${{ secrets.HOMEBREW_TAP_APP_PRIVATE_KEY }}
tap_token: ${{ secrets.HOMEBREW_TAP_GITHUB_TOKEN }}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 142f37d8..17c682a5 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
+## [2.19.0] — 2026-06-13
+
+### Added
+
+- **`scaffolded-math-tutorial` teaching skill** — a reusable methodology for turning a paper, proof, or formula into a college-algebra-floor self-study course (four pillars, the Terminology Closure Audit, self-explanation + faded worked examples, dual HTML/PDF Quarto). Brings the skill count to **18** under a new **Teaching** category.
+- **Skills surfaced in the hub** — `/scholar:hub skills` lists auto-activating skills by category, and the overview gains a SKILLS block. The discovery engine adds `discoverSkills()` / `getSkillStats()` / `getSkillsByCategory()` (scanning `skills/**/SKILL.md`), with 7 new node:test cases — zero changes to the command-scan path or cache.
+- **`skill_count` macro** in `mkdocs.yml`, synced by `scripts/version-sync.js` and consumed by `docs/skills.md`.
+- `docs/WHATS-NEW-v2.19.0.md`; a `/scholar:hub skills` row in the Reference Card and the hub tutorial.
+
+### Changed
+
+- `scaffolded-math-tutorial` gains a 4th Terminology-Closure-Audit rule — **one symbol, one meaning; flag context-dependent forms** — guarding against attaching one definition of a symbol (e.g. a degrees-of-freedom that differs between a pooled-$t$ and a pooled-LRT reference) to a reference that needs a different form.
+
+### Fixed
+
+- `markdown-link-check`: ignore `imsglobal.org` and `opensource.org/licenses` — valid external links that intermittently return Status 0 / 403 to the checker and flaked the docs CI.
+
## [2.18.1] — 2026-06-12
### Security
@@ -1386,6 +1403,7 @@ text.replace(/\$([^$]+)\$/g, (match, content) => {
---
+[2.19.0]: https://github.com/Data-Wise/scholar/compare/v2.18.1...v2.19.0
[2.18.1]: https://github.com/Data-Wise/scholar/compare/v2.18.0...v2.18.1
[2.18.0]: https://github.com/Data-Wise/scholar/compare/v2.17.0...v2.18.0
[2.17.0]: https://github.com/Data-Wise/scholar/compare/v2.16.0...v2.17.0
diff --git a/CLAUDE.md b/CLAUDE.md
index e88c5284..0b02acf6 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -54,15 +54,15 @@ This file contains project-specific instructions for Claude Code when working on
### Overview
Scholar is a Claude Code plugin for academic workflows with research + teaching capabilities.
-### Current State (v2.18.1 released 2026-06-12)
-- **Research:** 14 commands, 17 skills
+### Current State (v2.19.0 released 2026-06-13)
+- **Research:** 14 commands, 18 skills (4 mathematical + 5 implementation + 3 writing + 5 research + 1 teaching)
- **Teaching:** 18 commands (`/teaching:exam`, `/teaching:quiz`, `/teaching:slides`, `/teaching:assignment`, `/teaching:solution`, `/teaching:syllabus`, `/teaching:rubric`, `/teaching:feedback`, `/teaching:demo`, `/teaching:lecture`, `/teaching:validate`, `/teaching:validate-r`, `/teaching:diff`, `/teaching:sync`, `/teaching:migrate`, `/teaching:config`, `/teaching:preflight`, `/teaching:canvas`)
- **Hub:** 1 command (`/scholar:hub` — command discovery and navigation, with flag discovery)
-- **Tests:** 3,405 (3,268 Jest + 137 node:test), 143 suites
+- **Tests:** 3,411 (3,268 Jest + 143 node:test), 144 suites
- **Tutorials:** 38 (research-namespace coverage ~100%, teaching-namespace 100%; indexed at `docs/tutorials/index.md`)
- **Docs:** MkDocs site on GitHub Pages — https://Data-Wise.github.io/scholar/
- **Integration:** Works with flow-cli for workflow automation
-- **Release:** https://github.com/Data-Wise/scholar/releases/tag/v2.18.1 — maintenance: dep CVE patch (0 vulns), ESLint gate, `\printanswers` short-answer fix, timing de-flake
+- **Release:** https://github.com/Data-Wise/scholar/releases/tag/v2.19.0 — `scaffolded-math-tutorial` teaching skill (18th); skills surfaced in the hub (`/scholar:hub skills` + discovery `discoverSkills`); `skill_count` macro; df-conflation closure-audit guardrail; markdown-link-check flake fixes
- **Active branch:** `dev` (clean)
- **Next:** rich-exam v1 grading-line gap (`.STATUS` backlog #13); rich-exam v2 examark QTI (backlog #11)
diff --git a/README.md b/README.md
index 85ece726..2a7b8df5 100644
--- a/README.md
+++ b/README.md
@@ -5,8 +5,8 @@
A comprehensive Claude Code plugin for academic workflows combining research and teaching. Features unified Plugin + MCP architecture with 33 slash commands and research skills.
[](https://opensource.org/licenses/MIT)
-[](https://github.com/Data-Wise/scholar/releases/tag/v2.18.1)
-[](https://github.com/Data-Wise/scholar)
+[](https://github.com/Data-Wise/scholar/releases/tag/v2.19.0)
+[](https://github.com/Data-Wise/scholar)
[](https://github.com/Data-Wise/scholar/actions/workflows/ci.yml?query=branch%3Amain)
[](https://github.com/Data-Wise/scholar/actions/workflows/docs.yml?query=branch%3Amain)
@@ -113,7 +113,7 @@ This architecture eliminates IPC overhead by sharing core logic directly between
- `src/teaching/config/` - Configuration management
- `src/teaching/validators/` - Multi-layer validation (Schema + LaTeX + Completeness)
- `src/teaching/ai/` - AI content generation with retry logic
-- `tests/teaching/` - 3,405 unit tests (100% passing)
+- `tests/teaching/` - 3,411 unit tests (100% passing)
See [Phase 0 Architecture](docs/architecture/PHASE-0-FOUNDATION.md) for detailed documentation.
@@ -142,9 +142,9 @@ The Homebrew formula automatically:
- Makes it available in Claude Code CLI and Claude Desktop
- No additional configuration needed
-**Latest version:** v2.18.1 (released 2026-02-09)
+**Latest version:** v2.19.0 (released 2026-02-09)
- 33 commands (18 teaching + 14 research + 1 hub)
-- 3,405 tests with 100% pass rate
+- 3,411 tests with 100% pass rate
- Comprehensive documentation (95% coverage)
### Option 2: Manual Installation (Local Development)
@@ -198,7 +198,7 @@ cd ~/projects/dev-tools/scholar
- 33 commands present (18 teaching + 14 research + 1 hub)
- 17 skills present
- No hardcoded paths
-- v2.18.1 verified
+- v2.19.0 verified
```
### Using in Claude Code CLI
diff --git a/docs/API-REFERENCE.md b/docs/API-REFERENCE.md
index 868442ea..ecf8bb7c 100644
--- a/docs/API-REFERENCE.md
+++ b/docs/API-REFERENCE.md
@@ -4,7 +4,7 @@ render_macros: false
# Scholar Plugin - API Reference
-> **Version:** 2.18.1
+> **Version:** 2.19.0
> **Last Updated:** 2026-03-04
> **Audience:** Plugin developers and contributors
>
diff --git a/docs/REFCARD.md b/docs/REFCARD.md
index d2284038..78f93cc0 100644
--- a/docs/REFCARD.md
+++ b/docs/REFCARD.md
@@ -218,9 +218,11 @@
| `/scholar:hub` | Browse all commands | `/scholar:hub` |
| `/scholar:hub` | Drill into category | `/scholar:hub research` |
| `/scholar:hub` | Command detail | `/scholar:hub exam` |
+| `/scholar:hub` | List skills | `/scholar:hub skills` |
| `/scholar:hub` | Quick reference card | `/scholar:hub quick` |
- **NEW in v2.7.0:** `/scholar:hub` for command discovery with smart context detection
+- **NEW:** `/scholar:hub skills` lists the 18 auto-activating skills grouped by category
---
diff --git a/docs/TEACHING-WORKFLOWS.md b/docs/TEACHING-WORKFLOWS.md
index bfdccd2e..a48c6489 100644
--- a/docs/TEACHING-WORKFLOWS.md
+++ b/docs/TEACHING-WORKFLOWS.md
@@ -4,7 +4,7 @@ render_macros: false
# Scholar Teaching Workflows
-> **Version:** 2.18.1
+> **Version:** 2.19.0
> **Last Updated:** 2026-02-09
> **Audience:** Educators using Scholar for course material generation
>
@@ -958,5 +958,5 @@ Regenerate with new settings.
---
**Last updated:** 2026-02-09
-**Version:** 2.18.1
+**Version:** 2.19.0
**Contribute your workflows:** [GitHub Issues](https://github.com/Data-Wise/scholar/issues)
diff --git a/docs/WHATS-NEW-v2.18.0.md b/docs/WHATS-NEW-v2.18.0.md
index 8185eb5a..6c6d39a7 100644
--- a/docs/WHATS-NEW-v2.18.0.md
+++ b/docs/WHATS-NEW-v2.18.0.md
@@ -46,5 +46,4 @@ The generated `.qmd` compiles with `quarto render exam.qmd --to pdf` using `lual
## Related
- [Spec: Rich Exam Format](specs/SPEC-2026-05-12-rich-exam-format.md)
-- [ORCHESTRATE: exam-rich-latex](https://github.com/Data-Wise/scholar/blob/feature/exam-rich-latex/ORCHESTRATE-exam-rich-latex.md)
- [CHANGELOG v2.18.0](https://github.com/Data-Wise/scholar/blob/main/CHANGELOG.md#2180--2026-05-12)
diff --git a/docs/WHATS-NEW-v2.19.0.md b/docs/WHATS-NEW-v2.19.0.md
new file mode 100644
index 00000000..252a9a12
--- /dev/null
+++ b/docs/WHATS-NEW-v2.19.0.md
@@ -0,0 +1,37 @@
+# What's New in v2.19.0
+
+**Status:** In development (targets v2.19.0)
+
+This release adds a new teaching skill and makes **all** skills discoverable from the hub.
+
+## scaffolded-math-tutorial skill
+
+A new auto-activating skill for turning a paper, proof, or formula into a **self-study course** a motivated reader (college-algebra floor) can learn from alone. It encodes a proven methodology:
+
+- **Four pillars** — zero undefined jargon + a running glossary; prerequisite primers taught before use; self-explanation + faded worked examples as the backbone (quizzing as a supplement); and a per-section teaching scaffold (objectives → worked instance → recap).
+- **The Terminology Closure Audit** — the enforceable version of "define every term": a compound-term rule, a no-forward-reference (closure) rule, and a mandated final audit pass.
+- **Dual HTML/PDF Quarto** output with folded-answer checkpoints.
+
+It brings the skill count to **18** and adds a new **Teaching** category to the [Skills Reference](skills.md). Background and the learning-science basis live in the skill's `reference/pedagogy.md`.
+
+## Skills in the hub
+
+The hub now surfaces **skills** alongside commands:
+
+```bash
+/scholar:hub # overview now includes a SKILLS block (per-category counts)
+/scholar:hub skills # all auto-activating skills, grouped by category, with inline help
+```
+
+Under the hood, the discovery engine gained `discoverSkills()` / `getSkillStats()` / `getSkillsByCategory()`, scanning `skills/**/SKILL.md`. The change is additive — the command-scan path and cache are untouched, so there is no behavior change for existing commands.
+
+Unlike commands, skills are **not invoked** — they activate automatically when your conversation matches their description.
+
+## Docs & tooling
+
+- New **Teaching** category in the [Skills Reference](skills.md); the [Reference Card](REFCARD.md) lists `/scholar:hub skills`; the [hub tutorial](tutorials/getting-started-with-hub.md) shows how to list skills.
+- A `skill_count` macro is now tracked in `mkdocs.yml` and synced by `scripts/version-sync.js`, so the skill total stays consistent across docs.
+
+## Notes
+
+- Skills are not command-count-gated; CI's "≥15 skills" floor still holds.
diff --git a/docs/help/FAQ-teaching.md b/docs/help/FAQ-teaching.md
index e854582e..8c156665 100644
--- a/docs/help/FAQ-teaching.md
+++ b/docs/help/FAQ-teaching.md
@@ -2,7 +2,7 @@
render_macros: false
---
-# Teaching FAQ - Scholar v2.18.1
+# Teaching FAQ - Scholar v2.19.0
> **Quick answers to common questions about Scholar's teaching commands**
@@ -1768,4 +1768,4 @@ See [Migration Guide](../MIGRATION-v2.2.0.md).
---
-**Last Updated:** 2026-05-12 for Scholar v2.18.1
+**Last Updated:** 2026-05-12 for Scholar v2.19.0
diff --git a/docs/help/TROUBLESHOOTING-teaching.md b/docs/help/TROUBLESHOOTING-teaching.md
index 8dd1f08b..3f37ff6c 100644
--- a/docs/help/TROUBLESHOOTING-teaching.md
+++ b/docs/help/TROUBLESHOOTING-teaching.md
@@ -5,7 +5,7 @@ render_macros: false
# Troubleshooting Guide - Scholar Teaching Commands
> **Quick Fixes for Common Issues**
-> Version: 2.18.1 | Last Updated: 2026-05-12
+> Version: 2.19.0 | Last Updated: 2026-05-12
---
@@ -38,7 +38,7 @@ scholar --version
**Expected output:**
```
-Scholar v2.18.1
+Scholar v2.19.0
```
**If not found:**
@@ -574,7 +574,7 @@ claude plugin install scholar
```bash
# Check version
-scholar --version # Should be 2.18.1+
+scholar --version # Should be 2.19.0+
# Update if older
brew upgrade scholar
@@ -2642,7 +2642,7 @@ head -40 exam.tex # YAML preamble should match what's in the .qmd
| `! Class exam Error` | `exam` class not installed | Install `texlive-latex-extra` (Linux) or `mactex-extra` (macOS) |
| `! Undefined control sequence \printanswers` | Trying to render answer key without `exam` class | Same fix — install `texlive-latex-extra` |
| `Quarto not found` | Quarto CLI missing | Install Quarto 1.4+ from |
-| Bracket table shows `NaN` rows | Invalid df pair supplied (`df1: 0`, etc.) | Both `df1` and `df2` must be finite integers ≥ 1; Scholar v2.18.1+ throws on invalid input |
+| Bracket table shows `NaN` rows | Invalid df pair supplied (`df1: 0`, etc.) | Both `df1` and `df2` must be finite integers ≥ 1; Scholar v2.19.0+ throws on invalid input |
**Step 1: Verify the YAML preamble**
@@ -3379,7 +3379,7 @@ If custom prompts are complex, use refine:
**Solution:**
-1. File was generated before provenance tracking (requires Scholar v2.18.1+)
+1. File was generated before provenance tracking (requires Scholar v2.19.0+)
2. File was not generated by Scholar (e.g., manually created)
3. Frontmatter was modified and metadata comments were removed
4. Re-generate the file with current Scholar version to add provenance
@@ -4315,4 +4315,4 @@ Visit: https://console.anthropic.com/account/billing/usage
**Questions? Spotted an issue?** Open a GitHub issue: https://github.com/Data-Wise/scholar/issues
-**Last Updated:** 2026-05-12 for Scholar v2.18.1
+**Last Updated:** 2026-05-12 for Scholar v2.19.0
diff --git a/docs/skills.md b/docs/skills.md
index 15cd9215..8308ba97 100644
--- a/docs/skills.md
+++ b/docs/skills.md
@@ -1,6 +1,6 @@
# Scholar Skills Reference
-> **Version {{ scholar.version }}** - 17 A-grade auto-activating skills for statistical research and methods development
+> **Version {{ scholar.version }}** - {{ scholar.skill_count }} A-grade auto-activating skills for statistical research, methods development, and teaching
## Skill Categories
@@ -8,6 +8,7 @@
- **[Implementation](#implementation-skills)** (5 skills)
- **[Writing](#writing-skills)** (3 skills)
- **[Research](#research-skills)** (5 skills)
+- **[Teaching](#teaching-skills)** (1 skill)
## Mathematical Skills
@@ -238,6 +239,22 @@ Sensitivity analysis design.
**Activates on:** "sensitivity", "robustness", "assumptions"
+## Teaching Skills
+
+### scaffolded-math-tutorial
+
+Self-study math/stats tutorials that teach formulas and derivations from the ground up — a
+motivated reader (college-algebra floor) can learn from the document alone.
+
+**Expertise:**
+
+- College-algebra-floor scaffolding (prerequisite primers taught before use)
+- The Terminology Closure Audit (zero undefined jargon; no forward references)
+- Self-explanation + faded worked examples as the backbone (quizzing as supplement)
+- Folded-answer checkpoints; dual HTML (folded) / PDF (open) Quarto rendering
+
+**Activates on:** "tutorial", "teach me the math", "explain this derivation", "scaffold a proof"
+
## Usage Examples
### Automatic Activation
diff --git a/docs/tutorials/getting-started-with-hub.md b/docs/tutorials/getting-started-with-hub.md
index 7a5625ba..df782ff9 100644
--- a/docs/tutorials/getting-started-with-hub.md
+++ b/docs/tutorials/getting-started-with-hub.md
@@ -237,6 +237,14 @@ Tip: You're in a teaching project. Try /teaching:exam or /scholar:hub for all co
Look for `[AI]` markers in the overview, or drill into a command to check for `--instructions / -i` in its Options section.
+### "What skills do I have?"
+
+```bash
+/scholar:hub skills # All auto-activating skills, grouped by category
+```
+
+Skills aren't invoked like commands -- they activate automatically when your conversation matches their description. See the [Skills Reference](../skills.md) for the full list.
+
### "I'm new -- where do I start?"
```bash
diff --git a/docs/workflows/research/latex-integration.md b/docs/workflows/research/latex-integration.md
index 5e0a5d7b..cb929065 100644
--- a/docs/workflows/research/latex-integration.md
+++ b/docs/workflows/research/latex-integration.md
@@ -1031,7 +1031,7 @@ Week 4: Advanced automation (Makefiles, CI/CD)
---
-**Document Version:** v2.18.1
+**Document Version:** v2.19.0
**Last Updated:** 2026-02-01
**Word Count:** ~7,500
**Example Scripts:** 15+
diff --git a/docs/workflows/research/literature-review.md b/docs/workflows/research/literature-review.md
index df18133a..3181b4f0 100644
--- a/docs/workflows/research/literature-review.md
+++ b/docs/workflows/research/literature-review.md
@@ -1249,7 +1249,7 @@ After completing literature review:
---
-**Document Version:** v2.18.1
+**Document Version:** v2.19.0
**Last Updated:** 2026-02-01
**Word Count:** ~9,500
**Time to Complete:** 2-4 weeks for systematic review
diff --git a/docs/workflows/research/manuscript-writing.md b/docs/workflows/research/manuscript-writing.md
index 9b28cba8..a42158bf 100644
--- a/docs/workflows/research/manuscript-writing.md
+++ b/docs/workflows/research/manuscript-writing.md
@@ -1813,7 +1813,7 @@ pandoc manuscript.md --bibliography references.bib -o manuscript.pdf
---
-**Document Version:** 2.18.1
+**Document Version:** 2.19.0
**Last Updated:** 2026-02-04
**Author:** Data-Wise Team
**Status:** Complete
diff --git a/mkdocs.yml b/mkdocs.yml
index 2d3452cf..2c993a91 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -44,17 +44,18 @@ extra_css:
extra:
scholar:
- version: "2.18.1"
- prev_version: "2.18.0"
- release_date: "2026-06-12"
- test_count: "3,405"
+ version: "2.19.0"
+ prev_version: "2.18.1"
+ release_date: "2026-06-13"
+ test_count: "3,411"
jest_count: "3,268"
- node_test_count: "137"
+ node_test_count: "143"
command_count: 33
teaching_commands: 18
research_commands: 14
+ skill_count: 18
hub_commands: 1
- suite_count: 143
+ suite_count: 144
markdown_extensions:
- pymdownx.highlight:
@@ -238,6 +239,7 @@ nav:
- Phase 0 Foundation: architecture/PHASE-0-FOUNDATION.md
- Release Notes:
+ - What's New in v2.19.0: WHATS-NEW-v2.19.0.md
- What's New in v2.18.0: WHATS-NEW-v2.18.0.md
- What's New in v2.17.0: WHATS-NEW-v2.17.0.md
- What's New in v2.16.0: WHATS-NEW-v2.16.0.md
diff --git a/package.json b/package.json
index bed83e33..fb06fd85 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@data-wise/scholar",
- "version": "2.18.1",
+ "version": "2.19.0",
"description": "Academic workflows for research and teaching - 33 commands for literature management, manuscript writing, simulation studies, course material generation, and config management",
"main": "src/plugin-api/commands/index.js",
"type": "module",
diff --git a/scripts/version-sync.js b/scripts/version-sync.js
index cb6aa542..8c9676a9 100755
--- a/scripts/version-sync.js
+++ b/scripts/version-sync.js
@@ -66,6 +66,8 @@ const mkdocsPath = join(rootDir, 'mkdocs.yml');
const mkdocsContent = existsSync(mkdocsPath) ? readFileSync(mkdocsPath, 'utf-8') : '';
const commandCountMatch = mkdocsContent.match(/command_count:\s*(\d+)/);
const commandCount = commandCountMatch ? Number(commandCountMatch[1]) : 28;
+const skillCountMatch = mkdocsContent.match(/skill_count:\s*(\d+)/);
+const skillCount = skillCountMatch ? Number(skillCountMatch[1]) : 18;
// Format number with commas (e.g. 2252 -> "2,252")
function formatCount(n) {
@@ -360,6 +362,12 @@ const docPatterns = {
replacement: `$1${commandCount}$3`,
label: 'Command count',
},
+ // XX specialized Claude skills (skill count, e.g. skills/README.md)
+ skillCount: {
+ regex: /(contains )(\d+)( specialized Claude skills)/,
+ replacement: `$1${skillCount}$3`,
+ label: 'Skill count',
+ },
// Should be X.Y.Z+ (troubleshooting expected output)
shouldBeVersion: {
regex: /(Should be )\d+\.\d+\.\d+(\+)/,
@@ -386,6 +394,11 @@ const targets = [
label: 'SCHOLAR_VERSION constant',
}])},
+ // skills/README.md hardcodes the total skill count (not macro-rendered)
+ { rel: 'src/plugin-api/skills/README.md', sync: (f) => syncDocFile(f, [
+ docPatterns.skillCount,
+ ])},
+
// Doc files with render_macros: false
{ rel: 'docs/API-REFERENCE.md', sync: (f) => syncDocFile(f, [
docPatterns.versionFooter,
diff --git a/src/discovery/index.js b/src/discovery/index.js
index 2accbe27..133430ae 100644
--- a/src/discovery/index.js
+++ b/src/discovery/index.js
@@ -21,6 +21,9 @@ const COMMANDS_REL = 'src/plugin-api/commands';
/** Cache file path (relative to project root). */
const CACHE_REL = 'src/discovery/cache.json';
+/** Root of the plugin-api skills directory (relative to project root). */
+const SKILLS_REL = 'src/plugin-api/skills';
+
/**
* Directories that map to the "teaching" top-level category.
* Everything else rolls up to "research".
@@ -554,3 +557,116 @@ export function getCommandDetail(commandName) {
hasInstructions: hasInstructionsFlag(flags),
};
}
+
+// ---------------------------------------------------------------------------
+// Skill discovery
+//
+// The hub surfaces *skills* alongside commands. Skills live at
+// src/plugin-api/skills///SKILL.md. We scan for SKILL.md
+// files (case-insensitive), derive the category from the first path segment
+// under skills/, and read name + description from frontmatter. Flat helper
+// files (e.g. teaching/canvas.md) without a SKILL.md are intentionally excluded.
+// ---------------------------------------------------------------------------
+
+/**
+ * Recursively collect SKILL.md file paths under a directory.
+ *
+ * @param {string} dir - Absolute directory to walk.
+ * @returns {string[]} Absolute paths to SKILL.md files.
+ */
+function findSkillFiles(dir) {
+ const out = [];
+ let entries;
+ try {
+ entries = readdirSync(dir, { withFileTypes: true });
+ } catch {
+ return out;
+ }
+ for (const e of entries) {
+ const p = join(dir, e.name);
+ if (e.isDirectory()) {
+ out.push(...findSkillFiles(p));
+ } else if (/^skill\.md$/i.test(e.name)) {
+ out.push(p);
+ }
+ }
+ return out;
+}
+
+/**
+ * Scan all SKILL.md files, parse frontmatter, and return structured skill data.
+ *
+ * Each entry contains:
+ * - name: skill name from frontmatter (e.g. "proof-architect")
+ * - description: one-line description from frontmatter
+ * - category: top-level skill category (dir under skills/, e.g. "mathematical", "teaching")
+ * - file: relative path from project root
+ * - kind: "skill" (distinguishes skills from commands when surfaced together)
+ *
+ * @returns {object[]} Array of skill metadata objects, sorted by category then name.
+ */
+export function discoverSkills() {
+ const root = getProjectRoot();
+ const skillsDir = join(root, SKILLS_REL);
+ if (!existsSync(skillsDir)) {
+ return [];
+ }
+
+ const skills = [];
+ for (const file of findSkillFiles(skillsDir)) {
+ const content = readFileSync(file, 'utf-8');
+ const { frontmatter } = parseFrontmatter(content);
+
+ const relUnderSkills = file.slice(skillsDir.length + 1).split(/[/\\]/);
+ const category = relUnderSkills[0] || 'other';
+ const dirName = relUnderSkills.length >= 2
+ ? relUnderSkills[relUnderSkills.length - 2]
+ : category;
+
+ skills.push({
+ name: frontmatter.name || dirName,
+ description: frontmatter.description || '',
+ category,
+ file: file.slice(root.length + 1),
+ kind: 'skill',
+ });
+ }
+
+ skills.sort((a, b) => {
+ if (a.category !== b.category) return a.category.localeCompare(b.category);
+ return a.name.localeCompare(b.name);
+ });
+
+ return skills;
+}
+
+/**
+ * Return aggregate skill counts by category plus the total.
+ *
+ * @returns {{ byCategory: Object, total: number }}
+ */
+export function getSkillStats() {
+ const skills = discoverSkills();
+ const byCategory = Object.create(null);
+ for (const s of skills) {
+ byCategory[s.category] = (byCategory[s.category] || 0) + 1;
+ }
+ return { byCategory, total: skills.length };
+}
+
+/**
+ * Return skills grouped by category (for hub rendering).
+ *
+ * @returns {Object} Map of category -> array of skills.
+ */
+export function getSkillsByCategory() {
+ const skills = discoverSkills();
+ const grouped = Object.create(null);
+ for (const s of skills) {
+ if (!grouped[s.category]) {
+ grouped[s.category] = [];
+ }
+ grouped[s.category].push(s);
+ }
+ return grouped;
+}
diff --git a/src/plugin-api/commands/hub.md b/src/plugin-api/commands/hub.md
index 07e4a478..b19846a6 100644
--- a/src/plugin-api/commands/hub.md
+++ b/src/plugin-api/commands/hub.md
@@ -5,7 +5,7 @@ description: Command discovery and navigation hub for all scholar commands
# Scholar Hub
-Discover and navigate all 33 scholar commands across research and teaching workflows.
+Discover and navigate all 33 scholar commands and 18 auto-activating skills across research and teaching workflows.
**Usage:** `/scholar:hub [argument]`
@@ -14,6 +14,7 @@ Discover and navigate all 33 scholar commands across research and teaching workf
- `/scholar:hub research` - Drill into research commands
- `/scholar:hub teaching` - Drill into teaching commands
- `/scholar:hub exam` - Show details for a specific command
+- `/scholar:hub skills` - List auto-activating skills by category
- `/scholar:hub quick` - Compact one-line reference card
## Navigation Layers
@@ -23,6 +24,7 @@ Discover and navigate all 33 scholar commands across research and teaching workf
| Overview | *(none)* | All commands grouped by category |
| Category | `research` or `teaching` | Commands with descriptions and usage |
| Detail | `` | Full info, usage, and examples |
+| Skills | `skills` | Auto-activating skills grouped by category |
| Quick | `quick` | One-line-per-command reference table |
@@ -34,7 +36,7 @@ It uses the discovery engine and smart-help engine to produce formatted output.
Load command metadata from the discovery engine and context tips from smart-help:
```javascript
-import { loadCachedCommands, getCategoryInfo, getCommandDetail } from '${CLAUDE_PLUGIN_ROOT}/src/discovery/index.js';
+import { loadCachedCommands, getCategoryInfo, getCommandDetail, getSkillsByCategory, getSkillStats } from '${CLAUDE_PLUGIN_ROOT}/src/discovery/index.js';
import { detectContext, getAutoTip } from '${CLAUDE_PLUGIN_ROOT}/src/discovery/smart-help.js';
```
@@ -46,6 +48,7 @@ Parse the argument provided after `/scholar:hub`:
- `research` -> Layer 2 (Research drill-down)
- `teaching` -> Layer 2 (Teaching drill-down)
- `quick` -> Quick reference card
+- `skills` -> Skills view (auto-activating skills grouped by category)
- Anything else -> Layer 3 (Command detail lookup)
## Layer 1: Overview (no argument)
@@ -74,9 +77,15 @@ then render the following box-drawing layout:
| Config ...... validate, diff, sync, migrate, |
| demo, config, preflight |
| |
+| SKILLS (18 auto-activating) |
+| Mathematical 4 Implementation 5 Writing 3 |
+| Research 5 Teaching 1 |
+| -> /scholar:hub skills for the list |
+| |
+-----------------------------------------------------------+
| /scholar:hub research Drill into research commands |
| /scholar:hub teaching Drill into teaching commands |
+| /scholar:hub skills List skills by category |
| /scholar:hub quick Compact reference card |
+-----------------------------------------------------------+
```
@@ -87,6 +96,8 @@ Rules for Layer 1 rendering:
- Group teaching commands by subcategory: content, assessment, config
- Use dotted leaders (periods) to align subcategory names with command lists
- Wrap long command lists onto the next line, indented to align with the first command
+- Render the SKILLS block from `getSkillStats()` (per-category counts). Skills are
+ *auto-activating*, not invoked like commands — point to `/scholar:hub skills`
- After the box, call `detectContext(process.cwd())` from smart-help and append
the result of `getAutoTip(context)` as a final line below the box
@@ -114,6 +125,40 @@ Rules for AI markers:
- Research commands may also have AI markers — always derive from `hasInstructions`, not a hardcoded list
- Account for the extra width of `[AI]` markers when wrapping command lists within the box
+## Skills View (`skills` argument)
+
+Call `getSkillsByCategory()` (and `getSkillStats()` for counts) to list the
+auto-activating skills. Unlike commands, skills are *not* invoked — they activate
+automatically when the conversation matches their description. Render:
+
+```
++-----------------------------------------------------------+
+| SCHOLAR SKILLS (18 auto-activating) |
+| Activate automatically from conversation context |
++-----------------------------------------------------------+
+| |
+| MATHEMATICAL (4) |
+| proof-architect Rigorous proof construction |
+| mathematical-foundations Core statistical theory |
+| identification-theory Causal identification |
+| asymptotic-theory Large-sample behavior |
+| |
+| ... Implementation (5), Writing (3), Research (5) ... |
+| |
+| TEACHING (1) |
+| scaffolded-math-tutorial Self-study math tutorials |
+| |
++-----------------------------------------------------------+
+| Skills need no invocation — describe your task and the |
+| matching skill activates. Full list: docs/skills.md |
++-----------------------------------------------------------+
+```
+
+Rules for the Skills view:
+- Group by `category` from `getSkillsByCategory()`; show the per-category count in the header
+- For each skill, show its `name` and a short form of its `description` (wrap ~40 chars)
+- Make clear skills auto-activate (they are not slash commands) — no `/scholar:` prefix
+
## Layer 2: Category Drill-Down (`research` or `teaching`)
Call `getCategoryInfo(category)` which returns an object keyed by subcategory,
diff --git a/src/plugin-api/skills/README.md b/src/plugin-api/skills/README.md
index 5316d619..fc7ede05 100644
--- a/src/plugin-api/skills/README.md
+++ b/src/plugin-api/skills/README.md
@@ -1,6 +1,6 @@
# Statistical Research Skills
-This directory contains 17 specialized Claude skills for statistical methodology research.
+This directory contains 18 specialized Claude skills for statistical methodology research.
## Categories
@@ -29,6 +29,9 @@ This directory contains 17 specialized Claude skills for statistical methodology
- **mediation-meta-analyst** - Meta-analysis for mediation
- **sensitivity-analyst** - Sensitivity analysis design
+### Teaching (1 skill)
+- **scaffolded-math-tutorial** - Self-study math/stats tutorials: closure-audited glossary, primers-before-use, self-explanation + faded worked examples, folded-answer checkpoints, dual HTML/PDF Quarto
+
## Installation
Skills are installed to `~/.claude/skills/` via symlinks:
@@ -46,7 +49,7 @@ Each skill contains:
## Benchmark Scores
-All skills have been benchmarked and achieve A-grade (90+/100):
+Skills are benchmarked for quality (A-grade target, 90+/100); newly added skills are marked *new* pending benchmarking:
| Skill | Score | Grade |
|-------|-------|-------|
@@ -67,6 +70,7 @@ All skills have been benchmarked and achieve A-grade (90+/100):
| method-transfer-engine | 93.0 | A |
| mediation-meta-analyst | 94.5 | A |
| sensitivity-analyst | 92.5 | A |
+| scaffolded-math-tutorial | — | new |
## Usage
diff --git a/src/plugin-api/skills/teaching/scaffolded-math-tutorial/SKILL.md b/src/plugin-api/skills/teaching/scaffolded-math-tutorial/SKILL.md
new file mode 100644
index 00000000..67797272
--- /dev/null
+++ b/src/plugin-api/skills/teaching/scaffolded-math-tutorial/SKILL.md
@@ -0,0 +1,162 @@
+---
+name: scaffolded-math-tutorial
+description: Build college-algebra-floor, self-study tutorials that teach statistical formulas and derivations from the ground up — primers before use, a closure-audited glossary, self-explanation + faded worked examples, and folded-answer checkpoints, rendered as dual HTML/PDF Quarto
+---
+
+# Scaffolded Math Tutorial
+
+**Turn a paper, proof, or formula into a self-study course a motivated reader can learn from *alone* — nothing undefined, every prerequisite taught before it is used, understanding checked at every step.**
+
+Use this skill when working on: teaching a statistical derivation or formula step by step; converting a methods proof into a learnable tutorial; writing a "technical addendum" or self-study course; explaining estimands/test statistics/asymptotics to a reader with only college algebra + intro calculus; or auditing an existing tutorial for undefined jargon and forward references.
+
+This skill is **conversational** — Claude Code reads the source material and writes the tutorial directly (no API key, full repo context). It is **domain-general**; project-specific notation and sources are supplied by the caller (e.g. a project's `/tutor` command).
+
+---
+
+## The non-negotiable standard
+
+> A motivated reader who knows only **college algebra and introductory calculus** can learn every concept from the document alone. Nothing is left undefined, every prerequisite tool is taught before it is used, and understanding is checked at every step. *If a term would send the reader to Google or a textbook, the document has failed.*
+
+State the assumed floor explicitly at the top ("this course assumes only …") and teach everything above it, in dependency order.
+
+## The four pillars (how to hit the standard)
+
+1. **Zero undefined jargon.** On a term's first use, give in order: (a) a one-line plain-language gloss, (b) a precise definition, (c) a tiny example where it helps. Maintain a running **glossary** (the reader's panic button). Ban "clearly", "obviously", "it is well known", "it follows that".
+2. **Teach the prerequisites.** Before any step that uses a foundational tool, insert a short **Primer box** that teaches the tool from scratch with a minimal worked example, *then* apply it. Never use a tool before its primer.
+3. **Self-explanation backbone, quizzing as supplement.** Make "explain *why* this step follows" prompts and **faded worked examples** the load-bearing pedagogy (strongest, cheapest evidence for math — see `reference/pedagogy.md`). Keep attempt-before-reveal **Checkpoints** and one **end-of-section quiz** + a **cumulative final**, but do *not* saturate every subsection with quizzes.
+4. **Teaching scaffold.** Open each section with **learning objectives** ("after this you can …") and close with a "you can now …" recap. Give every abstract claim a **worked numeric instance**. Use progressive disclosure, analogies (flagged as analogies — they motivate, they do not prove), labeled diagrams, and explicit common-misconception callouts.
+
+**Rigor guardrail:** an analogy or simplification may *never* introduce an error. If the material proves things, the tutorial must stay correct.
+
+---
+
+## The Terminology Closure Audit (Pillar 1, made enforceable)
+
+"Define every term" is unverifiable without a verification pass. Three rules + a final audit catch the failures that slip through:
+
+1. **Compound-term rule.** A glossed head noun does *not* discharge a modified phrase. Define the phrase *as used* **and** each meaning-bearing modifier. Test: if removing the modifier changes the math, the modifier needs its own gloss→def→example. (Canonical trap: "projection" is glossed but "$\mathcal I$-orthogonal projection" — and the "$\mathcal I$-norm" it rests on — are not.)
+2. **Closure / no forward references.** A definition may use only already-defined terms. Define the metric before the operation built on it (the $\mathcal I$-norm primer precedes the $\mathcal I$-orthogonal projection).
+3. **Mandated audit pass.** After drafting, sweep the document and enumerate every technical term *and compound phrase* in order of first appearance. For each, confirm (i) gloss→def→example at or before first use, (ii) non-circular, (iii) every symbol in it already defined. Emit a coverage report.
+4. **One symbol, one meaning — flag context-dependent forms.** When a symbol legitimately takes *different forms in different contexts*, the audit must catch it and the tutorial must state **which form applies to which reference** — never let one definition silently stand in for the other. The signature defect (seen repeatedly in generated tutorials): a degrees-of-freedom $\nu$ defined once (e.g. the *scalar Rubin* $(m-1)(1+1/r)^2$) and then attached to a *different* reference that needs another form (e.g. the *Meng–Rubin/LRR* pooled-LRT df) — numerically far apart (≈62 vs ≈48.5 in a real case), so the document contradicts itself. Relatedly, never state a quantity *equals* a function of itself (e.g. ARIV **is** $r$; the deflation factor $1/(1+r)$ is a function *of* $r$, not ARIV itself).
+
+**Audit algorithm** (run before rendering):
+(a) extract terms + compound phrases in appearance order; (b) coverage check; (c) closure check; (d) topological-sort primers, reorder violations; (e) mechanical sweep — grep banned words and any symbol used before its glossary row, **and check that any symbol carrying more than one formula across the document is explicitly disambiguated per context** (rule 4); (f) output a coverage + violations report. (a)–(d) are reasoned; (e) is grep-checkable:
+
+```bash
+grep -nE '\b(clearly|obviously|trivially)\b|it is well known|it follows that|one can show' tutorial.qmd
+```
+
+A phrase that fails any check is a **bug**, not a stylistic nit. Fix before declaring the document done.
+
+---
+
+## Depth modes (the unit of one tutorial)
+
+| Mode | Scope | Shape |
+|---|---|---|
+| `formula` | one formula/concept | floor → primer(s) → derivation → worked instance → self-explanation prompt → Checkpoint → mini-quiz → recap |
+| `derivation` | one proposition/proof | the above, plus dependency-ordered steps, each justified ("which rule licenses this move and why it is legal here") |
+| `course` | a whole topic | a roadmap (symbols + glossary + dependency table) and several dependency-ordered **rungs**, each a `derivation`, plus cumulative final quiz, self-diagnostic, and appendices |
+
+Apply all four pillars *fully* regardless of mode (per the standard); depth selects *scope*, not rigor.
+
+---
+
+## What to include (the device catalog)
+
+A full tutorial contains, in order:
+
+1. **Frontmatter** — dual output: HTML (folded answers, KaTeX) + PDF (answers open, TikZ). See render conventions below.
+2. **How-to-use callout** + a one-sentence "the theorem this course earns".
+3. **Roadmap** (course mode): assumed-floor statement; three reference tables — **symbols-at-a-glance**, **bridge-to-literature** (local symbol ↔ standard notation ↔ where you'll meet it), **running glossary**; and a **rung-dependency table**.
+4. **Per rung/section**: learning objectives → "Plain words" preamble → **Primer boxes** (for each new tool) → derivation (equations introduced in prose; **boxed result + inline assumptions**; geometric "the picture" notes) → **self-explanation prompt** + **faded worked example** (full → partial → blank) → **Checkpoint** → folded **Answer** → "you can now…" recap.
+5. **End-of-section quiz** (3–5 items spanning recall/application/reasoning; misconception-targeting MC distractors) with a folded answer key + section pointers for each miss.
+6. **Cumulative final quiz**; **self-diagnostic checklist** (failure-mode → section); **common misconceptions** ("No — [fact]" pattern).
+7. **Appendices** (course mode): dependency graph (Mermaid for HTML / TikZ for PDF — the *same* DAG); map to manuscript sections; fully-worked closed-form derivations.
+
+### Quarto syntax for each device
+
+```markdown
+::: {.callout-note}
+## Primer —
+. . *Tiny example:* .
+:::
+
+::: {.callout-note}
+## Learning objectives
+After this section you can: (1) … (2) … (3) …
+:::
+
+::: {.callout-tip}
+## Checkpoint
+
+:::
+
+::: {.callout-note collapse="true"}
+## Answer
+
+:::
+
+::: {.callout-warning}
+## Common misconceptions
+- **"."** No — ; .
+:::
+```
+
+- **Boxed result + assumptions:** `$$\boxed{\ \ }$$` immediately followed by `*Assumes:* `.
+- **Reference tables:** three-column markdown tables (symbol/term | plain gloss | precise form-or-location).
+- **Faded worked example:** show the computation fully once, then a near-identical one with the key step blanked for the reader, then one with only the setup.
+
+### Render conventions (dual HTML + PDF)
+
+```yaml
+format:
+ html: { toc: true, html-math-method: katex, theme: cosmo }
+ pdf:
+ toc: true
+ include-in-header:
+ text: |
+ \usepackage{tikz}
+ \usetikzlibrary{positioning, arrows.meta}
+```
+
+- HTML keeps Answers **folded** (`collapse="true"`) for self-study discipline; PDF shows them all.
+- **Diagrams:** Mermaid wrapped in `::: {.content-visible when-format="html"}`; an equivalent **TikZ** block in ```` ```{=tex} ```` for the PDF path (Mermaid silently fails in PDF). Keep both encoding the same DAG.
+- **LaTeX-safe math** for PDF: write `\theta^*`, not `\theta^\*`; no raw non-ASCII inside `$…$`.
+- If the project's root `_quarto.yml` scopes `render:` to one file, render the tutorial in a project-free temp dir to escape that scope.
+
+### Notation contract
+
+- **Define estimands before symbols.** Introduce the quantity ("the indirect effect — the thing we test") before its symbol (`$ab$`).
+- Use the project's strict notation; add a **bridge-to-literature** table mapping local symbols to standard names.
+- Flag any needed-but-unverified fact as `[CITE]` — never invent results, numbers, or citations.
+
+---
+
+## Workflow
+
+1. **Scope & floor.** Pick the depth mode; state the assumed math floor.
+2. **Gather sources.** Read the source math + the project's notation contract. List the concepts to teach.
+3. **Order by dependency.** Build the term/primer dependency DAG; this fixes primer order and (course mode) the rung order.
+4. **Draft** per the device catalog — pillars 1/2/4 fully; self-explanation + faded examples as the backbone; quizzes per policy.
+5. **Closure audit.** Run the audit algorithm; fix coverage/closure/ordering violations + the banned-word sweep.
+6. **Render-check** both HTML and PDF; fix LaTeX/PDF-safety issues.
+
+---
+
+## Integration with other skills
+
+This skill works with:
+- **proof-architect** — for the rigorous proof skeleton a `derivation`/`course` tutorial teaches (this skill is the pedagogical presentation layer over it).
+- **mathematical-foundations** — source of the core concepts and theorems to scaffold (sufficiency, Fisher information, asymptotics).
+- **asymptotic-theory** / **identification-theory** — for limiting-distribution and causal-identification material taught pedagogically.
+- **methods-paper-writer** — when a tutorial's result is promoted into a manuscript (shared VanderWeele/standard notation).
+- **`/teaching:lecture`** (command) — lecture notes are the broader-coverage cousin; this skill is the deep single-derivation treatment.
+
+---
+
+**Version**: 1.0
+**Created**: 2026-06-12
+**Domain**: Statistical teaching, mathematical pedagogy, self-study course design
+**Prerequisite skills**: proof-architect, mathematical-foundations
+**Reference**: `reference/pedagogy.md` (learning-science basis + per-formula checklist + citations)
diff --git a/src/plugin-api/skills/teaching/scaffolded-math-tutorial/reference/pedagogy.md b/src/plugin-api/skills/teaching/scaffolded-math-tutorial/reference/pedagogy.md
new file mode 100644
index 00000000..90a8c756
--- /dev/null
+++ b/src/plugin-api/skills/teaching/scaffolded-math-tutorial/reference/pedagogy.md
@@ -0,0 +1,90 @@
+# Pedagogy reference — the learning-science basis for scaffolded math tutorials
+
+Evidence-informed backing for the choices in `SKILL.md`. Load when you need the *why*, or to justify a design tradeoff. Each principle ends with a concrete "in a math tutorial, this means…".
+
+## 1. Learning-science principles
+
+### Worked-example effect & faded worked examples (guidance fading)
+Studying fully worked examples, then examples with progressively more steps blanked, beats unguided problem-solving for novices — it shows the solution *path* before demanding recall.
+→ **In a tutorial:** for each formula, give one fully worked numeric instance, then a near-identical one with the key step blanked, then one with only the setup. Make fading explicit.
+
+### Cognitive load theory (intrinsic / extraneous / germane)
+Working memory is limited. Intrinsic load is the material's inherent difficulty; extraneous load is poor presentation; germane load is the effort that builds schemas. Reduce extraneous, manage intrinsic, protect germane.
+→ **Primer boxes** chunk intrinsic load (teach one tool at a time before use); **folded answers** cut extraneous load (the solution isn't on screen tempting a skip); **self-explanation prompts** drive germane load.
+
+### Self-explanation effect (strongest, cheapest gain)
+Prompting learners to explain *why* a step follows produces moderate-to-large gains across a large meta-analytic base, and is nearly free in a written document.
+→ **Make it first-class:** before each folded Answer, ask "explain why this step is legal." This is the backbone, not a garnish.
+
+### Retrieval practice / testing effect — weaker *in mathematics*
+The testing effect is robust in general but **notably weaker for mathematics specifically** (a 2025 meta-analysis reports g ≈ 0.18 with a CI crossing zero). Treat embedded quizzes as a supplement, not the load-bearing strategy.
+→ Keep attempt-before-reveal Checkpoints and one end-of-section quiz + a cumulative final; do **not** saturate every subsection with quizzes.
+
+### Productive struggle / desirable difficulties
+A brief genuine attempt before seeing the answer improves retention and transfer.
+→ The Checkpoint → folded-Answer pattern *is* a desirable difficulty; the discipline of trying first is the point.
+
+### Concreteness fading (concrete → pictorial → abstract)
+Start concrete (numbers, a picture), then generalize to symbols. Fading the concreteness aids transfer better than staying concrete or starting abstract.
+→ Open each idea with a numeric instance or a named picture; introduce the general symbolic statement only after.
+
+### Misconception-targeting / refutation instruction
+Naming the wrong idea and explaining why it's wrong outperforms presenting only the correct idea.
+→ MC distractors should target the *common misconception* (e.g. "size is α because the cutoff is χ²₁" when the true origin size is α²); a `callout-warning` lists myths with "No — [fact]".
+
+### Dual coding (words + visuals)
+Pairing verbal and visual representations aids memory and understanding more than either alone.
+→ Give the same idea in words, a (described/labeled) picture, and a formula. Redundancy across channels is a feature.
+
+### Polya's "How to Solve It" (understand → plan → execute → review)
+A derivation reads better when it states the goal first, sketches the plan in plain words, executes with justified steps, then reviews.
+→ "Plain words" preamble = understand+plan; the boxed result + recap = review.
+
+### Bloom's taxonomy for quiz design
+Span cognitive levels deliberately. Stems by level: **Recall** ("define X in one sentence"); **Apply** ("compute …"); **Analyze/Reason** ("why does X signal Y?").
+→ Every Concept-Check carries one recall, one application, one reasoning item.
+
+### Spaced & interleaved practice
+Revisiting and mixing related ideas beats massing.
+→ The cumulative final quiz interleaves all rungs; the self-diagnostic routes misses back to earlier sections.
+
+## 2. Checklist — explaining ONE formula well
+
+- [ ] Plain-language statement of what it computes (before any symbol)
+- [ ] Symbol table: every symbol's meaning, units, domain/range
+- [ ] Where it comes from (derivation or a pointer to one)
+- [ ] Assumptions / conditions / scope (boxed with the result)
+- [ ] One fully worked numeric example, carried to a checkable number
+- [ ] A faded version (key step blanked) for the reader
+- [ ] A self-explanation prompt ("why is this step legal?")
+- [ ] Edge cases / degeneracies (what breaks it)
+- [ ] Common misconceptions, refuted
+- [ ] Relationship to neighboring formulas (bridge to standard notation)
+- [ ] How to compute it (code) and how to sanity-check a result
+- [ ] Visual / geometric intuition (a labeled or described picture)
+
+## 3. Explaining derivations/proofs
+
+State the goal first; sketch the plan in plain words; order steps by dependency; justify *each* step (name the rule and why it is legal here, never "it follows that"); signpost which assumption each step uses; give geometric intuition; and mark explicitly where rigor is relaxed (an analogy) versus exact (the proof). An analogy may never introduce an error.
+
+## 4. Notation & accessibility
+
+One symbol, one meaning. Define before use. Keep a symbols-at-a-glance table and a running glossary as lookup ("panic button"). Bridge local notation to the standard literature names. For accessibility, prefer real LaTeX/MathML over images of equations.
+
+## 5. SKILL-authoring notes (Anthropic guidance)
+
+- The **`description`** field is the trigger — write it in the third person, concrete, naming when to use the skill; it is the only thing matched before activation.
+- **Progressive disclosure:** keep `SKILL.md` focused (aim < 500 lines); push depth into one-level-deep `reference/` files loaded on demand (this file).
+- Prefer checklists and templates the model can copy over abstract prose; **show, don't just tell**.
+- State the rule *and* the why; keep skills focused on one capability.
+
+## Sources
+
+- Sweller, van Merriënboer & Paas — cognitive load theory and worked examples.
+- Renkl; Atkinson et al. — faded worked examples / guidance fading.
+- Bisra et al. (2018), *Educational Psychology Review* — self-explanation meta-analysis (64 studies).
+- Rohrer & Pashler; Dunlosky et al. (2013) — testing, spacing, interleaving; and the math-specific weakness of the testing effect (2025 meta-analysis).
+- Fyfe et al. — concreteness fading.
+- Polya, *How to Solve It*.
+- Anderson & Krathwohl — revised Bloom's taxonomy.
+- Anthropic — Agent Skills authoring guidance (description-as-trigger, progressive disclosure).
diff --git a/src/teaching/ai/prompt-config-bridge.js b/src/teaching/ai/prompt-config-bridge.js
index 70d63e03..57f31644 100644
--- a/src/teaching/ai/prompt-config-bridge.js
+++ b/src/teaching/ai/prompt-config-bridge.js
@@ -22,7 +22,7 @@ import { loadTeachConfig } from '../config/loader.js';
* Current Scholar version for compatibility checking
* Should match package.json version
*/
-const SCHOLAR_VERSION = '2.18.1';
+const SCHOLAR_VERSION = '2.19.0';
/**
* Error thrown when prompt configuration fails
diff --git a/tests/README.md b/tests/README.md
index 856047a6..eb479c46 100644
--- a/tests/README.md
+++ b/tests/README.md
@@ -16,7 +16,7 @@ tests/
└── ai-provider.test.js # AI provider (28 tests)
```
-**Total:** 3,405 tests, all passing ✅
+**Total:** 3,411 tests, all passing ✅
## Running Tests
diff --git a/tests/discovery/discovery.test.js b/tests/discovery/discovery.test.js
index e2a994d2..132b5d3e 100644
--- a/tests/discovery/discovery.test.js
+++ b/tests/discovery/discovery.test.js
@@ -17,6 +17,9 @@ import {
getCommandStats,
getCategoryInfo,
getCommandDetail,
+ discoverSkills,
+ getSkillStats,
+ getSkillsByCategory,
} from '../../src/discovery/index.js';
// ---------------------------------------------------------------------------
@@ -376,3 +379,58 @@ describe('flag extraction', () => {
}
});
});
+
+// ---------------------------------------------------------------------------
+// discoverSkills()
+// ---------------------------------------------------------------------------
+
+describe('discoverSkills()', () => {
+ let skills;
+
+ before(() => {
+ skills = discoverSkills();
+ });
+
+ it('returns an array', () => {
+ assert.ok(Array.isArray(skills), 'Expected an array of skills');
+ });
+
+ it('finds exactly 18 skills', () => {
+ assert.equal(skills.length, 18, `Expected 18 skills, got ${skills.length}`);
+ });
+
+ it('each skill has required fields: name, description, category, file, kind', () => {
+ for (const s of skills) {
+ for (const field of ['name', 'description', 'category', 'file', 'kind']) {
+ assert.ok(field in s, `Skill "${s.name || '(unnamed)'}" is missing field "${field}"`);
+ }
+ assert.equal(s.kind, 'skill', `Skill "${s.name}" should have kind "skill"`);
+ }
+ });
+
+ it('groups into the expected per-category counts (4/5/3/5/1)', () => {
+ const { byCategory, total } = getSkillStats();
+ assert.equal(total, 18, `Expected 18 skills total, got ${total}`);
+ assert.equal(byCategory.mathematical, 4, 'mathematical should have 4 skills');
+ assert.equal(byCategory.implementation, 5, 'implementation should have 5 skills');
+ assert.equal(byCategory.writing, 3, 'writing should have 3 skills');
+ assert.equal(byCategory.research, 5, 'research should have 5 skills');
+ assert.equal(byCategory.teaching, 1, 'teaching should have 1 skill');
+ });
+
+ it('surfaces the scaffolded-math-tutorial teaching skill', () => {
+ const s = skills.find(x => x.name === 'scaffolded-math-tutorial');
+ assert.ok(s, 'scaffolded-math-tutorial should be discovered');
+ assert.equal(s.category, 'teaching');
+ assert.ok(s.description.length > 0, 'should carry a description from frontmatter');
+ });
+
+ it('getSkillsByCategory groups skills under their category', () => {
+ const byCat = getSkillsByCategory();
+ assert.ok(Array.isArray(byCat.teaching), 'teaching group should be an array');
+ assert.ok(
+ byCat.teaching.some(s => s.name === 'scaffolded-math-tutorial'),
+ 'teaching group should include scaffolded-math-tutorial'
+ );
+ });
+});