@erclx/canon 5.32.0 → 5.34.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 (250) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/api-design/REQUIREMENT.md +1 -2
  3. package/claude/skills/api-design/SKILL.md +2 -3
  4. package/claude/skills/api-design/references/adopted.md +1 -1
  5. package/claude/skills/auto-ship/SKILL.md +1 -1
  6. package/claude/skills/auto-ship/references/worktree-name.md +1 -1
  7. package/claude/skills/backlog-triage/REQUIREMENT.md +2 -2
  8. package/claude/skills/backlog-triage/SKILL.md +1 -1
  9. package/claude/skills/canon-cli/REQUIREMENT.md +16 -13
  10. package/claude/skills/canon-cli/SKILL.md +75 -32
  11. package/claude/skills/canon-feedback/REQUIREMENT.md +1 -0
  12. package/claude/skills/canon-feedback/SKILL.md +11 -29
  13. package/claude/skills/canon-feedback/references/template.md +53 -0
  14. package/claude/skills/{canvas → canvas-board}/REQUIREMENT.md +2 -2
  15. package/claude/skills/{canvas → canvas-board}/SKILL.md +6 -3
  16. package/claude/skills/{canvas → canvas-board}/references/canvas.md +26 -3
  17. package/{standards → claude/skills/canvas-board/references}/design.md +11 -2
  18. package/claude/skills/code-craft/REQUIREMENT.md +1 -1
  19. package/claude/skills/code-craft/SKILL.md +0 -1
  20. package/claude/skills/context-fold/REQUIREMENT.md +25 -33
  21. package/claude/skills/context-fold/SKILL.md +25 -70
  22. package/claude/skills/context-fold/references/classify.md +3 -3
  23. package/claude/skills/context-fold/references/completion-report.md +4 -4
  24. package/claude/skills/context-fold/references/context-refresh.md +5 -5
  25. package/{standards → claude/skills/context-fold/references}/context.md +16 -5
  26. package/claude/skills/context-fold/references/unusable-baseline.md +3 -5
  27. package/claude/skills/create-rule/SKILL.md +3 -3
  28. package/{standards → claude/skills/create-rule/references}/rule.md +15 -6
  29. package/claude/skills/create-skill/SKILL.md +2 -2
  30. package/{standards → claude/skills/create-skill/references}/skill.md +18 -15
  31. package/claude/skills/design-taste/REQUIREMENT.md +3 -3
  32. package/claude/skills/design-taste/SKILL.md +1 -1
  33. package/claude/skills/docs-sync/REQUIREMENT.md +1 -1
  34. package/claude/skills/docs-sync/SKILL.md +3 -3
  35. package/{standards → claude/skills/docs-sync/references}/docs.md +11 -0
  36. package/{standards → claude/skills/docs-sync/references}/readme.md +9 -2
  37. package/claude/skills/draft-and-pick/SKILL.md +5 -5
  38. package/claude/skills/draft-doc/SKILL.md +6 -6
  39. package/claude/skills/draft-figure/REQUIREMENT.md +2 -2
  40. package/claude/skills/draft-figure/SKILL.md +2 -2
  41. package/claude/skills/draft-figure/references/hand-drawn.md +1 -1
  42. package/claude/skills/draft-figure/references/mermaid-path.md +1 -1
  43. package/claude/skills/draft-identity/REQUIREMENT.md +2 -2
  44. package/claude/skills/draft-identity/SKILL.md +2 -2
  45. package/claude/skills/draft-ready/SKILL.md +1 -1
  46. package/claude/skills/git-branch/SKILL.md +1 -1
  47. package/{standards → claude/skills/git-branch/references}/branch.md +1 -1
  48. package/claude/skills/git-commit/SKILL.md +2 -2
  49. package/claude/skills/git-followup/REQUIREMENT.md +1 -1
  50. package/claude/skills/git-followup/SKILL.md +1 -1
  51. package/claude/skills/git-issue/SKILL.md +1 -1
  52. package/claude/skills/git-issue/references/issue.md +4 -1
  53. package/claude/skills/git-pr/SKILL.md +13 -13
  54. package/claude/skills/git-pr/references/evidence.md +2 -2
  55. package/claude/skills/git-pr/references/final-command.md +38 -14
  56. package/claude/skills/git-pr/references/labels.md +5 -1
  57. package/{standards → claude/skills/git-pr/references}/pr.md +19 -9
  58. package/{standards → claude/skills/git-pr/references}/publish.md +4 -2
  59. package/claude/skills/git-pr/references/task-number.md +1 -1
  60. package/claude/skills/git-ship/SKILL.md +15 -14
  61. package/claude/skills/git-split/SKILL.md +3 -3
  62. package/claude/skills/git-stage/SKILL.md +1 -1
  63. package/claude/skills/plan-feature/REQUIREMENT.md +1 -1
  64. package/claude/skills/review-address/SKILL.md +1 -1
  65. package/claude/skills/review-address/references/post-review-findings.md +1 -1
  66. package/claude/skills/review-craft/references/ui.md +1 -1
  67. package/claude/skills/review-pr/REQUIREMENT.md +1 -1
  68. package/claude/skills/review-pr/SKILL.md +3 -3
  69. package/claude/skills/review-pr/references/body-variants.md +2 -2
  70. package/claude/skills/review-pr/references/key-changes.md +3 -3
  71. package/claude/skills/review-pr/references/post.md +4 -2
  72. package/claude/skills/review-ui/REQUIREMENT.md +1 -1
  73. package/claude/skills/review-ui/SKILL.md +8 -6
  74. package/claude/skills/review-ui/references/driving.md +8 -8
  75. package/claude/skills/review-ui/references/post.md +53 -17
  76. package/claude/skills/role-orchestrator/REQUIREMENT.md +3 -0
  77. package/claude/skills/role-orchestrator/SKILL.md +2 -2
  78. package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +2 -2
  79. package/claude/skills/role-orchestrator/references/orchestrator-handoff.md +8 -5
  80. package/claude/skills/role-orchestrator/references/orchestrator-launch.md +32 -1
  81. package/claude/skills/role-orchestrator/references/orchestrator-refill.md +2 -2
  82. package/claude/skills/role-orchestrator/references/orchestrator-resume.md +3 -0
  83. package/claude/skills/role-planner/REQUIREMENT.md +2 -1
  84. package/claude/skills/role-planner/SKILL.md +13 -2
  85. package/claude/skills/role-reviewer/SKILL.md +1 -1
  86. package/claude/skills/role-worker/REQUIREMENT.md +1 -0
  87. package/claude/skills/role-worker/SKILL.md +9 -1
  88. package/claude/skills/session-map/SKILL.md +1 -1
  89. package/claude/skills/session-resume/REQUIREMENT.md +2 -2
  90. package/claude/skills/session-worktree/SKILL.md +5 -5
  91. package/claude/skills/target-setup/SKILL.md +10 -4
  92. package/claude/skills/target-setup/references/detect.md +20 -3
  93. package/claude/skills/task-board/REQUIREMENT.md +7 -12
  94. package/claude/skills/task-board/SKILL.md +5 -17
  95. package/claude/skills/task-board/references/tasks.md +2 -2
  96. package/claude/skills/task-complete/REQUIREMENT.md +47 -0
  97. package/claude/skills/task-complete/SKILL.md +86 -0
  98. package/claude/skills/{task-board → task-complete}/references/archive.md +4 -4
  99. package/claude/skills/{context-fold → task-complete}/references/receipt-sweep.md +5 -5
  100. package/claude/skills/task-complete/references/unusable-baseline.md +19 -0
  101. package/claude/skills/teach-workspace/REQUIREMENT.md +6 -2
  102. package/claude/skills/teach-workspace/SKILL.md +8 -4
  103. package/claude/skills/teach-workspace/references/lesson-craft.md +1 -1
  104. package/claude/skills/{context-fold/references/promoted-pages.md → teach-workspace/references/promotion-fold.md} +3 -3
  105. package/claude/skills/teach-workspace/references/promotion.md +3 -3
  106. package/claude/skills/test-craft/REQUIREMENT.md +2 -3
  107. package/claude/skills/test-craft/SKILL.md +15 -3
  108. package/claude/skills/ui-checklist/SKILL.md +1 -1
  109. package/claude/skills/ux-audit/SKILL.md +1 -1
  110. package/claude/skills/ux-measure/SKILL.md +1 -1
  111. package/docs/agents/canvas.md +6 -2
  112. package/docs/agents/commands.md +4 -3
  113. package/docs/agents/context-audit-checks.md +4 -4
  114. package/docs/agents/gov-detect.md +47 -0
  115. package/docs/agents/index.md +7 -4
  116. package/docs/agents/indexes.md +1 -1
  117. package/docs/agents/install-and-sync.md +10 -11
  118. package/docs/agents/key-changes.md +5 -5
  119. package/docs/agents/label-coverage.md +11 -0
  120. package/docs/agents/migrate.md +1 -1
  121. package/docs/agents/pr-evidence-layout.md +70 -0
  122. package/docs/agents/pr-evidence.md +8 -9
  123. package/docs/agents/pr-frames.md +7 -2
  124. package/docs/agents/pr-lift.md +132 -0
  125. package/docs/agents/records-push.md +2 -2
  126. package/docs/agents/records-stale.md +12 -47
  127. package/docs/agents/records-validate.md +3 -7
  128. package/docs/agents/records.md +5 -27
  129. package/docs/agents/rule-citations.md +1 -1
  130. package/docs/agents/sandbox.md +4 -4
  131. package/docs/agents/scripting.md +2 -1
  132. package/docs/agents/skills-audit.md +1 -1
  133. package/docs/agents/tasks-plans.md +2 -2
  134. package/docs/agents/tasks.md +2 -2
  135. package/docs/target/migrations.md +10 -2
  136. package/docs/target/projects.md +4 -4
  137. package/docs/target/sync.md +1 -1
  138. package/docs/workflow/operating-model.md +2 -2
  139. package/docs/workflow/parallel-features.md +7 -7
  140. package/docs/workflow/skill-map-on-request.md +9 -9
  141. package/docs/workflow/skill-map.md +12 -11
  142. package/docs/workflow/visual-design-workflow.md +2 -2
  143. package/governance/detect.toml +201 -0
  144. package/governance/renames.toml +0 -11
  145. package/governance/rules/canon/context.md +13 -0
  146. package/governance/rules/claude/skill.md +17 -0
  147. package/governance/rules/code/000-code.md +1 -13
  148. package/governance/rules/code/010-testing.md +2 -30
  149. package/governance/rules/ui/400-ui.md +1 -1
  150. package/governance/rules/ui/480-canvas.md +13 -0
  151. package/governance/stacks/base.toml +2 -4
  152. package/package.json +4 -4
  153. package/scripts/core/install-check.sh +3 -3
  154. package/scripts/core/regen-hero.ts +0 -6
  155. package/scripts/lib/ui.sh +0 -168
  156. package/src/audits/catalog.ts +0 -1
  157. package/src/canvas/arrange.ts +66 -0
  158. package/src/canvas/capture.ts +20 -6
  159. package/src/canvas/content.ts +39 -0
  160. package/src/canvas/fit.ts +238 -0
  161. package/src/canvas/tokens.ts +28 -10
  162. package/src/capture/frame-values.ts +2 -32
  163. package/src/claude/cases/misc.ts +1 -1
  164. package/src/claude/cases/setup.ts +4 -0
  165. package/src/claude/cases/workflow.ts +6 -1
  166. package/src/claude/seeds.ts +1 -1
  167. package/src/claude/skills-audit.ts +2 -2
  168. package/src/cli/help.ts +3 -1
  169. package/src/cli/ui.ts +2 -3
  170. package/src/commands/canvas.ts +179 -1
  171. package/src/commands/claude.ts +1 -1
  172. package/src/commands/gov.ts +146 -16
  173. package/src/commands/labels.ts +326 -7
  174. package/src/commands/migrate.ts +6 -1
  175. package/src/commands/pr.ts +377 -2
  176. package/src/commands/records.ts +13 -399
  177. package/src/commands/sandbox.ts +3 -6
  178. package/src/commands/tasks.ts +3 -3
  179. package/src/context/audit.ts +5 -5
  180. package/src/context/folders.ts +1 -1
  181. package/src/design/budget.ts +1 -1
  182. package/src/design/components.ts +1 -1
  183. package/src/design/document.ts +1 -1
  184. package/src/design/regen.ts +1 -1
  185. package/src/design/render.ts +1 -1
  186. package/src/feedback/body.ts +26 -5
  187. package/src/gate/measures.ts +59 -45
  188. package/src/gate/sequencer.ts +56 -1
  189. package/src/gate/stages.ts +4 -11
  190. package/src/gov/detect.ts +301 -0
  191. package/src/gov/install.ts +2 -3
  192. package/src/gov/list.ts +23 -2
  193. package/src/gov/stacks.ts +10 -1
  194. package/src/hooks/post-merge.ts +1 -1
  195. package/src/labels/apply.ts +39 -0
  196. package/src/labels/format.ts +3 -3
  197. package/src/labels/phase.ts +3 -3
  198. package/src/labels/sections.ts +43 -0
  199. package/src/migrate/skill-names.ts +20 -1
  200. package/src/pr/evidence.ts +218 -45
  201. package/src/pr/frames.ts +23 -3
  202. package/src/pr/lift.ts +418 -0
  203. package/src/pr/paths.ts +4 -4
  204. package/src/pr/rest.ts +3 -0
  205. package/src/pr/review-scope.ts +76 -0
  206. package/src/records/backup.ts +16 -6
  207. package/src/records/stale-canonical.ts +31 -1
  208. package/src/records/validate.ts +2 -188
  209. package/src/sandbox/census.ts +1 -1
  210. package/src/sandbox/coverage.ts +2 -6
  211. package/src/sandbox/equivalence.ts +19 -51
  212. package/src/sandbox/expect.ts +4 -4
  213. package/src/sandbox/provision.ts +13 -36
  214. package/src/sandbox/scenario.ts +26 -48
  215. package/src/sandbox/tree.ts +2 -6
  216. package/src/standards/read.ts +14 -1
  217. package/src/sync/git.ts +1 -1
  218. package/src/tasks/archive.ts +5 -5
  219. package/src/tasks/branch.ts +3 -3
  220. package/src/tasks/label.ts +1 -1
  221. package/src/tasks/record.ts +2 -2
  222. package/src/tasks/validate.ts +1 -1
  223. package/standards/index.md +0 -13
  224. package/standards/standard.md +1 -7
  225. package/tooling/base/reference.md +1 -1
  226. package/tooling/base/seeds/.github/pull_request_template.md +2 -2
  227. package/tooling/claude/reference.md +1 -1
  228. package/tooling/claude/seeds/.claude/hooks/pr-create-log.sh +9 -1
  229. package/tooling/claude/seeds/.claude/hooks/review-post-scan.sh +171 -0
  230. package/tooling/claude/seeds/.claude/settings.json +9 -0
  231. package/governance/rules/standards/context.md +0 -14
  232. package/governance/rules/standards/design.md +0 -12
  233. package/governance/rules/standards/readme.md +0 -12
  234. package/governance/rules/standards/rule.md +0 -13
  235. package/governance/rules/standards/skill.md +0 -21
  236. package/governance/rules/standards/standard.md +0 -13
  237. package/scripts/config.sh +0 -11
  238. package/scripts/lib/gov.sh +0 -14
  239. package/scripts/lib/sandbox-fixtures.sh +0 -191
  240. package/scripts/lib/sandbox-git.sh +0 -125
  241. package/scripts/lib/sandbox-path.sh +0 -50
  242. package/scripts/sandbox-hook.sh +0 -99
  243. package/src/gov/standard-rules.ts +0 -179
  244. package/src/records/migrate.ts +0 -78
  245. package/src/records/stale.ts +0 -243
  246. package/src/sandbox/hooks.ts +0 -128
  247. /package/{standards → claude/skills/draft-figure/references}/figures.md +0 -0
  248. /package/{standards → claude/skills/git-branch/references}/slug.md +0 -0
  249. /package/{standards → claude/skills/git-commit/references}/commit.md +0 -0
  250. /package/{standards → claude/skills/git-commit/references}/versioning.md +0 -0
@@ -0,0 +1,201 @@
1
+ # Evidence that marks a project as wanting an opt-in rule. Each table is keyed by
2
+ # a rule basename, the same key `renames.toml` and the stacks use, so a rename
3
+ # sweep reaches this file too. `canon gov detect` reads it and proposes every
4
+ # rule whose evidence a target holds, and `target-setup` puts those proposals to
5
+ # the operator before anything installs.
6
+ #
7
+ # `deps` are package names read from `package.json` (`dependencies` and
8
+ # `devDependencies`), `pyproject.toml`, `go.mod`, and `composer.json`, at the
9
+ # root and in every folder to depth two. `files` are globs matched against the
10
+ # target's git-listed paths to depth two, and against each folder on those
11
+ # paths, so `.github/workflows` matches a folder holding a workflow. A glob with
12
+ # no wildcard is also tested on disk, which reaches a gitignored path such as
13
+ # `.canon/canvas`.
14
+ #
15
+ # Every rule no stack reaches needs a table here, which the `unreferenced-rules`
16
+ # gate stage checks, along with every key naming a live rule. A table for a rule
17
+ # a stack already reaches is harmless, since the verb leaves out every rule the
18
+ # caller's stack resolves.
19
+
20
+ ["skill"]
21
+ deps = []
22
+ files = [".claude/skills", "claude/skills"]
23
+
24
+ ["700-ci-workflow"]
25
+ deps = []
26
+ files = [".github/workflows"]
27
+
28
+ ["765-spelling"]
29
+ deps = ["cspell"]
30
+ files = [".cspell", "cspell.json", ".cspell.json", "cspell.config.*"]
31
+
32
+ ["775-dependencies"]
33
+ deps = []
34
+ files = ["**/package.json", "**/pyproject.toml", "**/go.mod", "**/composer.json"]
35
+
36
+ ["780-config-comments"]
37
+ deps = []
38
+ files = [".editorconfig", "**/Dockerfile*", "**/*.config.*", "**/.env.example"]
39
+
40
+ ["790-code-comments"]
41
+ deps = []
42
+ files = ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx", "**/*.sh", "**/*.py"]
43
+
44
+ ["130-go"]
45
+ deps = []
46
+ files = ["**/go.mod"]
47
+
48
+ ["140-php"]
49
+ deps = []
50
+ files = ["**/composer.json"]
51
+
52
+ ["200-react"]
53
+ deps = ["react"]
54
+ files = []
55
+
56
+ ["210-astro"]
57
+ deps = ["astro"]
58
+ files = ["**/astro.config.*"]
59
+
60
+ ["220-fastapi"]
61
+ deps = ["fastapi"]
62
+ files = []
63
+
64
+ ["230-nextjs"]
65
+ deps = ["next"]
66
+ files = ["**/next.config.*"]
67
+
68
+ ["250-tailwind"]
69
+ deps = ["tailwindcss", "@tailwindcss/vite", "@tailwindcss/postcss"]
70
+ files = ["**/tailwind.config.*"]
71
+
72
+ ["260-shadcn"]
73
+ deps = []
74
+ files = ["**/components.json"]
75
+
76
+ ["305-e2e-reliability"]
77
+ deps = ["@playwright/test", "playwright", "cypress"]
78
+ files = ["**/e2e"]
79
+
80
+ ["306-test-scope"]
81
+ deps = ["@playwright/test", "playwright", "cypress"]
82
+ files = ["**/e2e"]
83
+
84
+ ["310-zod"]
85
+ deps = ["zod"]
86
+ files = []
87
+
88
+ ["320-tanstack-query"]
89
+ deps = [
90
+ "@tanstack/react-query",
91
+ "@tanstack/vue-query",
92
+ "@tanstack/solid-query",
93
+ "@tanstack/svelte-query",
94
+ "@tanstack/query-core",
95
+ ]
96
+ files = []
97
+
98
+ ["335-testing-go"]
99
+ deps = []
100
+ files = ["**/go.mod"]
101
+
102
+ ["336-testing-php"]
103
+ deps = ["phpunit/phpunit", "pestphp/pest"]
104
+ files = ["**/phpunit.xml", "**/phpunit.xml.dist"]
105
+
106
+ ["340-pydantic"]
107
+ deps = ["pydantic"]
108
+ files = []
109
+
110
+ ["350-security-web"]
111
+ deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
112
+ files = ["index.html", "*/index.html"]
113
+
114
+ ["360-security-server"]
115
+ deps = [
116
+ "express",
117
+ "fastify",
118
+ "hono",
119
+ "koa",
120
+ "elysia",
121
+ "@nestjs/core",
122
+ "fastapi",
123
+ "django",
124
+ "flask",
125
+ "starlette",
126
+ "laravel/framework",
127
+ "symfony/http-kernel",
128
+ "slim/slim",
129
+ "github.com/gin-gonic/gin",
130
+ "github.com/labstack/echo/v4",
131
+ "github.com/go-chi/chi/v5",
132
+ "github.com/gofiber/fiber/v2",
133
+ ]
134
+ files = []
135
+
136
+ ["370-database"]
137
+ deps = [
138
+ "prisma",
139
+ "@prisma/client",
140
+ "drizzle-orm",
141
+ "typeorm",
142
+ "sequelize",
143
+ "knex",
144
+ "kysely",
145
+ "mongoose",
146
+ "pg",
147
+ "mysql2",
148
+ "better-sqlite3",
149
+ "sqlalchemy",
150
+ "alembic",
151
+ "psycopg",
152
+ "psycopg2",
153
+ "psycopg2-binary",
154
+ "asyncpg",
155
+ "django",
156
+ "doctrine/orm",
157
+ "illuminate/database",
158
+ "gorm.io/gorm",
159
+ "github.com/jackc/pgx/v5",
160
+ ]
161
+ files = ["**/migrations", "**/schema.prisma", "**/*.sql"]
162
+
163
+ ["400-ui"]
164
+ deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
165
+ files = ["index.html", "*/index.html"]
166
+
167
+ ["410-a11y"]
168
+ deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
169
+ files = ["index.html", "*/index.html"]
170
+
171
+ ["420-forms"]
172
+ deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
173
+ files = ["index.html", "*/index.html"]
174
+
175
+ ["430-ux-completeness"]
176
+ deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
177
+ files = ["index.html", "*/index.html"]
178
+
179
+ ["440-surface-capture"]
180
+ deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
181
+ files = ["index.html", "*/index.html"]
182
+
183
+ ["450-link-behavior"]
184
+ deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
185
+ files = ["index.html", "*/index.html"]
186
+
187
+ ["460-design-taste"]
188
+ deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
189
+ files = ["canon/DESIGN.md", "index.html", "*/index.html"]
190
+
191
+ ["465-interface-casing"]
192
+ deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
193
+ files = ["index.html", "*/index.html"]
194
+
195
+ ["470-motion"]
196
+ deps = ["react", "vue", "svelte", "astro", "next", "solid-js", "preact"]
197
+ files = ["index.html", "*/index.html"]
198
+
199
+ ["480-canvas"]
200
+ deps = []
201
+ files = [".canon/canvas"]
@@ -13,10 +13,6 @@
13
13
  # resolves A only while both links stay. A key must name no live rule and every
14
14
  # chain must end on one, which `src/gov/renames.test.ts` checks against this
15
15
  # file.
16
- #
17
- # A numbered rule replaced by the rule `canon gov regen` generates from its
18
- # standard is a rename too: the generated rule keeps every glob and bullet, so
19
- # the pair is one-to-one identity under the standard's name.
20
16
  [renamed]
21
17
  "015-output" = "566-output"
22
18
  "035-tasks" = "602-tasks"
@@ -25,22 +21,15 @@
25
21
  "087-git" = "606-git"
26
22
  "510-context" = "610-context"
27
23
  "511-indexes" = "611-indexes"
28
- "550-design" = "650-design"
29
24
  "555-tasks" = "655-tasks"
30
25
  "558-plan" = "658-plan"
31
26
  "501-markdown" = "801-markdown"
32
- "580-readme" = "880-readme"
33
- "591-standard-authoring" = "891-standard-authoring"
34
27
  "065-spelling" = "765-spelling"
35
28
  "075-dependencies" = "775-dependencies"
36
29
  "080-config-comments" = "780-config-comments"
37
30
  "090-code-comments" = "790-code-comments"
38
31
  "658-plan" = "plan"
39
32
  "610-context" = "context"
40
- "650-design" = "design"
41
33
  "655-tasks" = "tasks"
42
34
  "570-skill" = "skill"
43
- "590-rule-authoring" = "rule"
44
35
  "801-markdown" = "markdown"
45
- "880-readme" = "readme"
46
- "891-standard-authoring" = "standard"
@@ -0,0 +1,13 @@
1
+ ---
2
+ description: Route edits under canon/context/ to the context-fold skill for the entry shape, and keep each entry conforming to the work in its domain
3
+ paths:
4
+ - 'canon/context/**'
5
+ ---
6
+
7
+ # Context standards
8
+
9
+ ## Context entries
10
+
11
+ - Load the `canon:context-fold` skill before a hand edit under `canon/context/`. It carries the entry shape and the content rules for a domain entry. Report it rather than proceeding silently when the skill does not resolve.
12
+ - Before non-trivial work in a domain, read its `canon/context/<domain>/` entry. Use `canon/context/index.md` to find it.
13
+ - Leave the entry conforming when work in its domain changes what it describes.
@@ -0,0 +1,17 @@
1
+ ---
2
+ description: Route edits to a skill body or its requirement to the create-skill skill for the shape, and hold the creation-time questions and the re-read rule
3
+ paths:
4
+ - '.claude/skills/**/SKILL.md'
5
+ - 'claude/skills/**/SKILL.md'
6
+ - '.claude/skills/**/REQUIREMENT.md'
7
+ - 'claude/skills/**/REQUIREMENT.md'
8
+ ---
9
+
10
+ # Skill standards
11
+
12
+ ## Skill files
13
+
14
+ - Load the `canon:create-skill` skill before a hand edit to a `SKILL.md` or a `REQUIREMENT.md`. It carries the skill structure, the requirement shape, and the path rules for a skill body. Report it rather than proceeding silently when the skill does not resolve. It ships with the plugin and this rule ships with the CLI, so a project that installed governance alone does not have it.
15
+ - Confirm `canon:create-skill`'s two creation-time questions are answered before a new `SKILL.md` lands, whether drafted by hand, by another skill, or by `canon:create-skill` itself. Carry the third question into the sibling `REQUIREMENT.md`'s `Must not` section as a review criterion rather than a gate.
16
+ - Re-read a skill body this session edited before invoking that skill again in the same session.
17
+ - Do not read a resolved file path in a held body as evidence the body is current.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Code placement, shape, dependency, error, and naming choices a model does not make by default
2
+ description: Routes code placement and shape decisions to the skills that carry them
3
3
  ---
4
4
 
5
5
  # Code standards
@@ -7,19 +7,7 @@ description: Code placement, shape, dependency, error, and naming choices a mode
7
7
  ## Placement
8
8
 
9
9
  - Load the `canon:codebase-layout` skill before placing a new file, and report it rather than proceeding silently when it does not resolve.
10
- - Prioritize native platform capabilities over third-party libraries.
11
- - Ensure data and configuration reside in designated Single Source of Truth locations.
12
10
 
13
11
  ## Shape
14
12
 
15
13
  - Load the `canon:code-craft` skill before deciding the shape of a new function, class, or module, and report it rather than proceeding silently when it does not resolve.
16
-
17
- ## Errors
18
-
19
- - Return structured error types for recoverable failures.
20
- - Never expose internal implementation details in error messages.
21
-
22
- ## Naming
23
-
24
- - Prefix booleans with `is`, `has`, `should`, or `can`: `isLoading`, `hasAccess`.
25
- - Prefix event handlers with `handle`: `handleClick`, `handleSubmit`.
@@ -1,37 +1,9 @@
1
1
  ---
2
- description: Enforce universal testing standards and best practices
2
+ description: Routes a test edit to the skill that carries the testing floors
3
3
  ---
4
4
 
5
5
  # Testing standards
6
6
 
7
7
  ## Before writing a test
8
8
 
9
- - Load the `canon:test-craft` skill before choosing the layer for a new test, and report it rather than proceeding silently when the skill does not resolve.
10
-
11
- ## Test structure
12
-
13
- - Structure tests using the Arrange, Act, Assert (AAA) pattern.
14
- - Each test should verify a single behavior.
15
- - Do not use conditional logic or loops within test bodies.
16
-
17
- ## Test focus
18
-
19
- - Do not test private functions or internal state directly.
20
- - Do not target arbitrary coverage percentages.
21
-
22
- ## Organization and isolation
23
-
24
- - Group related tests using the framework's nesting mechanism.
25
- - Keep nesting shallow (max 2 levels).
26
- - Ensure tests are independent with no shared side effects.
27
- - Clean up side effects and restore state after each test.
28
-
29
- ## Test data and async
30
-
31
- - Use factory functions or builders for test data over inline object literals.
32
- - Always await async operations.
33
- - Do not fire-and-forget promises in tests.
34
-
35
- ## Verification
36
-
37
- - Do not use snapshot testing for verification.
9
+ - Load the `canon:test-craft` skill before writing or changing a test, and report it rather than proceeding silently when the skill does not resolve.
@@ -11,7 +11,7 @@ paths:
11
11
 
12
12
  ## Punctuation
13
13
 
14
- - Do not use em dashes (`—`). Use a comma or period, or restructure the sentence.
14
+ - Do not use em dashes (`—`) or semicolons (`;`). Use a comma or period, or restructure the sentence.
15
15
  - Do not add punctuation to button labels or short action strings.
16
16
 
17
17
  ## Button copy
@@ -0,0 +1,13 @@
1
+ ---
2
+ description: Route edits to canvas frames under .canon/canvas/ to the canvas-board skill for the house style, and keep frame text and box height readable
3
+ paths:
4
+ - '.canon/canvas/**'
5
+ ---
6
+
7
+ # Canvas standards
8
+
9
+ ## Frames
10
+
11
+ - Load the `canon:canvas-board` skill before drawing or editing a frame. It carries the house style for an explanation frame and the content format. Report it rather than proceeding silently when the skill does not resolve.
12
+ - Write explanation frame text in sentence case. A mockup of the project's interface follows its design document instead.
13
+ - Size each explanation frame's box to show all its content with no scrollbar.
@@ -5,7 +5,5 @@ extends = ""
5
5
  # session conduct and `.claude/` authoring rules, `tooling` the dev setup and
6
6
  # CI workflow rules, and `writing` the prose and document-shape rules. The
7
7
  # `code` group is left to the stacks that write code, so a docs or writing
8
- # project loads no rule it can never apply. `standards` holds one rule per
9
- # standard routing its paths to it, generated by `canon gov regen` from each
10
- # standard's frontmatter rather than authored.
11
- rules = ["canon", "claude", "standards", "tooling", "writing"]
8
+ # project loads no rule it can never apply.
9
+ rules = ["canon", "claude", "tooling", "writing"]
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@erclx/canon",
3
3
  "type": "module",
4
- "version": "5.32.0",
4
+ "version": "5.34.0",
5
5
  "description": "Runs your agent's work and keeps its code good, on one setup for every repo.",
6
6
  "license": "MIT",
7
7
  "bin": {
@@ -26,9 +26,9 @@
26
26
  },
27
27
  "scripts": {
28
28
  "check:spell": "cspell '**' '.*/**' '.*' --no-progress --color --show-context",
29
- "format": "prettier --write --log-level warn --ignore-path .gitignore --ignore-path .prettierignore . && shfmt --write --indent 2 scripts/ sandbox/ tooling/ claude/",
30
- "check:format": "prettier --check --log-level warn --ignore-path .gitignore --ignore-path .prettierignore . && shfmt --diff --indent 2 scripts/ sandbox/ tooling/ claude/",
31
- "check:shell": "find scripts sandbox tooling claude .claude/hooks -name '*.sh' -exec shellcheck --severity=warning {} + && find .husky -maxdepth 1 -type f -exec shellcheck --severity=warning --shell=sh {} +",
29
+ "format": "prettier --write --log-level warn --ignore-path .gitignore --ignore-path .prettierignore . && shfmt --write --indent 2 scripts/ tooling/ claude/",
30
+ "check:format": "prettier --check --log-level warn --ignore-path .gitignore --ignore-path .prettierignore . && shfmt --diff --indent 2 scripts/ tooling/ claude/",
31
+ "check:shell": "find scripts tooling claude .claude/hooks -name '*.sh' -exec shellcheck --severity=warning {} + && find .husky -maxdepth 1 -type f -exec shellcheck --severity=warning --shell=sh {} +",
32
32
  "check:types": "tsc --noEmit",
33
33
  "check:install": "./scripts/core/install-check.sh",
34
34
  "test": "bun --bun vitest run",
@@ -55,10 +55,10 @@ open_timeline "Install verification"
55
55
  # nothing, so the excluded tree has to exist here before its absence below can
56
56
  # mean the publish left it out.
57
57
  log_step "Assert excluded path exists in source"
58
- if [ ! -f "$PROJECT_ROOT/sandbox/run.sh" ]; then
59
- log_error "sandbox/run.sh is missing from the source tree, so the absence check below would pass on nothing"
58
+ if [ ! -f "$PROJECT_ROOT/sandbox/exempt.toml" ]; then
59
+ log_error "sandbox/exempt.toml is missing from the source tree, so the absence check below would pass on nothing"
60
60
  fi
61
- log_info "Present: sandbox/run.sh"
61
+ log_info "Present: sandbox/exempt.toml"
62
62
 
63
63
  log_step "Pack"
64
64
  TARBALL_PATH="$(cd "$PROJECT_ROOT" && bun pm pack --quiet --ignore-scripts --destination "$PACK_DIR" | tail -n 1)"
@@ -50,7 +50,6 @@ import { listSkills } from '../../src/claude/skills-list'
50
50
  import { countCommands } from '../../src/counts/catalogs'
51
51
  import { buildDesignCss } from '../../src/design/css'
52
52
  import { buildGovCatalog } from '../../src/gov/list'
53
- import { listStandardEntries } from '../../src/standards/list'
54
53
  import { buildStackSummaries } from '../../src/tooling/list'
55
54
 
56
55
  const root = new URL('../..', import.meta.url).pathname
@@ -87,11 +86,6 @@ function run(): void {
87
86
  const { values, frames } = buildFrameValues({
88
87
  skills: listSkills(root).map((entry) => entry.name),
89
88
  gov: buildGovCatalog(root),
90
- // The toolkit root only: a project-local standard would put a row in the
91
- // hero the toolkit does not ship.
92
- standards: listStandardEntries(root).filter((entry) =>
93
- entry.source.startsWith('standards/'),
94
- ),
95
89
  toolingStacks: buildStackSummaries(root),
96
90
  commandCount: countCommands(root) ?? 0,
97
91
  tokenCss,
package/scripts/lib/ui.sh CHANGED
@@ -6,12 +6,6 @@ if [ "${BASH_VERSINFO[0]:-0}" -lt 4 ]; then
6
6
  exit 1
7
7
  fi
8
8
 
9
- # Resolved from this file's own location rather than `$PROJECT_ROOT`, because
10
- # `require_project_root` is what several scripts call before anything has
11
- # established a root.
12
- # shellcheck source=/dev/null
13
- source "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")/sandbox-path.sh"
14
-
15
9
  # `NO_COLOR` follows the published convention, where any non-empty value turns
16
10
  # color off whatever the value says.
17
11
  supports_color() {
@@ -102,165 +96,3 @@ close_timeline() {
102
96
  set_palette 2
103
97
  echo -e "${GREY}└${NC}" >&2
104
98
  }
105
-
106
- guard_root() {
107
- local target="$1"
108
- local target_abs
109
- target_abs=$(cd "$target" && pwd)
110
- if [ "$target_abs" = "$PROJECT_ROOT" ]; then
111
- log_error "Cannot run against toolkit root. Files here are the source of truth."
112
- fi
113
- }
114
-
115
- require_project_root() {
116
- local GREEN RED YELLOW WHITE GREY NC
117
- set_palette 2
118
- local sandbox in_sandbox=0
119
- if [ -n "${CANON_SANDBOX_DIR:-}" ]; then
120
- sandbox="$CANON_SANDBOX_DIR"
121
- [[ "$PWD" == "$sandbox" || "$PWD" == "$sandbox"/* ]] && in_sandbox=1
122
- else
123
- sandbox="$(sandbox_dir_prefix)"
124
- [[ "$PWD" == "$sandbox" || "$PWD" == "$sandbox"/* || "$PWD" == "$sandbox"-* ]] && in_sandbox=1
125
- fi
126
- if [ "$in_sandbox" -eq 1 ]; then
127
- echo -e "${GREY}┌${NC}" >&2
128
- log_error "Execution restricted: Command cannot be run from inside the sandbox environment."
129
- fi
130
- if [[ "$PWD" != "$PROJECT_ROOT"* ]]; then
131
- echo -e "${GREY}┌${NC}" >&2
132
- log_error "Context Error: You must run this command from inside the repository."
133
- fi
134
- }
135
-
136
- # The retired spelling stays honored, and permanently. This variable is the
137
- # documented way to drive any command headlessly, so every skill body, CI job,
138
- # and operator script already written sets the old name, and those callers live
139
- # in repositories and plugin caches this release cannot reach. Dropping it
140
- # leaves them waiting on a TTY nobody is watching.
141
- is_non_interactive() {
142
- # canon-keep-retired
143
- [[ "${CANON_NON_INTERACTIVE:-}" == "1" || "${AITK_NON_INTERACTIVE:-}" == "1" ]]
144
- }
145
-
146
- ask() {
147
- local GREEN RED YELLOW WHITE GREY NC
148
- set_palette 2
149
- local prompt_text=$1
150
- local var_name=$2
151
- local default_val=$3
152
- local input=""
153
- local char
154
- local display_default=""
155
- if [ -n "$default_val" ]; then
156
- display_default=" (${default_val})"
157
- fi
158
- if is_non_interactive; then
159
- echo -e "${GREY}│${NC}" >&2
160
- echo -e "${GREY}◇${NC} ${prompt_text} ${WHITE}${default_val}${NC}" >&2
161
- export "$var_name"="$default_val"
162
- return
163
- fi
164
- echo -e "${GREY}│${NC}" >&2
165
- echo -ne "${GREEN}◆${NC} ${prompt_text}${display_default} " >&2
166
- while IFS= read -r -s -n1 char; do
167
- if [[ $char == $'\x1b' ]]; then
168
- read -rsn2 -t 0.001 _ || true
169
- echo -ne "\r\033[K" >&2
170
- echo -e "${GREY}◇${NC} ${prompt_text} ${RED}Cancelled${NC}" >&2
171
- exit 1
172
- elif [[ $char == $'\x7f' || $char == $'\x08' ]]; then
173
- if [ -n "$input" ]; then
174
- input="${input%?}"
175
- echo -ne "\b \b" >&2
176
- fi
177
- elif [[ -z "$char" ]]; then
178
- break
179
- else
180
- input+="$char"
181
- echo -n "$char" >&2
182
- fi
183
- done
184
- [ -z "$input" ] && input="$default_val"
185
- echo -ne "\r\033[K" >&2
186
- echo -e "${GREY}◇${NC} ${prompt_text} ${WHITE}${input}${NC}" >&2
187
- export "$var_name"="$input"
188
- }
189
-
190
- select_or_route_scenario() {
191
- local GREEN RED YELLOW WHITE GREY NC
192
- set_palette 2
193
- local prompt_text=$1
194
- shift
195
- local options=("$@")
196
-
197
- if [ -n "${SANDBOX_SCENARIO:-}" ]; then
198
- echo -e "${GREY}│${NC}" >&2
199
- echo -e "${GREY}◇${NC} ${prompt_text} ${WHITE}${SANDBOX_SCENARIO}${NC}" >&2
200
- export SELECTED_OPTION="$SANDBOX_SCENARIO"
201
- return
202
- fi
203
-
204
- select_option "$prompt_text" "${options[@]}"
205
- }
206
-
207
- select_option() {
208
- local GREEN RED YELLOW WHITE GREY NC
209
- set_palette 2
210
- local prompt_text=$1
211
- shift
212
- local options=("$@")
213
- local cur=0
214
- local count=${#options[@]}
215
-
216
- if is_non_interactive; then
217
- echo -e "${GREY}│${NC}" >&2
218
- echo -e "${GREY}◇${NC} ${prompt_text} ${WHITE}${options[0]}${NC}" >&2
219
- export SELECTED_OPTION="${options[0]}"
220
- return
221
- fi
222
-
223
- if [ ! -t 0 ]; then
224
- log_error "${prompt_text} requires a TTY. Pass an argument or set CANON_NON_INTERACTIVE=1."
225
- fi
226
-
227
- echo -e "${GREY}│${NC}" >&2
228
- echo -ne "${GREEN}◆${NC} ${prompt_text}\n" >&2
229
-
230
- while true; do
231
- for i in "${!options[@]}"; do
232
- if [ "$i" -eq "$cur" ]; then
233
- echo -e "${GREY}│${NC} ${GREEN}❯ ${options[$i]}${NC}" >&2
234
- else
235
- echo -e "${GREY}│${NC} ${GREY}${options[$i]}${NC}" >&2
236
- fi
237
- done
238
-
239
- read -rsn1 key
240
- case "$key" in
241
- $'\x1b')
242
- if read -rsn2 -t 0.001 key_seq; then
243
- if [[ "$key_seq" == "[A" ]]; then cur=$(((cur - 1 + count) % count)); fi
244
- if [[ "$key_seq" == "[B" ]]; then cur=$(((cur + 1) % count)); fi
245
- else
246
- echo -ne "\033[$((count + 1))A\033[J" >&2
247
- echo -e "${GREY}◇${NC} ${prompt_text} ${RED}Cancelled${NC}" >&2
248
- exit 1
249
- fi
250
- ;;
251
- "k") cur=$(((cur - 1 + count) % count)) ;;
252
- "j") cur=$(((cur + 1) % count)) ;;
253
- "q")
254
- echo -ne "\033[$((count + 1))A\033[J" >&2
255
- echo -e "${GREY}◇${NC} ${prompt_text} ${RED}Cancelled${NC}" >&2
256
- exit 1
257
- ;;
258
- "") break ;;
259
- esac
260
- echo -ne "\033[${count}A" >&2
261
- done
262
-
263
- echo -ne "\033[$((count + 1))A\033[J" >&2
264
- echo -e "${GREY}◇${NC} ${prompt_text} ${WHITE}${options[$cur]}${NC}" >&2
265
- export SELECTED_OPTION="${options[$cur]}"
266
- }
@@ -468,7 +468,6 @@ const RECORD_KINDS: readonly (readonly [string, Corpus])[] = [
468
468
  ['plans', 'per-machine'],
469
469
  ['groundwork', 'per-machine'],
470
470
  ['intake', 'per-machine'],
471
- ['memory', 'per-machine'],
472
471
  ['standards', 'tracked'],
473
472
  ['teach', 'per-machine'],
474
473
  ]