@erclx/aitk 0.52.0 → 0.54.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 (45) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/claude-design-extract/SKILL.md +2 -1
  3. package/claude/skills/claude-docs/SKILL.md +1 -1
  4. package/claude/skills/claude-groundwork/SKILL.md +1 -0
  5. package/claude/skills/claude-intake/REQUIREMENT.md +46 -0
  6. package/claude/skills/claude-intake/SKILL.md +139 -0
  7. package/claude/skills/claude-intake/references/folder-format.md +97 -0
  8. package/claude/skills/claude-memory-capture/SKILL.md +2 -1
  9. package/claude/skills/claude-standards-audit/SKILL.md +5 -3
  10. package/claude/skills/create-skill/SKILL.md +2 -1
  11. package/claude/skills/create-snippet/SKILL.md +3 -2
  12. package/claude/skills/create-snippet/references/snippets.md +2 -1
  13. package/claude/skills/create-standard/SKILL.md +2 -1
  14. package/claude/skills/docs-sync/SKILL.md +2 -1
  15. package/claude/skills/git-issue/SKILL.md +2 -1
  16. package/claude/skills/git-issue/references/issue.md +2 -1
  17. package/claude/skills/git-pr/SKILL.md +2 -1
  18. package/claude/skills/git-pr/references/pr.md +2 -1
  19. package/claude/skills/git-split/references/pr.md +2 -1
  20. package/claude/skills/git-stage/SKILL.md +2 -1
  21. package/docs/agents/index.md +1 -1
  22. package/docs/agents/output-shape.md +9 -1
  23. package/docs/agents/overview.md +1 -1
  24. package/docs/ai-workflow.md +2 -0
  25. package/governance/rules/claude/500-prose.md +4 -3
  26. package/governance/rules/claude/501-markdown.md +13 -0
  27. package/governance/stacks/base.toml +1 -1
  28. package/package.json +1 -1
  29. package/scripts/core/install-check.sh +1 -1
  30. package/src/comments/vocabulary.ts +1 -1
  31. package/standards/bundled/issue.md +2 -1
  32. package/standards/bundled/pr.md +2 -1
  33. package/standards/bundled/snippets.md +2 -1
  34. package/standards/diagrams.md +4 -3
  35. package/standards/index.md +2 -1
  36. package/standards/markdown.md +72 -0
  37. package/standards/prose.md +6 -57
  38. package/standards/publish.md +3 -2
  39. package/standards/readme.md +3 -2
  40. package/standards/rule.md +8 -0
  41. package/standards/skill.md +10 -1
  42. package/standards/standard.md +2 -1
  43. package/standards/versioning.md +2 -1
  44. package/standards/wireframes.md +3 -2
  45. package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +5 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "aitk",
3
3
  "description": "Automated governance, versioning, and discovery tools for Claude Code.",
4
- "version": "0.52.0",
4
+ "version": "0.54.0",
5
5
  "author": {
6
6
  "name": "Eric Le",
7
7
  "url": "https://github.com/erclx"
@@ -33,6 +33,7 @@ Read these from the project root on both paths, skipping any that do not exist:
33
33
  - `CLAUDE.md`: voice, personality, spelling rules
34
34
  - `.claude/REQUIREMENTS.md`: the `## Personality` paragraph, worldview, non-goals
35
35
  - `.claude/standards/prose.md`: tone constraints
36
+ - `.claude/standards/markdown.md`: punctuation and formatting constraints
36
37
 
37
38
  Read a standard from `${CLAUDE_SKILL_DIR}/../../standards/` instead when the project does not have it.
38
39
 
@@ -54,7 +55,7 @@ Use the returned content as the target shape. Keep every section heading and eve
54
55
 
55
56
  ## Step 4: fill the template
56
57
 
57
- Walk each section once. Follow `.claude/standards/prose.md` throughout: no em dashes, no semicolons, no marketing buzzwords. Use commas or separate sentences instead.
58
+ Walk each section once. Follow `.claude/standards/markdown.md` for punctuation and `.claude/standards/prose.md` for word choice throughout: no em dashes, no semicolons, no marketing buzzwords. Use commas or separate sentences instead.
58
59
 
59
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.
60
61
 
@@ -97,7 +97,7 @@ For each doc with relevant changes, apply updates following these rules. Read a
97
97
 
98
98
  - Update only the sections affected by session decisions.
99
99
  - Do not rewrite sections unrelated to what changed.
100
- - Follow `.claude/standards/prose.md` for all edits.
100
+ - Follow `.claude/standards/prose.md` and `.claude/standards/markdown.md` for all edits.
101
101
 
102
102
  Write each updated file immediately. Claude Code's tool permission dialog is the confirmation gate. Do not wait for user input.
103
103
 
@@ -14,6 +14,7 @@ Read `${CLAUDE_SKILL_DIR}/references/folder-format.md` before writing any file i
14
14
  - If no topic is given, stop: `❌ No topic. Name what needs measuring.`
15
15
  - Apply the qualifying test in open mode alone, after Step 1 resolves the mode and before the folder is created. Two of these three must hold: the current state is not known, more than one approach is live, and committing wrong costs more than a day of measuring. When one or fewer holds, stop: `❌ Already decided enough to plan. Run /claude-feature instead.`
16
16
  - Resume and close are exempt from the test above. A track that has already been measured fails it by definition, since its current state is now known and its approaches have narrowed, so applying the test to either mode refuses the folder that same test admitted.
17
+ - A refused topic that is a broad dump rather than one question routes to `claude-intake`, not to the planning skill the stop names. Intake dispositions many findings in breadth from what the repository already holds, and one folder holding dozens of unrelated threads is what forcing them past this guard produces.
17
18
  - Do not pause for approval between steps. The write scope below is what makes that safe.
18
19
 
19
20
  ## Write scope
@@ -0,0 +1,46 @@
1
+ ---
2
+ name: claude-intake
3
+ description: Why a brain dump gets a filed inventory rather than ten plans, and why an empty operator slot means unread
4
+ ---
5
+
6
+ # Claude intake requirement
7
+
8
+ ## Gap
9
+
10
+ Without this skill, a brain dump reaches a session that has nowhere to put it. `claude-feature` answers with one plan per independent concern, so forty findings produce ten plan files before anything has been measured. `claude-groundwork` refuses a breadth pass outright, since its qualifying test asks whether the current state is unknown and most items are knowable by grep. What gets filed instead is a list of opinions, because nothing forces a count against the tree and a complaint reads the same whether it covers three sites or three hundred.
11
+
12
+ Two failure modes cost more than the rest. An operator's silence on an item reads as consent when the folder borrows the plan file's blank-means-accept contract, which ships changes nobody approved across a folder read over weeks. And a report naming only a path cannot distinguish three new items from one reworded sentence in a file that holds a dozen items, so every reader diffs it against memory to find out what moved.
13
+
14
+ Four more are cheaper to name than to rediscover. A question filed without a pick comes back unresolved, measured across one folder's 19 open items, where every one carrying a suggestion resolved on a bare `ok` and the five carrying none did not. A session with no numbering convention re-decides the folder shape per dump, so no two intakes are readable the same way and the second one has to be learned from scratch. A question answerable both in the index and on its item resolves to whichever a reader opens first, with no rule saying which wins. And a pass with no write scope starts fixing what it files, which turns a triage into a branch nobody asked for and nobody reviewed.
15
+
16
+ ## Must
17
+
18
+ - Route each item on whether the repository can answer it today, sending what needs an experiment or an outside source to the groundwork skill and what is already decided to the planning skill
19
+ - Measure every problem line against the tree during this pass, carrying a number or a file path rather than a figure from recall
20
+ - Close every item with a verdict, and pair every open question with a suggested pick
21
+ - Treat an empty operator slot as unread rather than as agreement
22
+ - Reserve the index number and carry the domain in every other filename, leaving the rest of the numbering as read order
23
+ - Keep answers on items alone, with the index pointing at them
24
+ - Name the heading and the act beside every path the pass wrote
25
+ - Confine writes to the intake folder
26
+
27
+ ## Must not
28
+
29
+ - Write a plan, a task file, a standard, a rule, or a source change
30
+ - Fill an operator's answer slot, or infer a disposition from an empty one
31
+ - Replace a verdict with an overlap line, which drops the call on exactly the items where a live board task might be the thing that is wrong
32
+ - Reserve mid-range numbers, which would force every future intake into one dump's shape
33
+ - Date every file, since the first edit to one leaves the rest stale
34
+ - Open a folder for a single question, which is either a groundwork track or a plan
35
+
36
+ ## Guards
37
+
38
+ - No dump given: stop rather than inferring one
39
+ - One question rather than a set of findings: stop and route to the groundwork or planning skill
40
+
41
+ ## Out of scope
42
+
43
+ - Measuring one question in depth, which `claude-groundwork` owns
44
+ - Planning a promoted item, which `claude-feature` owns
45
+ - Promoting an item onto the board, which `claude-tasks` owns
46
+ - Enforcing any of this. The folder is gitignored, so no check reaches its contents and every rule holds only while a session reads it.
@@ -0,0 +1,139 @@
1
+ ---
2
+ name: claude-intake
3
+ description: Files a raw brain dump into a numbered intake folder under `.claude/intake/<slug>/`, one item per finding carrying a measured problem, a proposed fix, and a verdict. Use when asked to "file this dump", "triage my notes", "work through this list", "sort out this brain dump", or "run an intake pass". Do NOT use for one question that has to be measured before anyone can plan it. That is `claude-groundwork`.
4
+ ---
5
+
6
+ # Claude intake
7
+
8
+ Intake dispositions many findings in breadth. A dump goes in, an inventory comes out, and every item carries a problem measured against the tree, one proposed fix, and a verdict. The item that turns out to be already settled is the highest-value output, and it is the one thing neither a plan nor a groundwork track has anywhere to put.
9
+
10
+ Read `${CLAUDE_SKILL_DIR}/references/folder-format.md` before writing any file in the folder. It holds the numbering, the file map, the frontmatter, and the item template.
11
+
12
+ ## Routing
13
+
14
+ The test is one question. Can the item be answered by reading the repository today?
15
+
16
+ - Yes: intake owns it, and the cost is a session of grepping
17
+ - No, because it needs an experiment or a source outside the project: route it to `claude-groundwork`, where the cost is measured in runs and days
18
+ - Already decided, with only the work left: route it to `claude-feature`
19
+
20
+ Apply the test per item rather than per dump. A dump of forty items typically yields one groundwork candidate, so routing the whole dump on its worst item buys a folder nobody can close.
21
+
22
+ Using the wrong one fails in two shapes. Intake on a question that needs measuring yields a confident verdict with nothing behind it. Groundwork on a brain dump is refused by its own qualifying guard, and forcing past that refusal gives one folder holding dozens of unrelated threads and a decision file that can close one of them.
23
+
24
+ ## Guards
25
+
26
+ - If no dump is given, stop: `❌ No dump to file. Paste the notes or name what to triage.`
27
+ - If the dump is one question rather than a set of findings, stop: `❌ One question, not a dump. Run /claude-groundwork to measure it or /claude-feature to plan it.`
28
+ - Do not pause for approval between steps. The write scope below is what makes that safe.
29
+
30
+ ## Write scope
31
+
32
+ - Write only inside `.claude/intake/<slug>/`. A plan file, a task file, a source change, a standard, and a rule all live outside that folder, so this one rule forbids every one of them.
33
+ - There is no exception. Promoting an item onto the board runs through `claude-tasks` after the operator has answered, which is a separate invocation.
34
+ - Reading is unrestricted inside the project. Measuring is the work.
35
+ - Treat the folder as gitignored and unbacked. No check reaches its contents, so every rule stated here holds only while a session reads it.
36
+
37
+ Nothing outside this body carries the floor, and no path-scoped rule can. The item format and the answer contract are heading for a standard covering this folder and a groundwork track together, which is queued rather than written.
38
+
39
+ ## Step 1: detect open or resume
40
+
41
+ List `.claude/intake/` from the project root and match the topic against the folders already there before deriving a slug. A second pass over the same subject rarely phrases the topic the way the folder was named, so a fresh slug would open a duplicate beside a live folder.
42
+
43
+ Never match against `.claude/` itself. That directory holds every other workflow surface, so a topic matched there lands on a folder that was never an intake.
44
+
45
+ With no match, derive a kebab-case slug named for the subject rather than the activity. Prefer `toolkit-overview` over `august-triage`. An absent folder opens, and a present one resumes by appending items and revising verdicts the tree has moved under.
46
+
47
+ ## Step 2: orient
48
+
49
+ Read these in parallel from the project root, skipping any that do not exist:
50
+
51
+ - `CLAUDE.md`: behavior rules, conventions, commands
52
+ - `.claude/REQUIREMENTS.md`: scope and non-goals
53
+ - `.claude/ARCHITECTURE.md`: decisions already made
54
+ - `.claude/tasks/index.md`: what is already tracked. Open a task file whose entry looks related to an item.
55
+
56
+ Then read only what a live item needs. Do not read entire directories speculatively. Where a folder carries an `index.md`, read it first and load only the files it points at.
57
+
58
+ ## Step 3: measure against the tree
59
+
60
+ Grep for each construct an item names and count the sites. Every problem line carries a number or a file path taken during this pass.
61
+
62
+ Never carry a figure from an earlier session, a summary, or another document. The dump states the complaint and the tree states the size of it, and that measurement is the whole difference between an inventory and a list of opinions. Confirm that any work an item sequences behind is still open, so no item leads with something that already shipped.
63
+
64
+ Name the commit the pass measured against in the overview body. It is the half a later reader can check.
65
+
66
+ ## Step 4: cluster
67
+
68
+ Split items by domain, one file per cluster, and let the file count follow the number of separable domains rather than the size of the dump. An item belongs to the domain its fix touches, not the domain the complaint arrived from.
69
+
70
+ Two heading levels is the right depth. A third means the cluster should have been split into its own file.
71
+
72
+ ## Step 5: disposition each item
73
+
74
+ Write every item in the format below, in the cluster file its fix belongs to. Close each item with a verdict and an empty operator slot.
75
+
76
+ ## Step 6: write the index
77
+
78
+ Write `00-overview.md` last, once the clusters are filed and the counts are real. It carries the format block, the cluster table, the verdict counts, the ready list, and the open questions.
79
+
80
+ Each open question in the index is a labeled markdown link to its owning item's heading anchor. The index points and the item owns, so no answer slot appears in the index. One question in two answerable places has no rule for which wins, and retrieval walks item headings, so an answer typed into the index is found by nothing and lost silently.
81
+
82
+ Add `99-next-session.md` only where the pass ends holding context no cluster file carries, such as a dump half filed or a measurement that has to be redone. Write it self-contained, since the folder is unbacked and the conversation behind it compacts away.
83
+
84
+ ## Item format
85
+
86
+ ```markdown
87
+ ### N. Short title stating the defect
88
+
89
+ - **Problem:** what is wrong today, stated against the tree and carrying a number or a file path
90
+ - **Fix:** the one change proposed
91
+ - **Worth it:** yes, later, or no, with the reason
92
+ - **Open:** only where the call is the operator's
93
+ - **Suggested:** the pick in one sentence, then the reason and the main tradeoff in one or two
94
+ - **Overlaps:** the live board task that already owns this item
95
+ - **You:**
96
+ ```
97
+
98
+ - `Problem:`, `Fix:`, `Worth it:`, and the empty `You:` slot ship on every item. The other two are conditional.
99
+ - `Suggested:` is required whenever `Open:` is present. A bare question invites a bare answer, and `ok` against two defensible options carries no information. Where the answer is the operator's preference rather than a technical call, say so in that form rather than inventing a default. The toolkit's `decision-help` snippet writes the same four-line shape for chat use, and the four lines above are the whole spec.
100
+ - `Overlaps:` never replaces `Worth it:`. The items where a live board task might be the thing that is wrong are exactly the ones whose verdict matters most.
101
+
102
+ ## The answer contract
103
+
104
+ `You:` belongs to the operator and ships empty on every item.
105
+
106
+ Empty means unread. It never means agreement. Accepting a verdict is typed as one token, `- **You:** ok`.
107
+
108
+ That inverts the plan file's contract, where a blank `- Answer:` means accept the suggestion, and the inversion is deliberate. A plan is read in one sitting with every question already surfaced in chat. An intake folder is read over weeks, so an empty slot is ambiguous between accepting the verdict and never having reached the item, and the second reading is far more likely. Acting on silence as consent ships a change nobody approved.
109
+
110
+ Never fill a `You:` slot, and never infer a disposition from an empty one. On a resume pass, report unread items by count rather than deciding them.
111
+
112
+ ## Numbering
113
+
114
+ Numbers are read order and nothing else. Reserve `00` for the index and carry the domain in every other filename, so `07-tooling.md` says what it holds before anyone opens it.
115
+
116
+ Do not reserve mid-range numbers. Clusters differ per dump, so a contract over `06` would force every future intake into one dump's shape. `claude-groundwork` reserves its numbers because its shape is fixed, and that half of the convention does not transfer.
117
+
118
+ ## Output
119
+
120
+ Emit the full relative path from the project root for every file written, and name the heading and the act beside it. A path alone cannot distinguish three new items from one reworded sentence in a file that holds a dozen items and lives for weeks, so a bare path sends the reader to diff it against memory. This overrides the paths-only reporting the project states generally, which stays right wherever the reader is about to see a diff.
121
+
122
+ A file the pass only read gets no line, which is what keeps the block short.
123
+
124
+ ```plaintext
125
+ 📂 Opened .claude/intake/<slug>/
126
+
127
+ **Filed:**
128
+
129
+ - `.claude/intake/<slug>/05-coverage.md` gains items 6 to 8 under a new `## What the merge gate covers`
130
+ - `.claude/intake/<slug>/00-overview.md` cluster rows and verdict counts updated
131
+
132
+ **Routing:** <N> plan-ready, <N> groundwork candidates, <N> already settled
133
+
134
+ **Open questions:** <N> awaiting your call
135
+
136
+ Next: answer the `You:` slots, then /claude-tasks to promote what is ready
137
+ ```
138
+
139
+ Use `📂 Resumed` in place of `📂 Opened` on a resume pass.
@@ -0,0 +1,97 @@
1
+ ---
2
+ title: Intake folder reference
3
+ description: Reserved index number, file map, frontmatter and dating, the item template, retrieval, and anti-patterns
4
+ ---
5
+
6
+ # Intake folder reference
7
+
8
+ Applies to an intake folder at `.claude/intake/<slug>/`. One folder holds one dump, filed by domain, and every finding in it is an item carrying a measured problem and a verdict.
9
+
10
+ The folder is gitignored and unbacked. No check reaches its contents, so the shape below survives only by being read.
11
+
12
+ ## Files
13
+
14
+ | File | Holds | Required |
15
+ | -------------------- | ------------------------------------------------------------ | -------- |
16
+ | `00-overview.md` | Index: format block, cluster table, verdicts, open questions | Always |
17
+ | `NN-<domain>.md` | One cluster of items, filed by the domain their fixes touch | Always |
18
+ | `99-next-session.md` | What a compaction destroys that no cluster file carries | Optional |
19
+
20
+ `00` is the only reserved number. Everything else is read order, and the domain rides in the filename so a reader knows what `07-tooling.md` holds without opening it.
21
+
22
+ Do not reserve mid-range numbers. Clusters differ per dump, so a contract over `06` would force every future intake into one dump's shape. Groundwork reserves its numbers because its shape is fixed, and that half of the convention does not transfer.
23
+
24
+ Let the file count follow the number of separable domains. A large dump with two domains is a small folder.
25
+
26
+ ## Frontmatter and dating
27
+
28
+ Every file carries `title` and `description` per the project's prose standard. `00-overview.md` carries one field the others do not, a `date` holding the day the folder opened.
29
+
30
+ Date the folder once rather than every file. Twelve dated files leave eleven stale the first time one cluster is edited, and the opening date never rots. The checkable half is the commit, which the overview body names as what the claims were measured against.
31
+
32
+ ## 00-overview.md
33
+
34
+ The index. It points at items and answers nothing itself.
35
+
36
+ - The item format block, copied so a returning session picks the shape up from the folder
37
+ - The answer contract stated out loud, since it inverts the plan file's
38
+ - A cluster table of file, what it holds, item count, and open count
39
+ - The verdict counts across the folder
40
+ - A ready list, grouped by what shipping one actually costs
41
+ - The open questions, each a labeled markdown link to its owning item's heading anchor
42
+
43
+ The index carries no answer slot. One question in two answerable places has no rule for which wins, and retrieval walks item headings, so an answer typed into the index is found by nothing and lost silently.
44
+
45
+ Where an item touches a task already on the board, say so in the index rather than only inside the item. A reader deciding what to promote reads the index first.
46
+
47
+ ## Item template
48
+
49
+ ```markdown
50
+ ### N. Short title stating the defect
51
+
52
+ - **Problem:** what is wrong today, stated against the tree and carrying a number or a file path
53
+ - **Fix:** the one change proposed
54
+ - **Worth it:** yes, later, or no, with the reason
55
+ - **Open:** only where the call is the operator's
56
+ - **Suggested:** the pick in one sentence, then the reason and the main tradeoff in one or two
57
+ - **Overlaps:** the live board task that already owns this item
58
+ - **You:**
59
+ ```
60
+
61
+ `Problem:`, `Fix:`, `Worth it:`, and the empty `You:` slot ship on every item. `Open:` appears only where the call is the operator's, `Suggested:` is required whenever it does, and `Overlaps:` is optional and never replaces the verdict.
62
+
63
+ Two heading levels is the right depth inside a cluster file. A third means the cluster should have been its own file.
64
+
65
+ An item may carry a bolded standalone line between the bullets where a finding needs a name of its own. Keep it rare. Everything that fits the four bullets belongs in them.
66
+
67
+ ## Retrieval
68
+
69
+ Answers live on items, so one pass over the folder reports every touched slot.
70
+
71
+ ```bash
72
+ awk '/^### /{h=FILENAME": "$0} /^- \*\*You:\*\*./{print h; print " "$0}' *.md
73
+ ```
74
+
75
+ Counting what is still unread runs against the empty slot instead.
76
+
77
+ ```bash
78
+ grep -c '^- \*\*You:\*\*$' *.md
79
+ ```
80
+
81
+ Both walk `###` headings, which is the mechanical reason an answer typed anywhere else is lost.
82
+
83
+ ## Conventions
84
+
85
+ - State a number with what it settles. The strongest items are the ones where a measurement decides the verdict and says so.
86
+ - File an item under the domain its fix touches, not the domain the complaint arrived from.
87
+ - Name a live board task an item overlaps, and keep the verdict beside it.
88
+ - Revise a verdict the tree has moved under rather than appending a second one narrating the change.
89
+ - Report unread items by count on a resume pass. Never decide one.
90
+
91
+ ## Anti-patterns
92
+
93
+ - **Silence read as consent.** An empty slot on a folder read over weeks means nobody reached the item, and treating it as acceptance ships a change nobody approved.
94
+ - **A verdict with nothing behind it.** An item whose problem line carries no number is an opinion, and it reads exactly like the ones that were measured.
95
+ - **The overlap that ate the verdict.** Replacing `Worth it:` with `Overlaps:` drops the call on the items most likely to change what a live task should do.
96
+ - **A question in two places.** An open question answerable in the index and on the item resolves to whichever a reader happens to open.
97
+ - **The dump filed as one concern.** Forty findings under one heading is a folder nobody can promote from, and the split by domain is what makes each item liftable on its own.
@@ -23,7 +23,8 @@ Read in parallel from the project root, skipping any that do not exist:
23
23
  - `CLAUDE.md`: Memory section rules, including save thresholds and file format overrides
24
24
  - `.claude/memory/index.md`: existing index, to avoid duplicates
25
25
  - `.claude/context/index.md`: the domain catalog Step 3 routes against
26
- - `.claude/standards/prose.md`: prose conventions applied to memory file bodies
26
+ - `.claude/standards/prose.md`: voice and banned words applied to memory file bodies
27
+ - `.claude/standards/markdown.md`: punctuation and formatting applied to memory file bodies
27
28
 
28
29
  Read a standard from `${CLAUDE_SKILL_DIR}/../../standards/` instead when the project does not have it.
29
30
 
@@ -9,6 +9,7 @@ description: Audits changed markdown files against every authoring standard that
9
9
 
10
10
  - Resolve the base ref first, per Diff baseline below, then scope the file list exactly as Step 1 does, fallback included. If no markdown files changed, stop: `✅ No markdown changes to audit.` A guard that reads bare local `main`, or that skips the unusable-baseline fallback, passes the skill clean on a branch it never read.
11
11
  - If neither `.claude/standards/prose.md` nor `${CLAUDE_SKILL_DIR}/../../standards/prose.md` is present, stop: `❌ prose.md standard not found. Install toolkit standards first.` Test the file rather than the directory, since a project that installed standards before a given file existed keeps the directory without ever receiving that file.
12
+ - Apply the same test to `markdown.md`, stopping with its own name. It carries the character bans and the formatting rules, so a run reaching only `prose.md` reports word choice against a clean file and calls the pass complete.
12
13
 
13
14
  ## Diff baseline
14
15
 
@@ -72,7 +73,7 @@ Read each applicable standard once. For each changed file, audit against every r
72
73
  - **Pattern rules**: grep the file for every token the standard bans. Grep is authoritative. Reading alone misses occurrences.
73
74
  - **Judgment rules**: check each rule in context against the standard that states it.
74
75
 
75
- Every changed markdown file gets the prose pattern pass, since `.claude/standards/prose.md` applies to all of them. Take the banned tokens from that standard at read time rather than from a list held here.
76
+ Every changed markdown file gets the prose pattern pass, since `.claude/standards/prose.md` and `.claude/standards/markdown.md` both apply to all of them. Take the banned tokens from those standards at read time rather than from a list held here. The banned words sit in the first and the banned characters in the second, so a pass reading one file finds half the tokens.
76
77
 
77
78
  ## Step 4: report
78
79
 
@@ -81,8 +82,9 @@ Group findings by file with line references, naming the standard each one comes
81
82
  ```markdown
82
83
  path/to/file.md
83
84
 
84
- - L12: `prose.md`, em dash in prose
85
- - L34: `prose.md`, semicolon used to join clauses
85
+ - L12: `markdown.md`, em dash in prose
86
+ - L34: `markdown.md`, semicolon used to join clauses
87
+ - L51: `prose.md`, vague qualifier `simply`
86
88
  - L67: `context.md`, decision entry names no rejected alternative
87
89
  ```
88
90
 
@@ -9,7 +9,8 @@ disable-model-invocation: true
9
9
  Read these files from the project root in parallel:
10
10
 
11
11
  - `.claude/standards/skill.md`: skill structure, skill types, frontmatter fields, invocation rules
12
- - `.claude/standards/prose.md`: prose conventions for skill body text
12
+ - `.claude/standards/prose.md`: voice and banned words for skill body text
13
+ - `.claude/standards/markdown.md`: punctuation and formatting for skill body text
13
14
 
14
15
  Read a standard from `${CLAUDE_SKILL_DIR}/../../standards/` instead when the project does not have it.
15
16
 
@@ -7,10 +7,11 @@ 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/standards/prose.md` from the project root: prose conventions for all generated text
10
+ - `.claude/standards/prose.md` from the project root: voice and banned words for all generated text
11
+ - `.claude/standards/markdown.md` from the project root: punctuation and formatting for all generated text
11
12
  - `${CLAUDE_SKILL_DIR}/references/snippets.md`: authoring conventions, invocation channels, use patterns
12
13
 
13
- Read `${CLAUDE_SKILL_DIR}/../../standards/prose.md` instead when the project does not have it.
14
+ Read a standard from `${CLAUDE_SKILL_DIR}/../../standards/` instead when the project does not have it.
14
15
 
15
16
  ## Guards
16
17
 
@@ -13,7 +13,8 @@ Governs a snippet file: what one is for, whether a prompt qualifies as one, how
13
13
  Does not govern:
14
14
 
15
15
  - Skill folders, which carry frontmatter, references, and scripts a snippet has none of: `skill.md`
16
- - Voice, punctuation, and formatting in snippet prose: `prose.md`
16
+ - Voice and word choice in snippet prose: `prose.md`
17
+ - Punctuation and formatting in snippet prose: `markdown.md`
17
18
 
18
19
  ## What a snippet is
19
20
 
@@ -7,7 +7,8 @@ description: Creates a new standard file in `standards/` or `.claude/standards/`
7
7
 
8
8
  Creates one standard file. Read these files in parallel:
9
9
 
10
- - `.claude/standards/prose.md` from the project root: prose conventions for all generated text
10
+ - `.claude/standards/prose.md` from the project root: voice and banned words for all generated text
11
+ - `.claude/standards/markdown.md` from the project root: punctuation and formatting for all generated text
11
12
  - `.claude/standards/standard.md` from the project root: the meta-standard for shape, frontmatter, and structure
12
13
 
13
14
  Read a standard from `${CLAUDE_SKILL_DIR}/../../standards/` instead when the project does not have it.
@@ -7,7 +7,8 @@ description: Rewrites stale `README.md` and `docs/*.md` sections based on change
7
7
 
8
8
  Read these files from the project root in parallel:
9
9
 
10
- - `.claude/standards/prose.md`: prose conventions for all generated text
10
+ - `.claude/standards/prose.md`: voice and banned words for all generated text
11
+ - `.claude/standards/markdown.md`: punctuation and formatting for all generated text
11
12
  - `.claude/standards/readme.md`: README structure, required sections, and content rules
12
13
 
13
14
  Read a standard from `${CLAUDE_SKILL_DIR}/../../standards/` instead when the project does not have it.
@@ -12,7 +12,8 @@ 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/standards/prose.md` from the project root: prose conventions for all generated text
15
+ - `.claude/standards/prose.md` from the project root: voice and banned words for all generated text
16
+ - `.claude/standards/markdown.md` from the project root: punctuation and formatting for all generated text
16
17
 
17
18
  Read a standard from `${CLAUDE_SKILL_DIR}/../../standards/` instead when the project does not have it.
18
19
 
@@ -14,7 +14,8 @@ Does not govern:
14
14
 
15
15
  - Pull request title and body: `pr.md`
16
16
  - Whether a phase label may appear in issue text: `versioning.md`
17
- - Voice, punctuation, and banned words in issue prose: `prose.md`
17
+ - Voice and banned words in issue prose: `prose.md`
18
+ - Punctuation and formatting in issue prose: `markdown.md`
18
19
 
19
20
  ## Title
20
21
 
@@ -11,7 +11,8 @@ Read these files in parallel:
11
11
 
12
12
  - `${CLAUDE_SKILL_DIR}/references/branch.md`: branch format, valid types, and constraints
13
13
  - `${CLAUDE_SKILL_DIR}/references/pr.md`: structure, rules, and banned phrases
14
- - `.claude/standards/prose.md` from the project root: prose conventions for all generated text
14
+ - `.claude/standards/prose.md` from the project root: voice and banned words for all generated text
15
+ - `.claude/standards/markdown.md` from the project root: punctuation and formatting for all generated text
15
16
  - `.claude/standards/versioning.md` from the project root: phase label vs semver discipline
16
17
 
17
18
  Read a standard from `${CLAUDE_SKILL_DIR}/../../standards/` instead when the project does not have it.
@@ -15,7 +15,8 @@ Does not govern:
15
15
  - Commit subject format, which shares the title form: `commit.md`
16
16
  - Branch naming: `branch.md`
17
17
  - Whether a phase label or a semver tag may appear in a title or body: `versioning.md`
18
- - Voice, punctuation, and banned words in pull request prose: `prose.md`
18
+ - Voice and banned words in pull request prose: `prose.md`
19
+ - Punctuation and formatting in pull request prose: `markdown.md`
19
20
 
20
21
  ## Title
21
22
 
@@ -15,7 +15,8 @@ Does not govern:
15
15
  - Commit subject format, which shares the title form: `commit.md`
16
16
  - Branch naming: `branch.md`
17
17
  - Whether a phase label or a semver tag may appear in a title or body: `versioning.md`
18
- - Voice, punctuation, and banned words in pull request prose: `prose.md`
18
+ - Voice and banned words in pull request prose: `prose.md`
19
+ - Punctuation and formatting in pull request prose: `markdown.md`
19
20
 
20
21
  ## Title
21
22
 
@@ -8,7 +8,8 @@ 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}/references/commit.md`: format, types, scopes, and constraints
11
- - `.claude/standards/prose.md` from the project root: prose conventions for all generated text
11
+ - `.claude/standards/prose.md` from the project root: voice and banned words for all generated text
12
+ - `.claude/standards/markdown.md` from the project root: punctuation and formatting for all generated text
12
13
 
13
14
  Read a standard from `${CLAUDE_SKILL_DIR}/../../standards/` instead when the project does not have it.
14
15
 
@@ -16,7 +16,7 @@ CLI catalog and invocation rules for agents, split by command domain. Start with
16
16
  - [Docs](docs.md): How aitk docs resolves the toolkit's own reference surface from an install root, and how a split domain is named
17
17
  - [Indexes](indexes.md): Flags, exit codes, and JSON shape for aitk indexes regen, plus when it auto-stages what it rewrote
18
18
  - [Install and sync](install-and-sync.md): What each install and sync verb writes, refuses, or leaves alone, and how drift is attributed in a target project
19
- - [Output shape](output-shape.md): The two framed shapes every command renders into, and how JSON and --names modes keep stdout clean
19
+ - [Output shape](output-shape.md): Two framed shapes every command renders into, how JSON and --names modes keep stdout clean, and the exit discipline that lets piped output drain
20
20
  - [Overview](overview.md): What this folder covers, the invocation rules every command inherits, and where domain behavior is documented instead
21
21
  - [Sandbox](sandbox.md): Scenario routing, the expectation scoring surface, and the coverage census over scenarios and skills
22
22
  - [Scripting](scripting.md): The runtime catalogs that replace hardcoded names, what each carries, and a headless invocation per domain
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: Output shape
3
- description: The two framed shapes every command renders into, and how JSON and --names modes keep stdout clean
3
+ description: Two framed shapes every command renders into, how JSON and --names modes keep stdout clean, and the exit discipline that lets piped output drain
4
4
  ---
5
5
 
6
6
  # Output shape
@@ -43,3 +43,11 @@ Help skips the banner. The `Usage:` line sits directly on `├`. Help writes to
43
43
  ## JSON and `--names` modes
44
44
 
45
45
  `--json` and `--names` keep stdout clean and machine-readable. The frame still renders on stderr (open, banner, close) so the stream discipline is consistent across modes. Consumers that only read stdout see pure data.
46
+
47
+ ## Process exit
48
+
49
+ A command action that writes to stdout sets `process.exitCode` and returns. Calling `process.exit()` there ends the process before the write drains, which truncates piped output at the 64K pipe buffer while still reporting the right exit code. Redirecting to a file hides the truncation, so it surfaces only through a pipe, which is what a check has to use to catch it.
50
+
51
+ A fail-fast path that has written to stderr alone may still call `process.exit()`, and several do. The truncation has nothing to cut there, so the ban is scoped to the stream it protects rather than applied to every exit.
52
+
53
+ Diagnostics reach stderr in every mode, including `--json`. Name the file and the field that failed, because a JSON record carries an action and a reason and an operator reading stderr alone sees neither.
@@ -15,7 +15,7 @@ See `CLAUDE.md` design principles. They apply to every command in this folder.
15
15
 
16
16
  ## Where to start
17
17
 
18
- - `output-shape.md`: the stream contract every command renders into, which is what a caller parsing stdout depends on
18
+ - `output-shape.md`: the stream contract every command renders into and the exit discipline behind it, which is what a caller parsing stdout depends on
19
19
  - `commands.md`: the full command catalog, project-level and per-domain
20
20
  - `scripting.md`: the runtime catalogs that replace hardcoded names, plus headless invocation examples
21
21
 
@@ -44,6 +44,7 @@ One session works for most features. Prefer splitting across two sessions only w
44
44
 
45
45
  Work in Claude Code directly. It reads `CLAUDE.md` automatically and has full file access, no pasting needed.
46
46
 
47
+ - When the input is a pile of findings rather than one feature, invoke `aitk:claude-intake` first. It files the dump into `.claude/intake/<slug>/`, one item per finding carrying a problem measured against the tree, a proposed fix, and a verdict, then names which items are plan-ready, which need measuring, and which are already settled. The routing test is whether the repository can answer an item today, so a session grepping handles the yes and the next bullet handles the no.
47
48
  - When the current state is unmeasured and more than one approach is live, invoke `aitk:claude-groundwork` first. It opens a track folder under `.claude/groundwork/<slug>/` and ends in a decision, which may be to do nothing. Skip it when the approach is already settled. A track may run experiments to settle a question, writing a fixture it reads itself under `.claude/.tmp/groundwork-fixtures/<slug>/` and spawning up to three billed headless runs before it asks. A fixture a headless run is pointed at sits outside the repository, since a session started under the project root inherits that project's `CLAUDE.md` and rules and would measure them instead of the arm.
48
49
  - Invoke `aitk:claude-feature` to scan for code-level conflicts and ambiguities, confirm approach before proceeding
49
50
  - Implement the feature, then Claude Code runs the commands defined in `CLAUDE.md`, fixes failures, and iterates until all pass
@@ -131,6 +132,7 @@ Before the first feature session on a UI-heavy project, pick a design tier. The
131
132
 
132
133
  | Skill | When to use |
133
134
  | ---------------------------- | -------------------------------------------------------------------------------------------------------------------- |
135
+ | `aitk:claude-intake` | File a brain dump into an inventory under `.claude/intake/`, one item per finding with a verdict |
134
136
  | `aitk:claude-groundwork` | Before a plan is warranted, measure an unknown in a track folder under `.claude/groundwork/` |
135
137
  | `aitk:claude-feature` | Before implementation, scan for conflicts and ambiguities |
136
138
  | `aitk:claude-roadmap` | Sequence MVP scope into ordered versions in `.claude/ROADMAP.md` |
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Route markdown edits to the prose standard for voice, structure, formatting, and punctuation
2
+ description: Route markdown edits to the prose standard for voice, language, and frontmatter wording
3
3
  paths:
4
4
  - '**/*.md'
5
5
  ---
@@ -8,5 +8,6 @@ paths:
8
8
 
9
9
  ## Authority
10
10
 
11
- - Follow `.claude/standards/prose.md` for all prose: voice, structure, formatting, language, and banned punctuation. It is the single source.
12
- - Read it before a substantial prose edit. Do not work the bans from memory.
11
+ - Follow `.claude/standards/prose.md` for voice, language, and the wording of a `title` or `description`. It is the single source.
12
+ - Read it before a substantial prose edit. Do not work the banned words from memory.
13
+ - Punctuation, formatting, and file references are a separate topic. `501-markdown` routes them.
@@ -0,0 +1,13 @@
1
+ ---
2
+ description: Route markdown edits to the markdown standard for headings, lists, punctuation, and file references
3
+ paths:
4
+ - '**/*.md'
5
+ ---
6
+
7
+ # Markdown mechanics standards
8
+
9
+ ## Authority
10
+
11
+ - Follow `.claude/standards/markdown.md` for headings, paragraph and list structure, code spans, punctuation, emphasis, and file references. It is the single source.
12
+ - Read it before a substantial markdown edit. Do not work the banned characters from memory.
13
+ - Voice, language, and frontmatter wording are a separate topic. `500-prose` routes them.
@@ -1,2 +1,2 @@
1
1
  extends = ""
2
- rules = ["000-constitution", "010-testing", "020-concurrency", "030-error-handling", "040-performance", "050-logging", "060-naming", "070-planning", "080-config-comments", "090-code-comments", "500-prose", "510-context", "520-wireframes", "530-requirements", "540-architecture", "550-design", "555-tasks", "560-diagrams", "570-skill", "580-readme", "590-rule-authoring", "591-standard-authoring"]
2
+ rules = ["000-constitution", "010-testing", "020-concurrency", "030-error-handling", "040-performance", "050-logging", "060-naming", "070-planning", "080-config-comments", "090-code-comments", "500-prose", "501-markdown", "510-context", "520-wireframes", "530-requirements", "540-architecture", "550-design", "555-tasks", "560-diagrams", "570-skill", "580-readme", "590-rule-authoring", "591-standard-authoring"]
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@erclx/aitk",
3
3
  "type": "module",
4
- "version": "0.52.0",
4
+ "version": "0.54.0",
5
5
  "description": "Infrastructure and quality tooling for developer workflows",
6
6
  "license": "MIT",
7
7
  "bin": {
@@ -79,7 +79,7 @@ log_step "Assert scaffold"
79
79
  # The snippets path has to name a slug the default preset still carries, since
80
80
  # init resolves snippets through `essentials`. Editing that preset without
81
81
  # editing this line fails the gate on a correct install.
82
- for path in "CLAUDE.md" ".claude/snippets/decision-help.md" ".claude/standards/prose.md" ".claude/wiki/index.md" ".claude" ".claude/context/index.md" ".claude/wireframes/index.md" ".claude/diagrams/index.md" \
82
+ for path in "CLAUDE.md" ".claude/snippets/decision-help.md" ".claude/standards/prose.md" ".claude/standards/markdown.md" ".claude/wiki/index.md" ".claude" ".claude/context/index.md" ".claude/wireframes/index.md" ".claude/diagrams/index.md" \
83
83
  ".prettierrc" ".editorconfig" ".lintstagedrc" ".husky/pre-commit" ".github/workflows/verify.yml" "scripts/verify.sh" \
84
84
  ".claude/rules/core/000-constitution.md"; do
85
85
  if [ ! -e "$TARGET_DIR/$path" ]; then
@@ -57,7 +57,7 @@ export function parseVocabulary(markdown: string): string[] | undefined {
57
57
  *
58
58
  * Reading the list out of the rule rather than hardcoding it is what keeps one
59
59
  * definition when the rule installs into a target, the same way
60
- * `.claude/hooks/standards-audit.sh` reads its bans out of `prose.md`.
60
+ * `.claude/hooks/standards-audit.sh` reads its word bans out of `prose.md`.
61
61
  */
62
62
  export async function loadVocabulary(root: string): Promise<Vocabulary> {
63
63
  for (const ruleRoot of RULE_ROOTS) {
@@ -14,7 +14,8 @@ Does not govern:
14
14
 
15
15
  - Pull request title and body: `pr.md`
16
16
  - Whether a phase label may appear in issue text: `versioning.md`
17
- - Voice, punctuation, and banned words in issue prose: `prose.md`
17
+ - Voice and banned words in issue prose: `prose.md`
18
+ - Punctuation and formatting in issue prose: `markdown.md`
18
19
 
19
20
  ## Title
20
21
 
@@ -15,7 +15,8 @@ Does not govern:
15
15
  - Commit subject format, which shares the title form: `commit.md`
16
16
  - Branch naming: `branch.md`
17
17
  - Whether a phase label or a semver tag may appear in a title or body: `versioning.md`
18
- - Voice, punctuation, and banned words in pull request prose: `prose.md`
18
+ - Voice and banned words in pull request prose: `prose.md`
19
+ - Punctuation and formatting in pull request prose: `markdown.md`
19
20
 
20
21
  ## Title
21
22
 
@@ -13,7 +13,8 @@ Governs a snippet file: what one is for, whether a prompt qualifies as one, how
13
13
  Does not govern:
14
14
 
15
15
  - Skill folders, which carry frontmatter, references, and scripts a snippet has none of: `skill.md`
16
- - Voice, punctuation, and formatting in snippet prose: `prose.md`
16
+ - Voice and word choice in snippet prose: `prose.md`
17
+ - Punctuation and formatting in snippet prose: `markdown.md`
17
18
 
18
19
  ## What a snippet is
19
20
 
@@ -15,7 +15,8 @@ Governs per-kind diagram entries under `.claude/diagrams/`: which question each
15
15
 
16
16
  Does not govern:
17
17
 
18
- - Punctuation, formatting, and language in explanation prose and node labels: `prose.md`, whose bans the yield does not lift
18
+ - Language and word choice in explanation prose and node labels: `prose.md`, whose bans the yield does not lift
19
+ - Punctuation and formatting in explanation prose: `markdown.md`, which the yield does not reach
19
20
  - The mechanism behind any component a diagram draws: `context.md`
20
21
  - UI layout, on-screen copy, and interaction intent: `wireframes.md`
21
22
  - The decision record a components diagram is drawn from: `architecture.md`
@@ -93,7 +94,7 @@ A second entry for one kind takes a suffixed name (`request-flow-admin.md`) and
93
94
  - Do not duplicate prose across entries. An entry that restates its neighbor has taken the neighbor's job.
94
95
  - The audience is mixed, so vocabulary runs as a gradient across the set. `System context` assumes no knowledge of the repository. `Deployment` may assume the reader has read the others.
95
96
 
96
- This section states the voice for the surface, which is what claims the yield `prose.md` grants to a surface whose own standard sets it. Explanation prose is pedagogical here and the default developer-facing voice does not apply. The yield covers voice alone. Punctuation, formatting, and language bans stay in force.
97
+ This section states the voice for the surface, which is what claims the yield `prose.md` grants to a surface whose own standard sets it. Explanation prose is pedagogical here and the default developer-facing voice does not apply. The yield covers voice alone. The language bans in `prose.md` stay in force, as do the punctuation and formatting rules in `markdown.md`, which grants no yield at all.
97
98
 
98
99
  ## Verification
99
100
 
@@ -120,7 +121,7 @@ Reference the context entry by path when a reader needs the mechanism. The diagr
120
121
  - `System context` has no named source signal beyond `.claude/REQUIREMENTS.md`, so nothing tells a session it went stale. Re-read it when the boundary or the set of external dependencies moves.
121
122
  - The `claude-docs` sweep watches two things and writes frontmatter only. It appends `stale` when a path an entry cites leaves the tree, and it stubs a kind when a diff adds the source signal that kind is drawn from. Diagram bodies and explanation paragraphs are off limits to it, because a change that removes a module does not carry the new correct shape of the picture.
122
123
  - That watch samples thinly. It sees the one or two paths an entry happened to cite and nothing else, so a change elsewhere leaves the entry looking current. `verified` is what covers the gap, and an entry whose date sits far behind the branch is due a read whether or not anything flagged it.
123
- - The explanation paragraphs around a Mermaid block are prose and follow `prose.md`. The fenced block itself is not, which is why a check scoped to prose is the wrong thing to rely on for what sits inside it.
124
+ - The explanation paragraphs around a Mermaid block are prose and follow `prose.md` and `markdown.md`. The fenced block itself is not, which is why a check scoped to prose is the wrong thing to rely on for what sits inside it.
124
125
  - The punctuation bans still apply to node and subgraph labels, and nothing checks them there. An em dash in a label passes every gate the repository has, so read the labels before shipping the entry.
125
126
 
126
127
  ## Template
@@ -11,7 +11,8 @@ Reference docs for consistent authoring across the toolkit and target projects.
11
11
  - [Context entry reference](context.md): Shape and content rules for .claude/context/<domain>.md entries
12
12
  - [Design reference](design.md): Shape and content rules for .claude/DESIGN.md
13
13
  - [Diagram reference](diagrams.md): Shape and content rules for .claude/diagrams/<kind>.md files
14
- - [Prose reference](prose.md): Voice, structure, formatting, and language rules for reference markdown
14
+ - [Markdown reference](markdown.md): Headings, paragraph and list structure, code spans, punctuation, emphasis, and file references
15
+ - [Prose reference](prose.md): Voice, language, and frontmatter wording for reference markdown
15
16
  - [Publish reference](publish.md): Scan run against finished text leaving through a channel no automated check covers
16
17
  - [Readme reference](readme.md): Readme voice, structure, and content conventions
17
18
  - [Requirements reference](requirements.md): Shape and content rules for .claude/REQUIREMENTS.md
@@ -0,0 +1,72 @@
1
+ ---
2
+ title: Markdown reference
3
+ description: Headings, paragraph and list structure, code spans, punctuation, emphasis, and file references
4
+ ---
5
+
6
+ # Markdown reference
7
+
8
+ Applies to markdown reference docs, READMEs, and inline documentation in repos. These are mechanics rather than voice, so no surface yields them. A surface stating its own voice claims that yield from `prose.md` and formats by this file regardless.
9
+
10
+ ## Scope
11
+
12
+ Governs the markdown mechanics of every markdown file: headings, paragraph and list structure, code spans and fences, punctuation, emphasis, and file references. It is an attribute standard rather than a document-type one, so it applies over documents whose shape another standard sets, and it carries no template because mechanics are written across every document and have none of their own to shape.
13
+
14
+ Does not govern:
15
+
16
+ - Voice, word choice, and the wording of a `title` or `description`: `prose.md`
17
+ - What sections a document has, or what belongs in each: the standard for that document type
18
+ - The text inside a fenced block, which follows the conventions of its own language rather than these
19
+ - The scan that applies the punctuation bans to finished text on its way out: `publish.md`
20
+
21
+ ## Headings
22
+
23
+ - H1 for document title, H2 for main sections, H3 for subsections
24
+ - Use sentence case for all headings (H1, H2, H3)
25
+ - Proper nouns and product names retain their casing in headings
26
+
27
+ ## Paragraphs and lists
28
+
29
+ - Use prose by default. Reserve bullets for discrete, unrelated items.
30
+ - Keep paragraphs to four sentences or fewer. Split longer blocks at the next logical boundary.
31
+ - Keep bullets tight. If a bullet needs more than a couple of sentences, it belongs in prose.
32
+ - Use dashes (`-`) not asterisks (`*`) for bulleted lists
33
+ - Do not end single-sentence or fragment bullets with a period. Use periods when a bullet has two or more sentences.
34
+ - For key path lists, use colon format: `- \`src/\`: description`. Never use an em dash.
35
+ - Do not introduce a list with a "Here are the X:" or "The following X:" lead-in
36
+
37
+ ## Code and identifiers
38
+
39
+ - Wrap commands, API names, file paths, and code identifiers in backticks
40
+ - Use a language identifier on all fenced code blocks (`markdown`, `typescript`, `plaintext`). Never use a bare ` ``` `
41
+ - In ASCII tree diagrams, use `←` for inline annotations. Never use `#`.
42
+
43
+ ## Punctuation
44
+
45
+ - Do not use em dashes (`—`) or semicolons (`;`). Rewrite or restructure the sentence to avoid them.
46
+ - Do not use parenthetical asides in prose (`the config (which is optional) controls...`). Split into its own sentence or drop it. Parentheses in rule definitions for grouping examples are fine.
47
+
48
+ The closed-set word bans sit in `prose.md` under `## Language` rather than here, because a banned word is a word-choice rule and these are character rules. A surface applying both reads both files.
49
+
50
+ ## Emphasis and dividers
51
+
52
+ - Do not over-format with excessive bold, italic, or header usage
53
+ - Do not use horizontal rules or dividers (`---`) in body content. The `---` delimiters of a YAML frontmatter block at the top of the file are allowed.
54
+
55
+ ## Links and file references
56
+
57
+ - Use descriptive anchor text for links. Avoid `click here` or `read more`.
58
+ - Wrap file references in backticks by default. Use a labeled markdown link (`[label](path)`) only on rendered-for-human surfaces (`README.md`, `docs/`) and in an index file, whose rows exist to be followed. Never repeat the path verbatim as the label.
59
+
60
+ ## Examples
61
+
62
+ Each pair shows a banned pattern and its fix.
63
+
64
+ ```markdown
65
+ Bad: See [.claude/context/retrieval.md](.claude/context/retrieval.md) for the retrieval flow.
66
+ Good: See `.claude/context/retrieval.md` for the retrieval flow.
67
+ ```
68
+
69
+ ```markdown
70
+ Bad: Read [docs/development.md](docs/development.md) before contributing.
71
+ Good: Read the [development guide](docs/development.md) before contributing.
72
+ ```
@@ -1,18 +1,19 @@
1
1
  ---
2
2
  title: Prose reference
3
- description: Voice, structure, formatting, and language rules for reference markdown
3
+ description: Voice, language, and frontmatter wording for reference markdown
4
4
  ---
5
5
 
6
6
  # Prose reference
7
7
 
8
- Applies to markdown reference docs, READMEs, and inline documentation in repos. It is the default voice for `.md` files and yields to any surface with its own voice, such as blogs, emails, changelogs, or commit messages. It also yields wherever another standard states the voice for the surface it governs, which is how a surface claims the exemption without this file having to name it. The yield covers voice alone. Punctuation, formatting, and language rules below stay in force on every surface, including the surfaces no automated check reaches.
8
+ Applies to markdown reference docs, READMEs, and inline documentation in repos. It is the default voice for `.md` files and yields to any surface with its own voice, such as blogs, emails, changelogs, or commit messages. It also yields wherever another standard states the voice for the surface it governs, which is how a surface claims the exemption without this file having to name it. The yield covers voice alone. The language rules below stay in force on every surface, including the surfaces no automated check reaches, as do the mechanics in `markdown.md`.
9
9
 
10
10
  ## Scope
11
11
 
12
- Governs voice, punctuation, formatting, and word choice wherever prose is written. It is an attribute standard rather than a document-type one, so it applies over documents whose shape another standard sets, and yields on voice alone where that standard states one.
12
+ Governs voice, word choice, and frontmatter wording wherever prose is written. It is an attribute standard rather than a document-type one, so it applies over documents whose shape another standard sets, yields on voice alone where that standard states one, and carries no template because voice is written across every document and has none of its own to shape.
13
13
 
14
14
  Does not govern:
15
15
 
16
+ - Headings, list and paragraph structure, code spans, punctuation, emphasis, and file references: `markdown.md`
16
17
  - What sections a document has, or what belongs in each: the standard for that document type
17
18
  - Which frontmatter fields a document carries, which is that standard's own subject. This file governs the wording of a `title` and a `description` and nothing else about them.
18
19
  - Phase-label and semver discipline: `versioning.md`
@@ -28,52 +29,8 @@ Does not govern:
28
29
  - Use substantive connectives where flow matters, but never add words solely for rhythm. Terse reference prose needs no padding.
29
30
  - Be direct on established facts. Hedge on genuinely uncertain claims.
30
31
  - Assume developer-level technical knowledge. Skip hand-holding explanations.
31
- - Keep paragraphs to four sentences or fewer. Split longer blocks at the next logical boundary.
32
-
33
- ## Structure
34
-
35
- ### Headings
36
-
37
- - H1 for document title, H2 for main sections, H3 for subsections
38
- - Use sentence case for all headings (H1, H2, H3)
39
- - Proper nouns and product names retain their casing in headings
40
-
41
- ### Paragraphs and lists
42
-
43
32
  - Front-load key information in each paragraph. Keep paragraphs concise and scannable.
44
33
  - Every sentence must provide new information. Cut redundant context.
45
- - Use prose by default. Reserve bullets for discrete, unrelated items.
46
- - Keep bullets tight. If a bullet needs more than a couple of sentences, it belongs in prose.
47
-
48
- ## Formatting
49
-
50
- ### Lists
51
-
52
- - Use dashes (`-`) not asterisks (`*`) for bulleted lists
53
- - Do not end single-sentence or fragment bullets with a period. Use periods when a bullet has two or more sentences.
54
- - For key path lists, use colon format: `- \`src/\`: description`. Never use an em dash.
55
- - Do not introduce a list with a "Here are the X:" or "The following X:" lead-in
56
-
57
- ### Code and identifiers
58
-
59
- - Wrap commands, API names, file paths, and code identifiers in backticks
60
- - Use a language identifier on all fenced code blocks (`markdown`, `typescript`, `plaintext`). Never use a bare ` ``` `
61
- - In ASCII tree diagrams, use `←` for inline annotations. Never use `#`.
62
-
63
- ### Punctuation
64
-
65
- - Do not use em dashes (`—`) or semicolons (`;`). Rewrite or restructure the sentence to avoid them.
66
- - Do not use parenthetical asides in prose (`the config (which is optional) controls...`). Split into its own sentence or drop it. Parentheses in rule definitions for grouping examples are fine.
67
-
68
- ### Emphasis and dividers
69
-
70
- - Do not over-format with excessive bold, italic, or header usage
71
- - Do not use horizontal rules or dividers (`---`) in body content. The `---` delimiters of a YAML frontmatter block at the top of the file are allowed.
72
-
73
- ### Links and file references
74
-
75
- - Use descriptive anchor text for links. Avoid `click here` or `read more`.
76
- - Wrap file references in backticks by default. Use a labeled markdown link (`[label](path)`) only on rendered-for-human surfaces (`README.md`, `docs/`) for cross-folder navigation. Never repeat the path verbatim as the label.
77
34
 
78
35
  ## Language
79
36
 
@@ -86,6 +43,8 @@ Does not govern:
86
43
  - Do not address the reader as a participant (`Let's`, `Here's`, `Here are`). State the content directly.
87
44
  - Commit to a position. Do not hedge in clusters (`It might be worth considering`) or use false balance (`While X is true, Y is also important`). Recommend, or state the tradeoff.
88
45
 
46
+ The character bans sit in `markdown.md` under `## Punctuation` rather than here, because an em dash and a semicolon are typography and these are word choice. A surface applying both reads both files.
47
+
89
48
  ## Frontmatter descriptions
90
49
 
91
50
  When frontmatter carries a short `title` or `description` used for catalog display:
@@ -122,13 +81,3 @@ Good: Use the `retry` option for failed webhooks. Set `maxRetries` to 3.
122
81
  Bad: It might be worth considering whether to enable caching.
123
82
  Good: Enable caching for read-heavy endpoints. Skip it for writes.
124
83
  ```
125
-
126
- ```markdown
127
- Bad: See [.claude/context/retrieval.md](.claude/context/retrieval.md) for the retrieval flow.
128
- Good: See `.claude/context/retrieval.md` for the retrieval flow.
129
- ```
130
-
131
- ```markdown
132
- Bad: Read [docs/development.md](docs/development.md) before contributing.
133
- Good: Read the [development guide](docs/development.md) before contributing.
134
- ```
@@ -11,7 +11,8 @@ Governs the scan an author runs against finished text on its way out, and the re
11
11
 
12
12
  Does not govern:
13
13
 
14
- - Which characters are banned, and the voice and formatting the text is written in: `prose.md`
14
+ - Which characters are banned, and the formatting the text carries: `markdown.md`
15
+ - The voice and word choice the text is written in: `prose.md`
15
16
  - The phase-label rule and the table of surfaces each namespace may appear on: `versioning.md`
16
17
  - Which gap a given surface has, and what it publishes through, which that surface names for itself
17
18
 
@@ -23,7 +24,7 @@ Run the scan as an explicit step against the finished text. Having read the unde
23
24
 
24
25
  ## Banned characters
25
26
 
26
- `prose.md` holds the character bans. Read it at scan time rather than working them from memory, then scan the drafted text and rewrite each occurrence.
27
+ `markdown.md` holds the character bans and `prose.md` holds the banned words. Read both at scan time rather than working them from memory, then scan the drafted text and rewrite each occurrence.
27
28
 
28
29
  Restructure the sentence rather than substituting the character. A semicolon swapped for a period leaves both clauses in the order the semicolon chose, which is the shape the ban exists to remove.
29
30
 
@@ -5,7 +5,7 @@ description: Readme voice, structure, and content conventions
5
5
 
6
6
  # Readme reference
7
7
 
8
- Applies to every `README.md`. The `## Voice` section states the voice for a repository's root README, so `prose.md` yields to it there. The yield covers voice alone. The punctuation bans, spelling rules, banned words, and formatting rules in `prose.md` stay in force, so the warmer register ships with the same hygiene: no em dashes, no semicolons, no buzzwords.
8
+ Applies to every `README.md`. The `## Voice` section states the voice for a repository's root README, so `prose.md` yields to it there. The yield covers voice alone. The spelling rules and banned words in `prose.md` stay in force, as do the punctuation and formatting rules in `markdown.md`, so the warmer register ships with the same hygiene: no em dashes, no semicolons, no buzzwords.
9
9
 
10
10
  The reader is what changes. Reference prose serves someone who already committed to the project and is scanning for a fact. A root README meets someone deciding whether to commit at all, and it is often the only file they read.
11
11
 
@@ -15,7 +15,8 @@ Governs every `README.md`: voice, heading structure, required and optional secti
15
15
 
16
16
  Does not govern:
17
17
 
18
- - Punctuation, formatting, spelling, and banned words in README prose: `prose.md`, which yields the voice and keeps the rest
18
+ - Spelling and banned words in README prose: `prose.md`, which yields the voice and keeps the rest
19
+ - Punctuation and formatting in README prose: `markdown.md`, which yields nothing
19
20
  - Product scope and goals: `requirements.md`
20
21
 
21
22
  ## Voice
package/standards/rule.md CHANGED
@@ -19,6 +19,14 @@ Does not govern:
19
19
  - Skill folders and skill frontmatter: `skill.md`
20
20
  - Cross-domain behavior rules, which live in `CLAUDE.md` at the project root
21
21
 
22
+ ## Whether a skill belongs behind the rule
23
+
24
+ A rule fires on a path match with no decision from the session, which is what makes it a floor. Every bullet is one directive and nothing else, so an invariant needing procedure, worked cases, or a branch on project state has no room in the body.
25
+
26
+ Run the two-part test in reverse before calling the rule finished. The rule already holds what fires on a path edit and ships silently when violated. Ask what a session still needs past the directive, and give that to a skill the rule points at, because a rule that grows a procedure has become a skill body wearing rule frontmatter.
27
+
28
+ Write both when both apply. A rule stating the directive and a skill stating how to carry it out are one invariant at two depths rather than two copies of it, and `skill.md` carries the same checkpoint for a session arriving from the other side. Nothing checks either one.
29
+
22
30
  ## Location
23
31
 
24
32
  - Rules live at `.claude/rules/<subdirectory>/<n>-<slug>.md`
@@ -17,10 +17,19 @@ Does not govern:
17
17
 
18
18
  - Path-scoped coding rules, which load on a file match rather than on a request match: `rule.md`
19
19
  - Single-purpose chat prompts carrying no frontmatter, references, or scripts: `snippets.md`
20
- - Voice, punctuation, and formatting in a skill body: `prose.md`
20
+ - Voice and word choice in a skill body: `prose.md`
21
+ - Punctuation and formatting in a skill body: `markdown.md`
21
22
  - The transform from a branch name to a slug a skill carries in a filename: `slug.md`
22
23
  - The domain conventions a skill cites, each of which belongs to the standard that owns it
23
24
 
25
+ ## Whether a rule belongs beside the skill
26
+
27
+ A skill fires when a session invokes it or its description matches the request. A path-scoped rule fires when a session reads a file matching its glob, with no decision from the session at all. The two are layers rather than alternatives, so the rule is the floor and the skill is the depth.
28
+
29
+ Run the two-part test over what the body states before calling the skill finished. Does the invariant fire when a specific path is edited, and does violating it ship silently? An invariant passing both halves belongs in a rule as well, because a session that never invoked the skill still edits that path and needs the floor under it. An invariant failing either half stays here, which is most of a body, since procedure and orientation are what a rule cannot carry.
30
+
31
+ Write that rule to the shape `rule.md` sets and leave the procedure here, since the two carry one invariant at two depths rather than two copies of it. Nothing checks the split. The checkpoint is a judgment prompt rather than an invariant, so it ships as prose with no gate behind it, and a skill that skips it fails silently in the same way the invariants it is meant to catch do.
32
+
24
33
  ## Skill types
25
34
 
26
35
  Pick the type before writing. It decides the body shape.
@@ -17,7 +17,8 @@ Governs each authored standard under `standards/`: its stated jurisdiction, succ
17
17
 
18
18
  Does not govern:
19
19
 
20
- - The voice, punctuation, and formatting a standard is written in: `prose.md`
20
+ - The voice and word choice a standard is written in: `prose.md`
21
+ - The punctuation and formatting a standard is written in: `markdown.md`
21
22
  - The shape of any artifact a standard governs, which is that standard's own subject
22
23
 
23
24
  ## What a working standard looks like
@@ -16,7 +16,8 @@ Does not govern:
16
16
  - The format of a phase label, which is project-specific by the rule below
17
17
  - Task filenames and board layout: `tasks.md`
18
18
  - Commit subject, branch name, and pull request title format: `commit.md`, `branch.md`, and `pr.md`
19
- - Voice, punctuation, and formatting in any text carrying a label: `prose.md`
19
+ - Voice and word choice in any text carrying a label: `prose.md`
20
+ - Punctuation and formatting in any text carrying a label: `markdown.md`
20
21
 
21
22
  ## Phase labels
22
23
 
@@ -17,7 +17,8 @@ Does not govern:
17
17
 
18
18
  - Tokens, typography, spacing, and the rest of the visual system: `design.md`
19
19
  - The mechanism behind a surface: `context.md`
20
- - Voice, punctuation, and formatting in wireframe prose: `prose.md`
20
+ - Voice and word choice in wireframe prose: `prose.md`
21
+ - Punctuation and formatting in wireframe prose: `markdown.md`
21
22
 
22
23
  ## What a working wireframe looks like
23
24
 
@@ -74,7 +75,7 @@ Reference the context entry from the wireframe by path when a reader needs the m
74
75
  ## Maintenance
75
76
 
76
77
  - When a surface's layout or interaction changes, update its wireframe file in the same PR. A wireframe showing a defunct layout is worse than none.
77
- - The Behavior and Copy prose around an ASCII block is prose and follows `prose.md`. The fenced block itself is not, so a check scoped to prose is the wrong thing to rely on for what sits inside it.
78
+ - The Behavior and Copy prose around an ASCII block is prose and follows `prose.md` and `markdown.md`. The fenced block itself is not, so a check scoped to prose is the wrong thing to rely on for what sits inside it.
78
79
 
79
80
  ## Template
80
81
 
@@ -19,6 +19,10 @@ esac
19
19
  # Read the closed-set word bans from the standard so the hook never carries a
20
20
  # second copy. Every "Do not use ... (`a`, `b`)" bullet contributes its
21
21
  # single-word backticked terms, which skips the multi-word and punctuation bans.
22
+ #
23
+ # The word bans sit in prose.md and the em-dash and semicolon bans in
24
+ # markdown.md, so this parses the first and hardcodes the second. A "Do not use"
25
+ # bullet added to markdown.md is parsed by nothing and enforces silently.
22
26
  standard="${CLAUDE_PROJECT_DIR:-.}/.claude/standards/prose.md"
23
27
  words=""
24
28
  if [ -f "$standard" ]; then
@@ -56,6 +60,6 @@ hits=$(awk -v words="$words" '
56
60
 
57
61
  [ -z "$hits" ] && exit 0
58
62
 
59
- msg=$(printf 'Standards-audit: prose.md violations in %s. Rewrite or restructure (do not lazy-swap).\n%s' "$file" "$hits")
63
+ msg=$(printf 'Standards-audit: prose.md and markdown.md violations in %s. Rewrite or restructure (do not lazy-swap).\n%s' "$file" "$hits")
60
64
 
61
65
  jq -nc --arg msg "$msg" '{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:$msg}}'