@erclx/canon 5.21.0 → 5.23.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 (88) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/auto-ship/SKILL.md +1 -1
  3. package/claude/skills/auto-ship/references/draft-mark.md +8 -6
  4. package/claude/skills/draft-doc/REQUIREMENT.md +45 -0
  5. package/claude/skills/draft-doc/SKILL.md +77 -0
  6. package/claude/skills/draft-doc/references/context.md +31 -0
  7. package/claude/skills/draft-doc/references/docs.md +33 -0
  8. package/claude/skills/draft-doc/references/readme.md +58 -0
  9. package/claude/skills/draft-doc/references/wiki.md +53 -0
  10. package/claude/skills/draft-doc/references/wireframes.md +48 -0
  11. package/claude/skills/draft-figure/REQUIREMENT.md +1 -1
  12. package/claude/skills/draft-figure/SKILL.md +1 -1
  13. package/claude/skills/git-pr/SKILL.md +5 -46
  14. package/claude/skills/git-pr/references/final-command.md +75 -0
  15. package/claude/skills/git-pr/references/labels.md +2 -2
  16. package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +76 -0
  17. package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +11 -1
  18. package/claude/skills/role-orchestrator/references/orchestrator-launch.md +5 -1
  19. package/claude/skills/search-craft/REQUIREMENT.md +4 -4
  20. package/claude/skills/search-craft/SKILL.md +1 -1
  21. package/claude/skills/target-check/SKILL.md +9 -9
  22. package/claude/skills/target-check/references/domains.md +11 -5
  23. package/docs/agents/architecture-record.md +2 -2
  24. package/docs/agents/commands.md +1 -1
  25. package/docs/agents/drift-surfaces.md +20 -9
  26. package/docs/agents/index.md +3 -3
  27. package/docs/agents/install-and-sync.md +3 -3
  28. package/docs/agents/migrate.md +1 -1
  29. package/docs/agents/rule-citations.md +1 -1
  30. package/docs/agents/slides.md +47 -3
  31. package/docs/agents/tasks-validate.md +4 -2
  32. package/docs/agents/tasks.md +2 -2
  33. package/docs/target/migrations.md +3 -1
  34. package/docs/target/projects.md +1 -1
  35. package/docs/target/sync.md +1 -1
  36. package/docs/workflow/skill-map.md +14 -18
  37. package/governance/rules/canon/604-scratch.md +0 -1
  38. package/governance/rules/claude/575-hooks.md +1 -2
  39. package/governance/rules/claude/576-settings.md +1 -2
  40. package/governance/rules/standards/architecture.md +0 -1
  41. package/governance/rules/standards/context.md +0 -1
  42. package/governance/rules/standards/design.md +0 -1
  43. package/governance/rules/standards/diagrams.md +0 -3
  44. package/governance/rules/standards/requirements.md +0 -1
  45. package/governance/rules/standards/wireframes.md +0 -1
  46. package/package.json +1 -1
  47. package/scripts/manage-sandbox.sh +7 -8
  48. package/src/claude/cases/authoring.ts +5 -5
  49. package/src/commands/slides.ts +14 -4
  50. package/src/commands/sync.ts +10 -0
  51. package/src/commands/tasks.ts +16 -0
  52. package/src/gov/citations.ts +1 -2
  53. package/src/migrate/skill-names.ts +12 -0
  54. package/src/slides/convert/deck.ts +83 -3
  55. package/src/slides/convert/export.ts +67 -19
  56. package/src/slides/convert/shapes.ts +43 -3
  57. package/src/slides/convert/walk.ts +43 -1
  58. package/src/slides/package/fonts.ts +297 -0
  59. package/src/slides/package/motion.ts +316 -0
  60. package/src/slides/package/test-face.ts +113 -0
  61. package/src/sync/check.ts +9 -0
  62. package/src/sync/layout.ts +27 -1
  63. package/src/tasks/validate.ts +65 -0
  64. package/standards/architecture.md +2 -3
  65. package/standards/board.md +2 -0
  66. package/standards/context.md +0 -1
  67. package/standards/design.md +0 -1
  68. package/standards/diagrams.md +0 -3
  69. package/standards/requirements.md +3 -2
  70. package/standards/rule.md +1 -0
  71. package/standards/wireframes.md +0 -1
  72. package/tooling/claude/seeds/.claude/hooks/path-form.sh +2 -2
  73. package/tooling/claude/seeds/.claude/hooks/pr-create-log.sh +10 -5
  74. package/tooling/claude/seeds/.claude/hooks/{tasks-index.sh → records-index.sh} +42 -35
  75. package/tooling/claude/seeds/.claude/settings.json +1 -5
  76. package/tooling/claude/seeds/canon/ARCHITECTURE.md +1 -1
  77. package/tooling/claude/seeds/canon/REQUIREMENTS.md +2 -0
  78. package/claude/skills/draft-context/REQUIREMENT.md +0 -37
  79. package/claude/skills/draft-context/SKILL.md +0 -61
  80. package/claude/skills/draft-docs/REQUIREMENT.md +0 -35
  81. package/claude/skills/draft-docs/SKILL.md +0 -59
  82. package/claude/skills/draft-readme/REQUIREMENT.md +0 -38
  83. package/claude/skills/draft-readme/SKILL.md +0 -73
  84. package/claude/skills/draft-wiki/REQUIREMENT.md +0 -42
  85. package/claude/skills/draft-wiki/SKILL.md +0 -83
  86. package/claude/skills/draft-wireframes/REQUIREMENT.md +0 -38
  87. package/claude/skills/draft-wireframes/SKILL.md +0 -69
  88. package/tooling/claude/seeds/.claude/hooks/memory-index.sh +0 -95
@@ -3,7 +3,6 @@ title: Requirements reference
3
3
  description: Shape and content rules for canon/REQUIREMENTS.md
4
4
  paths:
5
5
  - 'canon/REQUIREMENTS.md'
6
- - '.claude/REQUIREMENTS.md'
7
6
  ---
8
7
 
9
8
  # Requirements reference
@@ -41,7 +40,7 @@ Use `## Problem`, `## Goals`, `## Non-goals`, `## MVP features`, and `## Constra
41
40
 
42
41
  ## Length
43
42
 
44
- This file loads into every session, so its weight is paid before any work starts. Cap it by stating the clause `This record holds at most <n> words.` in the record itself, where a checker reads it and counts every word below the frontmatter. The cap is the record's own, so a record stating none is measured and never gated. Set it near 600, and at the cap cut a goal or a constraint that no longer changes a decision before adding one.
43
+ This file loads into every session, so its weight is paid before any work starts. Cap it by stating the clause `This record holds at most <n> words.` in the record itself, where a checker reads it and counts every word below the frontmatter. The cap is the record's own, so a record stating none is measured and never gated. The template and the seed a new project installs state it at 600, and a project loosens it by editing the number in its own record. At the cap, cut a goal or a constraint that no longer changes a decision before adding one.
45
44
 
46
45
  ## Lifecycle
47
46
 
@@ -60,6 +59,8 @@ State each entry as an outcome the consumer reaches, never as the mechanism that
60
59
  ```markdown
61
60
  # Requirements
62
61
 
62
+ This record holds at most 600 words.
63
+
63
64
  ## Problem
64
65
 
65
66
  ## Goals
package/standards/rule.md CHANGED
@@ -89,6 +89,7 @@ paths:
89
89
  - Cut any rule that resists crisp one-line phrasing. Vague guidance is worse than none.
90
90
  - Keep the file to one topic. A second topic is a second rule file.
91
91
  - Do not restate a rule that a sibling rule or `CLAUDE.md` already owns. Point once, never duplicate.
92
+ - Name the current layout only, in a glob and in the body alike. A layout change ships a migration verb, as `canon migrate surface-roots` and `canon migrate records` did, rather than a rule line or a glob that keeps the old spelling loading.
92
93
 
93
94
  ## Examples
94
95
 
@@ -3,7 +3,6 @@ title: Wireframe reference
3
3
  description: Shape and content rules for canon/wireframes/<surface>.md files
4
4
  paths:
5
5
  - 'canon/wireframes/**'
6
- - '.claude/wireframes/**'
7
6
  rule:
8
7
  - 'Read it before adding or revising a surface.'
9
8
  ---
@@ -12,8 +12,8 @@
12
12
  # its surface, not from this hook or the output rule.
13
13
  #
14
14
  # The worktree branch comes from the path rather than from `git rev-parse`,
15
- # the way `tasks-index.sh` and `memory-index.sh` already derive their main
16
- # root from a path suffix instead of the session. A git call would answer for
15
+ # the way `records-index.sh` already derives its main root from a path suffix
16
+ # instead of the session. A git call would answer for
17
17
  # whatever directory the hook's own process happens to run in, which is not
18
18
  # necessarily the worktree the write came from.
19
19
 
@@ -19,23 +19,28 @@ IFS= read -r -d '' -t 2 input
19
19
  exit 1
20
20
  }
21
21
 
22
+ # Two shapes open a pull request. `gh pr create` names itself in the command.
23
+ # git-pr opens one over REST and prints `opened=true` only on that path, since
24
+ # its edit path prints a URL as well and is not an opening.
22
25
  command=$(printf '%s' "$input" | jq -r '.tool_input.command // empty')
26
+ stdout=$(printf '%s' "$input" | jq -r '.tool_response.stdout // empty')
23
27
  case "$command" in
24
28
  *"gh pr create"*) ;;
25
- *) exit 0 ;;
29
+ *)
30
+ printf '%s\n' "$stdout" | grep -qx 'opened=true' || exit 0
31
+ ;;
26
32
  esac
27
33
 
28
- # gh pr create prints the new pull request's URL to stdout on success, so
34
+ # Either shape prints the new pull request's URL to stdout on success, so
29
35
  # matching it is what tells a creation apart from a failed or refused call.
30
- stdout=$(printf '%s' "$input" | jq -r '.tool_response.stdout // empty')
31
36
  url=$(printf '%s' "$stdout" | grep -Eo 'https://github\.com/[^[:space:]]+/pull/[0-9]+' | tail -1)
32
37
  [ -n "$url" ] || exit 0
33
38
 
34
39
  # CLAUDE_PROJECT_DIR is the session's own worktree rather than the main root,
35
40
  # so a worker building in a linked worktree would log into a folder that dies
36
41
  # with the worktree. The log is a denominator across a wave rather than a
37
- # per-session record, so strip back to the main root the way tasks-index.sh
38
- # and memory-index.sh already derive theirs, off a path suffix.
42
+ # per-session record, so strip back to the main root the way
43
+ # records-index.sh already derives its own, off a path suffix.
39
44
  root="${CLAUDE_PROJECT_DIR:-.}"
40
45
  case "$root" in
41
46
  */.claude/worktrees/*) root="${root%/.claude/worktrees/*}" ;;
@@ -1,11 +1,12 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
- # Regenerates .claude/tasks/index.md after a task file changes.
3
+ # Regenerates the index.md of a gitignored record folder, `tasks` or `memory`,
4
+ # after a file in it changes.
4
5
  #
5
- # The task folder is gitignored, so the whole-repo walk in `bun run check`
6
- # drops it and never regenerates this index. Naming the file as a positional
6
+ # These folders are gitignored, so the whole-repo walk in `bun run check` drops
7
+ # them and never regenerates their index. Naming the file as a positional
7
8
  # argument to `canon indexes regen` below bypasses that filter, which makes this
8
- # hook the only trigger that reaches the folder.
9
+ # hook the only trigger that reaches either folder.
9
10
 
10
11
  # Claude Code sends a payload and closes stdin. A bare read with nothing feeding
11
12
  # it blocks forever and holds the session open, so the read is bounded. `read`
@@ -25,45 +26,51 @@ esac
25
26
  file_path=$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty')
26
27
  [ -n "$file_path" ] || exit 0
27
28
 
28
- # Both record roots, since a project the move has reached keeps its board under
29
+ # Both record roots, since a project the move has reached keeps its records under
29
30
  # `.canon/` and a guard fixed at the old spelling stops matching with nothing
30
31
  # said. The index then goes stale while every save reports success.
31
- case "$file_path" in
32
- */.claude/tasks/*.md | */.canon/tasks/*.md) ;;
33
- *) exit 0 ;;
34
- esac
35
-
36
- # The board index covers the live folder alone. A shell pattern's wildcard
37
- # crosses a separator, so the guard above matches an archived or declined task
38
- # as well, and a regen fired on one would rebuild the index that task was
39
- # taken out of.
40
- case "$file_path" in
41
- */.claude/tasks/index.md | */.claude/tasks/archive/* | */.claude/tasks/declined/*) exit 0 ;;
42
- */.canon/tasks/index.md | */.canon/tasks/archive/* | */.canon/tasks/declined/*) exit 0 ;;
43
- esac
44
-
32
+ #
33
+ # A shell `case` `*` crosses `/`, so each arm also matches a file in a subfolder
34
+ # the index does not render: an archived or declined task, a memory receipt, a
35
+ # retired memory entry, or the index itself. Those exit here, before the regen
36
+ # call. The exclusions are per folder, since a task under `review/` is indexed
37
+ # and a memory `declined/` is not special. The arms are ordered tasks first,
38
+ # and no path carries both segments today.
39
+ #
45
40
  # The walk-up boundary has to come from the path, not from the session. Shared
46
41
  # scratch resolves at the main worktree root, so a session inside a linked
47
42
  # worktree passes a path that sits outside its own project directory and the
48
- # default boundary would reject it.
49
- #
50
- # The index this would have rebuilt is read out of the same branch, so both
51
- # messages below name the file that actually went stale rather than one root's
52
- # spelling of it.
43
+ # default boundary would reject it. The messages below name the index read out
44
+ # of the same match, so they name the file that actually went stale.
53
45
  case "$file_path" in
54
- */.canon/tasks/*)
55
- root="${file_path%/.canon/tasks/*}"
56
- index=".canon/tasks/index.md"
46
+ */.canon/tasks/index.md | */.canon/tasks/archive/* | */.canon/tasks/declined/*) exit 0 ;;
47
+ */.claude/tasks/index.md | */.claude/tasks/archive/* | */.claude/tasks/declined/*) exit 0 ;;
48
+ */.canon/memory/index.md | */.canon/memory/review/* | */.canon/memory/archive/*) exit 0 ;;
49
+ */.claude/memory/index.md | */.claude/memory/review/* | */.claude/memory/archive/*) exit 0 ;;
50
+ */.canon/tasks/*.md)
51
+ folder=tasks
52
+ base=.canon
53
+ ;;
54
+ */.claude/tasks/*.md)
55
+ folder=tasks
56
+ base=.claude
57
57
  ;;
58
- *)
59
- root="${file_path%/.claude/tasks/*}"
60
- index=".claude/tasks/index.md"
58
+ */.canon/memory/*.md)
59
+ folder=memory
60
+ base=.canon
61
61
  ;;
62
+ */.claude/memory/*.md)
63
+ folder=memory
64
+ base=.claude
65
+ ;;
66
+ *) exit 0 ;;
62
67
  esac
68
+ root="${file_path%/"$base/$folder"/*}"
69
+ index="$base/$folder/index.md"
63
70
  [ -n "$root" ] || exit 0
64
71
 
65
72
  # Report a missing CLI rather than exiting quietly. The path guard above already
66
- # scopes this to a task-file edit, so the message only fires where the stale
73
+ # scopes this to a record-file edit, so the message only fires where the stale
67
74
  # index it warns about is the actual outcome.
68
75
  if ! command -v canon >/dev/null 2>&1; then
69
76
  msg="canon is not on PATH, so $index was not regenerated and is now stale. Install the toolkit CLI or run canon indexes regen by hand."
@@ -73,18 +80,18 @@ if ! command -v canon >/dev/null 2>&1; then
73
80
  fi
74
81
 
75
82
  # `--no-stage` because a hook has no business touching the index. On a project
76
- # whose board is not gitignored, the default auto-stage would silently add task
77
- # files to whatever commit is being assembled.
83
+ # whose folder is not gitignored, the default auto-stage would silently add
84
+ # record files to whatever commit is being assembled.
78
85
  output=$(canon indexes regen --no-stage --root "$root" "$file_path" 2>&1) && exit 0
79
86
 
80
- # Regen failed, which on this folder means a task file is missing `title` or
87
+ # Regen failed, which on these folders means a file is missing `title` or
81
88
  # `description`. Report it. Nothing else can: the folder is gitignored, so the
82
89
  # whole-repo walk never reaches it and no gate stage will ever fail on a stale
83
90
  # index. Staying quiet here is what makes the drift permanent.
84
91
  errors=$(printf '%s\n' "$output" | grep '^ERROR: ' | head -5)
85
92
  [ -n "$errors" ] || errors="$output"
86
93
 
87
- msg="Task index regen failed, so $index is now stale. Fix the frontmatter and save again. $errors"
94
+ msg="The $folder index regen failed, so $index is now stale. Fix the frontmatter and save again. $errors"
88
95
  jq -nc --arg msg "$msg" \
89
96
  '{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:$msg}}'
90
97
  exit 0
@@ -39,11 +39,7 @@
39
39
  },
40
40
  {
41
41
  "type": "command",
42
- "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/tasks-index.sh"
43
- },
44
- {
45
- "type": "command",
46
- "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/memory-index.sh"
42
+ "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/records-index.sh"
47
43
  },
48
44
  {
49
45
  "type": "command",
@@ -4,7 +4,7 @@ Authoring guidance: the architecture standard.
4
4
 
5
5
  ## Overview
6
6
 
7
- This record holds at most 12 decisions.
7
+ This record holds at most 12 decisions, at most 150 words a decision, and at most 6 risk bullets.
8
8
 
9
9
  ## Key technical decisions
10
10
 
@@ -2,6 +2,8 @@
2
2
 
3
3
  Authoring guidance: the requirements standard.
4
4
 
5
+ This record holds at most 600 words.
6
+
5
7
  ## Problem
6
8
 
7
9
  ## Goals
@@ -1,37 +0,0 @@
1
- ---
2
- name: draft-context
3
- description: Why a brand-new canon/context/<domain>.md entry needs a catalog collision check and a confirm step, not the refresh path context-fold already owns
4
- ---
5
-
6
- # Context draft requirement
7
-
8
- ## Gap
9
-
10
- Without this skill, a session documenting a domain that has no context entry yet either invents a shape from memory or reaches for the refresh mechanism, which reads an existing entry and a diff and has neither to work from for a domain that never had one. Either way the entry ships with no read of `standards/context.md` and no check against the catalog for a sibling already covering the same ground under a different name.
11
-
12
- ## Must
13
-
14
- - Read `standards/context.md` before drafting, since the frontmatter contract and the three-question test are what make the entry arguable against a sibling
15
- - Check the domain against the existing catalog by slug and by title-and-description, not by slug alone, since a domain can be covered under a name the topic phrase does not guess
16
- - Default a brand-new entry to a flat file, since a fresh domain never holds the three or more sub-areas the standard requires before it earns a folder
17
- - Confirm the resolved path and the full content with the user before writing, since placement is a judgment call with no diff to preview it against
18
- - Run `canon indexes regen` on `canon/context/` after writing, so the catalog picks up the new domain immediately rather than drifting until the next unrelated regen
19
-
20
- ## Must not
21
-
22
- - Refresh or rewrite an existing entry. A domain already covered refuses toward the refresh mechanism.
23
- - Hand-edit `canon/context/index.md`. It regenerates from sibling frontmatter, and a hand edit is overwritten on the next regen.
24
- - Assume this skill's own invocation frequency needs no check. Whether anything reaches for it beyond an author typing its name has no answer at creation time, so a review pass some months in should read that back rather than take the assumption on faith.
25
-
26
- ## Guards
27
-
28
- - No domain given: stop and ask what domain the entry should cover.
29
- - The derived slug already resolves to `canon/context/<slug>.md` or `canon/context/<slug>/index.md`: stop and point at the refresh mechanism instead.
30
- - The catalog already covers the domain under a different name: stop the same way, checked against the titles and descriptions the Placement step already reads.
31
-
32
- ## Out of scope
33
-
34
- - Refreshing an existing `canon/context/<domain>.md` entry against a diff: `context-fold`
35
- - Drafting a `canon/wireframes/<surface>.md` file: `draft-wireframes`
36
- - Drafting a `docs/*.md` page: `draft-docs`
37
- - Drafting a standard or a governance rule: `create-standard`, `create-rule`
@@ -1,61 +0,0 @@
1
- ---
2
- name: draft-context
3
- description: Drafts a brand-new `canon/context/<domain>.md` entry against the context standard, checks the catalog for a name-or-topic collision, decides flat-file placement, confirms with the user, then writes. Use when asked to "write a context entry for X", "document the X domain", "add a context entry for X", or "create a canon/context page for X" where no existing entry covers the domain. Do NOT use to refresh an existing entry against a diff, which is `context-fold`.
4
- ---
5
-
6
- # Context draft
7
-
8
- Drafts one brand-new `canon/context/<domain>.md` entry end to end: read the standard, decide whether the domain is already covered under a different name, confirm the draft with the user, then write.
9
-
10
- A project the surface move has not reached keeps its context folder under `.claude/` rather than `canon/`. Check and write at whichever root already carries the folder, and create it under `canon/` only when neither does, since a new `canon/` folder would hide every entry the old one holds.
11
-
12
- Read these files in parallel:
13
-
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`: punctuation and formatting for all generated text
16
- - The `write-human` skill: voice, rhythm, and sentence construction for all generated text
17
-
18
- ## Guards
19
-
20
- - If no domain is given, stop: `❌ No domain given. Name the domain this entry should cover.`
21
- - Derive a kebab-case slug from the domain and check whether `canon/context/<slug>.md` or `canon/context/<slug>/index.md` already exists. Either resolving means the domain is already covered under that exact name. Stop: `❌ <slug> already has a context entry. Use context-fold to refresh it instead.`
22
-
23
- ## Placement
24
-
25
- - Read `canon/context/index.md` and check every title and description it lists against the domain. The Guards check above only catches an exact-slug collision, and a domain already covered under a different name still resolves here at no extra cost, since this read already runs.
26
- - Stop the same way on a match: `❌ <path> already covers this domain under a different name. Use context-fold to refresh it instead.`
27
- - Default a brand-new entry to a flat file, `canon/context/<slug>.md`. A domain starts as one page's worth of narrative, and the standard only splits it into a folder once it holds three or more sub-areas, which a fresh domain never does on day one.
28
-
29
- ## Draft
30
-
31
- - Read the domain's own folders and files well enough to answer the standard's three questions: where things live, why they are that way, and how to add one more of what the domain holds.
32
- - Draft `title` and `description` frontmatter, then `## Overview`, `## Layout` (folder ownership lines only, never a file-by-file list), and `## Decisions` or `## Gotchas` wherever the domain's history supplies a non-obvious choice or a workaround worth preserving. Omit an expected section with nothing to put in it rather than padding it.
33
- - Draft against `${CLAUDE_SKILL_DIR}/../../standards/context.md`'s template and ordering: `Overview`, `Layout`, `Decisions`, `Gotchas`, then anything else.
34
-
35
- ## Confirm
36
-
37
- - Show the resolved path and the full drafted content before writing.
38
- - Confirm both with the user. This skill waits for that answer rather than treating the tool permission dialog as the gate, since placement here is a judgment call with no diff to preview it against.
39
-
40
- ## Write
41
-
42
- - Write the file at the confirmed path, creating the folder when it is absent.
43
- - Run `canon markdown audit <path>`.
44
- - Run `canon indexes regen canon/context`, so the domain appears in `canon/context/index.md` immediately rather than drifting until the next unrelated regen.
45
-
46
- ## Response format
47
-
48
- ### Preview
49
-
50
- **Domain:** `<domain>`
51
- **Placement:** `<path>`
52
-
53
- ```markdown
54
- <drafted frontmatter and body>
55
- ```
56
-
57
- ### After confirmation
58
-
59
- ```plaintext
60
- ✅ Drafted: <path>
61
- ```
@@ -1,35 +0,0 @@
1
- ---
2
- name: draft-docs
3
- description: Why a brand-new docs/*.md page needs a placement decision and a confirm step, not the rewrite path docs-sync already owns
4
- ---
5
-
6
- # Docs draft requirement
7
-
8
- ## Gap
9
-
10
- Without this skill, a session drafting documentation for a surface that has no page yet either invents structure from memory or reaches for `docs-sync`, which has nothing to diff a nonexistent page against and reports the topic as unrelated to any change. Either way the page ships with no read of `standards/docs.md` and no catalog placement decided against the folder's actual shelves.
11
-
12
- ## Must
13
-
14
- - Read `standards/docs.md` before drafting, since the frontmatter contract and the four reader questions are what make the page arguable against a sibling
15
- - Decide placement from the existing catalog rather than guessing a folder, reusing a `category` value verbatim when one fits and defaulting to the `docs/` root when none does
16
- - Confirm the resolved path and the full content with the user before writing, since placement is a judgment call with no diff to preview it against
17
- - Run `canon indexes regen` on the containing folder after writing, so the folder's `index.md` picks up the new page immediately rather than drifting until the next unrelated regen
18
-
19
- ## Must not
20
-
21
- - Rewrite an existing page. A topic already covered by a page refuses toward `docs-sync`.
22
- - Hand-edit an `index.md`. It regenerates from sibling frontmatter, and a hand edit is overwritten on the next regen.
23
- - Build a hand-drawn diagram-and-capture authoring loop. `standards/docs.md`'s Mermaid-fence permission is the only path to a diagram this skill takes.
24
-
25
- ## Guards
26
-
27
- - No topic given: stop and ask what surface the page should cover.
28
- - The derived slug already resolves through `canon docs <slug>`: stop and point at `docs-sync` instead. This catches an exact-name collision only.
29
- - A page in the catalog already covers the topic under a different name: stop the same way, checked against the titles and descriptions Placement already reads.
30
-
31
- ## Out of scope
32
-
33
- - Rewriting or syncing an existing `docs/*.md` section against a diff since main: `docs-sync`
34
- - The context entries, requirements, architecture, wireframes, and task board: `context-fold`
35
- - Drafting a standard or a governance rule: `create-standard`, `create-rule`
@@ -1,59 +0,0 @@
1
- ---
2
- name: draft-docs
3
- description: Drafts a brand-new `docs/*.md` page against the docs standard, decides its placement in the existing catalog, confirms with the user, then writes. Use when asked to "add a docs page for X", "write a new doc for X", "document X under docs/", or "create a docs page for X" where no existing page covers the topic. Do NOT use to rewrite or sync an existing `docs/*.md` section against a diff, which is `docs-sync`.
4
- ---
5
-
6
- # Docs draft
7
-
8
- Drafts one brand-new `docs/*.md` page end to end: read the standard, decide where the page belongs in the existing catalog, confirm the draft with the user, then write.
9
-
10
- Read these files in parallel:
11
-
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`: punctuation and formatting for all generated text
14
- - The `write-human` skill: voice, rhythm, and sentence construction for all generated text
15
-
16
- ## Guards
17
-
18
- - If no topic is given, stop: `❌ No topic given. Name the surface this page should cover.`
19
- - Derive a kebab-case slug from the topic and run `canon docs <slug>`. A resolved page means the topic is already covered under that exact name. Stop: `❌ <slug> already resolves to an existing page. Run canon:docs-sync instead.` This is a name match rather than a topic match. Placement below checks the wider case.
20
-
21
- ## Placement
22
-
23
- - Read `docs/index.md` and its sub-catalogs for the closest existing `category`. <!-- canon-allow-reference: illustrates the target project's own docs/ tree, not a citation of this repository's own corpus -->
24
- - Check every page title and description this read surfaces against the topic. The Guards check above only catches an exact-slug collision, and a page already covering the same subject under a different slug still resolves here at no extra cost, since this read already runs. Stop the same way on a match: `❌ <path> already covers this topic under a different name. Run canon:docs-sync instead.`
25
- - Reuse a matching `category` value verbatim. A near-miss spelling opens a second shelf holding one page, per the docs standard.
26
- - Default to the `docs/` root with no `category` when nothing fits. A subfolder earns itself only once a shelf of pages already sits there, per the standard's splitting rule.
27
-
28
- ## Draft
29
-
30
- - Draft `title`, `description`, and `category` (where one applies), then the page body, against `${CLAUDE_SKILL_DIR}/../../standards/docs.md`.
31
- - Write for a reader with no source open. The standard's four questions are the test: what the surface is, what to run or write, what it refuses, and where to go for the adjacent surface.
32
-
33
- ## Confirm
34
-
35
- - Show the resolved path and the full drafted content before writing.
36
- - Confirm both with the user. This skill waits for that answer rather than treating the tool permission dialog as the gate, since placement here is a judgment call with no diff to preview it against.
37
-
38
- ## Write
39
-
40
- - Write the file at the confirmed path, creating the folder when it is absent.
41
- - Run `canon markdown audit <path>`.
42
- - Run `canon indexes regen <folder>` on the containing folder, so its `index.md` picks up the new page.
43
-
44
- ## Response format
45
-
46
- ### Preview
47
-
48
- **Topic:** `<topic>`
49
- **Placement:** `<path>` (category: `<category-or-root>`)
50
-
51
- ```markdown
52
- <drafted frontmatter and body>
53
- ```
54
-
55
- ### After confirmation
56
-
57
- ```plaintext
58
- ✅ Drafted: <path>
59
- ```
@@ -1,38 +0,0 @@
1
- ---
2
- name: draft-readme
3
- description: Why a README needs a project-type read and a confirm step, not the rewrite path docs-sync already owns
4
- ---
5
-
6
- # Readme draft requirement
7
-
8
- ## Gap
9
-
10
- Without this skill, a session drafting a README either copies the generic template from memory or reaches for `docs-sync`, which has nothing to diff a nonexistent page against and reports the topic as unrelated to any change. A scaffold-written stub meets the same dead end, since no diff touches it either. Either way the page ships with no read of `standards/readme.md`, no read of what the project actually is, and no badge chosen against its rendered value rather than its service name.
11
-
12
- A README whose real documentation lives in `canon/context/` or `docs/` was a second gap the standard itself carried until this build: nothing named a pointer page as complete, so a session drafting one either padded the page or read the required list as unsatisfied.
13
-
14
- ## Must
15
-
16
- - Read `standards/readme.md` before drafting, since its `## Voice` section is scoped to a repository-root README and yields to `write-human`'s reference voice everywhere else
17
- - Detect every project type the standard's `## Content` list applies to, from the manifest and the tree, rather than drafting against the closest single type
18
- - Treat an existing README with no H1, or with headings that name only the scaffold that wrote it, as unedited generator output to draft over rather than a page to sync section by section
19
- - Read the header block's slots off the repository, being the mark, the claim, the live link, and the product screenshot, and skip the link and the screenshot for a project with no page, so every element traces to a file or field the project holds
20
- - Verify a candidate badge by the value it would render rather than by a fetch's status code, since a badge service answers 200 for a query it cannot satisfy
21
- - Confirm the resolved path, the detected types, the badge candidates, and the full content with the user before writing, since project-type detection and badge selection are judgment calls with no diff to preview them against
22
-
23
- ## Must not
24
-
25
- - Rewrite an authored README. One carrying an H1 that names the project refuses toward `docs-sync`.
26
- - Offer to overwrite an authored README on the refusal path, or propose conforming it to what this skill would have drafted. A target project's own citations into its README are invisible from here, so the refusal reports rather than proposes.
27
- - Invent a screenshot or a mark the project does not hold, or write a placeholder path for one. An omitted slot is a correct page and an invented image is the failure.
28
- - Assume this skill's own invocation frequency needs no check. Whether anything reaches for it beyond an author typing its name has no answer at creation time, so a review pass some months in should read that back rather than take the assumption on faith.
29
-
30
- ## Guards
31
-
32
- - The target already exists and is authored, carrying an H1 that names the project: stop and point at `docs-sync` instead.
33
-
34
- ## Out of scope
35
-
36
- - Rewriting or syncing an existing authored `README.md` against a diff since main: `docs-sync`
37
- - The consumer-facing reference under `docs/`: `draft-docs`
38
- - Product scope and goals, and every other surface `standards/readme.md` already scopes out of its own governance
@@ -1,73 +0,0 @@
1
- ---
2
- name: draft-readme
3
- description: Drafts a project's README.md against the readme standard, detecting project type and badge candidates, and confirming with the user before write. Use when asked to "write a README", "draft a README for this project", "add a README", or "create a README.md" where none exists yet or the existing one is unedited scaffold output. Do NOT use to rewrite or resync an existing authored README against a diff, which is `docs-sync`.
4
- ---
5
-
6
- # Readme draft
7
-
8
- Drafts a project's `README.md` end to end: read the standard, detect the project's shape, confirm the draft with the user, then write.
9
-
10
- Read these files in parallel:
11
-
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`: punctuation and formatting for all generated text
14
- - The `write-human` skill: rhythm, density, and sentence construction for all generated text
15
-
16
- ## Guards
17
-
18
- - Default the target to `README.md` at the repository root when no path is given. A caller naming a path under a folder, a harness, or an internal tool is drafting a nested README instead, which keeps the reference voice per the standard's `## Voice` section rather than the root voice below.
19
- - Read the target if it exists.
20
- - It carries an H1 naming the project: it is authored. Stop: `❌ <path> already exists and covers the project. Run canon:docs-sync instead.`
21
- - It carries no H1, or its only headings restate the tool that scaffolded it rather than the project: it is unedited generator output. Continue, drafting over it rather than syncing its sections.
22
- - It does not exist: continue.
23
- - A hand-authored README opening with a badge block, or a title in some other form the H1 test misses, falls into the no-H1 branch the same as a scaffold page. The Confirm step below is what catches that case before the write happens, so treat it as load-bearing rather than a courtesy: never skip it on the reasoning that the guard already decided.
24
-
25
- ## Detect
26
-
27
- - Read the project's manifest (`package.json`, `pyproject.toml`, `Cargo.toml`, or equivalent) for a `bin` field or CLI entry point, an installable package name, and its declared dependencies.
28
- - Check for a `claude/skills/` or `.claude/skills/` folder, a `plugin.json`, or a marketplace manifest, each naming an agent-facing or marketplace-distributed surface.
29
- - A project is often several of these at once. Note every type that applies rather than stopping at the first match, since the Draft step covers each one the project actually is.
30
- - Check for a page. A dependency on a site framework or a site config file in the manifest or the tree marks a project as having one. Read a live URL separately, from a `homepage` field or a deploy config, since a project can have a page and no known URL.
31
- - A monorepo can carry a page in one package and a CLI in another, so both signals may fire. Report each rather than picking one.
32
- - Look for the mark and the screenshot among images the project already commits: scan the existing README for image references, then the asset and public folders.
33
-
34
- ## Draft
35
-
36
- - Draft the page against `${CLAUDE_SKILL_DIR}/../../standards/readme.md`: H1, a 2-3 sentence description in plain text, then the required sections, then whichever optional sections and per-type content the Detect step found.
37
- - Open the page with the standard's header block, filling each slot from what Detect found: mark, title, badges, a one-line claim from the manifest description, the live link, then the product screenshot.
38
- - Fill the screenshot slot only with an image the project already commits, referenced with alt text naming what it depicts. This skill cannot capture one. Omit the slot when no such image exists and say so in the preview. Never write a placeholder path.
39
- - Omit the link and the screenshot for a project with no page, and the mark for a project with none, without a note in the drafted page. A project with a page and no known URL gets the screenshot slot, and the Confirm step asks for the link.
40
- - Cover every applicable project type from the standard's `## Content` list rather than picking the closest one.
41
- - Candidate badges: check for a published package (a registry field in the manifest), a CI workflow, and a `LICENSE` file.
42
- - State each candidate's rendered value in the preview rather than trusting a fetch's status code, since a badge service answers 200 for a query it cannot satisfy.
43
- - Pin a status badge to the branch the standard names and confirm the workflow actually triggers on that branch before offering it. Zero badges is a correct answer when nothing passes the test.
44
-
45
- ## Confirm
46
-
47
- - Show the resolved path, the detected project types, the header slots filled or skipped with the reason for each, the badge candidates and what backs each one, and the full drafted content before writing.
48
- - The skill can confirm that an image file exists and is referenced, and it cannot verify the picture shows the product. Ask the user to look at it in the preview.
49
- - Confirm with the user. This skill waits for that answer rather than treating the tool permission dialog as the gate, since project-type detection and badge selection are judgment calls with no diff to preview them against.
50
-
51
- ## Write
52
-
53
- - Write the file at the confirmed path, creating the folder when it is absent.
54
- - Run `canon markdown audit <path>`.
55
-
56
- ## Response format
57
-
58
- ### Preview
59
-
60
- **Target:** `<path>` (root | nested)
61
- **Detected:** `<project types>`
62
- **Header:** `<each slot as filled (source) or skipped (reason)>`
63
- **Badges:** `<candidates, or none>`
64
-
65
- ```markdown
66
- <drafted H1 and body>
67
- ```
68
-
69
- ### After confirmation
70
-
71
- ```plaintext
72
- ✅ Drafted: <path>
73
- ```
@@ -1,42 +0,0 @@
1
- ---
2
- name: draft-wiki
3
- description: Why a brand-new wiki reference page needs both placement tests, a catalog collision check, and a sourced read before anything is written
4
- ---
5
-
6
- # Wiki draft requirement
7
-
8
- ## Gap
9
-
10
- Without this skill, a session asked for a wiki page writes one from training knowledge, which is the single thing the wiki standard forbids outright, and nothing in the resulting file shows that it happened. It also files the page by where the request came from rather than by who owns the subject, so material about the project itself lands in the wiki and material about a third-party tool acquires a folder the standard never sanctioned.
11
-
12
- The standard can state all of this and still be read by nothing, which is the condition this skill was written into in the toolkit. A page written under that condition conforms by the author's memory rather than by a read, and it ships looking identical to one that was checked.
13
-
14
- ## Must
15
-
16
- - Read the wiki standard before drafting, since the placement tests and the sourcing rule are the two things a session gets wrong from memory
17
- - Run both placement tests and refuse on either, since a page passing one and failing the other is still non-conforming
18
- - Check the subject against the catalog by title and description, not by slug alone, since a subject can be covered under a name the slug does not guess
19
- - Build the draft on a fetched read and stop when the fetch fails, since a page written from recall is indistinguishable from a checked one once it ships
20
- - Confirm the path, the source, and the content with the user before writing, since the standard forbids writing a wiki file unasked
21
- - Name the folder by resolving what the standard states rather than by carrying a path in the body, since the body ships to projects whose layout this repository does not set
22
-
23
- ## Must not
24
-
25
- - Widen the folder split to admit a subject the second placement test rejects. That is a change to the standard, argued there.
26
- - Edit or refresh a page that already exists. A collision refuses toward editing the existing page rather than drafting a second one.
27
- - Substitute recall for a failed fetch, even for a subject the session believes it knows.
28
-
29
- ## Guards
30
-
31
- - No subject given: stop and ask what subject the page should cover.
32
- - The wiki root does not resolve: say so and ask before creating it, since a project holding no wiki has never taken the placement rule.
33
- - The slug already resolves to a page: stop and point at editing that page.
34
- - The catalog already covers the subject under a different name: stop the same way, checked against the titles and descriptions the Collision step already reads.
35
-
36
- ## Out of scope
37
-
38
- - Editing or refreshing a wiki page that already exists: a plain edit against the same standard
39
- - Drafting a `docs/*.md` page: `draft-docs`
40
- - Drafting a `canon/context/<domain>.md` entry: `draft-context`
41
- - Voice, rhythm, and sentence construction in the drafted page: the `write-human` skill
42
- - Punctuation, headings, and word choice in the drafted page: the markdown standard