@erclx/canon 4.0.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 (643) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +129 -0
  3. package/claude/.claude-plugin/plugin.json +19 -0
  4. package/claude/skills/bash-cli-script/REQUIREMENT.md +42 -0
  5. package/claude/skills/bash-cli-script/SKILL.md +48 -0
  6. package/claude/skills/bash-cli-script/references/template.md +43 -0
  7. package/claude/skills/bash-script/REQUIREMENT.md +36 -0
  8. package/claude/skills/bash-script/SKILL.md +100 -0
  9. package/claude/skills/bash-script/references/patterns.md +349 -0
  10. package/claude/skills/canon-cli/REQUIREMENT.md +41 -0
  11. package/claude/skills/canon-cli/SKILL.md +103 -0
  12. package/claude/skills/canon-feedback-file/REQUIREMENT.md +40 -0
  13. package/claude/skills/canon-feedback-file/SKILL.md +80 -0
  14. package/claude/skills/canon-feedback-triage/REQUIREMENT.md +40 -0
  15. package/claude/skills/canon-feedback-triage/SKILL.md +63 -0
  16. package/claude/skills/canon-operator/REQUIREMENT.md +61 -0
  17. package/claude/skills/canon-operator/SKILL.md +108 -0
  18. package/claude/skills/canon-rollout/REQUIREMENT.md +59 -0
  19. package/claude/skills/canon-rollout/SKILL.md +147 -0
  20. package/claude/skills/canon-screencast/REQUIREMENT.md +39 -0
  21. package/claude/skills/canon-screencast/SKILL.md +167 -0
  22. package/claude/skills/canon-slides-draft/REQUIREMENT.md +39 -0
  23. package/claude/skills/canon-slides-draft/SKILL.md +62 -0
  24. package/claude/skills/ci-workflow/REQUIREMENT.md +40 -0
  25. package/claude/skills/ci-workflow/SKILL.md +65 -0
  26. package/claude/skills/ci-workflow/references/workflows.md +98 -0
  27. package/claude/skills/claude-address-review/REQUIREMENT.md +57 -0
  28. package/claude/skills/claude-address-review/SKILL.md +212 -0
  29. package/claude/skills/claude-address-review/references/rebase-conflicts.md +39 -0
  30. package/claude/skills/claude-autoship/REQUIREMENT.md +50 -0
  31. package/claude/skills/claude-autoship/SKILL.md +207 -0
  32. package/claude/skills/claude-design-extract/REQUIREMENT.md +42 -0
  33. package/claude/skills/claude-design-extract/SKILL.md +102 -0
  34. package/claude/skills/claude-diagram/REQUIREMENT.md +45 -0
  35. package/claude/skills/claude-diagram/SKILL.md +177 -0
  36. package/claude/skills/claude-docs/REQUIREMENT.md +60 -0
  37. package/claude/skills/claude-docs/SKILL.md +287 -0
  38. package/claude/skills/claude-docs/references/anchor-sweep.md +58 -0
  39. package/claude/skills/claude-docs/references/wireframe-sweep.md +45 -0
  40. package/claude/skills/claude-feature/REQUIREMENT.md +36 -0
  41. package/claude/skills/claude-feature/SKILL.md +115 -0
  42. package/claude/skills/claude-groundwork/REQUIREMENT.md +48 -0
  43. package/claude/skills/claude-groundwork/SKILL.md +142 -0
  44. package/claude/skills/claude-intake/REQUIREMENT.md +49 -0
  45. package/claude/skills/claude-intake/SKILL.md +114 -0
  46. package/claude/skills/claude-intake-answer/REQUIREMENT.md +48 -0
  47. package/claude/skills/claude-intake-answer/SKILL.md +90 -0
  48. package/claude/skills/claude-markdown-propose/REQUIREMENT.md +48 -0
  49. package/claude/skills/claude-markdown-propose/SKILL.md +118 -0
  50. package/claude/skills/claude-markdown-propose/references/format.md +107 -0
  51. package/claude/skills/claude-memory-capture/REQUIREMENT.md +50 -0
  52. package/claude/skills/claude-memory-capture/SKILL.md +101 -0
  53. package/claude/skills/claude-memory-review/REQUIREMENT.md +50 -0
  54. package/claude/skills/claude-memory-review/SKILL.md +210 -0
  55. package/claude/skills/claude-memory-review/references/receipt-format.md +48 -0
  56. package/claude/skills/claude-orchestrate/REQUIREMENT.md +121 -0
  57. package/claude/skills/claude-orchestrate/SKILL.md +241 -0
  58. package/claude/skills/claude-orchestrate/references/orchestrator-dispatch.md +132 -0
  59. package/claude/skills/claude-orchestrate/references/orchestrator-handoff.md +32 -0
  60. package/claude/skills/claude-orchestrate/references/orchestrator-parked.md +72 -0
  61. package/claude/skills/claude-orchestrate/references/orchestrator-poll.md +87 -0
  62. package/claude/skills/claude-orchestrate/references/orchestrator-resume.md +30 -0
  63. package/claude/skills/claude-orchestrate/references/orchestrator-sweep.md +21 -0
  64. package/claude/skills/claude-orchestrate/scripts/poll.sh +373 -0
  65. package/claude/skills/claude-orchestrate/scripts/watch.sh +181 -0
  66. package/claude/skills/claude-pr-review/REQUIREMENT.md +47 -0
  67. package/claude/skills/claude-pr-review/SKILL.md +295 -0
  68. package/claude/skills/claude-review/REQUIREMENT.md +39 -0
  69. package/claude/skills/claude-review/SKILL.md +142 -0
  70. package/claude/skills/claude-seed-sync/REQUIREMENT.md +45 -0
  71. package/claude/skills/claude-seed-sync/SKILL.md +156 -0
  72. package/claude/skills/claude-standards-audit/REQUIREMENT.md +33 -0
  73. package/claude/skills/claude-standards-audit/SKILL.md +99 -0
  74. package/claude/skills/claude-tasks/REQUIREMENT.md +43 -0
  75. package/claude/skills/claude-tasks/SKILL.md +161 -0
  76. package/claude/skills/claude-teach/REQUIREMENT.md +56 -0
  77. package/claude/skills/claude-teach/SKILL.md +196 -0
  78. package/claude/skills/claude-teach/references/lesson-craft.md +59 -0
  79. package/claude/skills/claude-teach/references/pedagogy.md +67 -0
  80. package/claude/skills/claude-teach/references/promotion.md +54 -0
  81. package/claude/skills/claude-ui-test/REQUIREMENT.md +40 -0
  82. package/claude/skills/claude-ui-test/SKILL.md +77 -0
  83. package/claude/skills/claude-ux-audit/REQUIREMENT.md +40 -0
  84. package/claude/skills/claude-ux-audit/SKILL.md +79 -0
  85. package/claude/skills/claude-ux-measure/REQUIREMENT.md +48 -0
  86. package/claude/skills/claude-ux-measure/SKILL.md +122 -0
  87. package/claude/skills/claude-worker/REQUIREMENT.md +54 -0
  88. package/claude/skills/claude-worker/SKILL.md +96 -0
  89. package/claude/skills/claude-worktree/REQUIREMENT.md +58 -0
  90. package/claude/skills/claude-worktree/SKILL.md +136 -0
  91. package/claude/skills/create-rule/REQUIREMENT.md +45 -0
  92. package/claude/skills/create-rule/SKILL.md +68 -0
  93. package/claude/skills/create-skill/REQUIREMENT.md +38 -0
  94. package/claude/skills/create-skill/SKILL.md +32 -0
  95. package/claude/skills/create-snippet/REQUIREMENT.md +39 -0
  96. package/claude/skills/create-snippet/SKILL.md +30 -0
  97. package/claude/skills/create-standard/REQUIREMENT.md +35 -0
  98. package/claude/skills/create-standard/SKILL.md +29 -0
  99. package/claude/skills/decision-escalate/REQUIREMENT.md +45 -0
  100. package/claude/skills/decision-escalate/SKILL.md +79 -0
  101. package/claude/skills/docs-sync/REQUIREMENT.md +41 -0
  102. package/claude/skills/docs-sync/SKILL.md +95 -0
  103. package/claude/skills/git-branch/REQUIREMENT.md +38 -0
  104. package/claude/skills/git-branch/SKILL.md +60 -0
  105. package/claude/skills/git-commit/REQUIREMENT.md +36 -0
  106. package/claude/skills/git-commit/SKILL.md +49 -0
  107. package/claude/skills/git-followup/REQUIREMENT.md +43 -0
  108. package/claude/skills/git-followup/SKILL.md +48 -0
  109. package/claude/skills/git-issue/REQUIREMENT.md +38 -0
  110. package/claude/skills/git-issue/SKILL.md +65 -0
  111. package/claude/skills/git-pr/REQUIREMENT.md +50 -0
  112. package/claude/skills/git-pr/SKILL.md +164 -0
  113. package/claude/skills/git-pr/references/labels.md +95 -0
  114. package/claude/skills/git-ship/REQUIREMENT.md +42 -0
  115. package/claude/skills/git-ship/SKILL.md +55 -0
  116. package/claude/skills/git-split/REQUIREMENT.md +39 -0
  117. package/claude/skills/git-split/SKILL.md +162 -0
  118. package/claude/skills/git-stage/REQUIREMENT.md +39 -0
  119. package/claude/skills/git-stage/SKILL.md +73 -0
  120. package/claude/skills/git-worktree/REQUIREMENT.md +38 -0
  121. package/claude/skills/git-worktree/SKILL.md +130 -0
  122. package/claude/skills/migration-claude-md/REQUIREMENT.md +40 -0
  123. package/claude/skills/migration-claude-md/SKILL.md +76 -0
  124. package/claude/skills/migration-context/REQUIREMENT.md +36 -0
  125. package/claude/skills/migration-context/SKILL.md +95 -0
  126. package/claude/skills/migration-standards-drop/REQUIREMENT.md +55 -0
  127. package/claude/skills/migration-standards-drop/SKILL.md +113 -0
  128. package/claude/skills/migration-superseded/REQUIREMENT.md +44 -0
  129. package/claude/skills/migration-superseded/SKILL.md +115 -0
  130. package/claude/skills/project-commands/REQUIREMENT.md +42 -0
  131. package/claude/skills/project-commands/SKILL.md +85 -0
  132. package/claude/skills/restate-plainly/REQUIREMENT.md +41 -0
  133. package/claude/skills/restate-plainly/SKILL.md +39 -0
  134. package/claude/skills/session-map/REQUIREMENT.md +57 -0
  135. package/claude/skills/session-map/SKILL.md +70 -0
  136. package/claude/skills/session-resume/REQUIREMENT.md +49 -0
  137. package/claude/skills/session-resume/SKILL.md +51 -0
  138. package/claude/skills/setup-gov/REQUIREMENT.md +37 -0
  139. package/claude/skills/setup-gov/SKILL.md +77 -0
  140. package/claude/skills/setup-indexes/REQUIREMENT.md +45 -0
  141. package/claude/skills/setup-indexes/SKILL.md +153 -0
  142. package/claude/skills/setup-init/REQUIREMENT.md +45 -0
  143. package/claude/skills/setup-init/SKILL.md +127 -0
  144. package/claude/skills/setup-plugins/REQUIREMENT.md +42 -0
  145. package/claude/skills/setup-plugins/SKILL.md +81 -0
  146. package/claude/skills/setup-plugins/references/plugin-catalog.md +53 -0
  147. package/claude/skills/setup-verify/REQUIREMENT.md +39 -0
  148. package/claude/skills/setup-verify/SKILL.md +51 -0
  149. package/claude/skills/systematic-debugging/REQUIREMENT.md +41 -0
  150. package/claude/skills/systematic-debugging/SKILL.md +70 -0
  151. package/claude/skills/write-human/REQUIREMENT.md +46 -0
  152. package/claude/skills/write-human/SKILL.md +68 -0
  153. package/claude/skills/write-human/references/density.md +38 -0
  154. package/claude/skills/write-human/references/machine-tells.md +107 -0
  155. package/claude/skills/write-human/references/source-material.md +37 -0
  156. package/claude/skills/youtube-transcripts/REQUIREMENT.md +38 -0
  157. package/claude/skills/youtube-transcripts/SKILL.md +34 -0
  158. package/docs/agents/audits.md +98 -0
  159. package/docs/agents/capture.md +37 -0
  160. package/docs/agents/census.md +23 -0
  161. package/docs/agents/commands.md +146 -0
  162. package/docs/agents/comments.md +34 -0
  163. package/docs/agents/context-audit-checks.md +120 -0
  164. package/docs/agents/context-audit.md +83 -0
  165. package/docs/agents/counts.md +76 -0
  166. package/docs/agents/demo.md +86 -0
  167. package/docs/agents/docs.md +17 -0
  168. package/docs/agents/gate.md +84 -0
  169. package/docs/agents/index.md +47 -0
  170. package/docs/agents/indexes.md +35 -0
  171. package/docs/agents/install-and-sync.md +385 -0
  172. package/docs/agents/intake.md +81 -0
  173. package/docs/agents/key-changes.md +103 -0
  174. package/docs/agents/label-coverage.md +73 -0
  175. package/docs/agents/markdown-audit.md +197 -0
  176. package/docs/agents/output-shape.md +70 -0
  177. package/docs/agents/overview.md +26 -0
  178. package/docs/agents/records.md +170 -0
  179. package/docs/agents/restated.md +81 -0
  180. package/docs/agents/review-classification.md +77 -0
  181. package/docs/agents/routing.md +61 -0
  182. package/docs/agents/rule-citations.md +98 -0
  183. package/docs/agents/sandbox.md +71 -0
  184. package/docs/agents/scripting.md +149 -0
  185. package/docs/agents/sessions.md +120 -0
  186. package/docs/agents/skills-audit.md +94 -0
  187. package/docs/agents/skills-reach.md +64 -0
  188. package/docs/agents/standards-audit.md +38 -0
  189. package/docs/agents/state-scoped-risk.md +105 -0
  190. package/docs/agents/superseded.md +85 -0
  191. package/docs/agents/targets.md +83 -0
  192. package/docs/agents/tasks.md +200 -0
  193. package/docs/agents/teach.md +158 -0
  194. package/docs/agents/test-order.md +56 -0
  195. package/docs/agents/worktrees.md +62 -0
  196. package/docs/ai-workflow.md +317 -0
  197. package/docs/index.md +23 -0
  198. package/docs/operating-model.md +223 -0
  199. package/docs/target-projects.md +258 -0
  200. package/docs/visual-design-workflow.md +151 -0
  201. package/docs/zshrc-aliases.md +65 -0
  202. package/governance/rules/ci/700-ci-workflow.md +44 -0
  203. package/governance/rules/claude/500-prose.md +15 -0
  204. package/governance/rules/claude/501-markdown.md +14 -0
  205. package/governance/rules/claude/510-context.md +28 -0
  206. package/governance/rules/claude/511-indexes.md +14 -0
  207. package/governance/rules/claude/520-wireframes.md +12 -0
  208. package/governance/rules/claude/530-requirements.md +11 -0
  209. package/governance/rules/claude/540-architecture.md +11 -0
  210. package/governance/rules/claude/550-design.md +11 -0
  211. package/governance/rules/claude/555-tasks.md +12 -0
  212. package/governance/rules/claude/556-groundwork.md +11 -0
  213. package/governance/rules/claude/557-intake.md +11 -0
  214. package/governance/rules/claude/558-plan.md +22 -0
  215. package/governance/rules/claude/559-memory.md +11 -0
  216. package/governance/rules/claude/560-diagrams.md +18 -0
  217. package/governance/rules/claude/561-teach.md +13 -0
  218. package/governance/rules/claude/562-session.md +15 -0
  219. package/governance/rules/claude/570-skill.md +24 -0
  220. package/governance/rules/claude/575-hooks.md +17 -0
  221. package/governance/rules/claude/576-settings.md +14 -0
  222. package/governance/rules/claude/580-readme.md +11 -0
  223. package/governance/rules/claude/590-rule-authoring.md +12 -0
  224. package/governance/rules/claude/591-standard-authoring.md +12 -0
  225. package/governance/rules/claude/592-claude-md.md +19 -0
  226. package/governance/rules/core/000-constitution.md +30 -0
  227. package/governance/rules/core/005-behavior.md +27 -0
  228. package/governance/rules/core/010-testing.md +35 -0
  229. package/governance/rules/core/015-output.md +20 -0
  230. package/governance/rules/core/020-concurrency.md +22 -0
  231. package/governance/rules/core/025-indexes.md +9 -0
  232. package/governance/rules/core/030-error-handling.md +31 -0
  233. package/governance/rules/core/035-tasks.md +13 -0
  234. package/governance/rules/core/040-performance.md +20 -0
  235. package/governance/rules/core/045-memory.md +12 -0
  236. package/governance/rules/core/050-logging.md +20 -0
  237. package/governance/rules/core/055-scratch.md +9 -0
  238. package/governance/rules/core/060-naming.md +19 -0
  239. package/governance/rules/core/065-spelling.md +19 -0
  240. package/governance/rules/core/070-planning.md +18 -0
  241. package/governance/rules/core/075-dependencies.md +25 -0
  242. package/governance/rules/core/080-config-comments.md +22 -0
  243. package/governance/rules/core/085-worktrees.md +17 -0
  244. package/governance/rules/core/087-git.md +11 -0
  245. package/governance/rules/core/090-code-comments.md +39 -0
  246. package/governance/rules/framework/200-react.md +51 -0
  247. package/governance/rules/framework/210-astro.md +41 -0
  248. package/governance/rules/framework/220-fastapi.md +43 -0
  249. package/governance/rules/framework/230-nextjs.md +48 -0
  250. package/governance/rules/framework/250-tailwind.md +32 -0
  251. package/governance/rules/framework/260-shadcn.md +34 -0
  252. package/governance/rules/lang/100-typescript.md +40 -0
  253. package/governance/rules/lang/110-python.md +42 -0
  254. package/governance/rules/lang/120-bash.md +19 -0
  255. package/governance/rules/lib/300-testing-ts.md +39 -0
  256. package/governance/rules/lib/305-e2e-reliability.md +34 -0
  257. package/governance/rules/lib/306-test-scope.md +25 -0
  258. package/governance/rules/lib/310-zod.md +25 -0
  259. package/governance/rules/lib/320-tanstack-query.md +32 -0
  260. package/governance/rules/lib/330-testing-py.md +44 -0
  261. package/governance/rules/lib/340-pydantic.md +38 -0
  262. package/governance/rules/lib/350-security-web.md +32 -0
  263. package/governance/rules/lib/360-security-server.md +39 -0
  264. package/governance/rules/lib/370-database.md +35 -0
  265. package/governance/rules/snippets/505-at-references.md +9 -0
  266. package/governance/rules/ui/400-ui.md +36 -0
  267. package/governance/rules/ui/410-a11y.md +48 -0
  268. package/governance/rules/ui/420-forms.md +36 -0
  269. package/governance/rules/ui/430-ux-completeness.md +65 -0
  270. package/governance/rules/ui/440-surface-capture.md +34 -0
  271. package/governance/rules/ui/450-link-behavior.md +19 -0
  272. package/governance/stacks/astro.toml +2 -0
  273. package/governance/stacks/base.toml +8 -0
  274. package/governance/stacks/node-server.toml +2 -0
  275. package/governance/stacks/node.toml +2 -0
  276. package/governance/stacks/python-fastapi.toml +2 -0
  277. package/governance/stacks/python.toml +2 -0
  278. package/governance/stacks/react.toml +2 -0
  279. package/package.json +69 -0
  280. package/scripts/config.sh +11 -0
  281. package/scripts/core/bootstrap.sh +81 -0
  282. package/scripts/core/check-color-source.sh +41 -0
  283. package/scripts/core/check-ignore-parity.sh +162 -0
  284. package/scripts/core/check-plugin-boundary.sh +45 -0
  285. package/scripts/core/check-seed-independence.sh +59 -0
  286. package/scripts/core/check-skill-paths.sh +24 -0
  287. package/scripts/core/clean.sh +36 -0
  288. package/scripts/core/install-check.sh +101 -0
  289. package/scripts/core/list-seed-roots.sh +18 -0
  290. package/scripts/core/regen-claude-copies.sh +10 -0
  291. package/scripts/core/regen-hero.sh +217 -0
  292. package/scripts/core/regen-indexes.sh +10 -0
  293. package/scripts/core/regen-tooling-paths.sh +61 -0
  294. package/scripts/core/repair-bare-flag.sh +19 -0
  295. package/scripts/core/snapshot.sh +134 -0
  296. package/scripts/core/update.sh +35 -0
  297. package/scripts/docs/list.sh +165 -0
  298. package/scripts/lib/frontmatter.sh +30 -0
  299. package/scripts/lib/gov.sh +14 -0
  300. package/scripts/lib/sandbox-fixtures.sh +191 -0
  301. package/scripts/lib/sandbox-git.sh +125 -0
  302. package/scripts/lib/sandbox-path.sh +206 -0
  303. package/scripts/lib/tooling.sh +35 -0
  304. package/scripts/lib/ui.sh +266 -0
  305. package/scripts/lib/worktree.sh +20 -0
  306. package/scripts/manage-sandbox.sh +466 -0
  307. package/scripts/snippets/create.sh +156 -0
  308. package/scripts/standards/list.sh +115 -0
  309. package/scripts/tooling/create.sh +109 -0
  310. package/scripts/tooling/verify.sh +179 -0
  311. package/snippets/align.md +12 -0
  312. package/snippets/claude/decision-memo.md +39 -0
  313. package/snippets/claude/feature-recap.md +19 -0
  314. package/snippets/claude/figma-steps.md +24 -0
  315. package/snippets/compact-summary.md +5 -0
  316. package/snippets/decision-help.md +6 -0
  317. package/snippets/meta-prompt.md +14 -0
  318. package/snippets/research-prompt.md +7 -0
  319. package/snippets/session-notes.md +11 -0
  320. package/snippets/snippets.toml +5 -0
  321. package/snippets/step-by-step.md +10 -0
  322. package/snippets/web-research.md +21 -0
  323. package/src/audits/baseline.ts +201 -0
  324. package/src/audits/catalog.ts +876 -0
  325. package/src/audits/run.ts +204 -0
  326. package/src/autoship/classify.ts +75 -0
  327. package/src/autoship/paths.ts +51 -0
  328. package/src/binary.ts +16 -0
  329. package/src/browser/engine.ts +40 -0
  330. package/src/census/count.ts +113 -0
  331. package/src/claude/cases/all.ts +24 -0
  332. package/src/claude/cases/authoring.ts +53 -0
  333. package/src/claude/cases/claude-workflow.ts +158 -0
  334. package/src/claude/cases/git.ts +44 -0
  335. package/src/claude/cases/misc.ts +27 -0
  336. package/src/claude/cases/setup.ts +94 -0
  337. package/src/claude/gitignore.ts +51 -0
  338. package/src/claude/routing.ts +283 -0
  339. package/src/claude/seeds-list.ts +47 -0
  340. package/src/claude/seeds.ts +150 -0
  341. package/src/claude/settings.ts +151 -0
  342. package/src/claude/skills-audit.ts +228 -0
  343. package/src/claude/skills-drift.ts +156 -0
  344. package/src/claude/skills-list.ts +99 -0
  345. package/src/claude/skills-rank.ts +320 -0
  346. package/src/claude/skills-reach.ts +227 -0
  347. package/src/cli-run.ts +43 -0
  348. package/src/cli.ts +200 -0
  349. package/src/commands/audits.ts +350 -0
  350. package/src/commands/autoship.ts +129 -0
  351. package/src/commands/capture.ts +133 -0
  352. package/src/commands/census.ts +105 -0
  353. package/src/commands/claude.ts +1286 -0
  354. package/src/commands/comments.ts +240 -0
  355. package/src/commands/context.ts +857 -0
  356. package/src/commands/demo.ts +389 -0
  357. package/src/commands/deps.ts +173 -0
  358. package/src/commands/design.ts +36 -0
  359. package/src/commands/docs.ts +60 -0
  360. package/src/commands/feedback-format.ts +23 -0
  361. package/src/commands/feedback.ts +112 -0
  362. package/src/commands/gate.ts +189 -0
  363. package/src/commands/gov.ts +1265 -0
  364. package/src/commands/indexes.ts +184 -0
  365. package/src/commands/init.ts +113 -0
  366. package/src/commands/intake.ts +406 -0
  367. package/src/commands/inventory.ts +256 -0
  368. package/src/commands/labels.ts +361 -0
  369. package/src/commands/markdown.ts +544 -0
  370. package/src/commands/migrate.ts +175 -0
  371. package/src/commands/pass-through.ts +39 -0
  372. package/src/commands/pr.ts +411 -0
  373. package/src/commands/records.ts +728 -0
  374. package/src/commands/sandbox.ts +468 -0
  375. package/src/commands/secrets.ts +132 -0
  376. package/src/commands/serve.ts +159 -0
  377. package/src/commands/sessions.ts +408 -0
  378. package/src/commands/slides.ts +126 -0
  379. package/src/commands/snippets.ts +84 -0
  380. package/src/commands/standards.ts +247 -0
  381. package/src/commands/sync.ts +428 -0
  382. package/src/commands/targets.ts +319 -0
  383. package/src/commands/tasks.ts +743 -0
  384. package/src/commands/teach.ts +786 -0
  385. package/src/commands/tooling.ts +573 -0
  386. package/src/commands/transcripts.ts +44 -0
  387. package/src/commands/upgrade.ts +231 -0
  388. package/src/commands/wiki.ts +100 -0
  389. package/src/commands/worktrees.ts +191 -0
  390. package/src/comments/scan.ts +338 -0
  391. package/src/comments/trend.ts +207 -0
  392. package/src/comments/vocabulary.ts +85 -0
  393. package/src/context/architecture.ts +364 -0
  394. package/src/context/audit.ts +790 -0
  395. package/src/context/citations.ts +196 -0
  396. package/src/context/folders.ts +186 -0
  397. package/src/context/gate.ts +57 -0
  398. package/src/context/index-drift.ts +64 -0
  399. package/src/context/narration.ts +99 -0
  400. package/src/copy.ts +30 -0
  401. package/src/counts/catalogs.ts +96 -0
  402. package/src/counts/numbers.ts +79 -0
  403. package/src/counts/scan.ts +314 -0
  404. package/src/demo/beats.ts +135 -0
  405. package/src/demo/compile.ts +326 -0
  406. package/src/demo/container.ts +63 -0
  407. package/src/demo/cursors.ts +55 -0
  408. package/src/demo/drive.ts +357 -0
  409. package/src/demo/pointer.ts +178 -0
  410. package/src/demo/theme.ts +112 -0
  411. package/src/deps/audit.ts +153 -0
  412. package/src/design/parse.ts +116 -0
  413. package/src/design/render.ts +249 -0
  414. package/src/docs/read.ts +77 -0
  415. package/src/exec.ts +16 -0
  416. package/src/exempt-marker.ts +43 -0
  417. package/src/frontmatter.ts +13 -0
  418. package/src/gate/measures.ts +682 -0
  419. package/src/gate/sequencer.ts +386 -0
  420. package/src/gate/stages.ts +412 -0
  421. package/src/git-env.ts +36 -0
  422. package/src/git-files.ts +105 -0
  423. package/src/git-ignore.ts +46 -0
  424. package/src/github-format.ts +13 -0
  425. package/src/github.ts +24 -0
  426. package/src/gov/adapter.ts +103 -0
  427. package/src/gov/citations.ts +514 -0
  428. package/src/gov/consumed.ts +129 -0
  429. package/src/gov/install.ts +132 -0
  430. package/src/gov/list.ts +106 -0
  431. package/src/gov/payload.ts +39 -0
  432. package/src/gov/restated.ts +814 -0
  433. package/src/gov/stacks.ts +205 -0
  434. package/src/gov/superseded.ts +415 -0
  435. package/src/gov/test-order.ts +407 -0
  436. package/src/indexes/frontmatter.ts +46 -0
  437. package/src/indexes/regen.ts +84 -0
  438. package/src/indexes/render.ts +201 -0
  439. package/src/indexes/walk.ts +83 -0
  440. package/src/init/flags.ts +60 -0
  441. package/src/init/plan.ts +114 -0
  442. package/src/init/run.ts +46 -0
  443. package/src/init/steps.ts +77 -0
  444. package/src/intake/folder.ts +320 -0
  445. package/src/intake/items.ts +174 -0
  446. package/src/inventory/config.ts +117 -0
  447. package/src/inventory/group.ts +76 -0
  448. package/src/inventory/subjects.ts +114 -0
  449. package/src/inventory/walk.ts +129 -0
  450. package/src/labels/audit.ts +82 -0
  451. package/src/labels/coverage.ts +79 -0
  452. package/src/labels/map.ts +101 -0
  453. package/src/labels/phase.ts +95 -0
  454. package/src/markdown/bans.ts +94 -0
  455. package/src/markdown/files.ts +102 -0
  456. package/src/markdown/gate.ts +28 -0
  457. package/src/markdown/scan.ts +295 -0
  458. package/src/markdown/structure.ts +730 -0
  459. package/src/migrate/apply.ts +115 -0
  460. package/src/migrate/plan.ts +103 -0
  461. package/src/migrate/rename.ts +183 -0
  462. package/src/pr/bijection.ts +145 -0
  463. package/src/pr/paths.ts +335 -0
  464. package/src/process/harness.ts +167 -0
  465. package/src/project-root.ts +19 -0
  466. package/src/records/backup.ts +455 -0
  467. package/src/records/migrate.ts +78 -0
  468. package/src/records/size.ts +260 -0
  469. package/src/records/validate.ts +1162 -0
  470. package/src/sandbox/census.ts +228 -0
  471. package/src/sandbox/coverage.ts +115 -0
  472. package/src/sandbox/expect.ts +629 -0
  473. package/src/sandbox/tree.ts +47 -0
  474. package/src/secrets/marker.ts +30 -0
  475. package/src/secrets/patterns.ts +142 -0
  476. package/src/secrets/scan.ts +123 -0
  477. package/src/secrets/shipped.ts +111 -0
  478. package/src/seed-marker.ts +74 -0
  479. package/src/serve/static.ts +322 -0
  480. package/src/sessions/claim.ts +85 -0
  481. package/src/sessions/live.ts +79 -0
  482. package/src/sessions/registry.ts +137 -0
  483. package/src/sessions/resolve.ts +333 -0
  484. package/src/slides/layouts.ts +391 -0
  485. package/src/slides/open.ts +18 -0
  486. package/src/slides/parse.ts +84 -0
  487. package/src/slides/render.ts +88 -0
  488. package/src/slides/styles.ts +44 -0
  489. package/src/snippets/categories.ts +66 -0
  490. package/src/snippets/list.ts +32 -0
  491. package/src/snippets/presets.ts +50 -0
  492. package/src/standards/audit.ts +132 -0
  493. package/src/standards/read.ts +100 -0
  494. package/src/sync/check.ts +692 -0
  495. package/src/sync/engine.ts +576 -0
  496. package/src/sync/git.ts +225 -0
  497. package/src/sync/history.ts +123 -0
  498. package/src/sync/layout.ts +140 -0
  499. package/src/sync/reverse.ts +268 -0
  500. package/src/sync/seeds-report.ts +126 -0
  501. package/src/sync/stamp.ts +358 -0
  502. package/src/sync/target.ts +70 -0
  503. package/src/sync/workflow.ts +200 -0
  504. package/src/target.ts +43 -0
  505. package/src/targets/pulls.ts +250 -0
  506. package/src/targets/registry.ts +203 -0
  507. package/src/targets/resolve.ts +145 -0
  508. package/src/targets/sweep.ts +246 -0
  509. package/src/tasks/archive.ts +506 -0
  510. package/src/tasks/record.ts +311 -0
  511. package/src/tasks/trunk.ts +89 -0
  512. package/src/tasks/validate.ts +1001 -0
  513. package/src/teach/lesson.ts +180 -0
  514. package/src/teach/workspace.ts +842 -0
  515. package/src/tooling/gitignore.ts +122 -0
  516. package/src/tooling/inject.ts +193 -0
  517. package/src/tooling/list.ts +39 -0
  518. package/src/tooling/manifest.ts +176 -0
  519. package/src/tooling/package.ts +166 -0
  520. package/src/tooling/read.ts +65 -0
  521. package/src/tooling/scan.ts +147 -0
  522. package/src/tooling/stamp.ts +44 -0
  523. package/src/transcripts/fetch.ts +156 -0
  524. package/src/transcripts/metadata.ts +54 -0
  525. package/src/transcripts/vtt.ts +114 -0
  526. package/src/ui.ts +266 -0
  527. package/src/version/compare.ts +53 -0
  528. package/src/version/installed.ts +40 -0
  529. package/src/version/manager.ts +67 -0
  530. package/src/version/skew.ts +192 -0
  531. package/src/wiki/init.ts +85 -0
  532. package/src/worktree.ts +143 -0
  533. package/src/worktrees/reclaim.ts +306 -0
  534. package/standards/architecture.md +72 -0
  535. package/standards/branch.md +59 -0
  536. package/standards/commit.md +72 -0
  537. package/standards/context.md +151 -0
  538. package/standards/design.md +93 -0
  539. package/standards/diagrams.md +152 -0
  540. package/standards/glossary.md +75 -0
  541. package/standards/groundwork.md +211 -0
  542. package/standards/index.md +36 -0
  543. package/standards/intake.md +192 -0
  544. package/standards/issue.md +94 -0
  545. package/standards/markdown.md +137 -0
  546. package/standards/memory.md +144 -0
  547. package/standards/plan.md +172 -0
  548. package/standards/pr.md +139 -0
  549. package/standards/publish.md +51 -0
  550. package/standards/readme.md +208 -0
  551. package/standards/requirements.md +70 -0
  552. package/standards/rule.md +118 -0
  553. package/standards/session.md +109 -0
  554. package/standards/skill.md +300 -0
  555. package/standards/slug.md +39 -0
  556. package/standards/snippets.md +76 -0
  557. package/standards/standard.md +170 -0
  558. package/standards/tasks.md +254 -0
  559. package/standards/teach.md +153 -0
  560. package/standards/versioning.md +71 -0
  561. package/standards/wireframes.md +113 -0
  562. package/tooling/astro/configs/astro.config.mjs +31 -0
  563. package/tooling/astro/configs/eslint.config.js +79 -0
  564. package/tooling/astro/configs/playwright.config.ts +26 -0
  565. package/tooling/astro/configs/tsconfig.json +12 -0
  566. package/tooling/astro/configs/vitest.config.ts +22 -0
  567. package/tooling/astro/manifest.toml +34 -0
  568. package/tooling/astro/reference.md +60 -0
  569. package/tooling/base/configs/.editorconfig +5 -0
  570. package/tooling/base/configs/.github/pull_request_template.md +18 -0
  571. package/tooling/base/configs/.github/workflows/verify.yml +35 -0
  572. package/tooling/base/configs/.husky/commit-msg +1 -0
  573. package/tooling/base/configs/.husky/post-merge +61 -0
  574. package/tooling/base/configs/.husky/post-rewrite +21 -0
  575. package/tooling/base/configs/.husky/pre-commit +1 -0
  576. package/tooling/base/configs/.husky/pre-push +1 -0
  577. package/tooling/base/configs/.prettierrc +12 -0
  578. package/tooling/base/configs/.shellcheckrc +1 -0
  579. package/tooling/base/configs/.vscode/extensions.json +9 -0
  580. package/tooling/base/configs/.vscode/settings.json +3 -0
  581. package/tooling/base/configs/commitlint.config.js +11 -0
  582. package/tooling/base/configs/scripts/verify.sh +64 -0
  583. package/tooling/base/manifest.toml +30 -0
  584. package/tooling/base/reference.md +98 -0
  585. package/tooling/base/seeds/.claude/context/ci.md +33 -0
  586. package/tooling/base/seeds/.claude/context/development.md +37 -0
  587. package/tooling/base/seeds/.claude/context/index.md +11 -0
  588. package/tooling/base/seeds/.cspell/project-terms.txt +0 -0
  589. package/tooling/base/seeds/.cspell/tech-stack.txt +19 -0
  590. package/tooling/base/seeds/.lintstagedrc +8 -0
  591. package/tooling/base/seeds/.prettierignore +0 -0
  592. package/tooling/base/seeds/cspell.json +20 -0
  593. package/tooling/claude/manifest.toml +14 -0
  594. package/tooling/claude/reference.md +79 -0
  595. package/tooling/claude/seeds/.claude/ARCHITECTURE.md +13 -0
  596. package/tooling/claude/seeds/.claude/DESIGN.md +62 -0
  597. package/tooling/claude/seeds/.claude/REQUIREMENTS.md +18 -0
  598. package/tooling/claude/seeds/.claude/diagrams/index.md +8 -0
  599. package/tooling/claude/seeds/.claude/hooks/index-reminder.sh +50 -0
  600. package/tooling/claude/seeds/.claude/hooks/memory-index.sh +68 -0
  601. package/tooling/claude/seeds/.claude/hooks/path-form.sh +57 -0
  602. package/tooling/claude/seeds/.claude/hooks/scratch-guard.sh +52 -0
  603. package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +86 -0
  604. package/tooling/claude/seeds/.claude/hooks/tasks-index.sh +71 -0
  605. package/tooling/claude/seeds/.claude/memory/index.md +8 -0
  606. package/tooling/claude/seeds/.claude/settings.json +47 -0
  607. package/tooling/claude/seeds/.claude/tasks/index.md +8 -0
  608. package/tooling/claude/seeds/.claude/wireframes/index.md +8 -0
  609. package/tooling/claude/seeds/CLAUDE.md +29 -0
  610. package/tooling/claude/user/settings.template.json +10 -0
  611. package/tooling/claude/user/statusline-command.sh +53 -0
  612. package/tooling/python/configs/.coveragerc +14 -0
  613. package/tooling/python/configs/.python-version +1 -0
  614. package/tooling/python/configs/mypy.ini +6 -0
  615. package/tooling/python/configs/pytest.ini +4 -0
  616. package/tooling/python/configs/ruff.toml +15 -0
  617. package/tooling/python/configs/scripts/verify.sh +77 -0
  618. package/tooling/python/manifest.toml +16 -0
  619. package/tooling/python/reference.md +66 -0
  620. package/tooling/python/seeds/.cspell/tech-stack.txt +19 -0
  621. package/tooling/python/seeds/tests/test_smoke.py +2 -0
  622. package/tooling/vite-react/configs/playwright.config.ts +26 -0
  623. package/tooling/vite-react/configs/tsconfig.json +35 -0
  624. package/tooling/vite-react/configs/vite.config.ts +24 -0
  625. package/tooling/vite-react/configs/vitest.config.ts +26 -0
  626. package/tooling/vite-react/manifest.toml +23 -0
  627. package/tooling/vite-react/reference.md +55 -0
  628. package/tooling/vite-react/seeds/.cspell/project-terms.txt +1 -0
  629. package/tooling/vite-react/seeds/.cspell/tech-stack.txt +1 -0
  630. package/tooling/web/configs/.github/workflows/verify.yml +134 -0
  631. package/tooling/web/configs/.vscode/extensions.json +13 -0
  632. package/tooling/web/configs/.vscode/settings.json +10 -0
  633. package/tooling/web/configs/e2e/home.spec.ts +6 -0
  634. package/tooling/web/configs/e2e/screenshot.ts +53 -0
  635. package/tooling/web/configs/eslint.config.js +82 -0
  636. package/tooling/web/configs/scripts/screenshot.sh +28 -0
  637. package/tooling/web/configs/scripts/verify.sh +80 -0
  638. package/tooling/web/configs/scripts/worktree-port.sh +74 -0
  639. package/tooling/web/configs/src/test/setup.ts +8 -0
  640. package/tooling/web/manifest.toml +58 -0
  641. package/tooling/web/reference.md +115 -0
  642. package/tooling/web/seeds/.cspell/tech-stack.txt +18 -0
  643. package/tsconfig.json +14 -0
@@ -0,0 +1,162 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+ set -o pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
7
+
8
+ GITIGNORE="$PROJECT_ROOT/.gitignore"
9
+ MANIFEST="$PROJECT_ROOT/tooling/claude/manifest.toml"
10
+ SECTION="# Claude"
11
+
12
+ # Divergences this repository has decided to keep, one `<entry>|<reason>` per
13
+ # line, matched after the trailing slash is stripped. Each names a path the
14
+ # enclosing repository ignores and the claude manifest deliberately does not
15
+ # ship, so a target keeps tracking it.
16
+ #
17
+ # This is the canonical list. `.gitignore` and the manifest carry a pointer
18
+ # beside their own entries rather than a second copy of the reason, and
19
+ # `.claude/context/tooling.md` carries the narrative behind both.
20
+ #
21
+ # A sanction that no longer describes a divergence fails the same as an
22
+ # unsanctioned one. An exception outliving its reason is what teaches the next
23
+ # reader to widen the list rather than to read it.
24
+ SANCTIONED=(
25
+ ".claude/diagrams|a target that tracks its diagrams keeps the context audit's default coverage of them, which ignoring the folder for every target would take away. This repository backs the folder through its records remote instead."
26
+ ".claude/README.md|the landing page a records pull writes back into a repository that set up a records remote. A target has not, so it never receives the file."
27
+ )
28
+
29
+ if [ ! -f "$GITIGNORE" ]; then
30
+ echo "No .gitignore at ${GITIGNORE#"$PROJECT_ROOT/"}, ignore parity unverifiable." >&2
31
+ exit 1
32
+ fi
33
+
34
+ if [ ! -f "$MANIFEST" ]; then
35
+ echo "No claude manifest at ${MANIFEST#"$PROJECT_ROOT/"}, ignore parity unverifiable." >&2
36
+ exit 1
37
+ fi
38
+
39
+ # A gitignore pattern and a manifest entry describe the same folder whether or
40
+ # not either spells the trailing slash, so presence is compared with it dropped.
41
+ # `.claude/.tmp` and `.claude/.tmp/` are the live instance of that pair.
42
+ normalize() {
43
+ printf '%s\n' "${1%/}"
44
+ }
45
+
46
+ # Every pattern the file carries, comments and blank lines dropped. The whole
47
+ # file rather than one header, because `.claude/teach/` sits under a header of
48
+ # its own and reading the `# Claude` header alone would report it missing from a
49
+ # list that carries it.
50
+ gitignore_patterns() {
51
+ awk '{ sub(/[[:space:]]+$/, "") } $0 ~ /^[[:space:]]*#/ || $0 == "" { next } { print }' "$GITIGNORE"
52
+ }
53
+
54
+ # Every entry of the named array in the manifest's `[gitignore]` table. The
55
+ # array is accumulated to its closing bracket before the quoted strings are read
56
+ # out, so a formatter wrapping it across lines does not silently empty this.
57
+ manifest_entries() {
58
+ awk -v key="\"$SECTION\"" '
59
+ /^\[/ { table = $0 }
60
+ table != "[gitignore]" { next }
61
+ index($0, key) == 1 { collecting = 1; buf = "" }
62
+ collecting { buf = buf $0 }
63
+ collecting && index($0, "]") > 0 {
64
+ collecting = 0
65
+ buf = substr(buf, index(buf, "["))
66
+ count = split(buf, parts, "\"")
67
+ for (i = 2; i <= count; i += 2) print parts[i]
68
+ }
69
+ ' "$MANIFEST"
70
+ }
71
+
72
+ contains() {
73
+ local needle=$1
74
+ shift
75
+ local candidate
76
+ for candidate in "$@"; do
77
+ [ "$candidate" = "$needle" ] || continue
78
+ return 0
79
+ done
80
+ return 1
81
+ }
82
+
83
+ ignored=()
84
+ while IFS= read -r pattern; do
85
+ [ -n "$pattern" ] || continue
86
+ ignored+=("$(normalize "$pattern")")
87
+ done < <(gitignore_patterns)
88
+
89
+ shipped=()
90
+ while IFS= read -r entry; do
91
+ [ -n "$entry" ] || continue
92
+ shipped+=("$(normalize "$entry")")
93
+ done < <(manifest_entries)
94
+
95
+ # An empty read on either side is a parse that failed rather than a repository
96
+ # ignoring nothing, and reporting parity off it would say the two lists agree
97
+ # having compared none of their entries.
98
+ if [ ${#ignored[@]} -eq 0 ]; then
99
+ echo "No patterns read from .gitignore, ignore parity unverifiable." >&2
100
+ exit 1
101
+ fi
102
+
103
+ if [ ${#shipped[@]} -eq 0 ]; then
104
+ echo "No entries read from the \"$SECTION\" array in ${MANIFEST#"$PROJECT_ROOT/"}, ignore parity unverifiable." >&2
105
+ exit 1
106
+ fi
107
+
108
+ failures=""
109
+ sanction_notes=""
110
+
111
+ # Entries the manifest ships that this repository does not ignore. A target is
112
+ # told to ignore a folder the toolkit itself tracks, which no decision sanctions,
113
+ # so this direction carries no exception list.
114
+ for entry in "${shipped[@]}"; do
115
+ contains "$entry" "${ignored[@]}" && continue
116
+ failures="$failures $entry is shipped by the manifest and absent from .gitignore"$'\n'
117
+ done
118
+
119
+ # Claude-scoped patterns this repository ignores that the manifest does not
120
+ # ship. Scoped to `.claude/` because the manifest is the claude stack and says
121
+ # nothing about `node_modules/` or `.env`.
122
+ for pattern in "${ignored[@]}"; do
123
+ case "$pattern" in
124
+ .claude/*) ;;
125
+ *) continue ;;
126
+ esac
127
+ contains "$pattern" "${shipped[@]}" && continue
128
+
129
+ matched=false
130
+ for sanction in "${SANCTIONED[@]}"; do
131
+ [ "${sanction%%|*}" = "$pattern" ] || continue
132
+ matched=true
133
+ sanction_notes="$sanction_notes $pattern stays out of the manifest: ${sanction#*|}"$'\n'
134
+ break
135
+ done
136
+
137
+ if [ "$matched" = false ]; then
138
+ failures="$failures $pattern is ignored here and absent from the manifest"$'\n'
139
+ fi
140
+ done
141
+
142
+ # A sanction naming a path that is no longer divergent, either because the
143
+ # manifest took it or because .gitignore dropped it.
144
+ for sanction in "${SANCTIONED[@]}"; do
145
+ entry="${sanction%%|*}"
146
+ if contains "$entry" "${ignored[@]}" && ! contains "$entry" "${shipped[@]}"; then
147
+ continue
148
+ fi
149
+ failures="$failures $entry is sanctioned as a divergence and is no longer one"$'\n'
150
+ done
151
+
152
+ if [ -n "$failures" ]; then
153
+ echo "The ignore set a target receives disagrees with this repository's own:" >&2
154
+ printf '%s' "$failures" >&2
155
+ echo "Add the entry to the \"$SECTION\" array in ${MANIFEST#"$PROJECT_ROOT/"} and to .gitignore, or record it in SANCTIONED in scripts/core/check-ignore-parity.sh with the reason it stays apart." >&2
156
+ exit 1
157
+ fi
158
+
159
+ if [ -n "$sanction_notes" ]; then
160
+ echo "Sanctioned divergences from the ignore set a target receives:"
161
+ printf '%s' "$sanction_notes"
162
+ fi
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+ set -o pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
7
+
8
+ INTERNAL_ROOT="$PROJECT_ROOT/internal"
9
+ PLUGIN_ROOT="$PROJECT_ROOT/claude"
10
+
11
+ # `find` writes to stderr and returns non-zero for a missing root, inside a
12
+ # process substitution whose status nothing reads. Without this the walk covers
13
+ # nothing and the check reports the boundary clean having never measured it.
14
+ if [ ! -d "$PLUGIN_ROOT" ]; then
15
+ echo "No plugin root at ${PLUGIN_ROOT#"$PROJECT_ROOT/"}, boundary unverifiable." >&2
16
+ exit 1
17
+ fi
18
+
19
+ # `realpath` resolves each walked path below. Absent, `set -e` aborts on the
20
+ # substitution and the stage reports a leak for a tool that is not installed,
21
+ # which is the same unmeasured-tree-with-a-verdict shape the guard above closes.
22
+ if ! command -v realpath >/dev/null 2>&1; then
23
+ echo "realpath is not installed, boundary unverifiable." >&2
24
+ exit 1
25
+ fi
26
+
27
+ # The plugin reaches `standards/` and `snippets/` through symlinks, which an
28
+ # installer dereferences with no code in the path to filter. Walking the plugin
29
+ # tree with symlinks followed is what an install actually copies, so resolving
30
+ # each file and rejecting anything under `internal/` asserts the boundary at the
31
+ # only place it can be measured.
32
+ leaked=""
33
+ while IFS= read -r file; do
34
+ resolved=$(realpath "$file")
35
+ case "$resolved" in
36
+ "$INTERNAL_ROOT"/*) leaked="$leaked ${file#"$PROJECT_ROOT/"} -> ${resolved#"$PROJECT_ROOT/"}"$'\n' ;;
37
+ esac
38
+ done < <(find -L "$PLUGIN_ROOT" -type f)
39
+
40
+ if [ -n "$leaked" ]; then
41
+ echo "Plugin ships toolkit-internal content:" >&2
42
+ printf '%s' "$leaked" >&2
43
+ echo "Author internal content under internal/, which nothing under claude/ reaches." >&2
44
+ exit 1
45
+ fi
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+ set -o pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
7
+
8
+ source "$PROJECT_ROOT/scripts/lib/tooling.sh"
9
+
10
+ TOOLKIT_TOKEN="canon"
11
+ TOOLING_ROOT="$PROJECT_ROOT/tooling"
12
+
13
+ # `find` writes to stderr and returns non-zero for a missing root, inside a
14
+ # process substitution whose status nothing reads. Without this the walk covers
15
+ # nothing and the check reports the seeds independent having never read one.
16
+ if [ ! -d "$TOOLING_ROOT" ]; then
17
+ echo "No tooling root at ${TOOLING_ROOT#"$PROJECT_ROOT/"}, seed independence unverifiable." >&2
18
+ exit 1
19
+ fi
20
+
21
+ # An empty discovery is a real state rather than a broken walk, and the Seed
22
+ # standards stage already reports it as a skip. Failing here would have the two
23
+ # stages disagree about what the same condition means.
24
+ seed_roots=$(collect_seed_roots)
25
+ if [ -z "$seed_roots" ]; then
26
+ echo "No seed root carries .claude/, nothing to check." >&2
27
+ exit 0
28
+ fi
29
+
30
+ # Markdown alone. The seed tree also ships hooks that call the toolkit CLI on
31
+ # purpose, each reporting a named stale-index warning when the binary is absent,
32
+ # and scoping by extension leaves them outside this walk without an exemption
33
+ # list that would have to be maintained against them.
34
+ cited=""
35
+ measured=0
36
+ while IFS= read -r seed_root; do
37
+ while IFS= read -r file; do
38
+ measured=$((measured + 1))
39
+ while IFS= read -r hit; do
40
+ cited="$cited ${file#"$PROJECT_ROOT/"}:$hit"$'\n'
41
+ done < <(grep -n "$TOOLKIT_TOKEN" "$file" || true)
42
+ done < <(find "$PROJECT_ROOT/$seed_root" -type f -name '*.md')
43
+ done <<<"$seed_roots"
44
+
45
+ # Roots resolved and no markdown under any of them is a walk that covered
46
+ # nothing, which is the verdict-without-a-measurement the guards above refuse for
47
+ # a missing tree. Reporting a pass here would say the seeds cite no CLI on the
48
+ # strength of having read no prose.
49
+ if [ "$measured" -eq 0 ]; then
50
+ echo "Seed roots resolved but carry no markdown, seed independence unverifiable." >&2
51
+ exit 1
52
+ fi
53
+
54
+ if [ -n "$cited" ]; then
55
+ echo "Seed prose cites the toolkit CLI:" >&2
56
+ printf '%s' "$cited" >&2
57
+ echo "A scaffolded project may not have $TOOLKIT_TOKEN installed. State the capability the line needs rather than the binary that supplies it." >&2
58
+ exit 1
59
+ fi
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+ set -o pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
7
+
8
+ SKILLS_DIR="$PROJECT_ROOT/claude/skills"
9
+
10
+ # A shipped skill runs from a target project, where the toolkit's own wiki/ does
11
+ # not exist. Anchoring on a non-path character keeps a target's .claude/wiki/ legal.
12
+ BANNED_PATH_PATTERN='(^|[^[:alnum:]._/-])wiki/'
13
+
14
+ [ -d "$SKILLS_DIR" ] || exit 0
15
+
16
+ matches=$(grep -rnE "$BANNED_PATH_PATTERN" "$SKILLS_DIR" || true)
17
+
18
+ [ -z "$matches" ] && exit 0
19
+
20
+ echo "Shipped skills reference a repo-local path that does not exist in a target project:"
21
+ echo "$matches" | sed "s|^$PROJECT_ROOT/||"
22
+ echo
23
+ echo "Reach supporting prose through a canon docs command, a standard cited at the flat root, or inlined text."
24
+ exit 1
@@ -0,0 +1,36 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+ set -o pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
7
+
8
+ source "$PROJECT_ROOT/scripts/lib/ui.sh"
9
+
10
+ check_dependencies() {
11
+ command -v bun >/dev/null 2>&1 || log_error "bun is not installed"
12
+ }
13
+
14
+ main() {
15
+ check_dependencies
16
+
17
+ echo -e "${GREY}┌${NC}"
18
+
19
+ echo -e "${GREY}├${NC} ${WHITE}Cleaning artifacts${NC}"
20
+ rm -rf node_modules
21
+
22
+ log_rem "node_modules/"
23
+
24
+ log_step "Cleaning cache"
25
+ bun pm cache rm
26
+ log_info "Package manager cache cleared"
27
+
28
+ log_step "Rehydrating project"
29
+ bun install
30
+ log_info "Dependencies installed"
31
+
32
+ echo -e "${GREY}└${NC}\n"
33
+ echo -e "${GREEN}✓ Clean complete${NC}"
34
+ }
35
+
36
+ main "$@"
@@ -0,0 +1,101 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+ set -o pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
7
+
8
+ source "$PROJECT_ROOT/scripts/lib/ui.sh"
9
+
10
+ TMP_ROOT="$PROJECT_ROOT/.claude/.tmp/install-check"
11
+ CLONE_DIR="$TMP_ROOT/clone"
12
+ TARGET_DIR="$TMP_ROOT/target"
13
+ KEEP=0
14
+
15
+ for arg in "$@"; do
16
+ case "$arg" in
17
+ --keep) KEEP=1 ;;
18
+ --help | -h)
19
+ cat <<HELP
20
+ Usage: scripts/core/install-check.sh [--keep]
21
+
22
+ Verifies the README install path end to end:
23
+ 1. Clones this repo into .claude/.tmp/install-check/clone
24
+ 2. Runs bun install in the clone
25
+ 3. Runs the CLI with --help to confirm it executes
26
+ 4. Scaffolds a fresh project in .claude/.tmp/install-check/target
27
+ 5. Runs canon init and asserts a scaffold landed
28
+
29
+ Flags:
30
+ --keep Keep the tmp tree on exit for inspection
31
+ HELP
32
+ exit 0
33
+ ;;
34
+ esac
35
+ done
36
+
37
+ cleanup() {
38
+ if [ "$KEEP" = "1" ]; then
39
+ log_info "Kept artifacts at $TMP_ROOT"
40
+ else
41
+ rm -rf "$TMP_ROOT"
42
+ fi
43
+ close_timeline
44
+ }
45
+ trap cleanup EXIT
46
+
47
+ rm -rf "$TMP_ROOT"
48
+ mkdir -p "$TMP_ROOT"
49
+
50
+ open_timeline "Install verification"
51
+
52
+ log_step "Clone"
53
+ git clone --quiet "$PROJECT_ROOT" "$CLONE_DIR" 2>&1 | pipe_output || true
54
+ log_info "Cloned to $CLONE_DIR"
55
+
56
+ log_step "Install dependencies"
57
+ (cd "$CLONE_DIR" && bun install --silent 2>&1 | pipe_output) || log_error "bun install failed"
58
+ log_info "Dependencies installed"
59
+
60
+ log_step "Confirm CLI runs"
61
+ (cd "$CLONE_DIR" && bun run src/cli.ts --help >/dev/null) || log_error "canon --help failed"
62
+ log_info "canon --help ran clean"
63
+
64
+ log_step "Scaffold fresh project"
65
+ mkdir -p "$TARGET_DIR"
66
+ (cd "$TARGET_DIR" && git init --quiet)
67
+ log_info "Initialized git in $TARGET_DIR"
68
+
69
+ log_step "Run canon init"
70
+ (cd "$TARGET_DIR" && CANON_NON_INTERACTIVE=1 bun run "$CLONE_DIR/src/cli.ts" init --stack base 2>&1 | pipe_output) || log_error "canon init failed"
71
+ log_info "canon init completed"
72
+
73
+ log_step "Assert scaffold"
74
+ # Every domain canon init installs needs at least one path here. A domain with
75
+ # no assertion can truncate silently: init still exits 0 because run_domain
76
+ # catches a failed domain, and the gate stays green while the target is
77
+ # missing everything that domain provides.
78
+ #
79
+ # Standards and snippets name no path because neither corpus installs into a
80
+ # target. A scaffold reads a standard through `canon standards <name>` and a
81
+ # snippet through the plugin's live `claude/snippets` symlink, both resolving
82
+ # against the toolkit rather than a copy this gate could assert on. The
83
+ # `@`-reference convention rule is the one snippets-domain file that still
84
+ # installs, since `base` carries `governance/rules/snippets/` as a
85
+ # folder-whole entry the same way it does `core` and `claude`.
86
+ for path in "CLAUDE.md" ".claude/wiki/index.md" ".claude" ".claude/context/index.md" ".claude/wireframes/index.md" ".claude/diagrams/index.md" \
87
+ ".prettierrc" ".editorconfig" ".lintstagedrc" ".husky/pre-commit" ".github/workflows/verify.yml" "scripts/verify.sh" \
88
+ ".claude/rules/core/000-constitution.md" ".claude/rules/snippets/505-at-references.md"; do
89
+ if [ ! -e "$TARGET_DIR/$path" ]; then
90
+ log_error "Missing after canon init: $path"
91
+ fi
92
+ log_info "Found: $path"
93
+ done
94
+
95
+ if [ ! -x "$TARGET_DIR/scripts/verify.sh" ]; then
96
+ log_error "Not executable after canon init: scripts/verify.sh"
97
+ fi
98
+ log_info "Executable: scripts/verify.sh"
99
+
100
+ log_step "Verification passed"
101
+ log_info "Manual check still needed: bun link and global canon invocation"
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env bash
2
+ # Prints every seed root carrying a `.claude/`, one per line and relative to
3
+ # the project root.
4
+ #
5
+ # The discovery rule has one definition, `collect_seed_roots` in
6
+ # `scripts/lib/tooling.sh`, which `check-seed-independence.sh` already reads.
7
+ # This file is the route a caller outside bash takes to that same answer, so a
8
+ # stack seeding `.claude/` later reaches both readers and the two stages
9
+ # measuring seed content cannot disagree about which roots exist.
10
+ set -e
11
+ set -o pipefail
12
+
13
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
14
+ PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
15
+
16
+ source "$PROJECT_ROOT/scripts/lib/tooling.sh"
17
+
18
+ collect_seed_roots
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env bash
2
+ set -e
3
+ set -o pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
7
+
8
+ # `.claude/rules/` is a subset rather than a mirror, so it resolves through the
9
+ # stack machinery. The record naming the subset is `internal/governance.toml`.
10
+ bun "$PROJECT_ROOT/src/cli.ts" gov regen --root "$PROJECT_ROOT"
@@ -0,0 +1,217 @@
1
+ #!/usr/bin/env bash
2
+ # Fills assets/hero.html.tmpl from the CLI catalogs and writes assets/hero.html.
3
+ #
4
+ # Only the HTML regenerates here. The PNG beside it is a chromium render whose
5
+ # bytes move with the browser version, so asserting it in verify.sh would fail
6
+ # on a machine whose chromium differs rather than on a stale count. Rebuild the
7
+ # image with `canon capture assets/hero.html` after this script reports a change.
8
+ # That capture also writes assets/hero.stamp, which records the digest of the
9
+ # markup it rendered and is what the Hero stage compares, so all three files
10
+ # commit together. The frame carries no version. `package.json` is bumped on main by the release
11
+ # tooling, so embedding it drifts every open branch on the next release and the
12
+ # stage then fails for work that touched nothing.
13
+ #
14
+ # Clone-only. `src/capture` is excluded from the published tarball, and this
15
+ # script reads the repository's own catalogs, so a registry install has neither.
16
+ set -e
17
+ set -o pipefail
18
+
19
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
20
+ PROJECT_ROOT="${PROJECT_ROOT:-$(cd "$SCRIPT_DIR/../.." && pwd)}"
21
+
22
+ TEMPLATE="$PROJECT_ROOT/assets/hero.html.tmpl"
23
+ OUTPUT="$PROJECT_ROOT/assets/hero.html"
24
+ LISTED=10
25
+
26
+ # `bun src/cli.ts` rather than `canon`, since a globally linked binary resolves to
27
+ # the main checkout no matter which worktree is running.
28
+ catalog() {
29
+ (cd "$PROJECT_ROOT" && CANON_NON_INTERACTIVE=1 bun src/cli.ts "$@" --json 2>/dev/null)
30
+ }
31
+
32
+ if [ ! -f "$TEMPLATE" ]; then
33
+ echo "regen-hero: missing template at $TEMPLATE" >&2
34
+ exit 1
35
+ fi
36
+
37
+ # The commands have no `--json` catalog of their own, so the count comes from
38
+ # `canon gov counts`, which already reads the registration block in the CLI
39
+ # entry point to judge a document stating its own command count. Reading that
40
+ # figure here rather than re-deriving it with a second regex is what keeps the
41
+ # two readings of `src/cli.ts` from drifting apart unwatched, which is the
42
+ # defect `canon gov counts` itself exists to catch.
43
+ # `gov counts` exits non-zero on an ordinary finding, unlike every `list` verb
44
+ # below, so its output is read past that under `set -e` rather than aborting
45
+ # a hero rebuild for a stale count somewhere unrelated in the tree.
46
+ COUNTS_JSON="$(catalog gov counts || true)"
47
+ SKILLS_JSON="$(catalog claude skills list)"
48
+ GOV_JSON="$(catalog gov list)"
49
+ STANDARDS_JSON="$(catalog standards list)"
50
+ SNIPPETS_JSON="$(catalog snippets list)"
51
+ TOOLING_JSON="$(catalog tooling list)"
52
+
53
+ for payload in "$COUNTS_JSON" "$SKILLS_JSON" "$GOV_JSON" "$STANDARDS_JSON" "$SNIPPETS_JSON" "$TOOLING_JSON"; do
54
+ if [ -z "$payload" ]; then
55
+ echo "regen-hero: a catalog returned nothing, refusing to write a zeroed hero" >&2
56
+ exit 1
57
+ fi
58
+ done
59
+
60
+ # The catalogs reach the eval as files rather than as environment entries. Linux
61
+ # caps a single env string at 128KB, and the standards payload crossed it, which
62
+ # fails the exec with E2BIG before any stage can report a stale count. A file
63
+ # path is bounded whatever the catalogs grow to.
64
+ PAYLOAD_DIR="$(mktemp -d)"
65
+ trap 'rm -rf "$PAYLOAD_DIR"' EXIT
66
+
67
+ printf '%s' "$COUNTS_JSON" >"$PAYLOAD_DIR/counts.json"
68
+ printf '%s' "$SKILLS_JSON" >"$PAYLOAD_DIR/skills.json"
69
+ printf '%s' "$GOV_JSON" >"$PAYLOAD_DIR/gov.json"
70
+ printf '%s' "$STANDARDS_JSON" >"$PAYLOAD_DIR/standards.json"
71
+ printf '%s' "$SNIPPETS_JSON" >"$PAYLOAD_DIR/snippets.json"
72
+ printf '%s' "$TOOLING_JSON" >"$PAYLOAD_DIR/tooling.json"
73
+
74
+ export PAYLOAD_DIR
75
+ export TEMPLATE OUTPUT LISTED PROJECT_ROOT
76
+
77
+ bun --eval '
78
+ const { readFileSync } = require("node:fs")
79
+
80
+ const { PAYLOAD_DIR, TEMPLATE, OUTPUT, LISTED, PROJECT_ROOT } = process.env
81
+
82
+ const payload = (name) => readFileSync(PAYLOAD_DIR + "/" + name + ".json", "utf8")
83
+
84
+ const COUNTS_JSON = payload("counts")
85
+ const SKILLS_JSON = payload("skills")
86
+ const GOV_JSON = payload("gov")
87
+ const STANDARDS_JSON = payload("standards")
88
+ const SNIPPETS_JSON = payload("snippets")
89
+ const TOOLING_JSON = payload("tooling")
90
+
91
+ const listed = Number(LISTED)
92
+ const skills = JSON.parse(SKILLS_JSON).skills.map((entry) => entry.name)
93
+ const gov = JSON.parse(GOV_JSON)
94
+ // Rule names carry a numeric prefix that orders the load, not the identity a
95
+ // reader knows them by, so the frame shows the slug alone.
96
+ const slug = (entry) => entry.name.replace(/^\d+-/, "")
97
+ const rules = gov.rules.map(slug)
98
+ // A rule no stack names is opt-in behind `--add`, so featuring one advertises
99
+ // an entry no ordinary `canon gov install` delivers. The column samples the
100
+ // stack-reached subset while its count and remainder describe the whole catalog.
101
+ const stacked = new Set(gov.stacks.flatMap((stack) => stack.rules))
102
+ const deliveredRules = gov.rules.filter((entry) => stacked.has(entry.name)).map(slug)
103
+ const standards = JSON.parse(STANDARDS_JSON).standards.map((entry) => entry.name)
104
+ const snippets = new Set(
105
+ JSON.parse(SNIPPETS_JSON).categories.flatMap((category) => category.entries),
106
+ )
107
+ const toolingStacks = JSON.parse(TOOLING_JSON).stacks
108
+ const commandCount = JSON.parse(COUNTS_JSON).catalogs.commands
109
+ if (!commandCount) {
110
+ console.error("regen-hero: gov counts read no commands catalog, refusing to write a zeroed hero")
111
+ process.exit(1)
112
+ }
113
+
114
+ const escape = (value) =>
115
+ value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")
116
+
117
+ // Even spacing across the sorted catalog rather than its first N, so a column
118
+ // whose names share a prefix does not read as a narrower catalog than the one
119
+ // that ships. Rules and standards sample. Skills do not, because the even step
120
+ // lands on the entries closest to commodity and on none of the workflow the
121
+ // toolkit exists to carry.
122
+ const sample = (names) => {
123
+ if (names.length <= listed) return names
124
+ const step = names.length / listed
125
+ return Array.from({ length: listed }, (_, i) => names[Math.floor(i * step)])
126
+ }
127
+
128
+ // The first seven are the method and exist nowhere else. The last three are
129
+ // recognizable on sight and are what keeps a column of chosen names from
130
+ // reading as an all-`claude-` catalog, which is the failure the sampler above
131
+ // was written against.
132
+ const FEATURED_SKILLS = [
133
+ "claude-feature",
134
+ "claude-groundwork",
135
+ "claude-intake",
136
+ "claude-orchestrate",
137
+ "claude-autoship",
138
+ "claude-pr-review",
139
+ "claude-tasks",
140
+ "git-ship",
141
+ "setup-init",
142
+ "systematic-debugging",
143
+ ]
144
+
145
+ // A chosen name is maintained by hand where a sample never goes stale, so a
146
+ // rename has to fail the run rather than quietly shrink the column. This is
147
+ // what makes the trade acceptable.
148
+ //
149
+ // The length is asserted because the `+N more` figure below counts down from
150
+ // `listed` rather than from what this returns, so a list of any other length
151
+ // renders a remainder that is wrong by the difference.
152
+ const featured = (names, chosen) => {
153
+ if (chosen.length !== listed) {
154
+ console.error(`regen-hero: ${chosen.length} featured skills, expected ${listed}`)
155
+ process.exit(1)
156
+ }
157
+ const catalog = new Set(names)
158
+ const missing = chosen.filter((name) => !catalog.has(name))
159
+ if (missing.length > 0) {
160
+ console.error(`regen-hero: featured skills missing from the catalog: ${missing.join(", ")}`)
161
+ process.exit(1)
162
+ }
163
+ return chosen
164
+ }
165
+
166
+ const markup = (names) =>
167
+ names
168
+ .map((name) => ` <div class="entry">${escape(name)}</div>`)
169
+ .join("\n")
170
+
171
+ const entries = (names) => markup(sample(names))
172
+
173
+ const remaining = (names) => String(Math.max(0, names.length - listed))
174
+
175
+ // An empty array is well-formed JSON, so the shell guard on an empty payload
176
+ // does not catch a catalog whose tree went missing. A zeroed count would ship a
177
+ // frame claiming the domain has nothing in it.
178
+ for (const [label, list] of [
179
+ ["skills", skills], ["rules", rules], ["standards", standards],
180
+ ["snippets", [...snippets]], ["tooling stacks", toolingStacks], ["gov stacks", gov.stacks],
181
+ ["stack-delivered rules", deliveredRules],
182
+ ]) {
183
+ if (list.length === 0) {
184
+ console.error(`regen-hero: the ${label} catalog is empty, refusing to write a zeroed hero`)
185
+ process.exit(1)
186
+ }
187
+ }
188
+
189
+ const values = {
190
+ SKILL_COUNT: String(skills.length),
191
+ RULE_COUNT: String(rules.length),
192
+ STANDARD_COUNT: String(standards.length),
193
+ SNIPPET_COUNT: String(snippets.size),
194
+ GOV_STACK_COUNT: String(gov.stacks.length),
195
+ TOOLING_STACK_COUNT: String(toolingStacks.length),
196
+ COMMAND_COUNT: String(commandCount),
197
+ SKILL_ENTRIES: markup(featured(skills, FEATURED_SKILLS)),
198
+ RULE_ENTRIES: entries(deliveredRules),
199
+ STANDARD_ENTRIES: entries(standards),
200
+ SKILL_MORE: remaining(skills),
201
+ RULE_MORE: remaining(rules),
202
+ STANDARD_MORE: remaining(standards),
203
+ }
204
+
205
+ let html = await Bun.file(TEMPLATE).text()
206
+ for (const [key, value] of Object.entries(values)) {
207
+ html = html.replaceAll(`{{${key}}}`, value)
208
+ }
209
+
210
+ const unresolved = html.match(/{{[A-Z_]+}}/g)
211
+ if (unresolved) {
212
+ console.error(`regen-hero: unresolved placeholders ${[...new Set(unresolved)].join(", ")}`)
213
+ process.exit(1)
214
+ }
215
+
216
+ await Bun.write(OUTPUT, html)
217
+ '