@erclx/canon 4.109.0 → 4.111.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.
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/{canon-feedback-file → canon-feedback}/REQUIREMENT.md +7 -6
- package/claude/skills/{canon-feedback-file → canon-feedback}/SKILL.md +9 -19
- package/claude/skills/canon-feedback-triage/REQUIREMENT.md +1 -1
- package/claude/skills/canon-feedback-triage/SKILL.md +1 -1
- package/claude/skills/canon-operator/REQUIREMENT.md +2 -2
- package/claude/skills/canon-operator/SKILL.md +3 -4
- package/claude/skills/draft-wiki/REQUIREMENT.md +42 -0
- package/claude/skills/draft-wiki/SKILL.md +83 -0
- package/claude/skills/git-issue/REQUIREMENT.md +1 -1
- package/claude/skills/git-issue/SKILL.md +1 -1
- package/claude/skills/target-check/references/domains.md +2 -2
- package/docs/agents/install-and-sync.md +4 -13
- package/docs/agents/teach.md +4 -2
- package/docs/target-projects.md +0 -2
- package/docs/workflow/ai-workflow.md +8 -11
- package/package.json +1 -1
- package/scripts/core/capture-home.sh +59 -0
- package/src/claude/cases/authoring.ts +5 -0
- package/src/claude/cases/setup.ts +3 -24
- package/src/commands/sync.ts +0 -16
- package/src/design/components.ts +459 -147
- package/src/shipped/references.ts +1 -2
- package/src/sync/reverse.ts +3 -74
- package/src/teach/nav.ts +410 -58
- package/claude/skills/migration-claude-md/REQUIREMENT.md +0 -40
- package/claude/skills/migration-claude-md/SKILL.md +0 -79
- package/claude/skills/migration-context/REQUIREMENT.md +0 -36
- package/claude/skills/migration-context/SKILL.md +0 -97
- package/claude/skills/migration-standards-drop/REQUIREMENT.md +0 -55
- package/claude/skills/migration-standards-drop/SKILL.md +0 -113
- package/claude/skills/migration-superseded/REQUIREMENT.md +0 -44
- package/claude/skills/migration-superseded/SKILL.md +0 -115
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: migration-claude-md
|
|
3
|
-
description: Why a bloated CLAUDE.md is rebalanced by proposal rather than by edit, and what the seed baseline settles
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Migration claude md requirement
|
|
7
|
-
|
|
8
|
-
## Gap
|
|
9
|
-
|
|
10
|
-
Without this skill, a session asked to slim `CLAUDE.md` deletes sections it judges stale and writes the rest into files it creates in the same pass, so a classification the user disagrees with is no longer one command to undo. The file is always-load context, so a wrong move costs every later session rather than one.
|
|
11
|
-
|
|
12
|
-
Three more failures share a cause. The session has no baseline for what belongs in `CLAUDE.md`, so it reads toolkit-seeded always-load behavior as bloat and proposes moving it, and the next seed sync puts it back. A section carrying a rule and a narrative together gets sorted whole into one bucket, which loses half of it either way. And a target that already exists gets written over, since a proposal blind to the folder cannot tell a create from a collision.
|
|
13
|
-
|
|
14
|
-
The skill also writes into `canon/context/`, a folder `migration-context` moves files into. A proposal drafted before those moves land cannot see the entries they create, so a move that should have resolved to an append reads as a create.
|
|
15
|
-
|
|
16
|
-
## Must
|
|
17
|
-
|
|
18
|
-
- Classify every `##` section against the three tiers in a fixed order, so the same section lands the same way twice
|
|
19
|
-
- Treat a section matching the seed baseline as always-load by definition and propose no move for it
|
|
20
|
-
- Read the existing rules and context folders before resolving a target, so an existing entry resolves to an append and a taken rule slot resolves to a conflict
|
|
21
|
-
- Derive a rule's glob from the scope the section names rather than from the folder it describes
|
|
22
|
-
- Propose and stop, leaving every file write and the `CLAUDE.md` edit to the user
|
|
23
|
-
- Report the already-lean case as a pass rather than manufacturing moves to justify the run
|
|
24
|
-
|
|
25
|
-
## Must not
|
|
26
|
-
|
|
27
|
-
- Sort a section holding both a rule and a narrative into either bucket. Flag it for a manual split.
|
|
28
|
-
- Create a rule file, create a context entry, or edit `CLAUDE.md`
|
|
29
|
-
- Propose a move onto an existing rule path. Report it as a conflict and skip it.
|
|
30
|
-
|
|
31
|
-
## Guards
|
|
32
|
-
|
|
33
|
-
- No `CLAUDE.md` at the project root stops before any classification runs
|
|
34
|
-
- Fewer than three `##` sections reports the file already lean, since a rebalance needs something to rebalance
|
|
35
|
-
|
|
36
|
-
## Out of scope
|
|
37
|
-
|
|
38
|
-
- Relocating `docs/` files, which `migration-context` proposes into this same `canon/context/` folder. Run that skill first when both apply, so Step 3 reads a folder its moves have already populated.
|
|
39
|
-
- Scaffolding the rule files it proposes, which `create-rule` does with the numbering and frontmatter
|
|
40
|
-
- Regenerating `canon/context/index.md`, which `canon indexes regen` does once the user has applied the moves
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: migration-claude-md
|
|
3
|
-
description: Classifies each section of a target project's bloated `CLAUDE.md` into the three-tier context model and proposes moves to path-scoped rules or context entries, keeping only always-load behavior in `CLAUDE.md`. Use when asked to "slim CLAUDE.md", "migrate CLAUDE.md to rules", "rebalance CLAUDE.md", or when a project's `CLAUDE.md` has grown large. Do NOT move `docs/` files (that is `migration-context`) and do NOT auto-execute. Proposal only.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Claude md migrate
|
|
7
|
-
|
|
8
|
-
Rebalance a large `CLAUDE.md` so only always-load behavior stays in it, path-scoped behavior becomes a rule, and domain narrative becomes a context entry. Every move is a proposal the user applies by hand.
|
|
9
|
-
|
|
10
|
-
Run `migration-context` first when both apply. Its moves populate `canon/context/`, and Step 3 has to read the folder those moves left so an existing entry resolves to an append rather than blocking the move that should have created it.
|
|
11
|
-
|
|
12
|
-
A project the surface move has not reached keeps its context folder under `.claude/` rather than `canon/`. Read and propose entries into whichever root already carries the folder, and propose `canon/` only when neither does, since a new `canon/` folder would hide every entry the old one holds.
|
|
13
|
-
|
|
14
|
-
## Guards
|
|
15
|
-
|
|
16
|
-
- If no `CLAUDE.md` exists at `pwd`, stop: `❌ No CLAUDE.md found at the project root.`
|
|
17
|
-
- If `CLAUDE.md` has fewer than three `##` sections, stop: `✅ CLAUDE.md is already lean. Nothing to rebalance.`
|
|
18
|
-
|
|
19
|
-
## Step 1: discover
|
|
20
|
-
|
|
21
|
-
Run these in parallel from `pwd`:
|
|
22
|
-
|
|
23
|
-
- Read `CLAUDE.md`
|
|
24
|
-
- `ls .claude/rules/ 2>/dev/null`: existing rule subdirs and numbers for placement
|
|
25
|
-
- `ls canon/context/ 2>/dev/null`: existing context entries for conflict checks
|
|
26
|
-
- `canon claude seeds list --json 2>/dev/null`: the base seed set. Read the `CLAUDE.md` entry's `content` as the always-load baseline. Skip this input when `canon` is not installed.
|
|
27
|
-
|
|
28
|
-
## Step 2: classify each section
|
|
29
|
-
|
|
30
|
-
Split `CLAUDE.md` by `##` heading. Score each section against this order:
|
|
31
|
-
|
|
32
|
-
1. **Always-load.** Stays in `CLAUDE.md`. Signals: cross-cutting behavior that applies every session, output and formatting rules, project-wide invariants, conventions with no file scope. A section that matches the seed baseline is always-load by definition. Keep it and propose no move.
|
|
33
|
-
2. **Path-scoped.** Propose a rule. Signals: behavior that only applies when working in a folder (`frontend/`, `backend/`) or on a file type, framework-specific conventions, "when editing X do Y" phrasing. Derive the glob from the named scope.
|
|
34
|
-
3. **Domain narrative.** Propose a context entry. Signals: prose describing how a system or domain is built, decisions, gotchas, structure. Not do-or-do-not rules.
|
|
35
|
-
4. **Mixed.** Both rule and narrative in one section. Flag as "needs manual split". Do not propose a single target.
|
|
36
|
-
|
|
37
|
-
## Step 3: resolve targets
|
|
38
|
-
|
|
39
|
-
For each section proposed for a move:
|
|
40
|
-
|
|
41
|
-
- Path-scoped: propose `.claude/rules/<subdir>/<n>-<slug>.md` with a `paths:` glob. Pick the subdir and a free number the way `create-rule` does. If `.claude/rules/<subdir>/` already holds a rule on the topic, mark as "conflict" and skip.
|
|
42
|
-
- Domain narrative: propose `canon/context/<domain>.md`. If the entry already exists, flat or as a same-named `canon/context/<domain>/` folder, propose appending to the file that owns it rather than creating a duplicate flat entry beside a domain already split.
|
|
43
|
-
|
|
44
|
-
## Step 4: output
|
|
45
|
-
|
|
46
|
-
Print one grouped proposal block. Omit empty groups.
|
|
47
|
-
|
|
48
|
-
```markdown
|
|
49
|
-
## Keep in CLAUDE.md
|
|
50
|
-
|
|
51
|
-
- `## <heading>` (<one-line reason: always-load behavior>)
|
|
52
|
-
|
|
53
|
-
## Extract to a path-scoped rule
|
|
54
|
-
|
|
55
|
-
- `## <heading>` → `.claude/rules/<subdir>/<n>-<slug>.md`, paths `<glob>` (<reason>)
|
|
56
|
-
|
|
57
|
-
## Extract to a context entry
|
|
58
|
-
|
|
59
|
-
- `## <heading>` → `canon/context/<domain>.md` (<reason>)
|
|
60
|
-
- `## <heading>` → `canon/context/<domain>/<sub-area>.md`, appending to the domain's existing sibling file (<reason>)
|
|
61
|
-
|
|
62
|
-
## Needs manual split
|
|
63
|
-
|
|
64
|
-
- `## <heading>` (rule and narrative mixed)
|
|
65
|
-
|
|
66
|
-
## Conflicts
|
|
67
|
-
|
|
68
|
-
- `## <heading>` → `.claude/rules/<subdir>/<n>-<slug>.md` already exists. Skipping.
|
|
69
|
-
|
|
70
|
-
## Reminder
|
|
71
|
-
|
|
72
|
-
Scaffold each rule with create-rule, which carries the rule standard.
|
|
73
|
-
Follow the context standard for each new context entry.
|
|
74
|
-
Run canon indexes regen after adding context entries.
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
If every section classified as always-load, output: `✅ CLAUDE.md holds only always-load behavior. No moves proposed.`
|
|
78
|
-
|
|
79
|
-
Do not edit `CLAUDE.md`, and do not create the rule or context files. The user reviews the proposal, then applies each move by hand.
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: migration-context
|
|
3
|
-
description: Scope boundary for the docs audience split and its ordering against the other two migrations
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Migration context requirement
|
|
7
|
-
|
|
8
|
-
## Gap
|
|
9
|
-
|
|
10
|
-
Without this skill, a session judges a `docs/` file agent-facing, moves it, and rewrites the inbound links in the same pass, so a classification the user rejects is no longer one command to undo.
|
|
11
|
-
|
|
12
|
-
Three more failures share a cause. The skill reads a folder two other surfaces also write, and a proposal blind to them destroys work.
|
|
13
|
-
|
|
14
|
-
A seed-derived `development.md` moved out of `docs/` comes back on the next seed sync. A move onto an existing `canon/context/` filename overwrites the entry sitting there. A proposal drafted while `migration-claude-md` is proposing entries into the same folder cannot see those targets, and running the two in the wrong order turns a legitimate move into a skipped conflict.
|
|
15
|
-
|
|
16
|
-
## Must
|
|
17
|
-
|
|
18
|
-
- Classify by audience signal in the file rather than by its name or its folder position
|
|
19
|
-
- Propose and stop. The `git mv` commands and the link fixes stay the user's to run.
|
|
20
|
-
- Report every inbound reference to a moved path as a TODO line, leaving the reference itself untouched
|
|
21
|
-
- Defer a seed-derived file to the seed sync path rather than proposing a move for it
|
|
22
|
-
- Skip a move whose destination already exists and report it as a conflict
|
|
23
|
-
|
|
24
|
-
## Must not
|
|
25
|
-
|
|
26
|
-
- Sort a file carrying both audiences into either bucket. Flag it for a manual split, since a whole-file move and a silent split are both wrong.
|
|
27
|
-
- Descend into `docs/` subfolders. List them for manual review and leave them alone.
|
|
28
|
-
|
|
29
|
-
## Guards
|
|
30
|
-
|
|
31
|
-
- A missing `docs/` directory, or one holding no top-level markdown, stops before any classification runs
|
|
32
|
-
|
|
33
|
-
## Out of scope
|
|
34
|
-
|
|
35
|
-
- Classifying `CLAUDE.md` sections, which `migration-claude-md` proposes into this same `canon/context/` folder. Run this skill first when both apply, so that skill's append-or-create check reads a folder the moves have already populated.
|
|
36
|
-
- Regenerating `canon/context/index.md`, which `canon indexes regen` does once the user has applied the moves
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: migration-context
|
|
3
|
-
description: Classifies markdown files in a target project's `docs/` folder and proposes `git mv` commands to relocate agent-flavored content to `canon/context/`. Use when asked to "migrate docs to context", "move docs to context", "split docs", or to align an existing project with the three-tier context model. Do NOT auto-execute moves or rewrite inbound links. Proposal only.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Claude context migrate
|
|
7
|
-
|
|
8
|
-
Run this skill before `migration-claude-md` when both apply. That skill proposes entries into the same `canon/context/` folder, and an entry landing there first makes the corresponding move here read as a conflict and get skipped, which loses the richer `docs/` file.
|
|
9
|
-
|
|
10
|
-
A project the surface move has not reached keeps its context folder under `.claude/` rather than `canon/`. Read and propose moves into whichever root already carries the folder, and propose `canon/` only when neither does, since a new `canon/` folder would hide every entry the old one holds.
|
|
11
|
-
|
|
12
|
-
## Guards
|
|
13
|
-
|
|
14
|
-
- If no `docs/` directory exists at `pwd`, stop: `❌ No docs/ directory found.`
|
|
15
|
-
- If `docs/` contains no `.md` files at the top level, stop: `❌ No markdown files in docs/.`
|
|
16
|
-
- This skill operates on flat `docs/*.md` only. Subfolders under `docs/` are listed in the output as "manual review needed" and skipped.
|
|
17
|
-
|
|
18
|
-
## Step 1: discover
|
|
19
|
-
|
|
20
|
-
Run these in parallel from `pwd`:
|
|
21
|
-
|
|
22
|
-
- `ls docs/*.md 2>/dev/null`: list flat markdown files
|
|
23
|
-
- `ls docs/*/ 2>/dev/null`: detect subfolders for the manual-review note
|
|
24
|
-
- `ls canon/context/ 2>/dev/null`: detect already-migrated content for conflict checks
|
|
25
|
-
- `canon claude seeds list --json 2>/dev/null`: get the canonical seed list to identify seed-derived files
|
|
26
|
-
|
|
27
|
-
Read each discovered `docs/*.md` file in parallel.
|
|
28
|
-
|
|
29
|
-
## Step 2: classify
|
|
30
|
-
|
|
31
|
-
For each file, score against this rule order:
|
|
32
|
-
|
|
33
|
-
1. **Seed-derived.** Filename matches `development.md` or `ci.md` and content shape resembles the toolkit's base seed (frontmatter plus a Setup or Triggers section plus tables for scripts or checks). These belong to the seed-migration path. Do not propose a move here.
|
|
34
|
-
2. **Agent-flavored.** Score the following signals. Classify as agent-flavored when two or more match:
|
|
35
|
-
- Dense file paths in code fences
|
|
36
|
-
- Sections titled "Anti-patterns", "Layer responsibilities", "Conventions", or "Commands"
|
|
37
|
-
- Tables of CLI commands
|
|
38
|
-
- Explicit "do not" rules
|
|
39
|
-
3. **Human-only.** Default fallback when no agent signals match. Typical signals:
|
|
40
|
-
- Tutorial prose
|
|
41
|
-
- Sections titled "Welcome", "Getting started", "Contributing", or "Installation"
|
|
42
|
-
- Second-person narrative aimed at new contributors
|
|
43
|
-
4. **Mixed.** Both agent and human signals present. Flag as "needs manual split". Do not propose a move.
|
|
44
|
-
|
|
45
|
-
## Step 3: check conflicts and inbound links
|
|
46
|
-
|
|
47
|
-
For every file proposed for a move:
|
|
48
|
-
|
|
49
|
-
- If `canon/context/<filename>` already exists, or a same-named folder exists at `canon/context/` with `<filename>`'s `.md` extension dropped, mark as "conflict" and skip the move. A folder of the same name is still a collision, since the domain already lives there split into siblings.
|
|
50
|
-
- Run `git grep -n "docs/<filename>"` (or grep equivalent) to list inbound references in `CLAUDE.md`, `README.md`, and other markdown. Report each as a TODO line. Do not rewrite.
|
|
51
|
-
|
|
52
|
-
## Step 4: output
|
|
53
|
-
|
|
54
|
-
Print one grouped proposal block. Omit empty groups.
|
|
55
|
-
|
|
56
|
-
```markdown
|
|
57
|
-
## Move to canon/context/
|
|
58
|
-
|
|
59
|
-
- docs/<file>.md → canon/context/<file>.md (<one-line reason>)
|
|
60
|
-
|
|
61
|
-
## Keep in docs/
|
|
62
|
-
|
|
63
|
-
- docs/<file>.md (<one-line reason>)
|
|
64
|
-
|
|
65
|
-
## Defer to seed-sync
|
|
66
|
-
|
|
67
|
-
- docs/<file>.md (matches toolkit base seed)
|
|
68
|
-
|
|
69
|
-
## Needs manual split
|
|
70
|
-
|
|
71
|
-
- docs/<file>.md (mixed agent and human signals)
|
|
72
|
-
|
|
73
|
-
## Conflicts
|
|
74
|
-
|
|
75
|
-
- docs/<file>.md → canon/context/<file>.md already exists. Skipping.
|
|
76
|
-
|
|
77
|
-
## Subfolders (manual review)
|
|
78
|
-
|
|
79
|
-
- docs/<subfolder>/
|
|
80
|
-
|
|
81
|
-
## Suggested git mv commands
|
|
82
|
-
|
|
83
|
-
git mv docs/<file>.md canon/context/<file>.md
|
|
84
|
-
|
|
85
|
-
## Inbound links to fix after moves
|
|
86
|
-
|
|
87
|
-
- CLAUDE.md:42 references docs/<file>.md
|
|
88
|
-
- README.md:17 references docs/<file>.md
|
|
89
|
-
|
|
90
|
-
## Reminder
|
|
91
|
-
|
|
92
|
-
Run canon indexes regen to update canon/context/index.md.
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
If every file classified as "Keep in docs/", output: `✅ All docs/ content is human-facing. No moves proposed.`
|
|
96
|
-
|
|
97
|
-
Do not execute the `git mv` commands. Do not edit `CLAUDE.md` or `README.md`. The user runs the commands and fixes the links manually after reviewing.
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: migration-standards-drop
|
|
3
|
-
description: Why the standards-tree drop ships as an ordered proposal, what the two pre-delete reads catch, and why one citation form serves every surface inside a target
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Migration standards drop requirement
|
|
7
|
-
|
|
8
|
-
## Gap
|
|
9
|
-
|
|
10
|
-
Without this skill, nothing names the tree. The sync engine registers governance alone and the unmigrated scan carries an empty root-layout set, both by decision rather than by omission, so a target holding 21 installed standards files reports clean and the drop runs off whoever remembers to look. The census that found the population walked one folder on one machine and moved the count from four to seven.
|
|
11
|
-
|
|
12
|
-
The order is the second failure and it has two halves. A session that deletes before syncing lands the installed rules citing a path it removed, and one that sweeps before syncing repoints citations the sync then rewrites.
|
|
13
|
-
|
|
14
|
-
The delete otherwise runs blind in two directions. Two of the five targets measured on 2026-08-28 carried a runtime reader, one a hook hand-parsing a standard for its banned-word set, and a hook whose input is gone audits nothing while reporting a clean run. In the other direction, nothing separates a file the project wrote from a toolkit copy by name, and the corpus had moved on from all 20 files at one target, so a content diff sorts every file as changed and a session reading that diff either keeps everything or loses the one file no corpus carries.
|
|
15
|
-
|
|
16
|
-
The repoint form is the fourth. A session applying the citation rule it knows from a shipped skill writes `${CLAUDE_SKILL_DIR}/../../standards/<name>.md`, which from a project-local skill at `.claude/skills/<name>/` resolves back into the tree the same pass deleted, and reports the sweep finished.
|
|
17
|
-
|
|
18
|
-
The last is the name map. `prose` split into `markdown.md` plus the `write-human` skill and resolves as no standard, so a mechanical one-to-one repoint produces a citation to nothing and every check on it passes.
|
|
19
|
-
|
|
20
|
-
## Must
|
|
21
|
-
|
|
22
|
-
- Detect from a read of `.claude/standards/` itself, since no report names the tree and a session waiting for one waits forever
|
|
23
|
-
- Report the state a binary behind the published version puts the sync in, before naming a sync a stale binary would run
|
|
24
|
-
- Split the tree against `canon standards list --json` three ways, separating an unchanged toolkit copy from a drifted one and from a name that resolves to no standard
|
|
25
|
-
- Name every runtime reader ahead of any delete, splitting a reader from a citation by whether the file is markdown, and say when the search could not run
|
|
26
|
-
- Give every citation inside a target one target form, `canon standards <name>`, and say why the plugin-root form fails there
|
|
27
|
-
- Order the proposal sync, drop, sweep, and state that the sweep re-reads after the sync rather than before it
|
|
28
|
-
- Report an unmatched name as the user's to place, naming the `prose` split as the recorded instance
|
|
29
|
-
- Report the measured empty case as a pass, since the guard is what proves the read ran
|
|
30
|
-
|
|
31
|
-
## Must not
|
|
32
|
-
|
|
33
|
-
- Run the sync, delete or move a file under the tree, or rewrite a citation
|
|
34
|
-
- Sort a drifted file as project-authored or as toolkit-owned on a content diff alone
|
|
35
|
-
- Propose the plugin-root citation form for a surface inside a target
|
|
36
|
-
- Relocate the install stamp. One visit per target is cheaper than two and a skill is not a visit, so the stamp rides with whatever else reaches the target.
|
|
37
|
-
- Stay in the catalog on the author typing its name alone. Nothing can answer that before the skill has run, so read the census back once it has and retire it if the answer is nobody.
|
|
38
|
-
|
|
39
|
-
## Guards
|
|
40
|
-
|
|
41
|
-
- A directory with no `.claude/` stops, since nothing there installed a tree
|
|
42
|
-
- A `.claude/standards/` holding no markdown is the pass rather than a refusal
|
|
43
|
-
- No `canon` on `PATH` stops, since every citation this move writes names a verb the target has to run
|
|
44
|
-
|
|
45
|
-
## Out of scope
|
|
46
|
-
|
|
47
|
-
- Classifying `CLAUDE.md` sections into the three-tier model: `migration-claude-md`
|
|
48
|
-
- Relocating `docs/` files by audience: `migration-context`
|
|
49
|
-
- Splitting a retired `.claude/` file into the folder that replaced it, which pairs one file against one folder rather than dropping a corpus: `migration-superseded`
|
|
50
|
-
- Reconciling a seed file against its source section by section: `seed-sync`
|
|
51
|
-
- Applying the drop and the sweep, which the user does after reviewing
|
|
52
|
-
|
|
53
|
-
## Why it ships while its consumer row is parked
|
|
54
|
-
|
|
55
|
-
The one task performing this move is parked on the operator declining outside-repository work, so the skill arrives with three known consumers and no live instance. It ships anyway, because the parked row is about who is authorized to visit a target rather than about the move being wrong, and the skill is what makes the move repeatable by whoever is authorized. The evidence behind it comes from the census rather than from a run, which is the weaker of the two and is recorded here as such.
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: migration-standards-drop
|
|
3
|
-
description: Proposes the ordered drop of an installed `.claude/standards/` tree and the repoint of every citation at `canon standards <name>`, separating a toolkit copy from a file the project wrote and naming any runtime reader before a delete is proposed. Use when asked to "drop the standards tree", "repoint the standards citations", "my project still has .claude/standards/", or when a toolkit update leaves an installed standards copy no command refreshes. Do NOT delete the tree, run the sync, or rewrite a citation. Proposal only.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Migration standards drop
|
|
7
|
-
|
|
8
|
-
## Guards
|
|
9
|
-
|
|
10
|
-
- If `.claude/` does not exist at `pwd`, stop: `❌ No .claude/ directory. Nothing here installed a standards tree.`
|
|
11
|
-
- If `.claude/standards/` holds no markdown, that is the pass: `✅ No installed standards tree. Nothing to drop.`
|
|
12
|
-
- If `canon` is not on `PATH`, stop: `❌ canon is not on PATH. Every citation this move writes names a verb the target has to run.`
|
|
13
|
-
|
|
14
|
-
Detection is the directory read above and nothing else. No report names this tree, since the sync engine registers governance alone and the unmigrated scan covers a root layout an older toolkit wrote rather than a copy under `.claude/`. A session waiting for a command to raise the tree waits forever.
|
|
15
|
-
|
|
16
|
-
## Step 1: read the version the sync would run from
|
|
17
|
-
|
|
18
|
-
Run `canon sync --check . --json` and read its `skew` object. The sync in Step 5 installs the rules the running binary carries, so a binary predating the citation change installs rules naming the path this move removes, and the sweep then has more to fix than it started with.
|
|
19
|
-
|
|
20
|
-
- `state` is `behind`: stop. `❌ The canon on PATH is <installed> against <latest> published. A gov sync from it installs rules citing the standards path. Update, then re-run.`
|
|
21
|
-
- `state` is `unknown`: report the reason and continue. A version that could not be read is unread rather than stale.
|
|
22
|
-
- `state` is `current`: continue.
|
|
23
|
-
|
|
24
|
-
## Step 2: split the tree three ways
|
|
25
|
-
|
|
26
|
-
Run `canon standards list --json`. Each entry carries `name` and `content`, so the comparison needs no second read. Match every `.claude/standards/<stem>.md` against `name`:
|
|
27
|
-
|
|
28
|
-
- **Matched, content identical.** A toolkit copy the corpus still carries unchanged. The drop loses nothing.
|
|
29
|
-
- **Matched, content differs.** A toolkit copy that has drifted, and the diff cannot say which side moved. Report it as a read the user owes rather than sorting it either way. All 20 files measured at one target on 2026-08-28 read as changed, because the corpus had moved on since the install, and none of them was project-authored.
|
|
30
|
-
- **Unmatched.** No standard resolves under that name. Either the project wrote the file or the toolkit retired the name, and the catalog cannot separate the two.
|
|
31
|
-
|
|
32
|
-
Report a project-authored file as one this move keeps. Its destination is `standards/<name>.md` at the project root, which `canon standards <name>` resolves ahead of the package corpus, so the citation form Step 4 gives every other file serves it too.
|
|
33
|
-
|
|
34
|
-
`prose` is the recorded retirement. It split into `markdown.md` plus the `write-human` skill and resolves as no standard at all, so a citation repointed one-to-one from it names nothing. Report an unmatched name as the user's to place and name that split as the instance.
|
|
35
|
-
|
|
36
|
-
## Step 3: name every runtime reader before naming a delete
|
|
37
|
-
|
|
38
|
-
Run both from the project root, in parallel:
|
|
39
|
-
|
|
40
|
-
- `git grep -ln 'claude/standards' -- '*.md'`: the citations Step 4 repoints
|
|
41
|
-
- `git grep -ln 'claude/standards' -- . ':!*.md'`: the readers
|
|
42
|
-
|
|
43
|
-
The extension is the split. Markdown cites the tree and a session reads the citation. A hook, a script, or a config opens a file under it at run time, and dropping the tree under one leaves a check whose input is gone reporting success. Two of the five targets in the 2026-08-28 census carried a reader, one of them a hook hand-parsing a standard for a banned-word set.
|
|
44
|
-
|
|
45
|
-
Report each reader with what replaces it. A reader parsing a standard for a list the CLI now ships reads that list through the verb instead, which is `canon markdown audit <file> --json` for the banned-word case.
|
|
46
|
-
|
|
47
|
-
When `pwd` is not a git work tree, say the reader search did not run rather than reporting no reader.
|
|
48
|
-
|
|
49
|
-
## Step 4: give every citation one target
|
|
50
|
-
|
|
51
|
-
Every citation repoints to `canon standards <name>`, whatever surface it sits on. One form rather than a choice per surface, which is the part a session gets wrong:
|
|
52
|
-
|
|
53
|
-
- A rule under `.claude/rules/` is markdown a glob match loads, so `${CLAUDE_SKILL_DIR}` expands to nothing there
|
|
54
|
-
- A project-local skill under `.claude/skills/<name>/` expands that variable to its own folder, so `${CLAUDE_SKILL_DIR}/../../standards/` resolves back into the tree being dropped
|
|
55
|
-
- `CLAUDE.md` and a context entry expand no variable at all
|
|
56
|
-
|
|
57
|
-
The plugin-root form belongs to a skill the toolkit ships beside its own corpus. Proposing it inside a target writes a path that resolves to the deleted tree.
|
|
58
|
-
|
|
59
|
-
A citation naming a name Step 2 left unmatched carries no target. Report it under what the user supplies.
|
|
60
|
-
|
|
61
|
-
## Step 5: output the ordered proposal
|
|
62
|
-
|
|
63
|
-
The order is fixed and the reverse is the failure. Deleting before the sync lands the installed rules citing a path that is gone, and sweeping before the sync repoints citations the sync then rewrites. The sweep re-reads after the sync for that reason, since the sync fixes the rules it installed and leaves a project's own rules and prose alone.
|
|
64
|
-
|
|
65
|
-
Take the drop command from whether the tree is tracked, read with `git ls-files .claude/standards`. A tracked tree goes out through `git rm -r` so the index moves with the files, and an untracked one through `rm -rf`. A tree holding both needs both commands, since `git rm -r` takes the tracked files, exits zero, and leaves every untracked one where it was.
|
|
66
|
-
|
|
67
|
-
Print the blocks below, omitting any that is empty.
|
|
68
|
-
|
|
69
|
-
````markdown
|
|
70
|
-
## Drop
|
|
71
|
-
|
|
72
|
-
`.claude/standards/` holds <n> files: <n> unchanged toolkit copies, <n> drifted, <n> matching no standard.
|
|
73
|
-
|
|
74
|
-
## Read before dropping
|
|
75
|
-
|
|
76
|
-
- `.claude/standards/<name>.md` drifted from the corpus copy. Confirm the project did not edit it.
|
|
77
|
-
|
|
78
|
-
## Keep
|
|
79
|
-
|
|
80
|
-
- `.claude/standards/<name>.md` matches no standard. Move it to `standards/<name>.md` at the project root, which `canon standards <name>` resolves first.
|
|
81
|
-
|
|
82
|
-
## Runtime readers
|
|
83
|
-
|
|
84
|
-
- `.claude/hooks/<file>.sh` parses a standard at run time. Route it through `canon markdown audit <file> --json` before the drop, or it reports a clean run having read nothing.
|
|
85
|
-
|
|
86
|
-
## Citations to repoint
|
|
87
|
-
|
|
88
|
-
- `CLAUDE.md:42` → `canon standards markdown`
|
|
89
|
-
- `.claude/rules/canon/core/<n>-<slug>.md:8` → `canon standards skill`
|
|
90
|
-
|
|
91
|
-
## You supply
|
|
92
|
-
|
|
93
|
-
- The destination for the `prose` citations. It split into `markdown.md` plus the `write-human` skill, so no single name replaces it.
|
|
94
|
-
|
|
95
|
-
## Run in this order
|
|
96
|
-
|
|
97
|
-
```bash
|
|
98
|
-
canon gov sync
|
|
99
|
-
git rm -r .claude/standards
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
Then re-read the citations and repoint what the sync left.
|
|
103
|
-
|
|
104
|
-
## Confirm
|
|
105
|
-
|
|
106
|
-
Run `canon standards <name>` from inside this project for every name the repointed citations carry, and confirm each resolves.
|
|
107
|
-
|
|
108
|
-
## Reminder
|
|
109
|
-
|
|
110
|
-
Nothing above was written or run. The tree holds files a delete cannot recover, so the drop and the sweep are yours to apply.
|
|
111
|
-
````
|
|
112
|
-
|
|
113
|
-
Run nothing and write nothing: not the sync, not a delete or a move under `.claude/standards/`, not a citation rewrite. The install stamp is out of scope too, and travels with whatever else reaches this target. The user applies the move after reviewing it.
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: migration-superseded
|
|
3
|
-
description: Why a retired file's split ships as a proposal read from the destination standard, and why detection stops rather than falling back to a listing
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Migration superseded requirement
|
|
7
|
-
|
|
8
|
-
## Gap
|
|
9
|
-
|
|
10
|
-
Without this skill, a target holding a retired `.claude/` file is told what replaced it and nothing else. The drift report names both halves and no command touches either, so the user hand-splits one file into a folder answering to a standard they have not read. The destination files land with frontmatter fields missing and filenames that sort out of order, which is the step the toolkit exists to remove.
|
|
11
|
-
|
|
12
|
-
A second failure comes from the ordering nobody gets right unaided. A retired file committed before its ignore entry was written is tracked and ignored at once, and removing the entry first leaves the file tracked with nothing naming it. No report catches that state, so the mistake is discovered by whoever next wonders why a gitignored path keeps appearing in diffs.
|
|
13
|
-
|
|
14
|
-
Two more follow from where a session looks when the report is thin. An uppercase stem under `.claude/` is not the test for a superseded file, so a session substituting a folder listing reaches `ARCHITECTURE.md`, `REQUIREMENTS.md`, and `DESIGN.md`, each a single file the layout intends to stay one, and proposes shredding three documents. A session falling back to the plugin's own copy of the destination standard proposes a shape the project never adopted, against content only the user can place.
|
|
15
|
-
|
|
16
|
-
The last is the two-speed release skew arriving as a confident wrong answer. `superseded` reached a release in `0.46.0`, and an older CLI exits zero with a well-formed report that never mentions the field. A session reading that absent key as an empty array reports a clean layout to exactly the population holding the retired files.
|
|
17
|
-
|
|
18
|
-
## Must
|
|
19
|
-
|
|
20
|
-
- Take detection from the report's `superseded` array alone, and stop when the key is absent rather than treating it as empty
|
|
21
|
-
- Resolve the governing standard by matching the replacement folder against the `appliesTo` the standards catalog declares, so a seed folder added later resolves without an edit to the body
|
|
22
|
-
- Read the destination shape with `canon standards <name>`, report the root it answered from, and propose nothing for a folder the catalog names no standard for
|
|
23
|
-
- Separate a folder no standard governs from one whose governing standard could not be read, since the catalog derives `appliesTo` from prose and answers an unparsed scope statement with an empty array
|
|
24
|
-
- Name the untrack command ahead of the ignore entry whenever a retired file is both tracked and ignored, and say when the check could not run
|
|
25
|
-
- Report what the destination standard leaves open, such as a phase label the retired file never recorded, rather than supplying a value for it
|
|
26
|
-
- Report the measured empty case as a pass, since the guard is what proves the section ran
|
|
27
|
-
|
|
28
|
-
## Must not
|
|
29
|
-
|
|
30
|
-
- Write, move, or delete the retired file or its replacement, or create the destination folder
|
|
31
|
-
- Run `git rm --cached` or edit the file carrying the ignore entry
|
|
32
|
-
- Substitute a folder listing for the `superseded` array
|
|
33
|
-
- Read the plugin's own copy of the destination standard when the target lacks that file
|
|
34
|
-
|
|
35
|
-
## Guards
|
|
36
|
-
|
|
37
|
-
- A directory with no `.claude/` stops, since nothing there was superseded and the report's sections would not be measured
|
|
38
|
-
|
|
39
|
-
## Out of scope
|
|
40
|
-
|
|
41
|
-
- Classifying `CLAUDE.md` sections into the three-tier model: `migration-claude-md`
|
|
42
|
-
- Relocating `docs/` files by audience: `migration-context`
|
|
43
|
-
- Reconciling a seed file against its source section by section, which diffs two files rather than splitting one into a folder: `seed-sync`
|
|
44
|
-
- Applying the split and running the untrack, which the user does after reviewing
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: migration-superseded
|
|
3
|
-
description: Proposes how to split a retired `.claude/` file into the folder that replaced it, reading the destination shape from the standard that folder answers to. Use when asked to "split TASKS.md", "my .claude/DIAGRAMS.md was replaced by a folder", "migrate the superseded file", or after a drift report names a superseded artifact. Do NOT write to the retired file or to its replacement, and do NOT run the untrack command. Proposal only.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Migration superseded
|
|
7
|
-
|
|
8
|
-
## Guards
|
|
9
|
-
|
|
10
|
-
- If `.claude/` does not exist at `pwd`, stop: `❌ No .claude/ directory. Nothing here was superseded.`
|
|
11
|
-
|
|
12
|
-
The guard is also what makes the report's `superseded` section measured. Every section is gated on the target being toolkit-managed, and a `.claude/` directory satisfies that gate, so the empty case below is a measured empty rather than a section that never ran.
|
|
13
|
-
|
|
14
|
-
## Step 1: read the report
|
|
15
|
-
|
|
16
|
-
Run `canon sync --check . --json` from the project root. Its `superseded` array is the detection. Each entry carries `rel`, the retired file, and `replacedBy`, the folder that took its job.
|
|
17
|
-
|
|
18
|
-
An empty array is the pass: `✅ No superseded artifact. Every .claude/ file the seeds replaced is already a folder.`
|
|
19
|
-
|
|
20
|
-
### When the report is unavailable
|
|
21
|
-
|
|
22
|
-
Stop on any of three conditions, naming which one fired:
|
|
23
|
-
|
|
24
|
-
- `canon` is not on `PATH`: `❌ canon is not on PATH. The superseded section is the only detection this skill has.`
|
|
25
|
-
- The command exits non-zero: `❌ canon sync --check failed. Fix the report before proposing a split.`
|
|
26
|
-
- The report parses and carries no `superseded` key at all: `❌ This canon predates the superseded field, which reached a release in 0.46.0. Upgrade, then re-run.`
|
|
27
|
-
|
|
28
|
-
Test for the key rather than for emptiness. A current CLI reporting `"superseded": []` has looked and found nothing, which is the pass above, and reading an absent key as an empty answer reports a clean layout to the projects this skill exists for.
|
|
29
|
-
|
|
30
|
-
No listing substitutes for the field. The pairing runs against the seed folder names the toolkit ships, and an uppercase stem is not the test, so a listing of `.claude/*.md` also reaches `ARCHITECTURE.md`, `REQUIREMENTS.md`, and `DESIGN.md`. Each of those is a single file the layout intends to stay one. A fallback that proposed splitting them would shred three documents to avoid reporting a stale CLI, which is why this skill stops where its siblings degrade.
|
|
31
|
-
|
|
32
|
-
## Step 2: resolve the destination standard
|
|
33
|
-
|
|
34
|
-
### Match the folder against the catalog
|
|
35
|
-
|
|
36
|
-
Run `canon standards list --json` and match each entry's `replacedBy` against the `appliesTo` array the catalog declares. Resolve from the catalog rather than from the folder stem, so a seed folder the toolkit adds later resolves without an edit here.
|
|
37
|
-
|
|
38
|
-
Compare on the folder rather than on the exact string. An `appliesTo` value matches when it equals `replacedBy` or begins with `replacedBy` followed by a slash. The report spells the folder `.canon/tasks` and the catalog spells it `.canon/tasks/`, and `memory` declares a filename pattern beneath its folder rather than the folder itself, so string equality matches nothing the catalog actually carries and sends every entry to a decline below.
|
|
39
|
-
|
|
40
|
-
### Read the standard through the verb
|
|
41
|
-
|
|
42
|
-
A match resolves to that standard's `name`. Read it with `canon standards <name>`, which writes the document to stdout and the root it answered from to stderr.
|
|
43
|
-
|
|
44
|
-
The verb is the one route. It resolves `standards/<name>.md` at the project root first, which is where a project that authors standards of its own keeps them, and falls back to the corpus inside the canon package. No toolkit standard installs into a project, so there is no third path to test and no case where the shape is unreachable while the catalog names it.
|
|
45
|
-
|
|
46
|
-
Report the root the frame named beside the proposal. A shape read from the project's own `standards/` is the project's stated agreement, and one read from the package is the toolkit's default, which is a difference the user weighs rather than a reason to refuse.
|
|
47
|
-
|
|
48
|
-
### The states that end an entry
|
|
49
|
-
|
|
50
|
-
Four states end an entry with no proposal. Name whichever one fired rather than collapsing them, because two of them are unmeasured and two are answers:
|
|
51
|
-
|
|
52
|
-
- The catalog carries no `appliesTo` key: `⚠️ This canon emits no appliesTo, so which standard governs <replacedBy> is unread.`
|
|
53
|
-
- No value covers `replacedBy` and some entry carries an empty `appliesTo`: an empty array is a scope statement that did not parse, so a no-match verdict is unread rather than negative. Name the standards that did not parse.
|
|
54
|
-
- No value covers `replacedBy` and every array is populated: `⚠️ The toolkit ships no standard for <replacedBy>. Nothing states the destination shape.` No command fixes it, so name none.
|
|
55
|
-
- The standard resolved in the catalog and `canon standards <name>` exits non-zero: name the standard and the exit, since the catalog and the read disagree and only one of them can be right.
|
|
56
|
-
|
|
57
|
-
## Step 3: read the shape and map the file onto it
|
|
58
|
-
|
|
59
|
-
Read the resolved standard and take four things from it: the filename convention, the required frontmatter, the required sections, and anything the folder holds that is not an item, such as a generated `index.md` no proposal may claim.
|
|
60
|
-
|
|
61
|
-
Then read the retired file and split it at the boundary the standard implies, one destination file per item. Propose a filename per item from the convention, and name the frontmatter and sections each destination file owes.
|
|
62
|
-
|
|
63
|
-
Report what the standard leaves open rather than inventing a value for it. A convention carrying a field the retired file never recorded, such as a phase label or a verified SHA, is the user's to supply, and a proposal that fills one in reads as a decision the split already made.
|
|
64
|
-
|
|
65
|
-
## Step 4: check the ignore ordering
|
|
66
|
-
|
|
67
|
-
Run both against each `rel`, in parallel:
|
|
68
|
-
|
|
69
|
-
- `git ls-files --error-unmatch <rel> 2>/dev/null`: whether the file is tracked
|
|
70
|
-
- `git check-ignore -v --no-index <rel> 2>/dev/null`: whether it is ignored, and which file and line names it
|
|
71
|
-
|
|
72
|
-
`--no-index` is what makes the second read answer the question. `git check-ignore` consults the index by default and reports a tracked path as not ignored, so the flagless form returns nothing in exactly the tracked-while-ignored state this step exists to find, and the run reads a clean result off the one case that is not clean.
|
|
73
|
-
|
|
74
|
-
A file that is both tracked and ignored carries an ignore entry added after the commit. Take it out of the index first, then remove the entry `check-ignore` named:
|
|
75
|
-
|
|
76
|
-
```bash
|
|
77
|
-
git rm --cached <rel>
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
Reversing the two leaves the file tracked with nothing naming it, and no report catches that state. Name both steps in that order and run neither. `git rm --cached` writes the index, which is a change to the project's own history even though no content moves.
|
|
81
|
-
|
|
82
|
-
When `pwd` is not a git work tree, say the tracked check did not run rather than reporting the ordering as clear.
|
|
83
|
-
|
|
84
|
-
## Step 5: output
|
|
85
|
-
|
|
86
|
-
Print one block per superseded entry, then the shared reminder. Omit empty groups.
|
|
87
|
-
|
|
88
|
-
```markdown
|
|
89
|
-
## Split
|
|
90
|
-
|
|
91
|
-
`.claude/TASKS.md` → `.canon/tasks/`, shaped by `canon standards tasks`
|
|
92
|
-
|
|
93
|
-
## Proposed files
|
|
94
|
-
|
|
95
|
-
- `.canon/tasks/vXX.Y-<slug>.md` ← the "<heading>" section
|
|
96
|
-
- `.canon/tasks/vXX.Y-<slug>.md` ← the "<heading>" section
|
|
97
|
-
|
|
98
|
-
Each carries `title` and `description` frontmatter, an `## Outcomes` heading, and a `## Findings` heading.
|
|
99
|
-
|
|
100
|
-
## You supply
|
|
101
|
-
|
|
102
|
-
- The phase label on each filename. The retired file records no version.
|
|
103
|
-
|
|
104
|
-
## Untrack before editing the ignore entry
|
|
105
|
-
|
|
106
|
-
git rm --cached .claude/TASKS.md
|
|
107
|
-
|
|
108
|
-
Then remove the `.claude/TASKS.md` line from `.gitignore:12`.
|
|
109
|
-
|
|
110
|
-
## Reminder
|
|
111
|
-
|
|
112
|
-
Nothing above was written or run. The retired file holds content the project authored, so the split is yours to apply and the destination folder shape is what this proposal supplies.
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
Do not create the destination folder. Do not write, move, or delete the retired file. Do not run `git rm --cached`. The user applies the split after reviewing it.
|