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. [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) -[![Version](https://img.shields.io/badge/version-2.18.1-blue.svg)](https://github.com/Data-Wise/scholar/releases/tag/v2.18.1) -[![Tests](https://img.shields.io/badge/tests-3,405%20passing-brightgreen.svg)](https://github.com/Data-Wise/scholar) +[![Version](https://img.shields.io/badge/version-2.19.0-blue.svg)](https://github.com/Data-Wise/scholar/releases/tag/v2.19.0) +[![Tests](https://img.shields.io/badge/tests-3,411%20passing-brightgreen.svg)](https://github.com/Data-Wise/scholar) [![Scholar CI](https://github.com/Data-Wise/scholar/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/Data-Wise/scholar/actions/workflows/ci.yml?query=branch%3Amain) [![Docs Deploy](https://github.com/Data-Wise/scholar/actions/workflows/docs.yml/badge.svg?branch=main)](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' + ); + }); +});