@erclx/canon 4.120.0 → 4.121.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 (72) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/auto-ship/SKILL.md +29 -115
  3. package/claude/skills/auto-ship/references/draft-mark.md +30 -0
  4. package/claude/skills/auto-ship/references/failure-recovery.md +27 -0
  5. package/claude/skills/auto-ship/references/tier-failures.md +26 -0
  6. package/claude/skills/auto-ship/references/verb-absent.md +37 -0
  7. package/claude/skills/auto-ship/references/worktree-name.md +22 -0
  8. package/claude/skills/bash-script/SKILL.md +1 -1
  9. package/claude/skills/bash-script/references/patterns.md +0 -99
  10. package/claude/skills/bash-script/references/prompts.md +100 -0
  11. package/claude/skills/create-skill/SKILL.md +1 -1
  12. package/claude/skills/create-snippet/SKILL.md +1 -1
  13. package/claude/skills/create-standard/SKILL.md +1 -1
  14. package/claude/skills/design-extract/SKILL.md +1 -1
  15. package/claude/skills/design-taste/REQUIREMENT.md +2 -2
  16. package/claude/skills/docs-sync/SKILL.md +1 -1
  17. package/claude/skills/draft-context/SKILL.md +1 -1
  18. package/claude/skills/draft-docs/SKILL.md +1 -1
  19. package/claude/skills/draft-figure/SKILL.md +1 -1
  20. package/claude/skills/draft-readme/SKILL.md +1 -1
  21. package/claude/skills/draft-wiki/SKILL.md +1 -1
  22. package/claude/skills/draft-wireframes/SKILL.md +1 -1
  23. package/claude/skills/git-issue/SKILL.md +1 -1
  24. package/claude/skills/git-issue/references/issue.md +1 -1
  25. package/claude/skills/git-pr/SKILL.md +1 -1
  26. package/claude/skills/git-stage/SKILL.md +1 -1
  27. package/claude/skills/memory-capture/SKILL.md +1 -1
  28. package/claude/skills/restate-plainly/REQUIREMENT.md +1 -1
  29. package/claude/skills/review-address/SKILL.md +4 -3
  30. package/claude/skills/review-branch/REQUIREMENT.md +1 -0
  31. package/claude/skills/review-branch/SKILL.md +5 -6
  32. package/claude/skills/review-craft/REQUIREMENT.md +43 -0
  33. package/claude/skills/review-craft/SKILL.md +50 -0
  34. package/claude/skills/review-craft/references/security.md +21 -0
  35. package/claude/skills/review-craft/references/ui.md +72 -0
  36. package/claude/skills/review-pr/REQUIREMENT.md +1 -0
  37. package/claude/skills/review-pr/SKILL.md +1 -1
  38. package/claude/skills/review-pr/references/post.md +1 -1
  39. package/claude/skills/role-planner/REQUIREMENT.md +1 -1
  40. package/claude/skills/standards-audit/SKILL.md +1 -1
  41. package/claude/skills/write-human/REQUIREMENT.md +7 -4
  42. package/claude/skills/write-human/SKILL.md +4 -2
  43. package/claude/skills/write-human/references/machine-tells.md +1 -1
  44. package/claude/skills/write-human/references/source-material.md +5 -2
  45. package/docs/agents/audits.md +1 -1
  46. package/docs/agents/commands.md +1 -1
  47. package/docs/agents/markdown-audit.md +13 -19
  48. package/docs/agents/pr-local.md +6 -3
  49. package/docs/target-projects.md +1 -1
  50. package/docs/workflow/ai-workflow.md +1 -0
  51. package/governance/rules/claude/500-prose.md +1 -1
  52. package/governance/rules/claude/501-markdown.md +3 -3
  53. package/package.json +1 -1
  54. package/src/autoship/paths.ts +3 -2
  55. package/src/claude/cases/workflow.ts +5 -0
  56. package/src/commands/audits.ts +2 -2
  57. package/src/commands/markdown.ts +7 -9
  58. package/src/commands/pr.ts +11 -4
  59. package/src/gate/measures.ts +4 -4
  60. package/src/gate/stages.ts +0 -1
  61. package/src/markdown/bans.ts +11 -68
  62. package/src/markdown/gate.ts +1 -1
  63. package/src/markdown/scan.ts +7 -88
  64. package/standards/docs.md +1 -1
  65. package/standards/index.md +1 -1
  66. package/standards/markdown.md +5 -7
  67. package/standards/pr.md +1 -1
  68. package/standards/publish.md +1 -1
  69. package/standards/readme.md +2 -2
  70. package/tooling/base/configs/scripts/verify.sh +2 -2
  71. package/tooling/base/seeds/canon/context/development.md +1 -1
  72. package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +5 -6
@@ -0,0 +1,100 @@
1
+ # Bash script prompts
2
+
3
+ Interactive prompt templates for the `bash-script` skill, read only when the script prompts. Copy verbatim, alongside the colors and logging functions from `patterns.md`.
4
+
5
+ Both prompts transition `◆` to `◇`, guard against non-TTY stdin with `[ -t 0 ]`, and write UI to stderr.
6
+
7
+ ```bash
8
+ ask() {
9
+ local prompt_text=$1
10
+ local var_name=$2
11
+ local default_val=$3
12
+ local input=""
13
+ local char
14
+ local display_default=""
15
+ if [ -n "$default_val" ]; then
16
+ display_default=" (${default_val})"
17
+ fi
18
+ if [ ! -t 0 ]; then
19
+ log_error "${prompt_text} requires a TTY"
20
+ fi
21
+ echo -e "${GREY}│${NC}" >&2
22
+ echo -ne "${GREEN}◆${NC} ${prompt_text}${display_default} " >&2
23
+ while IFS= read -r -s -n1 char; do
24
+ if [[ $char == $'\x1b' ]]; then
25
+ read -rsn2 -t 0.001 _ || true
26
+ echo -ne "\r\033[K" >&2
27
+ echo -e "${GREY}◇${NC} ${prompt_text} ${RED}Cancelled${NC}" >&2
28
+ exit 1
29
+ elif [[ $char == $'\x7f' || $char == $'\x08' ]]; then
30
+ if [ -n "$input" ]; then
31
+ input="${input%?}"
32
+ echo -ne "\b \b" >&2
33
+ fi
34
+ elif [[ -z "$char" ]]; then
35
+ break
36
+ else
37
+ input+="$char"
38
+ echo -n "$char" >&2
39
+ fi
40
+ done
41
+ [ -z "$input" ] && input="$default_val"
42
+ echo -ne "\r\033[K" >&2
43
+ echo -e "${GREY}◇${NC} ${prompt_text} ${WHITE}${input}${NC}" >&2
44
+ export "$var_name"="$input"
45
+ }
46
+ ```
47
+
48
+ ```bash
49
+ select_option() {
50
+ local prompt_text=$1
51
+ shift
52
+ local options=("$@")
53
+ local cur=0
54
+ local count=${#options[@]}
55
+
56
+ if [ ! -t 0 ]; then
57
+ log_error "${prompt_text} requires a TTY"
58
+ fi
59
+
60
+ echo -ne "${GREY}│${NC}\n${GREEN}◆${NC} ${prompt_text}\n" >&2
61
+
62
+ while true; do
63
+ for i in "${!options[@]}"; do
64
+ if [ "$i" -eq "$cur" ]; then
65
+ echo -e "${GREY}│${NC} ${GREEN}❯ ${options[$i]}${NC}" >&2
66
+ else
67
+ echo -e "${GREY}│${NC} ${GREY}${options[$i]}${NC}" >&2
68
+ fi
69
+ done
70
+
71
+ read -rsn1 key
72
+ case "$key" in
73
+ $'\x1b')
74
+ if read -rsn2 -t 0.001 key_seq; then
75
+ if [[ "$key_seq" == "[A" ]]; then cur=$(( (cur - 1 + count) % count )); fi
76
+ if [[ "$key_seq" == "[B" ]]; then cur=$(( (cur + 1) % count )); fi
77
+ else
78
+ echo -en "\033[$((count + 1))A\033[J" >&2
79
+ echo -e "\033[1A${GREY}│${NC}\n${GREY}◇${NC} ${prompt_text} ${RED}Cancelled${NC}" >&2
80
+ exit 1
81
+ fi
82
+ ;;
83
+ "k") cur=$(( (cur - 1 + count) % count ));;
84
+ "j") cur=$(( (cur + 1) % count ));;
85
+ "q")
86
+ echo -en "\033[$((count + 1))A\033[J" >&2
87
+ echo -e "\033[1A${GREY}│${NC}\n${GREY}◇${NC} ${prompt_text} ${RED}Cancelled${NC}" >&2
88
+ exit 1
89
+ ;;
90
+ "") break ;;
91
+ esac
92
+
93
+ echo -en "\033[${count}A" >&2
94
+ done
95
+
96
+ echo -en "\033[$((count + 1))A\033[J" >&2
97
+ echo -e "\033[1A${GREY}│${NC}\n${GREY}◇${NC} ${prompt_text} ${WHITE}${options[$cur]}${NC}" >&2
98
+ SELECTED_OPTION="${options[$cur]}"
99
+ }
100
+ ```
@@ -9,7 +9,7 @@ Read these files in parallel:
9
9
 
10
10
  - `${CLAUDE_SKILL_DIR}/../../standards/skill.md`: skill structure, skill types, frontmatter fields, invocation rules
11
11
  - `${CLAUDE_SKILL_DIR}/../../standards/skill-requirement.md`: what `REQUIREMENT.md` must answer, its sections, and its template
12
- - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting for skill body text
12
+ - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: punctuation and formatting for skill body text
13
13
  - The `write-human` skill: voice, rhythm, and sentence construction for skill body text
14
14
 
15
15
  ## Guards
@@ -7,7 +7,7 @@ description: Creates a new snippet file in `snippets/` or `.claude/snippets/`. U
7
7
 
8
8
  Creates one snippet file. Read these files in parallel:
9
9
 
10
- - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting for all generated text
10
+ - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: punctuation and formatting for all generated text
11
11
  - The `write-human` skill: voice, rhythm, and sentence construction for all generated text
12
12
  - `${CLAUDE_SKILL_DIR}/../../standards/snippets.md`: authoring conventions, invocation channels, use patterns
13
13
 
@@ -7,7 +7,7 @@ description: Creates a new standard file in `standards/`. Use when asked to "cre
7
7
 
8
8
  Creates one standard file. Read these files in parallel:
9
9
 
10
- - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting for all generated text
10
+ - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: punctuation and formatting for all generated text
11
11
  - The `write-human` skill: voice, rhythm, and sentence construction for all generated text
12
12
  - `${CLAUDE_SKILL_DIR}/../../standards/standard.md`: the meta-standard for shape, frontmatter, and structure
13
13
 
@@ -55,7 +55,7 @@ Use the returned content as the target shape. Keep every section heading and eve
55
55
 
56
56
  ## Step 4: fill the template
57
57
 
58
- Walk each section once. Follow `${CLAUDE_SKILL_DIR}/../../standards/markdown.md` for punctuation and word choice throughout: no em dashes, no semicolons, no marketing buzzwords. Use commas or separate sentences instead.
58
+ Walk each section once. Follow `${CLAUDE_SKILL_DIR}/../../standards/markdown.md` for punctuation throughout: no em dashes, no semicolons. Use commas or separate sentences instead. Load the `write-human` skill for word choice, which keeps marketing words out.
59
59
 
60
60
  Mark any cell not traced to a source value by appending ` ? verify` inside the cell value, never as a trailing column. The cell stays inside the table shape: `| #ffffff ? verify |`. A trailing `| ? verify` after the row breaks the parser. A prose section takes its uncertainty inline instead, for example `Proposed 150ms ease-out, not yet confirmed.`, because a trailing tag on a sentence renders raw in the preview.
61
61
 
@@ -15,7 +15,7 @@ The instruction against that already existed. `draft-and-pick` Step 1 says to na
15
15
 
16
16
  The second half is the output itself. A model with no stated direction draws the population average of its training data, which produces interfaces that satisfy every craft rule and still read templated.
17
17
 
18
- Prose is already governed in two halves and design is governed in neither. Banned words ship as data a command reads, and the shapes no closed word set can match needed a skill of their own, because each is a pattern rather than a token. `standards/design.md` governs the shape of a project's design document and is silent on whether its values are any good.
18
+ Prose is already governed in two halves and design is governed in neither. The character bans ship as data a command reads, and the shapes no closed word set can match needed a skill of their own, because each is a pattern rather than a token. `standards/design.md` governs the shape of a project's design document and is silent on whether its values are any good.
19
19
 
20
20
  Importing an external catalog wholesale fails on what those catalogs turn out to carry. The largest is 1,206 lines in one file, pinned to one framework, one styling library and one animation package, and it scopes itself out of dashboards, data tables and multi-step product UI. A second bans default fonts by name and prescribes a component library.
21
21
 
@@ -52,7 +52,7 @@ A rule failing any of the four is recorded as considered and declined rather tha
52
52
 
53
53
  - Name a framework, a styling library, an animation package, a component library or an icon set as a default. A rule that survives only inside one stack is not a taste rule.
54
54
  - Ship a frozen corpus of palettes, font pairings or product examples. A copy becomes a file some sync reconciles forever, and a traced reference is current by construction where a frozen one is not.
55
- - Restate the banned words, characters or spellings, which `markdown.md` states and `canon markdown audit` gates from package data
55
+ - Restate the banned characters, which `markdown.md` states and `canon markdown audit` gates from package data
56
56
  - Express intensity as a numeric scale. A session picks a middle value and reports compliance, which satisfies the rule and decides nothing.
57
57
  - Claim the reported failure is closed. Nothing measures whether a round follows these rules, so this skill states them and the measurement is owed separately.
58
58
  - Duplicate a rule a surface already states for itself, such as slide layout or terminal color, where pointing at that surface is the whole of the correct answer
@@ -7,7 +7,7 @@ description: Rewrites stale `README.md` and `docs/*.md` sections based on change
7
7
 
8
8
  Read these files in parallel:
9
9
 
10
- - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting for all generated text
10
+ - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: punctuation and formatting for all generated text
11
11
  - The `write-human` skill: voice, rhythm, and sentence construction for all generated text
12
12
  - `${CLAUDE_SKILL_DIR}/../../standards/readme.md`: README structure, required sections, and content rules
13
13
  - `${CLAUDE_SKILL_DIR}/../../standards/docs.md`: the reader a page under `docs/` serves, its frontmatter, structure, and what it links out rather than carrying
@@ -12,7 +12,7 @@ A project the surface move has not reached keeps its context folder under `.clau
12
12
  Read these files in parallel:
13
13
 
14
14
  - `${CLAUDE_SKILL_DIR}/../../standards/context.md`: the three questions an entry must answer, its frontmatter, required and expected sections, and what stays out of it
15
- - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting for all generated text
15
+ - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: punctuation and formatting for all generated text
16
16
  - The `write-human` skill: voice, rhythm, and sentence construction for all generated text
17
17
 
18
18
  ## Guards
@@ -10,7 +10,7 @@ Drafts one brand-new `docs/*.md` page end to end: read the standard, decide wher
10
10
  Read these files in parallel:
11
11
 
12
12
  - `${CLAUDE_SKILL_DIR}/../../standards/docs.md`: the reader a page serves, its frontmatter, structure, and what it links out to rather than restates
13
- - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting for all generated text
13
+ - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: punctuation and formatting for all generated text
14
14
  - The `write-human` skill: voice, rhythm, and sentence construction for all generated text
15
15
 
16
16
  ## Guards
@@ -18,7 +18,7 @@ Read these in parallel:
18
18
 
19
19
  - `${CLAUDE_SKILL_DIR}/../../standards/figures.md`: when a figure earns its place, the render-first policy, wrapping and captioning, and the color and accessibility rules
20
20
  - `${CLAUDE_SKILL_DIR}/../../standards/mermaid.md`: direction and layout, node and edge budgets, the accessibility fields, and how a render is verified, for the Mermaid path
21
- - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words and formatting for the caption prose
21
+ - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: formatting for the caption prose
22
22
  - The `write-human` skill: voice and rhythm for the caption prose
23
23
 
24
24
  ## Step 2: does it earn its place
@@ -10,7 +10,7 @@ Drafts a project's `README.md` end to end: read the standard, detect the project
10
10
  Read these files in parallel:
11
11
 
12
12
  - `${CLAUDE_SKILL_DIR}/../../standards/readme.md`: voice, structure, required and optional sections, badge selection, and what to link out to rather than carry. Voice is claimed here for a repository-root README, and `write-human` yields it there while keeping rhythm, density, and the machine-tell catalog everywhere, root README included.
13
- - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting for all generated text
13
+ - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: punctuation and formatting for all generated text
14
14
  - The `write-human` skill: rhythm, density, and sentence construction for all generated text
15
15
 
16
16
  ## Guards
@@ -10,7 +10,7 @@ Drafts one brand-new wiki reference page end to end: read the standard, settle p
10
10
  Read these files in parallel:
11
11
 
12
12
  - `${CLAUDE_SKILL_DIR}/../../standards/wiki.md`: the two placement tests, the frontmatter contract, the naming convention, the sourcing rule, and the page template
13
- - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting for all generated text
13
+ - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: punctuation and formatting for all generated text
14
14
  - The `write-human` skill: voice, rhythm, and sentence construction for all generated text
15
15
 
16
16
  The standard's `## Placement` section names the folder a page lands in and the vendor subfolder under it. Resolve both from the project root and call them `<wiki-root>` and `<vendor>` below, so the body states the rule once and the standard stays the one owner of the path.
@@ -12,7 +12,7 @@ A project the surface move has not reached keeps its wireframes folder under `.c
12
12
  Read these files in parallel:
13
13
 
14
14
  - `${CLAUDE_SKILL_DIR}/../../standards/wireframes.md`: the four questions a wireframe must answer, its frontmatter, the regions list and states table, the exclusions section, the Transcription-wireframes branch, and what moves to a context entry instead
15
- - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting for the prose around the fences
15
+ - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: punctuation and formatting for the prose around the fences
16
16
  - The `write-human` skill: voice, rhythm, and sentence construction for the prose around the fences
17
17
 
18
18
  This skill stays fully independent of `docs-fold`'s wireframe coverage sweep, which only ever writes a bare `TODO` stub for a surface a diff touched and reports drift against one a wireframe already covers. Neither the stub nor the drift check is a draft, and this skill never reads or writes through that mechanism.
@@ -12,7 +12,7 @@ Format an issue from session context following the issue standard, then file it
12
12
  Read these in parallel:
13
13
 
14
14
  - `${CLAUDE_SKILL_DIR}/references/issue.md`: issue title, labels, body sections, and banned phrases
15
- - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting for all generated text
15
+ - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: punctuation and formatting for all generated text
16
16
  - The `write-human` skill: voice, rhythm, and sentence construction for all generated text
17
17
 
18
18
  Then gather repo context in parallel:
@@ -9,7 +9,7 @@ Does not govern:
9
9
  - Pull request title and body: the pull request standard
10
10
  - Whether a phase label may appear in issue text: the versioning standard
11
11
  - Voice, rhythm, and sentence construction in issue prose: the `write-human` skill
12
- - Punctuation, formatting, and banned words in issue prose: the markdown standard
12
+ - Punctuation and formatting in issue prose: the markdown standard
13
13
 
14
14
  ## Title
15
15
 
@@ -12,7 +12,7 @@ Read these files in parallel:
12
12
  - `${CLAUDE_SKILL_DIR}/../../standards/branch.md`: branch format, valid types, and constraints
13
13
  - `${CLAUDE_SKILL_DIR}/../../standards/pr.md`: structure, rules, and banned phrases
14
14
  - `${CLAUDE_SKILL_DIR}/references/labels.md`: label map format, matching, and the missing-label warning. Skip when the project has no `canon/config/pr-labels.toml` and no `.claude/canon/pr-labels.toml`.
15
- - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting for all generated text
15
+ - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: punctuation and formatting for all generated text
16
16
  - The `write-human` skill: voice, rhythm, and sentence construction for all generated text
17
17
  - `${CLAUDE_SKILL_DIR}/../../standards/versioning.md`: phase label vs semver discipline
18
18
 
@@ -8,7 +8,7 @@ description: Groups staged files by concern and generates one conventional commi
8
8
  Read these files in parallel:
9
9
 
10
10
  - `${CLAUDE_SKILL_DIR}/../../standards/commit.md`: format, types, scopes, and constraints
11
- - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting for all generated text
11
+ - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: punctuation and formatting for all generated text
12
12
  - The `write-human` skill: voice, rhythm, and sentence construction for all generated text
13
13
 
14
14
  ## Context
@@ -27,7 +27,7 @@ Read in parallel, skipping any that do not exist:
27
27
  - `CLAUDE.md`: the project's write location and any rule it states over the folder
28
28
  - `.canon/memory/index.md`: existing index, to avoid duplicates
29
29
  - `canon/context/index.md`: the domain catalog Step 3 routes against, read under `.claude/` instead in a project the surface move has not reached
30
- - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: banned words, punctuation, and formatting applied to memory file bodies
30
+ - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: punctuation and formatting applied to memory file bodies
31
31
  - The `write-human` skill: voice, rhythm, and sentence construction applied to memory file bodies
32
32
 
33
33
  ## Step 2: classify candidates
@@ -38,4 +38,4 @@ A restatement also fails in a way a rewrite does not. A run that compresses by d
38
38
  - Drafting or revising a passage, which is `write-human` on a markdown edit
39
39
  - Measuring cadence in finished output, which `canon markdown audit` reports from package data
40
40
  - Rewriting a document into a file, which is a proposal against the source rather than a restatement of it
41
- - The banned words, characters, and spellings, which `markdown.md` states and the audit gates
41
+ - The banned characters, which `markdown.md` states and the audit gates
@@ -107,8 +107,9 @@ the write and the post. Note any `.claude/` docs refreshed as a result of the
107
107
  fixes.
108
108
 
109
109
  The reply is a rendered-for-human GitHub surface, so load the `write-human`
110
- skill for voice, follow `${CLAUDE_SKILL_DIR}/../../standards/markdown.md` for
111
- the banned words, and keep each mapping to a line or two.
110
+ skill for voice and word choice, follow
111
+ `${CLAUDE_SKILL_DIR}/../../standards/markdown.md` for punctuation, and keep each
112
+ mapping to a line or two.
112
113
 
113
114
  Open the body with the `## Review response` heading so it anchors as a section
114
115
  distinct from human threads and stays subordinate to the `## Review` heading the
@@ -244,7 +245,7 @@ Do not merge. Hand back to the orchestrator for re-review.
244
245
 
245
246
  ## Post-review findings
246
247
 
247
- Not everything worth reaching the reviewing session surfaces inside the numbered flow above. A worker that settled a risk, filed a follow-up, or found something else worth reporting after Step 7 already closed the review posts it directly rather than waiting on a review pass that has nothing left to trigger it. Write the body the way Step 6 writes a reply: load `write-human` for voice, follow `${CLAUDE_SKILL_DIR}/../../standards/markdown.md` for the banned words, and run the `${CLAUDE_SKILL_DIR}/../../standards/publish.md` scan before posting with `canon labels scan --body-file .canon/tmp/pr/reply/reply-<number>.md`.
248
+ Not everything worth reaching the reviewing session surfaces inside the numbered flow above. A worker that settled a risk, filed a follow-up, or found something else worth reporting after Step 7 already closed the review posts it directly rather than waiting on a review pass that has nothing left to trigger it. Write the body the way Step 6 writes a reply: load `write-human` for voice and word choice, follow `${CLAUDE_SKILL_DIR}/../../standards/markdown.md` for punctuation, and run the `${CLAUDE_SKILL_DIR}/../../standards/publish.md` scan before posting with `canon labels scan --body-file .canon/tmp/pr/reply/reply-<number>.md`.
248
249
 
249
250
  Open with `## Post-review findings` rather than `## Review response`, since nothing on the thread is being answered. `review-pr` states the full heading set this belongs to and routes it the same as a response: `role-orchestrator`'s poll picks it up and sends the reviewing session back for a pass. Close the body with `🤖 Addressed by Claude Code` on its own line, matching the reply's footer.
250
251
 
@@ -15,6 +15,7 @@ Without this skill, a branch ships on the confidence of the session that wrote i
15
15
  - Resolve the base ref once, preferring the remote over local `main`, and reuse it in the guard and the read
16
16
  - Say when the baseline is unusable and name the narrowed scope, rather than letting a clean summary read as a clean branch
17
17
  - Flag only what will cause incorrect behavior or break a documented rule
18
+ - Apply `canon:review-craft`'s axes and evidence bar, rendered output included, rather than carrying an axis list of its own
18
19
  - Grade every finding, since the caller gates on the counts rather than on the prose
19
20
  - Write the report to disk under a branch-derived slug, so what the ship step reads outlives the session
20
21
 
@@ -59,14 +59,13 @@ Read each file from the changed file list. Skip deleted files. Run reads in para
59
59
 
60
60
  ## Step 4: review and persist
61
61
 
62
+ Invoke `canon:review-craft` before reading the diff for findings, whatever the diff's size. It carries what to look for and the evidence bar, rendered output included, and this step carries no axis list of its own to fall back on. Report it rather than proceeding silently when the skill does not resolve.
63
+
62
64
  Review the full diff and changed file contents for:
63
65
 
64
- 1. Bugs and edge cases
65
- 2. Error handling gaps
66
- 3. Logic flaws that will cause problems when the code is extended
67
- 4. Security issues relevant to the project context
68
- 5. Violations of rules from `.claude/rules/` that apply to the changed files
69
- 6. When the diff touches a file this project ships to a target holding none of its own history: a repository-relative path, a phase label naming a gitignored board, a same-repository pull request or commit reference, or a layout, stack, or config-path claim true of this checkout but stated as if it were general
66
+ 1. Every axis `canon:review-craft` states, held to its evidence bar
67
+ 2. Violations of rules from `.claude/rules/` that apply to the changed files
68
+ 3. When the diff touches a file this project ships to a target holding none of its own history: a repository-relative path, a phase label naming a gitignored board, a same-repository pull request or commit reference, or a layout, stack, or config-path claim true of this checkout but stated as if it were general
70
69
 
71
70
  Use `CLAUDE.md`, `canon/REQUIREMENTS.md`, `canon/ARCHITECTURE.md`, and the auto-loaded `.claude/rules/` as project context to inform what is intentional vs problematic. Do not fix, rewrite, or suggest refactors outside the scope of a finding.
72
71
 
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: review-craft
3
+ description: Why every review needs one stated set of axes and an evidence bar, and where that judgment stops short of the procedures that run a review
4
+ ---
5
+
6
+ # Review craft requirement
7
+
8
+ ## Gap
9
+
10
+ Without this skill, what a review looks for is seven words copied between two procedure bodies: bugs, edge cases, error handling, logic flaws, security. Nothing states design and scope, what breaks in a consumer outside the diff, developer experience, executable prose, a doc the change made stale, which security classes to check, or how much evidence a finding needs before it is reported.
11
+
12
+ The miss is measured. On a seeded branch that deleted a dirty-tree guard while the README two headings below the edited hunk still promised it, two runs of the local review found the removed guard and called the README clean. Security was not the gap: both runs caught the planted injection and the unpinned package under the one-word axis.
13
+
14
+ Rendered output is the larger hole. `git-pr` posts an `## Evidence` comment through `canon pr evidence`, carrying base and head screenshots and a checklist a reviewer ticks. The pull request review named that heading only in its heading set, and no step opened an image. On a seeded pull request whose narrow head screenshot shows the navigation running off the edge while a ticked box claims it collapses, the review filed the finding off the stylesheet diff and said it had not rendered the page. On a styling change with no screenshot at all, on a project whose trunk keeps them, it did not mention the absence.
15
+
16
+ ## Must
17
+
18
+ - Open with the one fact the change's safety rests on, read on a ladder of asserted, pointed at, walked through, tested, and reproduced
19
+ - State the axes in reading order: design and scope, correctness and edge cases, what breaks outside the diff, tests, security, rendered output, developer experience and operations, and executable prose
20
+ - Require every consumer of a changed contract to be listed and checked, and every doc the diff touches to be read whole for a claim the change made false
21
+ - State a design finding as a concrete cost, so it survives the procedure's filter against subjective suggestions
22
+ - Carry the evidence bar: confirm against the file at the reviewed head, quote a cited rule, name the breaking input, and drop what a gate owns or what rests on unread state
23
+ - Carry security as classes with an exclusion list, in a reference loaded when the diff reaches one
24
+ - Open the evidence images on a rendered change through `git show` at the row's own sha, never through the embedded address, within a stated read budget
25
+ - Test each ticked checklist box against an opened image, and name a ticked box no image covers as untested
26
+ - Flag a rendered change that carries no screenshot, as a finding where the trunk already keeps them and as a question elsewhere
27
+ - Read the posted comment rather than running `canon pr evidence`, which compares the local checkout's diff and names the wrong change from a reviewing session not on the branch
28
+
29
+ ## Must not
30
+
31
+ - State a severity or a posting rule. `review-pr` and `review-branch` each own a ladder, and the two define `should-fix` differently.
32
+ - Restate the high-signal filter either procedure carries
33
+ - Name a repository-specific capture layout, width list, or folder. The evidence marker and `canon/wireframes/` are target contracts, and everything else is the project's.
34
+ - Carry a per-surface reference beyond security and rendered output before a measured miss asks for one
35
+
36
+ ## Out of scope
37
+
38
+ - Running a review, reading the diff, posting findings, and grading them: `review-branch` and `review-pr`
39
+ - The high-signal filter and the severity ladder, which stay in each procedure body
40
+ - Which layer a test belongs at: `test-craft`
41
+ - Capturing screenshots or writing the visual checklist: `canon pr evidence` and `ui-checklist`
42
+ - A dispatched reviewer session that loads this skill, which a later trial decides
43
+ - A deliberate full security audit: the built-in `security-review`
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: review-craft
3
+ description: Carries what a code review looks for and how much evidence a finding needs, from design and scope through breakage outside the diff, developer experience, executable prose, stale docs, security classes, and rendered output checked against the screenshots a pull request carries. Use when reviewing a change, when a review procedure loads it for its axes, or when asked "what should a review look for", "what does a good review check", "how sure do I need to be before flagging this", or "did the review look at the screenshots". Do NOT use to run a review, post it, or grade its findings, which is `review-branch` for local work and `review-pr` for a pull request, and do NOT use for a deliberate full security audit, which is the built-in `security-review`.
4
+ ---
5
+
6
+ # Review craft
7
+
8
+ A review with no stated axes reads the changed lines for bugs and stops there. What breaks in a consumer the diff never opened, a doc the change made false a section away from its hunk, or a screenshot showing the opposite of what a ticked box claims all go unread. This skill carries the judgment: what to look for, in what order, and how sure to be before calling it a finding.
9
+
10
+ The procedure that loaded this skill owns everything else: which files to read, the filter that decides what gets reported, the severity ladder, and where the report goes. Nothing here grades a finding or posts one.
11
+
12
+ ## Open with the one fact the change's safety rests on
13
+
14
+ Name the single claim that, if false, makes this change unsafe to merge, then say how far the change proves it. Read the proof on this ladder, weakest first:
15
+
16
+ - **Asserted.** The description or a comment says so.
17
+ - **Pointed at.** It names the code or the test that would show it.
18
+ - **Walked through.** The reasoning traces the path and holds.
19
+ - **Tested.** A test in the diff fails if the claim is false.
20
+ - **Reproduced.** Someone ran it and recorded what happened.
21
+
22
+ A risky claim resting on assertion alone is where the review spends its reading. A trivial one needs no more than asserted.
23
+
24
+ ## Read the axes in this order
25
+
26
+ An axis whose condition the diff meets is not optional. When axis 5 or 6 names a reference and its condition holds, read that reference before moving to the next axis, however clear the diff looks without it.
27
+
28
+ 1. **Design and scope.** Does the change do one thing, is it more complex than the problem needs, and does it build what nobody asked for? State a design finding as a concrete cost, such as a second path nobody calls, a layer with one caller, or a flag no caller passes, never as a preference.
29
+ 2. **Correctness and edge cases.** The empty input, the boundary value, the refused call, the second run, the concurrent run, and the error path a caller actually meets.
30
+ 3. **What breaks outside the diff.** List every consumer of a changed contract, whether a function signature, a file format, a flag, an output shape, or a heading another tool matches, and check the change against each one. Then list each behavior the diff removes or changes, such as a guard, a refusal, a default, or an output, and search every doc the diff touches, in full rather than at the hunk, for a sentence still promising the old behavior. File that sentence as a finding against the doc, quoting it and naming its section, since the doc is what goes wrong for the next reader.
31
+ 4. **Tests.** Hand each test the change adds or edits to `canon:test-craft` and its final filter. Report it rather than proceeding silently when that skill does not resolve.
32
+ 5. **Security.** Read `${CLAUDE_SKILL_DIR}/references/security.md` when the diff runs a command, writes a file, handles input from outside the process, touches a secret, adds a dependency, or changes a default a consumer installs.
33
+ 6. **Rendered output.** Read `${CLAUDE_SKILL_DIR}/references/ui.md` when the diff touches a file that paints, such as markup, a stylesheet, a component, a template, or a design token, or when the pull request carries an evidence comment. A finding read off a stylesheet diff says what the author changed, and only the screenshot says what a user sees, so the reference opens the images and checks whether any exist.
34
+ 7. **Developer experience and operations.** Ports, hooks, scripts, config, and scaffold defaults a consumer installs. A new required step nobody documented, a default that fails on a clean machine, or a hook that slows every commit is a finding even when the code is correct.
35
+ 8. **Executable prose.** A skill body, a rule, or a prompt is instructions a model runs. Read it the way you read code: a step that races another, a precondition it never states, a branch with no exit, and two instructions that contradict each other are bugs.
36
+
37
+ ## Hold every finding to the evidence bar
38
+
39
+ - Confirm each finding against the file at the reviewed head before grading it. A finding read off the diff alone misses the guard three lines outside the hunk.
40
+ - Quote the rule when a finding cites one, with its file, so the author can check the claim without finding the rule first.
41
+ - Name the input or the state that breaks, not only the line. A finding with no failing case is a suspicion.
42
+ - Drop what a linter, a type checker, or a gate in the project already owns. The gate reports it with more certainty than a review can.
43
+ - Drop a finding resting on state you did not read. Say what you would need to read instead.
44
+
45
+ ## What this delegates
46
+
47
+ - Which files a pass reads, the high-signal filter, the severity ladder, and where findings go: `review-branch` for local work and `review-pr` for a pull request
48
+ - Which layer a test belongs at and what makes it good: `test-craft`
49
+ - Writing what a reviewer should look at on a rendered change: `ui-checklist`
50
+ - A deliberate full security audit of a codebase: the built-in `security-review`
@@ -0,0 +1,21 @@
1
+ # Security classes
2
+
3
+ Read each class against the diff. A class the diff does not reach is skipped, not reported as clean. Name the input that reaches the sink and the path it takes, since a class named with no path is a suspicion rather than a finding.
4
+
5
+ ## Classes to check
6
+
7
+ - **Shell and command injection.** A value from an argument, an environment variable, a file, or a network response reaching a shell: through `eval`, an unquoted expansion, a string built into a command, or a subprocess call that takes a single command string. Quoting the variable at the call site is the fix to look for.
8
+ - **Path traversal in a file write.** A path built from outside input and written without being resolved and checked against the directory it must stay inside. A `..` segment, an absolute path, and a symlink inside the target each escape a naive join.
9
+ - **Secrets and personal data leaving the process.** A token, a key, a password, or personal data reaching a log line, an error message, a session transcript, a published page, a pull request comment, or a sync to a remote. Check what a debug line prints and what a verbose flag adds.
10
+ - **Supply chain.** One-shot package execution of an unpinned version, which runs whatever the registry serves that day. A new dependency, and what its install scripts run. A lockfile that changes without a manifest change.
11
+ - **Time of check to time of use on a file write.** An existence or permission check followed by a write to the same path in a later step, and a predictable name in a shared temporary directory. Another process can swap the path in between.
12
+ - **Insecure defaults a consumer installs.** A config, a scaffold, or a seed that turns a check off, opens a port on every interface, grants a broad permission, or ships a placeholder secret. The consumer inherits the default without reading it.
13
+
14
+ ## Excluded
15
+
16
+ Do not report these as security findings. Raise one as a correctness finding only when the diff shows a concrete failing case.
17
+
18
+ - Denial of service, rate limiting, and resource exhaustion
19
+ - Generic input validation with no proven impact
20
+ - Open redirects
21
+ - A theoretical attack needing access the attacker would already need to have
@@ -0,0 +1,72 @@
1
+ # Rendered output
2
+
3
+ A screenshot is the one artifact that shows what a change paints. Reading the markup and the styles tells you what the author meant, and the image tells you what happened. Open the images rather than inferring them from the diff.
4
+
5
+ ## When it applies
6
+
7
+ The diff touches a file that paints: markup, a stylesheet, a component or template, a design token file, a rendered document source, or a path a `canon/wireframes/` surface file names. Or the pull request carries an evidence comment, whatever the diff touches.
8
+
9
+ ## First, check that a screenshot exists
10
+
11
+ Run this before any other section, since a pass that finds nothing to open otherwise reads the stylesheet instead and reports as if it had looked. Read its answer before composing any report or body, never in the same batch as the write, since what it decides is a finding the report has to carry.
12
+
13
+ Read `gh pr view <number> --json comments,headRefOid` and take the comment whose body carries a `<!-- pr-evidence: head=<sha> -->` marker. Match the marker, never the first line, since the body opens with a `**Preview:**` line when the project has a preview address.
14
+
15
+ Flag the change as shipping no screenshot when it paints and the pull request carries no marked comment, carries one with no `## Evidence` section, or carries only a checklist posted alone. Then decide how to raise it by whether the project keeps captures, which is the same test `canon pr evidence` applies:
16
+
17
+ ```bash
18
+ git ls-tree -r --name-only <base> | grep -E '(^|/)evidence/.*\.(png|jpe?g|gif|webp|avif|svg)$' | head -1
19
+ ```
20
+
21
+ - A path prints: the project keeps captures and this change skipped them. File it as a finding against the pull request.
22
+ - Nothing prints: raise it as a question with no severity, since a project with no capture harness would otherwise take the flag on every styling change.
23
+
24
+ Stop reading this reference once the flag is raised, since there is nothing to open. Otherwise continue with the comment in hand.
25
+
26
+ ## Reading the comment
27
+
28
+ Compare the marker's head with `headRefOid`. When it trails, the images describe an older head. Name which later commits touched a painting file, and read the images as evidence about that older head only.
29
+
30
+ ## Opening the images
31
+
32
+ Each row embeds `github.com/<repo>/blob/<sha>/<path>?raw=true`. A session cannot fetch that address from a private repository, so never follow it and never report an image you did not open. Fetch the head instead:
33
+
34
+ ```bash
35
+ git fetch -q origin pull/<number>/head
36
+ mkdir -p .canon/tmp/pr/review/evidence/<number>
37
+ git show <sha>:<path> > .canon/tmp/pr/review/evidence/<number>/<side>-<name>.png
38
+ ```
39
+
40
+ Take the sha from the row, so the base and head sides are exactly what the comment shows. Then open each file with the file-reading tool. A `*(new)*` base cell has no before image.
41
+
42
+ ## How many to open
43
+
44
+ Open at most 12 images per pass, filled in this order:
45
+
46
+ 1. Every image a ticked checklist box or the `Seen at:` line names
47
+ 2. The head side of each state at its narrowest and widest captured width, in one theme
48
+ 3. The base side, only for a state whose head image looks wrong or whose diff was meant to change appearance
49
+
50
+ A second theme earns a read only when the diff touches a color token. Name the states left unopened on one line, as a note rather than a finding, so the reader knows what the pass did not see.
51
+
52
+ ## Comparing
53
+
54
+ Read `canon/wireframes/index.md` and open only the surface files the evidence states map to. Check each opened image for the layout, the order of regions, and the behavior at that width the surface file states. Check `canon/DESIGN.md` for the tokens the image makes visible: color, type scale, spacing, and component rules.
55
+
56
+ Read the width and theme from whatever the image path carries, and fix no width list, since which widths matter belongs to the project. Skip a comparison silently when the project has no wireframe or design file.
57
+
58
+ A finding names the wireframe or design-file line the image breaks, never a taste.
59
+
60
+ ## The checklist
61
+
62
+ The `## What to look at` block between the `pr-checklist` markers is the author's claim about what was verified.
63
+
64
+ - Test each ticked box against an opened image showing the state and width it names. Flag a box whose image contradicts it, quoting the box.
65
+ - A ticked box no image covers is untested rather than confirmed, and the finding says so.
66
+ - Read the `**Widths:**` block's `Seen at:` line against the widths the images carry.
67
+ - Test only the rows the current comment shows. A box ticked on an earlier head can describe images the comment no longer carries.
68
+ - Leave unchecked boxes to the procedure's own read of the description.
69
+
70
+ ## With no pull request
71
+
72
+ A local review has no comment to read. Read each changed image under an `evidence/` path segment from the working tree, and its base side with `git show <base>:<path>`. Read the checklist handoff at `.canon/tmp/handoff/ui-checklist/<slug>.md` at the main worktree root when it exists. A painting change with no changed evidence image takes the flag from the first section, decided by the same `git ls-tree` test.
@@ -22,6 +22,7 @@ Scoping a later pass off GitHub's review stamp skipped real work. On 2026-09-07
22
22
  - Detect the pass from the thread rather than taking it from the caller, matching the heading for equality so a neighboring comment cannot be read as a prior pass
23
23
  - Scope a later pass to the commits added since the prior one, once that commit is confirmed to still reach the head
24
24
  - Apply the integration, contract, and consumer lenses a self-review structurally cannot
25
+ - Apply `canon:review-craft`'s axes and evidence bar, rendered output included, rather than carrying an axis list of its own
25
26
  - Read each test the branch added or changed against `canon:test-craft`'s final filter, scoped to those files and never the suite
26
27
  - Post the closing pass even with nothing to report, since a review left unanswered reads as one nobody closed
27
28
  - State a withdrawal or a regrade on the thread with the fact that settled it, since a finding dropped in silence reads the same as one nobody answered
@@ -63,7 +63,7 @@ Read `${CLAUDE_SKILL_DIR}/references/scope.md` for finding the commit and verdic
63
63
 
64
64
  ## Step 3: review
65
65
 
66
- Review the diff and files for the same axes as `review-branch` (bugs, edge cases, error handling, logic flaws, security, rule violations, checkout assumptions in a shipped file), then add the three lenses a self-review structurally cannot apply:
66
+ Invoke `canon:review-craft` with the skill tool now, and read nothing for findings until it has loaded, whatever the diff's size. It carries what to look for and how much evidence a finding needs, rendered output included, and this step carries no axis list of its own to fall back on. Read the diff and files against its axes. Add the two that stay here: rule violations, and checkout assumptions in a shipped file. Report it rather than proceeding silently when the skill does not resolve. Then add the three lenses a self-review structurally cannot apply:
67
67
 
68
68
  - Integration: does this fit the board's order, the shared wiring seam, and any sibling PR in flight?
69
69
  - Contract: does a contract downstream features depend on land correctly, and should the plan itself be questioned?
@@ -13,7 +13,7 @@ Derive both segments from Step 1. Never pick a suffix by hand, and never reuse a
13
13
 
14
14
  When `<prior-oid>` from Step 2 equals `headRefOid`, the head repeats and the folder already holds `body-<number>-<short-sha>.md`. Add a third segment taking the id of the reply Step 2 resolved, giving `body-<number>-<short-sha>-r<comment-id>.md`, which is `<body-file>` on that path. That satisfies both prohibitions above rather than carving an exception into either. Step 2 already stopped the pass when that resolution came back empty, so reaching this line means the comment id is in hand.
15
15
 
16
- The comment is a rendered-for-human GitHub surface, so load the `write-human` skill for voice and follow `${CLAUDE_SKILL_DIR}/../../standards/markdown.md` for the banned words: cut editorializing, and keep every sentence load-bearing. Match this shape on a first pass:
16
+ The comment is a rendered-for-human GitHub surface, so load the `write-human` skill for voice and word choice and follow `${CLAUDE_SKILL_DIR}/../../standards/markdown.md` for punctuation: cut editorializing, and keep every sentence load-bearing. Match this shape on a first pass:
17
17
 
18
18
  ```markdown
19
19
  ## Review
@@ -41,7 +41,7 @@ confident merge order off a partial picture. Which rows collide, what merges
41
41
  before what, and whether a row should run at all stay with the controlling
42
42
  session, and no body states that boundary for the planning side.
43
43
 
44
- Nothing scans a plan for banned words either. `.gitignore` ignores
44
+ Nothing scans a plan for ban hits either. `.gitignore` ignores
45
45
  `.canon/plans/`, and the audit's default path set is what git lists, so no gate
46
46
  ever opens one. Six ban hits landed across the four trial plans and three of the
47
47
  four carried at least one, caught only because the planner ran
@@ -75,7 +75,7 @@ For each changed file, audit against every rule:
75
75
  - **Pattern rules**: grep the file for every token the standard bans. Grep is authoritative. Reading alone misses occurrences.
76
76
  - **Judgment rules**: check each rule in context against the standard that states it.
77
77
 
78
- Every changed markdown file gets the pattern pass, since `${CLAUDE_SKILL_DIR}/../../standards/markdown.md` applies to all of them. Take the banned tokens from that standard at read time rather than from a list held here. It carries the banned words, the banned spellings, and the banned characters together, so one read covers every token this pass greps for.
78
+ Every changed markdown file gets the pattern pass, since `${CLAUDE_SKILL_DIR}/../../standards/markdown.md` applies to all of them. Take the banned tokens from that standard at read time rather than from a list held here. It carries the banned characters, so one read covers every token this pass greps for.
79
79
 
80
80
  ## Step 4: report
81
81