explainer-video 0.0.0-stage → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (150) hide show
  1. package/.claude-plugin/plugin.json +12 -0
  2. package/LICENSE +21 -0
  3. package/README.md +152 -2
  4. package/cordis.patch.yml +7 -0
  5. package/lib/index.js +35 -0
  6. package/package.json +56 -4
  7. package/plugin.json +13 -0
  8. package/skills/coursework-author/.synced-from +5 -0
  9. package/skills/coursework-author/SKILL.md +209 -0
  10. package/skills/craft-codeflow-flows/SKILL.md +116 -0
  11. package/skills/craft-codeflow-mine/SKILL.md +207 -0
  12. package/skills/craft-codeflow-plan/SKILL.md +65 -0
  13. package/skills/craft-codeflow-scene/SKILL.md +168 -0
  14. package/skills/craft-video-align/SKILL.md +109 -0
  15. package/skills/craft-video-assemble/SKILL.md +69 -0
  16. package/skills/craft-video-audio/SKILL.md +59 -0
  17. package/skills/craft-video-enrich/SKILL.md +46 -0
  18. package/skills/craft-video-plan/SKILL.md +57 -0
  19. package/skills/craft-video-publish/SKILL.md +79 -0
  20. package/skills/craft-video-render/SKILL.md +68 -0
  21. package/skills/craft-video-scene/SKILL.md +112 -0
  22. package/skills/craft-video-script/SKILL.md +80 -0
  23. package/skills/explainer-video-from-codebase/FLOWS.md +577 -0
  24. package/skills/explainer-video-from-codebase/SKILL.md +659 -0
  25. package/skills/explainer-video-from-codebase/tools/apply-flows.mjs +531 -0
  26. package/skills/explainer-video-from-codebase/tools/approve-flows.mjs +56 -0
  27. package/skills/explainer-video-from-codebase/tools/codemap-md.mjs +116 -0
  28. package/skills/explainer-video-from-codebase/tools/config/dotenv.mjs +13 -0
  29. package/skills/explainer-video-from-codebase/tools/config/json.mjs +14 -0
  30. package/skills/explainer-video-from-codebase/tools/config/redact.mjs +16 -0
  31. package/skills/explainer-video-from-codebase/tools/config/toml-lite.mjs +13 -0
  32. package/skills/explainer-video-from-codebase/tools/config/yaml-lite.mjs +18 -0
  33. package/skills/explainer-video-from-codebase/tools/excerpt-check.mjs +186 -0
  34. package/skills/explainer-video-from-codebase/tools/excerpt.mjs +116 -0
  35. package/skills/explainer-video-from-codebase/tools/flow-diagram.mjs +168 -0
  36. package/skills/explainer-video-from-codebase/tools/flow-plan.mjs +129 -0
  37. package/skills/explainer-video-from-codebase/tools/flows-md.mjs +87 -0
  38. package/skills/explainer-video-from-codebase/tools/lang/c.mjs +684 -0
  39. package/skills/explainer-video-from-codebase/tools/lang/go.mjs +673 -0
  40. package/skills/explainer-video-from-codebase/tools/lang/python-config.mjs +143 -0
  41. package/skills/explainer-video-from-codebase/tools/lang/python-deps.mjs +62 -0
  42. package/skills/explainer-video-from-codebase/tools/lang/python-stdlib.mjs +24 -0
  43. package/skills/explainer-video-from-codebase/tools/lang/python.mjs +609 -0
  44. package/skills/explainer-video-from-codebase/tools/lang/typescript.mjs +963 -0
  45. package/skills/explainer-video-from-codebase/tools/lib/decompose.mjs +102 -0
  46. package/skills/explainer-video-from-codebase/tools/lib/groups.mjs +77 -0
  47. package/skills/explainer-video-from-codebase/tools/lib/observe-coverage.mjs +68 -0
  48. package/skills/explainer-video-from-codebase/tools/lib/observe-v8.mjs +232 -0
  49. package/skills/explainer-video-from-codebase/tools/lib/observe.mjs +162 -0
  50. package/skills/explainer-video-from-codebase/tools/lib/redact.mjs +28 -0
  51. package/skills/explainer-video-from-codebase/tools/lib/sandbox.mjs +97 -0
  52. package/skills/explainer-video-from-codebase/tools/lib/test-links.mjs +28 -0
  53. package/skills/explainer-video-from-codebase/tools/lib/toml.mjs +129 -0
  54. package/skills/explainer-video-from-codebase/tools/lib/trace-c.mjs +95 -0
  55. package/skills/explainer-video-from-codebase/tools/lib/trace-go.mjs +101 -0
  56. package/skills/explainer-video-from-codebase/tools/lib/trace-js.mjs +136 -0
  57. package/skills/explainer-video-from-codebase/tools/lib/tree-sitter.mjs +19 -0
  58. package/skills/explainer-video-from-codebase/tools/lib/walk.mjs +138 -0
  59. package/skills/explainer-video-from-codebase/tools/mine.mjs +409 -0
  60. package/skills/explainer-video-from-codebase/tools/propose.mjs +127 -0
  61. package/skills/explainer-video-from-codebase/tools/rank.mjs +119 -0
  62. package/skills/explainer-video-from-codebase/tools/ranking-md.mjs +76 -0
  63. package/skills/explainer-video-from-codebase/tools/rules/c-handlers.mjs +53 -0
  64. package/skills/explainer-video-from-codebase/tools/rules/celery-taskiq.mjs +48 -0
  65. package/skills/explainer-video-from-codebase/tools/rules/click-typer.mjs +6 -0
  66. package/skills/explainer-video-from-codebase/tools/rules/express.mjs +72 -0
  67. package/skills/explainer-video-from-codebase/tools/rules/fastapi.mjs +99 -0
  68. package/skills/explainer-video-from-codebase/tools/rules/go-http.mjs +173 -0
  69. package/skills/explainer-video-from-codebase/tools/rules/go-test.mjs +108 -0
  70. package/skills/explainer-video-from-codebase/tools/rules/grpc.mjs +57 -0
  71. package/skills/explainer-video-from-codebase/tools/rules/gtest.mjs +97 -0
  72. package/skills/explainer-video-from-codebase/tools/rules/haystack.mjs +55 -0
  73. package/skills/explainer-video-from-codebase/tools/rules/jest-vitest.mjs +100 -0
  74. package/skills/explainer-video-from-codebase/tools/rules/js-http-client.mjs +111 -0
  75. package/skills/explainer-video-from-codebase/tools/rules/nextjs.mjs +53 -0
  76. package/skills/explainer-video-from-codebase/tools/rules/process-spawn.mjs +49 -0
  77. package/skills/explainer-video-from-codebase/tools/rules/py-http-client.mjs +26 -0
  78. package/skills/explainer-video-from-codebase/tools/rules/pytest.mjs +107 -0
  79. package/skills/explainer-video-from-codebase/tools/rules/react-router.mjs +17 -0
  80. package/skills/explainer-video-from-codebase/tools/rules/registry.mjs +31 -0
  81. package/skills/explainer-video-from-codebase/tools/trace/c/fmtrace-sh +14 -0
  82. package/skills/explainer-video-from-codebase/tools/trace/js/fmtrace-net.cjs +33 -0
  83. package/skills/explainer-video-from-codebase/tools/trace/js/fmtrace-srcmap.cjs +41 -0
  84. package/skills/explainer-video-from-codebase/tools/trace/python/fmtrace_plugin.py +87 -0
  85. package/skills/explainer-video-from-codebase/tools/trace/python/sitecustomize.py +330 -0
  86. package/skills/explainer-video-from-codebase/tools/trace/sandbox/linux-bwrap.sh +73 -0
  87. package/skills/explainer-video-from-codebase/tools/trace/sandbox/macos-nonet.sb +41 -0
  88. package/skills/explainer-video-from-codebase/tools/trace.mjs +577 -0
  89. package/skills/explainer-video-from-codebase/vendor/tree-sitter/LICENSES/tree-sitter-c.txt +21 -0
  90. package/skills/explainer-video-from-codebase/vendor/tree-sitter/LICENSES/tree-sitter-cpp.txt +21 -0
  91. package/skills/explainer-video-from-codebase/vendor/tree-sitter/LICENSES/tree-sitter-go.txt +21 -0
  92. package/skills/explainer-video-from-codebase/vendor/tree-sitter/LICENSES/tree-sitter-javascript.txt +21 -0
  93. package/skills/explainer-video-from-codebase/vendor/tree-sitter/LICENSES/tree-sitter-python.txt +21 -0
  94. package/skills/explainer-video-from-codebase/vendor/tree-sitter/LICENSES/tree-sitter-typescript.txt +21 -0
  95. package/skills/explainer-video-from-codebase/vendor/tree-sitter/LICENSES/web-tree-sitter.txt +21 -0
  96. package/skills/explainer-video-from-codebase/vendor/tree-sitter/MANIFEST.json +172 -0
  97. package/skills/explainer-video-from-codebase/vendor/tree-sitter/tree-sitter-c.wasm +0 -0
  98. package/skills/explainer-video-from-codebase/vendor/tree-sitter/tree-sitter-cpp.wasm +0 -0
  99. package/skills/explainer-video-from-codebase/vendor/tree-sitter/tree-sitter-go.wasm +0 -0
  100. package/skills/explainer-video-from-codebase/vendor/tree-sitter/tree-sitter-javascript.wasm +0 -0
  101. package/skills/explainer-video-from-codebase/vendor/tree-sitter/tree-sitter-python.wasm +0 -0
  102. package/skills/explainer-video-from-codebase/vendor/tree-sitter/tree-sitter-tsx.wasm +0 -0
  103. package/skills/explainer-video-from-codebase/vendor/tree-sitter/tree-sitter-typescript.wasm +0 -0
  104. package/skills/explainer-video-from-codebase/vendor/tree-sitter/web-tree-sitter.js +4081 -0
  105. package/skills/explainer-video-from-codebase/vendor/tree-sitter/web-tree-sitter.wasm +0 -0
  106. package/skills/explainer-video-from-coursework/ARCHITECTURE.md +59 -0
  107. package/skills/explainer-video-from-coursework/PIPELINE.md +343 -0
  108. package/skills/explainer-video-from-coursework/ROADMAP.md +725 -0
  109. package/skills/explainer-video-from-coursework/SERIES.md +232 -0
  110. package/skills/explainer-video-from-coursework/SETUP.md +105 -0
  111. package/skills/explainer-video-from-coursework/SKILL.md +858 -0
  112. package/skills/explainer-video-from-coursework/scenes/_pt-chart.js +12 -0
  113. package/skills/explainer-video-from-coursework/scenes/_pt-equation.js +10 -0
  114. package/skills/explainer-video-from-coursework/scenes/_pt-hubspoke.js +7 -0
  115. package/skills/explainer-video-from-coursework/scenes/_pt-loopflow.js +7 -0
  116. package/skills/explainer-video-from-coursework/scenes/_pt-sequence.js +12 -0
  117. package/skills/explainer-video-from-coursework/scenes/_pt-timeline.js +11 -0
  118. package/skills/explainer-video-from-coursework/src/scene-code.html +127 -0
  119. package/skills/explainer-video-from-coursework/src/scene-code.js +379 -0
  120. package/skills/explainer-video-from-coursework/src/scene-core.js +1250 -0
  121. package/skills/explainer-video-from-coursework/src/scene-diagram.html +50 -0
  122. package/skills/explainer-video-from-coursework/src/scene-svg.html +50 -0
  123. package/skills/explainer-video-from-coursework/src/timeline.js +297 -0
  124. package/skills/explainer-video-from-coursework/src/timing-chart.js +160 -0
  125. package/skills/explainer-video-from-coursework/tools/align.mjs +419 -0
  126. package/skills/explainer-video-from-coursework/tools/apply-enrichment.mjs +206 -0
  127. package/skills/explainer-video-from-coursework/tools/assemble.mjs +223 -0
  128. package/skills/explainer-video-from-coursework/tools/build-audio.mjs +234 -0
  129. package/skills/explainer-video-from-coursework/tools/chromium.mjs +73 -0
  130. package/skills/explainer-video-from-coursework/tools/debug-page.mjs +75 -0
  131. package/skills/explainer-video-from-coursework/tools/env.mjs +30 -0
  132. package/skills/explainer-video-from-coursework/tools/frame-dedup.mjs +131 -0
  133. package/skills/explainer-video-from-coursework/tools/key-source.mjs +151 -0
  134. package/skills/explainer-video-from-coursework/tools/model.mjs +21 -0
  135. package/skills/explainer-video-from-coursework/tools/naming.mjs +38 -0
  136. package/skills/explainer-video-from-coursework/tools/onset-audit.mjs +51 -0
  137. package/skills/explainer-video-from-coursework/tools/pacing-check.mjs +350 -0
  138. package/skills/explainer-video-from-coursework/tools/planner.mjs +616 -0
  139. package/skills/explainer-video-from-coursework/tools/publish.mjs +230 -0
  140. package/skills/explainer-video-from-coursework/tools/render.mjs +205 -0
  141. package/skills/explainer-video-from-coursework/tools/resolve-beats.mjs +239 -0
  142. package/skills/explainer-video-from-coursework/tools/script-check.mjs +174 -0
  143. package/skills/explainer-video-from-coursework/tools/stamp.mjs +71 -0
  144. package/skills/explainer-video-from-coursework/tools/timing-report.mjs +299 -0
  145. package/skills/explainer-video-from-coursework/tools/transcribe-gemini.mjs +96 -0
  146. package/skills/explainer-video-from-coursework/tools/tts-gemini.mjs +394 -0
  147. package/skills/explainer-video-from-coursework/tools/verify-audio.mjs +88 -0
  148. package/skills/explainer-video-from-coursework/tools/workdir.mjs +124 -0
  149. package/skills/explainer-video-from-coursework/vendor/plotly-basic.min.js +8 -0
  150. package/skills/explainer-video-from-coursework/vendor/plotly-basic.min.js.LICENSE.txt +16 -0
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "explainer-video",
3
+ "version": "0.4.0",
4
+ "description": "Turn structured coursework notes, or a codebase's major code flows, into a narrated, animated explainer-video series.",
5
+ "author": {
6
+ "name": "Akshay Prabhakant"
7
+ },
8
+ "license": "MIT",
9
+ "homepage": "https://github.com/akshayDev17/ai-explainer-video",
10
+ "repository": "https://github.com/akshayDev17/ai-explainer-video",
11
+ "keywords": ["explainer-video", "coursework", "codebase", "code-flow", "narration", "animation", "text-to-speech", "video"]
12
+ }
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Akshay Prabhakant
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,153 @@
1
- # Temporary Holding Version
1
+ # explainer-video
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Turn a directory of structured coursework notes, or a codebase's major code flows,
4
+ into a narrated, animated explainer-video series.
5
+
6
+ A skill for AI coding agents — Claude Code, Codex, DeepSeek Harness and
7
+ Antigravity. Point it at a folder of course notes: it plans the series, writes
8
+ the narration, synthesizes the audio, authors the visuals, then renders and
9
+ assembles finished MP4s with YouTube-ready chapters and captions.
10
+
11
+ Its planner does not merely invent titles — it **proves completeness**: every
12
+ content-bearing section is assigned to a video or classified as navigation
13
+ (`0 orphaned`) before any expensive stage runs.
14
+
15
+ ## The pipeline
16
+
17
+ Stage 0 (`/inputs`) collects the two things only you can decide — the source
18
+ notes directory, and where the finished videos land.
19
+
20
+ | # | stage | what it does | cost |
21
+ |---|-------|--------------|------|
22
+ | 1 | `/plan` | decompose the notes, prove coverage | free, local |
23
+ | 2 | `/enrich` | retitle and curate (skip / merge) | free, agent |
24
+ | 3 | `/script` | write the narration segments | free, agent |
25
+ | 4 | `/audio` | TTS → a measured timeline | **network — spends the Gemini key** |
26
+ | 5 | `/scene` | author the visuals (`diagram` / `code` / `svg`) | free, agent |
27
+ | 6 | `/publish` | YouTube chapters + captions | free — no TTS, no Chromium |
28
+ | 7 | `/render` | frames → H.264 MP4 | local CPU |
29
+ | 8 | `/assemble` | per-segment parts → the finished cut | local CPU |
30
+
31
+ Stages 1–2 run once for the whole directory; stages 3–8 run once per video. One
32
+ video end to end is a valid stopping point — a pilot, or a single-target run.
33
+
34
+ ## Install
35
+
36
+ > **Renamed.** This plugin was published as `explainer-video-from-coursework`; it is now
37
+ > `explainer-video`. The skills inside are unchanged — `/explainer-video-from-coursework` and
38
+ > `/explainer-video-from-codebase` keep their names. If you installed the old name, uninstall it
39
+ > and install the new one: `claude plugin uninstall explainer-video-from-coursework@akshaydev17`
40
+ > then `claude plugin marketplace update akshaydev17` and the install line below (Codex and
41
+ > DeepSeek Harness: remove the old name the same way, then add `explainer-video`). Antigravity
42
+ > installs from git and needs nothing. The old npm package stays published but receives no new
43
+ > releases.
44
+
45
+ **Claude Code**
46
+
47
+ ```sh
48
+ claude plugin marketplace add akshayDev17/ai-explainer-video
49
+ claude plugin install explainer-video@akshaydev17
50
+ ```
51
+
52
+ **Codex**
53
+
54
+ ```sh
55
+ codex plugin marketplace add akshayDev17/ai-explainer-video
56
+ codex plugin add explainer-video@akshaydev17
57
+ ```
58
+
59
+ **DeepSeek Harness**
60
+
61
+ ```sh
62
+ dsh plugin --profile web add explainer-video
63
+ ```
64
+
65
+ **Antigravity**
66
+
67
+ ```sh
68
+ agy plugin install https://github.com/akshayDev17/ai-explainer-video
69
+ ```
70
+
71
+ All four commands install the **same** npm package — one package, three manifest surfaces,
72
+ one copy of all sixteen skills: the ten video skills, `coursework-author`, the companion
73
+ skill for writing the coursework these videos come from, and the five code-flow skills:
74
+ `explainer-video-from-codebase`, which makes explainer videos of a codebase's major code flows
75
+ (Python, TypeScript / JavaScript, Go, C, C++, or a mix), and its four stage skills. It mines the
76
+ repo, ranks candidate flows, optionally traces the test suite in a sandbox, has you approve the
77
+ flow list, plans the videos, then runs the same per-video stages with verified code panels and
78
+ generated flow diagrams. How each platform reads it, and how
79
+ to publish, is in
80
+ [`DISTRIBUTION.md`](./DISTRIBUTION.md).
81
+
82
+ ## Prerequisites
83
+
84
+ - **Node ≥ 22** — `render.mjs` relies on the built-in global `WebSocket`.
85
+ - **`ffmpeg` + `ffprobe`** — H.264 encoding, muxing, and duration measurement.
86
+ - **Headless Chromium** — `npx playwright install --with-deps --only-shell`.
87
+ - **A Gemini API key** — for TTS. It lives in the **OS secret store** (macOS
88
+ Keychain · Linux `secret-tool` · Windows Credential Manager) under the service
89
+ name `gemini-tts` — never in env, never in a plaintext file. A free key:
90
+ <https://aistudio.google.com/apikey>.
91
+
92
+ The tools **fail loud** on a missing prerequisite rather than quietly producing a
93
+ broken video. Per-OS commands and citations:
94
+ [`SETUP.md`](./skills/explainer-video-from-coursework/SETUP.md).
95
+
96
+ ## Use it
97
+
98
+ Invoke the skill with the notes directory:
99
+
100
+ ```
101
+ /explainer-video-from-coursework path/to/your/notes/
102
+ ```
103
+
104
+ You get one `.mp4` per video, plus `description.md` (blurb and a paste-ready
105
+ chapter block) and `captions.srt`, copied to the destination you chose — by
106
+ default `videos/` beside the source. Scratch stays in a gitignored
107
+ `out/<name>/<NN>/`.
108
+
109
+ For a codebase, invoke the code-flow skill with the repo root instead:
110
+
111
+ ```
112
+ /explainer-video-from-codebase path/to/your/repo/
113
+ ```
114
+
115
+ It shows you the ranked candidate flows and its proposed series, and plans no video until you
116
+ approve the flow list. Its scratch root sits outside the repo.
117
+
118
+ Run every command from the **project** (where `out/` lives), not from the skill's
119
+ install folder. The tools self-locate their own `tools/`, `src/` and `scenes/`,
120
+ so only the work and scratch paths depend on the current directory.
121
+
122
+ ## Repository layout
123
+
124
+ ```
125
+ plugin.json Agent Plugins manifest (Codex, Antigravity)
126
+ .claude-plugin/ plugin.json + marketplace.json (Claude Code)
127
+ .agents/plugins/ marketplace.json (Codex)
128
+ cordis.patch.yml + lib/index.js DSH bundle plugin (serves this package's skills/)
129
+ skills/explainer-video-from-coursework/ the main skill: SKILL.md, tools/, src/, scenes/, SETUP.md
130
+ skills/craft-video-<stage>/ the 9 stage skills, separately invocable
131
+ skills/coursework-author/ the companion skill: authoring the coursework (vendored copy)
132
+ skills/explainer-video-from-codebase/ the code-flow skill: SKILL.md, FLOWS.md, tools/, vendored tree-sitter
133
+ skills/craft-codeflow-<stage>/ its 4 stage skills (mine, flows, plan, scene), separately invocable
134
+ DISTRIBUTION.md publish + install commands
135
+ ```
136
+
137
+ ## Docs
138
+
139
+ | file | what it covers |
140
+ |------|----------------|
141
+ | [`SKILL.md`](./skills/explainer-video-from-coursework/SKILL.md) | the contract of record — the agent's entry point |
142
+ | [`SKILL.md`](./skills/explainer-video-from-codebase/SKILL.md) (codebase) | the code-flow pipeline's contract of record |
143
+ | [`FLOWS.md`](./skills/explainer-video-from-codebase/FLOWS.md) | every code-flow artifact's fields, from the code map to the code panels |
144
+ | [`SETUP.md`](./skills/explainer-video-from-coursework/SETUP.md) | cited, per-OS machine prerequisites |
145
+ | [`ARCHITECTURE.md`](./skills/explainer-video-from-coursework/ARCHITECTURE.md) | how the pieces fit together |
146
+ | [`PIPELINE.md`](./skills/explainer-video-from-coursework/PIPELINE.md) | the stage-by-stage pipeline |
147
+ | [`ROADMAP.md`](./skills/explainer-video-from-coursework/ROADMAP.md) | design record and open work |
148
+ | [`DISTRIBUTION.md`](./DISTRIBUTION.md) | publishing, and installing on each platform |
149
+ | [`RELEASING.md`](./RELEASING.md) | how a release works — a dispatch, not a merge |
150
+
151
+ ## License
152
+
153
+ MIT — see [`LICENSE`](./LICENSE).
@@ -0,0 +1,7 @@
1
+ # DSH bundle patch — mounts this package's plugin in the global composition.
2
+ # `insert` appends rows; a relative `name` is anchored beside this patch file
3
+ # (see dsh-app-boot `anchorInsertedPluginNames`), so './lib/index.js' resolves
4
+ # to this package's plugin module wherever it is installed.
5
+ - insert:
6
+ - id: explainer-video
7
+ name: './lib/index.js'
package/lib/index.js ADDED
@@ -0,0 +1,35 @@
1
+ import { dirname, join } from "node:path";
2
+ import { fileURLToPath } from "node:url";
3
+ // Deliberately not declared in package.json: only DSH ever loads this module, and
4
+ // the harness's `healProfilesModuleFallback` puts its own dependency closure on
5
+ // Node's parent-walk from the profile directory. Declaring it here would put a
6
+ // DeepSeek dependency into the manifest that Claude Code and Codex install.
7
+ import {
8
+ apply as skillFilesystemApply,
9
+ Config as skillFilesystemConfig,
10
+ inject as skillFilesystemInject,
11
+ name as skillFilesystemName,
12
+ } from "@deepseek-ai/dsh-skill-filesystem";
13
+
14
+ export const name = "explainer-video";
15
+ export const inject = ["skills"];
16
+
17
+ const SkillFilesystem = {
18
+ name: skillFilesystemName,
19
+ inject: skillFilesystemInject,
20
+ Config: skillFilesystemConfig,
21
+ apply: skillFilesystemApply,
22
+ };
23
+
24
+ export function apply(ctx) {
25
+ // This module lives in <pkg>/lib; the skill folders live in <pkg>/skills,
26
+ // so one copy of the skills serves every platform that installs this package.
27
+ const skillsDir = join(dirname(fileURLToPath(import.meta.url)), "..", "skills");
28
+ ctx.plugin(SkillFilesystem, {
29
+ // A unique provider name: the base bundle already registers a "filesystem"
30
+ // provider in the same (global) layer, and duplicate names would throw.
31
+ providerName: "explainer-video",
32
+ includeDefaultRoots: false,
33
+ customSkillDirs: [skillsDir],
34
+ });
35
+ }
package/package.json CHANGED
@@ -1,6 +1,58 @@
1
1
  {
2
2
  "name": "explainer-video",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.4.0",
4
+ "description": "Turn structured coursework notes, or a codebase's major code flows, into a narrated, animated explainer-video series.",
5
+ "type": "module",
6
+ "main": "lib/index.js",
7
+ "engines": {
8
+ "node": ">=22"
9
+ },
10
+ "author": {
11
+ "name": "Akshay Prabhakant"
12
+ },
13
+ "license": "MIT",
14
+ "scripts": {
15
+ "sync:coursework-author": "node scripts/sync-coursework-author.mjs",
16
+ "check:coursework-author-sync": "node scripts/check-coursework-author-sync.mjs",
17
+ "test": "node --test \"test/*.test.mjs\"",
18
+ "sync:tree-sitter": "node scripts/sync-tree-sitter.mjs",
19
+ "check:tree-sitter-vendor": "node scripts/check-tree-sitter-vendor.mjs"
20
+ },
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/akshayDev17/ai-explainer-video.git"
24
+ },
25
+ "keywords": [
26
+ "explainer-video",
27
+ "coursework",
28
+ "codebase",
29
+ "code-flow",
30
+ "narration",
31
+ "animation",
32
+ "text-to-speech",
33
+ "video"
34
+ ],
35
+ "files": [
36
+ "plugin.json",
37
+ ".claude-plugin/plugin.json",
38
+ "skills/",
39
+ "!skills/*/fixtures/",
40
+ "lib/",
41
+ "cordis.patch.yml"
42
+ ],
43
+ "dsh": {
44
+ "bundle": {
45
+ "patch": "./cordis.patch.yml"
46
+ }
47
+ },
48
+ "devDependencies": {
49
+ "coursework-author": "^1.0.2",
50
+ "tree-sitter-c": "0.24.1",
51
+ "tree-sitter-cpp": "0.23.4",
52
+ "tree-sitter-go": "0.25.0",
53
+ "tree-sitter-javascript": "0.25.0",
54
+ "tree-sitter-python": "0.25.0",
55
+ "tree-sitter-typescript": "0.23.2",
56
+ "web-tree-sitter": "0.27.1"
57
+ }
58
+ }
package/plugin.json ADDED
@@ -0,0 +1,13 @@
1
+ {
2
+ "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
3
+ "name": "explainer-video",
4
+ "version": "0.4.0",
5
+ "description": "Turn structured coursework notes, or a codebase's major code flows, into a narrated, animated explainer-video series.",
6
+ "author": {
7
+ "name": "Akshay Prabhakant"
8
+ },
9
+ "license": "MIT",
10
+ "homepage": "https://github.com/akshayDev17/ai-explainer-video",
11
+ "repository": "https://github.com/akshayDev17/ai-explainer-video",
12
+ "keywords": ["explainer-video", "coursework", "codebase", "code-flow", "narration", "animation", "text-to-speech", "video"]
13
+ }
@@ -0,0 +1,5 @@
1
+ {
2
+ "package": "coursework-author",
3
+ "version": "1.0.2",
4
+ "sha256": "edbbfee454aa7958b7cb7636708d04a17d698c8c893ebf0761b9b13d5a25d552"
5
+ }
@@ -0,0 +1,209 @@
1
+ ---
2
+ name: coursework-author
3
+ description: Author a structured, module-based self-study course on any technical topic — a syllabus blueprint, one README per module, a fixed module anatomy, and verification gates (memory-less logic review + literature survey). Use when asked to create, build, or author a course, coursework, curriculum, or syllabus; to turn a topic into a module sequence; or to scaffold a self-study program grounded in a reference stack.
4
+ ---
5
+
6
+ # Author a structured coursework
7
+
8
+ Produce a self-study curriculum on any technical topic: a `syllabus.md` blueprint, one README per module (`modules/NN-topic/README.md`), a fixed module anatomy repeated in every module, a running domain spine, and named cross-cutting threads — with every claim grounded where it belongs: stack claims against the stack's own docs, field claims against the literature.
9
+
10
+ The core insight: **the structure is the product.** A course is not a list of topics; it is a designed system — a spine that runs through every module, a fixed anatomy repeated in each, and failure modes named up front. Author the structure first; the prose follows it.
11
+
12
+ ## Inputs
13
+
14
+ Capture these before writing anything:
15
+
16
+ - **Topic** and **learner** — who is this for (senior engineer, beginner, self-study), and the subject.
17
+ - **Reference stack** — the one framework/SDK every stack claim gets grounded in (e.g. ADK). One stack, not several.
18
+ - **Backends** — the models/providers the examples target (e.g. LiteLLM/Azure), if any.
19
+ - **Scope knobs** — labs? capstone? assessment? and the depth target ("as broad and deep as possible" is a legitimate answer; record it, don't leave it implicit).
20
+
21
+ ## Steps
22
+
23
+ 1. **Freeze scope and audience.**
24
+ Decide the learner profile, the reference stack, the backends, and each scope knob.
25
+ **A topic may have no reference stack.** If it is a field topic rather than a framework topic — the literature owns the claims, not an SDK — record `reference stack: NONE` with one sentence of justification and put it in the syllabus. Then Step 4 is N/A, the `<Stack>` blocks, the stack-docs bullet in Sources and the `<Stack> at a glance` thread all drop, and every claim belongs to Step 7. Same for `backends: NONE`. Never invent a framework to satisfy this step.
26
+ *Done when every knob has an explicit value — even "deferred" or "NONE" — and the reference stack is either a single named framework or an explicit `NONE` with its reason.*
27
+
28
+ 2. **Write the blueprint first (`syllabus.md`).**
29
+ Enumerate the modules `M1..Mn` as a table with a status column, then sketch each module leanly — core question · content bullets · domain · exercise. That sketch is what the module gets written from; the table alone is too thin to write from. Define the repo structure (`modules/`, `discussions/`, any reference maps). Name the two or three cross-cutting threads that will repeat, and name the one module that owns each recurring claim — that ownership map is what stops the same paper being surveyed five times. In a one-module course the map is trivially degenerate; say so in a line instead of building a table with one row.
30
+ **Freeze the bibliography format here too** — the key style (`authorYearTopic`), the section order every module's Sources block copies, and the entry shape with its fields named: title · full author list · venue · link · key · `accessed: YYYY-MM-DD` · owns-what. The first claim-dense module then becomes the named gold standard that Step 7 mirrors.
31
+ The status column has three states — `⬜ planned`, `🟡 written`, `✅ verified` — and **written is not verified**: a module becomes `✅` only after **both** gates in Steps 7 and 8 have run on its final text, with their rounds and residual findings recorded in the module's Verification note.
32
+ *Done when the module list is complete, every module carries its lean sketch, every cross-cutting claim has a named owning module, the thread count and the bibliography format are frozen before any module prose exists, and the three-state status vocabulary is written into the syllabus.*
33
+
34
+ 3. **Define the module anatomy once, then repeat it.**
35
+ Write down the fixed README template (see "The module anatomy" below) and reuse it for every module.
36
+ *Done when every module header carries the same blocks, in the same order.*
37
+
38
+ 4. **Ground the reference stack.**
39
+ Attach the stack's docs (an MCP server, the docs site) and verify every API/feature claim against them — never from memory. Flag anything thinly documented honestly, in place.
40
+ This step owns **stack API claims only**; conceptual and scientific claims are Step 7's, so the two never survey the same sentence twice.
41
+ *Done when no stack claim rests on memory; each is traceable to a doc page.*
42
+
43
+ 5. **Write modules in order, cross-referenced.**
44
+ Each module opens with its question + spine + opening scene, delivers its payload, ends with a design exercise and a next-module link. Cross-reference forward and back ("→ M6", "M2's position bias").
45
+ *Done when every module is self-contained AND wired into its neighbours by links.*
46
+
47
+ 6. **End every module with a design exercise.**
48
+ Paper-based, "think, then write", applied to the learner's own context — not a recall quiz.
49
+ *Done when each exercise forces a decision (an ADR, a schema, a budget) rather than a recall.*
50
+
51
+ 7. **Survey the literature for each module — before its verification round, not after it.**
52
+ The module already makes claims. Support them with papers, then make the support checkable: a bibliography whose entries open the paper itself, and a section recording where the literature disagrees. Every edit stays inside this module's own file. The survey runs **before** Step 8 so the verifier reads the finished artifact; a `✅` earned on a pre-bibliography draft is a stale verification.
53
+ - **Inputs.** *Target* — the module README. *Gold standard* — the format frozen in Step 2; if none is frozen yet, this module becomes it, and you freeze it in the syllabus. *Exempt* — the opening scene, the invented domain with its worked example, and the design exercise. Exemption covers narrative and exercise only: payload prose, tables and the policy ledger carry claims and need a citation or an unsupported-bucket entry.
54
+ - **1 · Read the target and the gold standard.** Note the key format, entry format, section order, and tags; everything you write copies those. *Done when you can write one entry from its shape without looking at it.*
55
+ - **2 · List the claims, in document order.** One line per statement a paper could support; mark each exempt passage and skip it. *Done when every heading has a claim attached to it, or is marked exempt.*
56
+ - **3 · Find each claim's owner, and FETCH it — this is the gate.** The owner is the paper that introduced the finding, definition, or taxonomy — not the paper that repeats it. Fetch the page and read the title, the author list, the year, and the identifier off that page. **Every source this module cites must have been fetched in this run**; knowing the literature is not evidence, and a recalled citation is precisely the failure this gate exists to catch. On a **re-survey** — a module back through this step after an edit — re-fetch every cited URL; an entry you did not re-fetch keeps its original `accessed:` date and is *not* claimed as verified this pass, and the Verification note records how many sources this pass fetched. *Done when every entry carries either a fetch from this run or its earlier access date, and every recalled identifier has been checked against the page it resolves to.*
57
+ - **4 · Write the bibliography section.** One entry per source: title, full author list, venue, a link that opens the paper, a stable key written the way the gold standard does, `accessed: YYYY-MM-DD`, and a note naming what that paper owns. *Done when every entry matches the gold-standard shape, carries its access date, and names its own contribution.*
58
+ - **5 · Write the contradictions section, immediately before the bibliography.** For each claim the literature contests, weakens, or contradicts: what the module says, what the sources say (quoted, not paraphrased), and what to change. *Done when every contested claim you found is recorded with a source.*
59
+ - **6 · Cite inline.** Each key on its claim's sentence, in the gold standard's inline style. *Done when every non-exempt claim carries a citation, or sits in the unsupported bucket.*
60
+ - **7 · Check the citation graph.** Count the citations, count the entries, match them. *Done when they are one-to-one — no dangling citation, no orphan entry.*
61
+ - **Course deltas.** *Bootstrap the gold standard* — freeze it in the syllabus; every later module mirrors it. *Exempt the narrative, not the prose* (see Inputs). Step 4 owns stack API claims; this step owns conceptual and scientific claims. *Respect the ownership map* — a claim owned by another module is cited by the same key, not re-surveyed. *Survey by weight, not by count* — framing-bearing claims (taxonomies, causal mechanisms, numbers) are surveyed here, in-module, because a contradiction found at this point attacks the module's *structure*, not a paragraph. Only a reference carrying **no** framing may batch into Step 11, and the module records how many it deferred and which. **Unbounded deferral is not a survey** — a module deferring more than a handful of supporting references is not `✅`. *Keep bibliographies per-module* — module self-containment wants the entries local; the key format is the only course-wide part.
62
+ *Done when the module carries a bibliography in the frozen gold-standard format with a fetched URL and access date per entry, a contradictions section immediately before it, a one-to-one citation graph, an unsupported bucket for the module's own synthesis, and either a citation or an unsupported-bucket entry for every non-exempt claim.*
63
+
64
+ **Unsupported bucket.** A `### Unsupported — this module's own synthesis (no located source)` sub-heading **inside** the Sources section, holding every load-bearing claim that no fetched page owns — the module's own derivations, taxonomies and framings. Never attach such a claim to a nearest-topic paper.
65
+
66
+ **Citation rules.** *Primary sources* — cite the paper that owns the claim; a survey can point you to the owner, so cite the owner. *A link that opens the paper* — link the arXiv **abs** page (or the publisher's landing page), not a bare PDF: the abs page is what carries title, authors, year and identifier, so it is the link a reader can check against. If the published version is paywalled and the preprint is the same paper, link the preprint and tag the venue. *A term the literature may not own* — when the module coins a word for a concept, say so in that entry's note, and cite the concept under the field's own name. *Your own synthesis* — anything the module asserts that no located source supports goes in the unsupported bucket; never attach it to an invented reference. *Full author lists* — every author, written the way the gold standard writes them.
67
+
68
+ **Failure modes** (invisible to memory; they only show up when you fetch). *The near-miss identifier* — a plausible identifier that resolves to an unrelated field; one such id turned out to be an atomic-physics paper. *The merged citation* — one entry built from one paper's title, a second paper's author list, and a third paper's identifier. *The borrowed authority* — a coined term cited to whichever paper sits nearest in topic. *The plausible paraphrase* — a quotation reconstructed from an abstract's gist rather than from the text. *The orphan and the dangling citation* — an entry nothing cites, a citation with no entry; either one breaks the key system.
69
+
70
+ 8. **Verify the finished artifact with a memory-less verifier.**
71
+ Self-review cannot catch your own unstated assumptions. Author what you believe, then have it audited by a fresh agent that sees only the artifact, has no memory of writing it, and is forbidden from fixing anything. Run it on the **post-survey** text: the verifier must see the bibliography and the contradictions section, because the inconsistency that matters most is a citation disagreeing with its own sentence.
72
+ - Dump one artifact per pass to a scratch file outside the module tree (`tmp/<slug>.md` at the repo root) — the claim-bearing note, not the whole tree. **Delete it only after the final round has run and the Verification note is written**: the fixed point below needs the last round to audit the final text, so the dump must outlive the round that produced it. It is working space, not a deliverable. The dump sits one directory shallower than the module, so relative links written for the tree (`../../syllabus.md`) resolve wrongly *in the copy under review* — ignore link-resolution findings taken from the dump, or write those links absolute.
73
+ - Dispatch a fresh subagent with the fixed prompt below. It must end with an explicit verdict on whether it could follow every step *without supplying an assumption of its own*; that verdict, not the finding count, is the signal.
74
+ - Fix the artifact, never the verifier, then re-dispatch the **identical** prompt — byte-identical including its descriptive sentence — so the rounds stay comparable and the decay of findings means something. Re-dumping to the same `tmp/` path each round is expected.
75
+ - Record **every** round in the module's Verification note, including the findings you fixed: the note is the audit trail, not a summary of what survived.
76
+ - Expect decay: substantive first (wrong inequality direction, unstated premise, contradiction, circular definition, stale cross-reference, a symbol defined twice), cosmetic later (label collisions, forward-reference nits, wording).
77
+ - **Stopping rule.** Converged = one round whose findings are all cosmetic; record the residual list and stop. Cap the rounds: ~3 for a prose-only module, ~5–8 for one carrying derivations, budgets or thresholds. **Take the higher band whenever the module contains any derivation, budget or threshold** — a mostly-prose module with one proof in it belongs to the 5–8 band, not the 3. **For such a module the cap is the normal exit, not a failure**: rebuilt maths produces substantive findings in every round, and late rounds catch damage the earlier repairs did, so stopping at the cap with the residuals written down is the correct end. Past the cap the findings are style and the cost is real.
78
+ - **The fixed point.** `✅` means both gates ran on the *same final text*. A verification round that changes any claim re-opens Step 7 for the claims it touched (their citations, ownership, contradictions); a survey that rewrites a claim-bearing sentence re-opens this step.
79
+ - For prose-only modules the same prompt degrades gracefully into a "what did you assume" review; use it unchanged.
80
+
81
+ Verifier prompt (fixed; substitute the absolute path and one descriptive sentence):
82
+
83
+ ```
84
+ You are a memory-less file verifier. Your ONLY job: examine the single file at the
85
+ absolute path <ABSOLUTE PATH> and report on it. You have no other context. Do not fix
86
+ anything, do not propose edits, do not rewrite content. Read the file carefully, then
87
+ produce a findings report.
88
+
89
+ The file is <ONE SENTENCE: what the artifact claims to be, and what it is for>. Your job
90
+ is adversarial verification of the file's internal logic only.
91
+
92
+ Report, exhaustively and pedantically:
93
+ 1. EVERY unstated assumption the text relies on but never declares.
94
+ 2. EVERY skipped mathematical step: anywhere an equation, inequality, or numeric claim
95
+ appears, verify it can be derived from what precedes it using only standard results;
96
+ flag any step you cannot reproduce line by line. Check every arithmetic claim by hand.
97
+ 3. EVERY internal inconsistency: symbols defined more than once or used before definition;
98
+ claims that contradict other claims in the file; requirements that reference concepts
99
+ not yet defined at that point; any place where the ordering (what is pre-committed,
100
+ what is derived, what is verified) breaks down or becomes circular.
101
+ 4. Ambiguities that force a reader to guess.
102
+
103
+ End your report with a clear statement of whether, reading the file ALONE (no outside
104
+ knowledge, no conversation history), you were able to follow every step in order. If you
105
+ had to assume anything yourself to make sense of a step, that counts as a finding. Be
106
+ exhaustive and pedantic. Do not fix anything.
107
+ ```
108
+
109
+ *Done when the latest round **ran on the final text**, produced only cosmetic findings (or the round cap was hit), and the module carries its round count plus residual findings in its Verification note.*
110
+
111
+ 9. **Fold refinements into the files (the iteration loop).**
112
+ The learner's probing questions ("but what about X?", "is this legitimate?") are the real curriculum driver. Answer them, then write the answer back into the relevant module — not into a chat that vanishes. Capture meta-discussions (Q&A, worked examples) into `discussions/` as durable files. An edit that touches verified content re-opens Steps 7 and 8 for that module (or marks it `🟡` until it is re-verified).
113
+ *Done when every open question raised during authoring has landed in a file, or is explicitly parked.*
114
+
115
+ 10. **Add reference maps and verify sources.**
116
+ For breadth topics (e.g. "the other frameworks"), build a map file: a matrix with per-entry "covers / gaps", verified sources, and licenses. Verify links resolve; replace dead ones.
117
+ *Done when every external claim carries a working source, and thin coverage is flagged, not papered over.*
118
+
119
+ 11. **Verify the whole tree.**
120
+ Walk the repo: the syllabus status matches reality (every `✅` carries a Verification note from Steps 7 and 8), every module has all anatomy blocks, every cross-reference resolves, no orphan files. Then the course-wide survey pass: one key format across every bibliography, no module's contradictions section contradicting another module's claim, and the batched sweep of the supporting references deferred from Step 7.
121
+ *Done when the syllabus's status table is true, the cross-module key and contradiction check is clean, and a fresh reader can follow links from module 1 to module N.*
122
+
123
+ ## The module anatomy
124
+
125
+ Every module README is this skeleton, filled in — same blocks, same order, same form:
126
+
127
+ ```markdown
128
+ # M# · <Topic>
129
+
130
+ > **Module question:** <the one question this module answers>
131
+ > **Cross-cutting threads:** Failure modes · Tradeoff ledger · <Stack> at a glance
132
+ > **Domain spine:** <the running example>
133
+
134
+ ---
135
+
136
+ ## Opening scene — <a narrative that ends on the failure this module prevents>
137
+ <3–6 short paragraphs.>
138
+
139
+ > **Failure mode (the module in one line):** treating <X> as <Y>, not "the model was wrong".
140
+
141
+ ---
142
+
143
+ ## <Payload — one concept per section>
144
+ <Prose + a table + a mermaid diagram where shape matters.>
145
+
146
+ > **<Stack> at a glance:** <the stack's primitive here — verified against its docs.>
147
+ > **Tradeoff (the ledger entry):** <decision> costs <cost>; accepted because <reason>.
148
+
149
+ ---
150
+
151
+ ## Worked example: <the domain spine, made concrete>
152
+
153
+ ---
154
+
155
+ ## Design exercise
156
+ > *Paper-based. Think, then write.*
157
+ **Task.** <decision-forcing task: an ADR, a schema, a budget>
158
+ 1. … 2. … 3. …
159
+ **Why this exercise matters.** <one paragraph>
160
+
161
+ ---
162
+
163
+ ## Where the literature disagrees
164
+ - **<claim>** — what this module says; what the sources say, quoted; what to change. ← omit when the literature is unanimous
165
+
166
+ ---
167
+
168
+ ## Sources
169
+ - [<stack primitive>](<url>) ← stack-docs bullet: conditional, see below
170
+ - [<paper>](<url>) — `<key>` · accessed: <YYYY-MM-DD> · owns <what it owns>
171
+
172
+ ---
173
+
174
+ **Verification note:** <survey sources fetched + Steps 7–8 rounds run + residual findings accepted>
175
+
176
+ **Next module:** [M## — <title>](../NN-slug/README.md) — <one line>
177
+ ```
178
+
179
+ Blocks marked `<Stack>`, the stack-docs bullet in Sources, and the `<Stack> at a glance` thread are conditional; drop all three for a topic whose Step 1 records `reference stack: NONE`.
180
+
181
+ ## Cross-cutting threads
182
+
183
+ Pick two or three and repeat them in every module — they are the connective tissue:
184
+
185
+ - **Failure modes** — a named taxonomy that every module maps back to.
186
+ - **Tradeoff ledger** — every decision's cost recorded as an entry.
187
+ - **[Stack] at a glance** — the reference stack's primitives, one line each.
188
+
189
+ ## Failure modes (of authoring a course)
190
+
191
+ - **The topic list disguised as a course.** Modules that are adjacent facts instead of a spine with a running example. A course has a shape; a topic list doesn't.
192
+ - **Claims from memory.** Describing a framework's API without opening its docs. Every stack claim must be traceable.
193
+ - **The unsourced field claim.** A confident conceptual claim — a taxonomy, a causal mechanism, a number — resting on no paper at all. Stack docs cannot support it; only the literature can.
194
+ - **The prose monolith.** No opening scene, no tables, no diagrams — a wall of paragraphs the learner skims. Structure is the medium.
195
+ - **The missing exercise.** Modules that end on content instead of a decision. The exercise is where learning lands.
196
+ - **The chat-only refinement.** Answering the learner's sharp question in chat and never writing it into a file, so it evaporates. Fold it in.
197
+ - **Papering over thin coverage.** Pretending a thinly-documented area is solid. Flag it honestly; "thinly documented" is a legitimate answer.
198
+
199
+ ## Completion criteria
200
+
201
+ Every run ends when:
202
+
203
+ - `syllabus.md` exists with a complete module list + status table + repo structure, and the status table is true — every module `⬜ planned`, `🟡 written`, or `✅ verified`, with none silently missing.
204
+ - Every module is sketched in the syllabus and follows the fixed anatomy, ending with a decision-forcing design exercise and a next-module link.
205
+ - No module is `✅ verified` on self-review alone: each carries a Verification note with its Steps 7 and 8 rounds and any residual (cosmetic) findings, and the loop ended by the Step 8 stopping rule — a cosmetic-only round or the round cap — not by exhaustion.
206
+ - Every non-exempt claim carries a citation or sits in the unsupported bucket, and every module's bibliography matches the frozen gold-standard key format.
207
+ - The reference stack is grounded in its own docs, or recorded as `NONE` with a reason; no claim rests on memory.
208
+ - Every cross-reference resolves; there are no orphan files.
209
+ - All refinements raised during authoring are folded into files, and every external source link is verified.