@erclx/canon 5.41.0 → 5.42.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/api-design/references/adopted.md +34 -14
- package/claude/skills/auto-ship/REQUIREMENT.md +1 -0
- package/claude/skills/auto-ship/SKILL.md +22 -2
- package/claude/skills/auto-ship/references/draft-mark.md +32 -6
- package/claude/skills/auto-ship/references/failure-recovery.md +15 -13
- package/claude/skills/auto-ship/references/tier-failures.md +31 -10
- package/claude/skills/auto-ship/references/ui-checklist.md +9 -4
- package/claude/skills/auto-ship/references/worktree-name.md +9 -3
- package/claude/skills/build-in-slices/references/adopted.md +35 -21
- package/claude/skills/canvas-board/references/canvas.md +17 -6
- package/claude/skills/canvas-board/references/design.md +26 -7
- package/claude/skills/code-craft/references/adopted.md +58 -20
- package/claude/skills/codebase-layout/references/adopted.md +49 -16
- package/claude/skills/codebase-layout/references/frontend.md +11 -4
- package/claude/skills/codebase-layout/references/tests.md +4 -2
- package/claude/skills/context-fold/references/classify.md +10 -15
- package/claude/skills/context-fold/references/completion-report.md +11 -9
- package/claude/skills/context-fold/references/context-refresh.md +26 -9
- package/claude/skills/context-fold/references/unusable-baseline.md +5 -3
- package/claude/skills/create-rule/REQUIREMENT.md +5 -0
- package/claude/skills/create-rule/SKILL.md +9 -1
- package/claude/skills/create-rule/references/checklist.md +26 -0
- package/claude/skills/create-rule/references/rule.md +98 -20
- package/claude/skills/create-skill/SKILL.md +1 -0
- package/claude/skills/create-skill/references/skill-disclosure.md +10 -2
- package/claude/skills/create-skill/references/skill-frontmatter.md +43 -0
- package/claude/skills/create-skill/references/skill-paths.md +7 -4
- package/claude/skills/create-skill/references/skill-practice.md +6 -3
- package/claude/skills/create-skill/references/skill-requirement.md +4 -2
- package/claude/skills/create-skill/references/skill.md +67 -44
- package/claude/skills/deploy-app/references/vercel.md +2 -1
- package/claude/skills/deprecation-migration/references/adopted.md +44 -25
- package/claude/skills/design-taste/references/adopted.md +9 -1
- package/claude/skills/design-taste/references/craft.md +3 -1
- package/claude/skills/design-taste/references/kinds.md +8 -7
- package/claude/skills/design-taste/references/preflight.md +12 -0
- package/claude/skills/design-taste/references/systems.md +7 -6
- package/claude/skills/design-taste/references/tells.md +24 -25
- package/claude/skills/design-taste/references/vocabulary.md +7 -5
- package/claude/skills/document-health/references/axes.md +54 -30
- package/claude/skills/draft-and-pick/references/live-arms.md +2 -2
- package/claude/skills/draft-doc/references/context.md +4 -3
- package/claude/skills/draft-doc/references/docs.md +6 -3
- package/claude/skills/draft-doc/references/readme/agent-facing.md +6 -0
- package/claude/skills/draft-doc/references/readme/application.md +8 -2
- package/claude/skills/draft-doc/references/readme/cli.md +5 -1
- package/claude/skills/draft-doc/references/readme/library.md +4 -0
- package/claude/skills/draft-doc/references/readme/plugin.md +9 -1
- package/claude/skills/draft-doc/references/readme.md +30 -13
- package/claude/skills/draft-doc/references/requirements.md +17 -4
- package/claude/skills/draft-doc/references/wiki-kind.md +20 -10
- package/claude/skills/draft-figure/references/architecture-set.md +7 -3
- package/claude/skills/draft-figure/references/figures.md +8 -6
- package/claude/skills/draft-figure/references/hand-drawn.md +3 -1
- package/claude/skills/draft-figure/references/mermaid-path.md +19 -9
- package/claude/skills/draft-figure/references/mermaid.md +10 -5
- package/claude/skills/draft-ready/references/ready.md +22 -15
- package/claude/skills/git-branch/references/branch.md +11 -1
- package/claude/skills/git-branch/references/slug.md +17 -5
- package/claude/skills/git-commit/references/commit.md +8 -0
- package/claude/skills/git-commit/references/versioning.md +23 -17
- package/claude/skills/git-followup/REQUIREMENT.md +1 -1
- package/claude/skills/git-followup/SKILL.md +5 -6
- package/claude/skills/git-issue/references/issue.md +29 -16
- package/claude/skills/git-pr/REQUIREMENT.md +1 -5
- package/claude/skills/git-pr/SKILL.md +11 -22
- package/claude/skills/git-pr/references/final-command.md +21 -8
- package/claude/skills/git-pr/references/labels.md +45 -28
- package/claude/skills/git-pr/references/pr.md +28 -9
- package/claude/skills/git-pr/references/publish.md +42 -28
- package/claude/skills/git-pr/references/task-number.md +20 -8
- package/claude/skills/git-ship/SKILL.md +1 -1
- package/claude/skills/plan-feature/references/plan-lifecycle.md +10 -3
- package/claude/skills/plan-feature/references/plan.md +57 -20
- package/claude/skills/plan-groundwork/references/groundwork-spikes.md +4 -1
- package/claude/skills/plan-groundwork/references/groundwork.md +14 -16
- package/claude/skills/plan-intake/references/intake.md +29 -24
- package/claude/skills/pr-evidence/REQUIREMENT.md +40 -0
- package/claude/skills/pr-evidence/SKILL.md +53 -0
- package/claude/skills/pr-evidence/references/evidence.md +150 -0
- package/claude/skills/review-address/references/post-review-findings.md +10 -3
- package/claude/skills/review-address/references/rebase-conflicts.md +15 -7
- package/claude/skills/review-address/references/rest-reads.md +3 -1
- package/claude/skills/review-craft/references/adopted.md +35 -18
- package/claude/skills/review-craft/references/security.md +42 -7
- package/claude/skills/review-craft/references/ui.md +23 -8
- package/claude/skills/review-pr/SKILL.md +6 -6
- package/claude/skills/review-pr/references/body-variants.md +29 -9
- package/claude/skills/review-pr/references/close-out.md +20 -5
- package/claude/skills/review-pr/references/key-changes.md +27 -3
- package/claude/skills/review-pr/references/post.md +83 -31
- package/claude/skills/review-pr/references/scope.md +54 -19
- package/claude/skills/review-ui/references/close-out.md +7 -5
- package/claude/skills/review-ui/references/driving.md +24 -4
- package/claude/skills/review-ui/references/post.md +43 -15
- package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +67 -17
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +80 -40
- package/claude/skills/role-orchestrator/references/orchestrator-handback.md +52 -15
- package/claude/skills/role-orchestrator/references/orchestrator-handoff.md +48 -26
- package/claude/skills/role-orchestrator/references/orchestrator-inbound.md +12 -13
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +72 -36
- package/claude/skills/role-orchestrator/references/orchestrator-output.md +12 -4
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +64 -24
- package/claude/skills/role-orchestrator/references/orchestrator-poll.md +80 -26
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +41 -18
- package/claude/skills/role-orchestrator/references/orchestrator-resume.md +19 -7
- package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +22 -12
- package/claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md +15 -6
- package/claude/skills/role-orchestrator/references/orchestrator-sweep.md +25 -7
- package/claude/skills/role-orchestrator/references/orchestrator-watch.md +34 -8
- package/claude/skills/role-orchestrator/scripts/poll.ts +16 -24
- package/claude/skills/role-worker/REQUIREMENT.md +1 -0
- package/claude/skills/role-worker/SKILL.md +8 -0
- package/claude/skills/search-craft/references/adopted.md +18 -6
- package/claude/skills/session-map/references/session.md +26 -7
- package/claude/skills/session-worktree/references/main-root-writes.md +25 -8
- package/claude/skills/systematic-debugging/references/adopted.md +30 -16
- package/claude/skills/target-check/references/domains.md +39 -11
- package/claude/skills/target-setup/references/detect.md +80 -65
- package/claude/skills/target-setup/references/indexes.md +8 -6
- package/claude/skills/task-board/references/board.md +86 -30
- package/claude/skills/task-board/references/decline.md +29 -13
- package/claude/skills/task-board/references/tasks-decline.md +12 -5
- package/claude/skills/task-board/references/tasks.md +65 -33
- package/claude/skills/task-complete/references/archive.md +41 -17
- package/claude/skills/task-complete/references/receipt-sweep.md +23 -9
- package/claude/skills/task-complete/references/unusable-baseline.md +10 -3
- package/claude/skills/teach-workspace/references/glossary.md +6 -2
- package/claude/skills/teach-workspace/references/lesson-build.md +44 -16
- package/claude/skills/teach-workspace/references/lesson-craft.md +12 -7
- package/claude/skills/teach-workspace/references/pedagogy.md +6 -3
- package/claude/skills/teach-workspace/references/promotion-fold.md +17 -11
- package/claude/skills/teach-workspace/references/promotion.md +31 -8
- package/claude/skills/teach-workspace/references/revisit.md +8 -2
- package/claude/skills/teach-workspace/references/teach.md +17 -9
- package/claude/skills/test-craft/references/adopted.md +48 -14
- package/claude/skills/test-craft/references/component.md +7 -4
- package/claude/skills/test-craft/references/e2e.md +25 -7
- package/claude/skills/test-craft/references/unit.md +3 -1
- package/claude/skills/test-first/references/adopted.md +12 -4
- package/claude/skills/ui-checklist/REQUIREMENT.md +1 -1
- package/claude/skills/ui-checklist/SKILL.md +1 -1
- package/claude/skills/video-craft/references/adopted.md +62 -18
- package/claude/skills/write-human/references/adopted.md +21 -8
- package/docs/workflow/parallel-features.md +1 -1
- package/docs/workflow/skill-map.md +1 -0
- package/package.json +1 -1
- package/src/claude/cases/workflow.ts +5 -0
- package/src/commands/pr.ts +142 -28
- package/src/markdown/scope.ts +144 -0
- package/src/pr/lift.ts +6 -3
- package/src/pr/review-state.ts +182 -0
- package/claude/skills/git-pr/references/evidence.md +0 -124
|
@@ -37,11 +37,11 @@ api = ["services/api/"]
|
|
|
37
37
|
web = ["apps/web/", "packages/ui/"]
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
A label takes more than one prefix when two folders read as one surface
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
The map is authored
|
|
40
|
+
- A label takes more than one prefix when two folders read as one surface, and a path under two overlapping labels earns both
|
|
41
|
+
- Matching is prefix-anchored, so a row written for an authoring root reaches nothing under the copy a project consumes
|
|
42
|
+
- A surface living only under a dotted folder carries its own prefix on the row owning its subject
|
|
43
|
+
- A folder holding several subjects splits across the rows that own them
|
|
44
|
+
- The map is hand-authored, so a surface added later labels nothing until someone adds a row, and `canon labels audit` names it before the merge
|
|
45
45
|
|
|
46
46
|
## Paths a map declines to label
|
|
47
47
|
|
|
@@ -55,44 +55,54 @@ release-managed = ["CHANGELOG.md", "package.json"]
|
|
|
55
55
|
generated = ["build/manifest.json"]
|
|
56
56
|
```
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
A path claimed by a `[domains]` row and a `[declined]` row takes the label. It already has a subject, so reporting it as deliberately unlabelled would contradict the label the same run applies.
|
|
58
|
+
- It is a table rather than a comment because the check reads it, separating a decision already taken from a gap nobody has reached
|
|
59
|
+
- A path claimed by both a `[domains]` row and a `[declined]` row takes the label, since it already has a subject
|
|
61
60
|
|
|
62
61
|
## Reporting a surface no row reaches
|
|
63
62
|
|
|
63
|
+
The audit names every changed path no row reaches.
|
|
64
|
+
|
|
64
65
|
```bash
|
|
65
66
|
canon labels audit --base <base> --json
|
|
66
67
|
```
|
|
67
68
|
|
|
68
|
-
The record carries `labels`, `declined`, and `uncovered`. It exits 2 when `uncovered` has anything in it and 1 when it refuses, with `reason` naming the cause
|
|
69
|
+
The record carries `labels`, `declined`, and `uncovered`. It exits 2 when `uncovered` has anything in it and 1 when it refuses, with `reason` naming the cause, `no-map` for a project that declared none and a parse or range failure otherwise.
|
|
69
70
|
|
|
70
|
-
It reports and never gates
|
|
71
|
-
|
|
72
|
-
|
|
71
|
+
- It reports and never gates, since whether a surface deserves a label is a call only its owner makes
|
|
72
|
+
- A push failing on one teaches a contributor to route around the check while the surface stays unchanged
|
|
73
|
+
- A prefix reaching no path stays unmeasured, so a row left by a deleted folder stays in the map. That staleness needs a second measure.
|
|
73
74
|
|
|
74
75
|
## Matching
|
|
75
76
|
|
|
76
|
-
- Take the changed set from `git diff --name-only <base>...HEAD`,
|
|
77
|
+
- Take the changed set from `git diff --name-only <base>...HEAD`, against the same base the body is written from
|
|
78
|
+
- The three dots hold whether `<base>` is already a merge base or a bare ref, where two dots would hand the branch somebody else's merged paths
|
|
77
79
|
- A path earns a label when the path starts with one of that label's prefixes
|
|
78
80
|
- Collect the distinct labels across the whole set, ordered as the map declares them, so two runs over one branch produce one string
|
|
79
81
|
- Pass the result as a single comma-separated value. An empty result runs no labelling step.
|
|
80
82
|
|
|
81
83
|
## Applying
|
|
82
84
|
|
|
83
|
-
Apply labels after the pull request resolves, never as a field on the create. A create carrying a label the remote lacks either fails whole or creates the label, depending on the surface, and neither is the map's call.
|
|
85
|
+
Apply labels after the pull request resolves, never as a field on the create. A create carrying a label the remote lacks either fails whole or creates the label, depending on the surface, and neither is the map's call.
|
|
86
|
+
|
|
87
|
+
- One step against an existing pull request covers the create and the edit path alike, over REST, so it works where GraphQL is blocked
|
|
88
|
+
- The REST endpoint creates any label it is handed, so the step reads each name off the remote first and warns on a missing one
|
|
84
89
|
|
|
85
|
-
|
|
90
|
+
### The apply verb
|
|
86
91
|
|
|
87
|
-
|
|
92
|
+
`canon labels apply <number>` is that step. It resolves the earned set from the pull request's files listing, or from the git range when `--base` is passed, and adds each earned label the pull request lacks.
|
|
88
93
|
|
|
89
|
-
|
|
94
|
+
- It binds only when the pull request's head is the current branch and it is open
|
|
95
|
+
- `--check` reports what is owed and writes nothing
|
|
96
|
+
- The record carries `number`, `earned`, `present`, `added`, `owed`, `missingOnRemote`, and `uncovered`
|
|
97
|
+
- A pull request opened outside this skill, such as by `gh pr create`, takes the same command, since nothing else labels it
|
|
90
98
|
|
|
91
|
-
|
|
99
|
+
### When labelling runs
|
|
92
100
|
|
|
93
|
-
|
|
101
|
+
Labelling runs whenever this skill runs and at no other time, recomputing over the whole branch diff. A push made any other way leaves the labels as the last run left them, so an ordinary branch labels once, when the pull request opens.
|
|
94
102
|
|
|
95
|
-
The
|
|
103
|
+
- The review return leg pushes through `git-followup`, which refreshes the body without this skill, so commits answering a review reach no labelling
|
|
104
|
+
- A follow-up reaching a new surface merges under-labelled, a cost worth paying since a review fix rarely opens a surface the branch had not touched
|
|
105
|
+
- The add endpoint never removes, so a hand-applied label stays and a surface the branch has since dropped keeps its label
|
|
96
106
|
|
|
97
107
|
## A label the remote does not carry
|
|
98
108
|
|
|
@@ -102,9 +112,9 @@ Warn and continue rather than creating it, naming the command in the warning:
|
|
|
102
112
|
gh label create <name> --description "<text>"
|
|
103
113
|
```
|
|
104
114
|
|
|
105
|
-
Creating a label writes to the repository settings from a run
|
|
115
|
+
Creating a label writes to the repository settings from a run invoked to open a pull request, and a label created from a map typo is harder to notice than a warning.
|
|
106
116
|
|
|
107
|
-
The refusal names the label it rejected and applies none of the set, so
|
|
117
|
+
The refusal names the label it rejected and applies none of the set, so an unseen warning leaves the run reading like one that labelled. Surface it beside the result line rather than letting the pull request URL stand alone.
|
|
108
118
|
|
|
109
119
|
## Release pull requests
|
|
110
120
|
|
|
@@ -118,14 +128,21 @@ The labels step of `git-pr` reads from here. Ask the CLI first:
|
|
|
118
128
|
canon labels audit --base <base> --json
|
|
119
129
|
```
|
|
120
130
|
|
|
121
|
-
|
|
131
|
+
Join the record's `labels`, the set this branch earns, with commas into `pr_labels`, which the final command takes. Report each `uncovered` path beside the result line, naming the map so the reader knows where a row would go, since an uncovered surface merges bare and nothing else says so.
|
|
132
|
+
|
|
133
|
+
### Reading the reason
|
|
122
134
|
|
|
123
|
-
Branch on the record rather than on the exit.
|
|
135
|
+
Branch on the record rather than on the exit. A shell profile may wrap `canon` in a function whose status comes from a trailing command, and the binary exits 1 for an unknown subcommand and an ordinary refusal alike.
|
|
124
136
|
|
|
125
|
-
|
|
137
|
+
- `no-map` means the project declared no map, so label nothing and warn about nothing, since a set this skill supplied would be a guess
|
|
138
|
+
- `unreadable-map`, `no-domains`, `no-base`, `unreadable-changes`, and `bad-base` take the fallback below, with a warning naming the reason
|
|
139
|
+
- A map with a typo still has rows a prefix can reach, and reading its refusal as absence would open the pull request bare and silent
|
|
126
140
|
|
|
127
|
-
|
|
141
|
+
### The fallback
|
|
128
142
|
|
|
129
|
-
|
|
143
|
+
Read `canon/config/pr-labels.toml`, or `.claude/canon/pr-labels.toml` when the project has not moved, and match it against the name-only diff per `## Matching`. The fallback labels correctly.
|
|
130
144
|
|
|
131
|
-
|
|
145
|
+
- It also covers no record at all, an installed `canon` predating the verb, since a skill reaches a target on merge and the CLI only on release
|
|
146
|
+
- Both spellings matter here, since the binary old enough to need the fallback may predate the move too
|
|
147
|
+
- It reports an uncovered path only when `canon labels audit` answered, passing that record's `uncovered` as `pr_uncovered`
|
|
148
|
+
- Leave `pr_labels` empty when no map resolves or no prefix matches, which skips the labelling command
|
|
@@ -42,6 +42,8 @@ Does not govern:
|
|
|
42
42
|
|
|
43
43
|
### What to leave out
|
|
44
44
|
|
|
45
|
+
A body describes the new behavior and nothing the diff or the commits already say.
|
|
46
|
+
|
|
45
47
|
- Do not describe historical behavior or unchanged code. Describe new behavior only.
|
|
46
48
|
- Do not include future promises or speculative documentation
|
|
47
49
|
- Do not explain obvious changes (formatting, renaming variables)
|
|
@@ -54,38 +56,49 @@ Does not govern:
|
|
|
54
56
|
|
|
55
57
|
### Context section
|
|
56
58
|
|
|
57
|
-
|
|
59
|
+
`## Technical context` is optional and carries 1-2 lines of architectural reasoning explaining why, not what.
|
|
60
|
+
|
|
58
61
|
- Omit Technical context for docs, config, or trivial changes
|
|
59
62
|
- Use bullet points for multiple reasons, one sentence for a single reason
|
|
60
63
|
|
|
61
64
|
### Testing section
|
|
62
65
|
|
|
63
|
-
|
|
66
|
+
`## Testing` is optional and names the exact commands or test cases run.
|
|
67
|
+
|
|
64
68
|
- Omit Testing for docs, config, or trivial sync changes
|
|
65
69
|
- Use checkboxes, never prose. See Testing discipline for which box gets ticked.
|
|
66
70
|
|
|
67
71
|
### Reviewer section and visuals
|
|
68
72
|
|
|
69
|
-
|
|
73
|
+
`## For the reviewer` is optional and lists what the reviewing session should confirm, one bullet per request.
|
|
74
|
+
|
|
70
75
|
- Visuals: include only when they clarify architecture, UI, or complex logic flows
|
|
71
|
-
- The list is closed
|
|
76
|
+
- The list is closed, so a body carries nothing after its last section, including a trailer a harness appends once the body is composed
|
|
77
|
+
- `canon labels scan` fails a level-two heading outside the five above, and a body missing `## Summary` or `## Key changes`
|
|
78
|
+
- A review body and a release-please body are exempt
|
|
72
79
|
|
|
73
80
|
## Testing discipline
|
|
74
81
|
|
|
75
82
|
- Run the check before writing its line. A `- [ ]` reports a check that has not run rather than one that is planned.
|
|
76
83
|
- Tick the box and state the observed result. `- [x] npm test passes, 42 tests` beats `- [ ] run npm test`.
|
|
77
84
|
- Quote the count or output the run reported, never a figure carried from elsewhere.
|
|
78
|
-
- A ticked box describes the tree as it stands
|
|
85
|
+
- A ticked box describes the tree as it stands. A later commit removing or replacing what it names makes the box false.
|
|
86
|
+
- The branch that made that commit corrects the box in the same pass, as with any other stale claim in the body
|
|
79
87
|
|
|
80
88
|
### Human-only boxes
|
|
81
89
|
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
-
|
|
85
|
-
-
|
|
90
|
+
Leave a box unchecked only when a human is required, and name which human and why on the same line. The agent runs everything else.
|
|
91
|
+
|
|
92
|
+
- Human-only covers visual or aesthetic judgment, credentials or a live third-party service, and a second machine or a fresh OS
|
|
93
|
+
- It also covers judgment about whether a boundary or an abstraction reads correctly
|
|
94
|
+
- A human is required by a capability the agent lacks, never the cost of the run. Authorizing a spend is the operator's and performing the run is not.
|
|
95
|
+
- An arm the repository ships a harness for gets driven once the operator has cleared the spend, and the box records what it returned
|
|
96
|
+
- A tool refusal that actually fired is a capability gap, and the line names the refusal rather than the cost. A refusal predicted and never met is not one.
|
|
86
97
|
|
|
87
98
|
### Live sessions and reviewer requests
|
|
88
99
|
|
|
100
|
+
A live agent session is never the human a box waits on.
|
|
101
|
+
|
|
89
102
|
- A live agent session is not a human. A box reading `needs a live session driving the skill` names the thing writing the description, so that run is owed rather than blocked.
|
|
90
103
|
- Put a request for the reviewer under `## For the reviewer`. It is a request rather than unfinished testing, so it never appears as an unchecked Testing box.
|
|
91
104
|
|
|
@@ -97,6 +110,8 @@ Does not govern:
|
|
|
97
110
|
|
|
98
111
|
### Template
|
|
99
112
|
|
|
113
|
+
Every section a body may carry, in order.
|
|
114
|
+
|
|
100
115
|
```markdown
|
|
101
116
|
## Summary
|
|
102
117
|
|
|
@@ -124,6 +139,8 @@ Does not govern:
|
|
|
124
139
|
|
|
125
140
|
### Correct
|
|
126
141
|
|
|
142
|
+
Each line's comment names the rule it follows.
|
|
143
|
+
|
|
127
144
|
```markdown
|
|
128
145
|
## Summary
|
|
129
146
|
|
|
@@ -151,6 +168,8 @@ Update auth middleware to enforce jwt expiration checks. # imperative + direct o
|
|
|
151
168
|
|
|
152
169
|
### Incorrect
|
|
153
170
|
|
|
171
|
+
Each line's comment names the rule it breaks.
|
|
172
|
+
|
|
154
173
|
```markdown
|
|
155
174
|
## Summary
|
|
156
175
|
|
|
@@ -7,7 +7,7 @@ description: Scan an author runs against finished text, the cross-reference form
|
|
|
7
7
|
|
|
8
8
|
## Scope
|
|
9
9
|
|
|
10
|
-
Governs the scan an author runs against finished text on its way out, the form a pull request or issue reference takes in every destination, and the
|
|
10
|
+
Governs the scan an author runs against finished text on its way out, the form a pull request or issue reference takes in every destination, and the response when a source the scan reaches for cannot be read. As an attribute standard it applies wherever no automated check covers the text, and carries no template.
|
|
11
11
|
|
|
12
12
|
Does not govern:
|
|
13
13
|
|
|
@@ -18,68 +18,82 @@ Does not govern:
|
|
|
18
18
|
|
|
19
19
|
## When it runs
|
|
20
20
|
|
|
21
|
-
Wherever text leaves through a channel no automated check covers, the author is the only gate and runs this scan. Text sent to another service, written to a path the
|
|
21
|
+
Wherever text leaves through a channel no automated check covers, the author is the only gate and runs this scan. Text sent to another service, text written to a path the checks exclude, and text inside a fenced block are the usual cases.
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
- The surface publishing the text knows which gap applies, so it names its own rather than reading one here
|
|
24
|
+
- Run the scan as an explicit step against the finished text, since the check has to happen after the text exists
|
|
24
25
|
|
|
25
|
-
Scope
|
|
26
|
+
### Scope by destination
|
|
27
|
+
|
|
28
|
+
Text published to a remote takes every check below. Text staying in the repository takes the character bans alone, since those hold wherever the text lands.
|
|
29
|
+
|
|
30
|
+
- Phase labels and board identifiers depend on the reader holding this checkout, so repository text skips both
|
|
31
|
+
- Session links depend on the reader holding the account, a narrower dependency stated under their own heading
|
|
26
32
|
|
|
27
33
|
## Banned characters
|
|
28
34
|
|
|
29
35
|
`${CLAUDE_SKILL_DIR}/../markdown-craft/references/markdown.md` holds the character bans. Read it at scan time rather than working the sets from memory, then scan the drafted text and rewrite each occurrence.
|
|
30
36
|
|
|
31
|
-
`canon labels scan` fails on these characters in a title or body
|
|
32
|
-
|
|
33
|
-
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.
|
|
37
|
+
- `canon labels scan` fails on these characters in a title or body outside a code span or a link, for a pull request and a posted review alike
|
|
38
|
+
- Restructure the sentence rather than substituting the character, since a semicolon swapped for a period keeps the shape the ban exists to remove
|
|
34
39
|
|
|
35
40
|
## Phase labels
|
|
36
41
|
|
|
37
42
|
`${CLAUDE_SKILL_DIR}/../git-commit/references/versioning.md` holds the label rule and the table of surfaces. Read it at scan time rather than working the format from memory.
|
|
38
43
|
|
|
39
|
-
|
|
44
|
+
The reader inside the repository has the task board and the reader on a remote does not, so this check is scoped by destination.
|
|
40
45
|
|
|
41
46
|
## Board identifiers
|
|
42
47
|
|
|
43
|
-
A phase label is one way text names the board, and a path under a record root is the other. Both resolve for a reader holding this checkout and
|
|
48
|
+
A phase label is one way text names the board, and a path under a record root is the other. Both resolve for a reader holding this checkout and for nobody else, so this check is scoped by destination too.
|
|
44
49
|
|
|
45
|
-
|
|
50
|
+
- A code span whose whole content is a label is still the label and a hit. A longer token inside a span is a fixture name and stays.
|
|
51
|
+
- A path under a record root is gitignored and absent from every clone, so `.canon/feedback/` names a folder the remote's reader cannot open
|
|
52
|
+
- Tracked `canon/` and `.claude/` paths are no hit, since `canon/context/surfaces/governance.md` resolves everywhere
|
|
53
|
+
- Every path under `.canon/` is a hit whichever folder it names, since one ignore line covers the root whole
|
|
46
54
|
|
|
47
|
-
|
|
55
|
+
### Fixing a hit
|
|
48
56
|
|
|
49
|
-
Rewrite a hit to name what the reader can reach rather than deleting it.
|
|
57
|
+
Rewrite a hit to name what the reader can reach rather than deleting it. State a row's subject plainly in place of its label, and say in a sentence what a record folder holds in place of its path.
|
|
50
58
|
|
|
51
|
-
`canon labels scan` runs this check and the phase-label one over a pull request title and body, and over a posted review's
|
|
59
|
+
`canon labels scan` runs this check and the phase-label one over a pull request title and body, and over a posted review's text once submitted. Any other channel, a plain issue comment among them, is still the author's own scan.
|
|
52
60
|
|
|
53
61
|
## Session links
|
|
54
62
|
|
|
55
|
-
A link to one Claude Code session names the session that wrote the text rather than the change
|
|
56
|
-
|
|
57
|
-
This check depends on the reader holding the account rather than the checkout, which is narrower than the dependency the destination rule above scopes. A reader inside this checkout opens a record path and still cannot open a session, since the session resolves for the one account that started it and for nobody else. The scoping still sits at the invocation site, because `canon labels scan` reads a pull request title and body and reaches no other text.
|
|
58
|
-
|
|
59
|
-
Delete a hit rather than rewriting it. The other two checks replace a hit with what the reader can reach instead, and a session has no such form, so what stands in its place is the body already written above it.
|
|
63
|
+
A link to one Claude Code session names the session that wrote the text rather than the change it describes. The harness tells the composing session to end its published text with one, so the author writes it deliberately and reads that compliance as correct. That is how it passes a scan the same author runs.
|
|
60
64
|
|
|
61
|
-
|
|
65
|
+
- The session resolves only for the account that started it, so a reader inside this checkout still cannot open it
|
|
66
|
+
- The scoping sits at the invocation site, because `canon labels scan` reads a pull request title and body and no other text
|
|
67
|
+
- Delete a hit rather than rewriting it, since a session has no reachable form and the body above it already stands in its place
|
|
68
|
+
- Removing it before a merge is no substitute for never writing it, since a squash can land it from an earlier snapshot, permanently on the trunk
|
|
62
69
|
|
|
63
70
|
## Cross-reference form
|
|
64
71
|
|
|
65
|
-
A number referring to a pull request or an issue takes the form its destination renders. Write it bare where the destination auto-links it
|
|
72
|
+
A number referring to a pull request or an issue takes the form its destination renders. Write it bare where the destination auto-links it and in backticks where it does not, so a reference moved between destinations is rewritten rather than copied.
|
|
66
73
|
|
|
67
|
-
|
|
74
|
+
| Destination | Form |
|
|
75
|
+
| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
76
|
+
| Pull request or issue body, a comment on either, a commit | `#123`, or `owner/repo#123` across repositories <!-- canon-allow-reference: the two spellings this section defines, which a qualified form would destroy --> |
|
|
77
|
+
| A markdown file browsed from the repository tree | the number in backticks, since neither spelling links there |
|
|
78
|
+
| Content installed into another repository | qualified against a different, resolvable repository, or no number |
|
|
68
79
|
|
|
69
|
-
|
|
80
|
+
A commit message takes the bare form even though the log links nothing, since the remote is what the form is chosen for. Text quoted from another surface keeps the spelling it arrived with, since rewriting it reports the source as saying something it never said.
|
|
70
81
|
|
|
71
|
-
|
|
82
|
+
### Installed content
|
|
72
83
|
|
|
73
|
-
|
|
84
|
+
A skill body loads from a plugin cache and a docs page is read through `canon docs`, so the reader holds their own repository rather than the one a bare number belongs to.
|
|
74
85
|
|
|
75
|
-
|
|
86
|
+
- Write `owner/repo#123` and `owner/repo@abc1234` for a different, resolvable repository, which the reader can open without this one
|
|
87
|
+
- Qualifying against `erclx/canon` fixes nothing, since a reader holding the cache or the package still cannot open this repository's history
|
|
88
|
+
- A same-repository citation takes no number, so state the fact it stood in for, and carry a one-off incident's identifier into the `canon/context/` entry owning the surface
|
|
89
|
+
- `canon gate run` fails a push on a bare reference there, and a line whose bare form is the point carries `canon-allow-reference: <reason>` on itself or the line above
|
|
76
90
|
|
|
77
|
-
|
|
91
|
+
### Number or sha
|
|
78
92
|
|
|
79
|
-
|
|
93
|
+
Choose the number where the citation names a decided change, since it resolves to the diff and the review behind it. Take the sha only for a tree or measurement state, the `Measured at <sha>` shape a context entry already uses. The choice holds for the bare and the qualified spelling alike.
|
|
80
94
|
|
|
81
95
|
## An unreadable source
|
|
82
96
|
|
|
83
97
|
Stop and name the source when one this scan reaches for cannot be read. Do not scan what resolved and report the result.
|
|
84
98
|
|
|
85
|
-
A run that
|
|
99
|
+
A half-run scan that says nothing is worse than one that visibly did not happen, because the surfaces running this scan describe themselves as the only gate. Its clean result is read as coverage.
|
|
@@ -7,22 +7,34 @@ description: How git-pr writes the pull request number the final command printed
|
|
|
7
7
|
|
|
8
8
|
The last step of `git-pr` before its report, reached on every run whose final command printed a number.
|
|
9
9
|
|
|
10
|
-
Write the `number` the final command printed onto the task the branch is closing
|
|
10
|
+
Write the `number` the final command printed onto the task the branch is closing, and never resolve it again. A lookup by branch alone can return a closed pull request sharing that head, per `${CLAUDE_SKILL_DIR}/REQUIREMENT.md`. A final command that refused on a head mismatch printed no number, so this step writes nothing on that run.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
## Name the plan
|
|
13
|
+
|
|
14
|
+
The task is the one whose `Plan:` line names the plan this branch implemented. That plan is `.canon/plans/feature-<slug>.md` at the main worktree root, with `<slug>` derived per `${CLAUDE_SKILL_DIR}/../git-branch/references/slug.md`.
|
|
15
|
+
|
|
16
|
+
- `plan-feature` writes the plan under the branch slug, so the two correspond on any branch that came through the plan-to-execute path
|
|
17
|
+
- When a caller earlier in the chain already read the plan, use that filename instead of re-deriving
|
|
18
|
+
- The slug is a guess at the plan rather than a fact about the task, so the verb re-checks it against the board and refuses on a near miss
|
|
13
19
|
|
|
14
20
|
```bash
|
|
15
21
|
canon tasks pull-request <number> --plan feature-<slug> --json
|
|
16
22
|
```
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
## What the verb writes
|
|
25
|
+
|
|
26
|
+
The verb resolves the board at the main worktree root in-process, the root `session-worktree` resolves on entry. It is the route because the write edits an existing main-root file, which `session-worktree` routes through a verb.
|
|
27
|
+
|
|
28
|
+
- It adds `Pull request: #NNN` under the task's `Plan:`, `Groundwork:`, `Intake:`, or `Issue:` lines, and corrects the number in place when the line exists
|
|
29
|
+
- A line already reading as a list of `#NNN` entries takes the new number appended, reported as `appended`, so a task shipped in slices keeps every pull request
|
|
30
|
+
- The same write drops this branch from the `Pending branch:` line `canon tasks outcome` wrote, which lets the merge-time archive close the task
|
|
19
31
|
|
|
20
|
-
|
|
32
|
+
## Refusals
|
|
21
33
|
|
|
22
|
-
|
|
34
|
+
Skip silently when the record is `ok: false` and `reason` is `no-board`, `no-match`, or `ambiguous`, meaning no board, no task naming the plan, or more than one. A guessed write would compound each, since a wrong match archives the wrong task unattended once the branch merges. Report any other refusal rather than swallowing it.
|
|
23
35
|
|
|
24
|
-
|
|
36
|
+
A branch whose slug names no plan file lands on `no-match`, the same as one whose plan no task cites.
|
|
25
37
|
|
|
26
|
-
|
|
38
|
+
## Why the number
|
|
27
39
|
|
|
28
|
-
|
|
40
|
+
Every merge on `main` is a squash carrying the number in its subject, so the number survives where a branch name does not. `post-merge` reads it back to call `canon tasks archive`, which is why this step runs at pull request time rather than at worktree time.
|
|
@@ -89,7 +89,7 @@ On a `passing` wake, run `canon pr evidence <number> --check --json` against the
|
|
|
89
89
|
| Any other `reason`, such as `gh-failed` | Stop and report it, since an unread thread is not a settled one |
|
|
90
90
|
| No record, or an unknown flag error | The binary predates `--check`, so report the thread unread and continue without claiming it was checked |
|
|
91
91
|
|
|
92
|
-
On `owed`,
|
|
92
|
+
On `owed`, invoke `canon:pr-evidence` with the number, which runs the evidence step first and then the preview the thread owes, and re-read with the same command. Continue only on `settled`, and stop on any other reading with the `reason` and the `owed` list, never looping back.
|
|
93
93
|
|
|
94
94
|
A refused preview step or a failed deploy leaves `preview` owed on the re-read, so that is the stop and not a retry. The read is a closing step, so the draft mark stays the only thing between steps 8 and 9, and a caller closing on its own block waits on the same wake.
|
|
95
95
|
|
|
@@ -30,7 +30,14 @@ A plan lost to deletion, or carrying two answers to one question, fails both.
|
|
|
30
30
|
## Lifecycle
|
|
31
31
|
|
|
32
32
|
- Write the plan before implementation starts, and treat it as the scope of the run that executes it. A subject that has to be measured before anyone can plan against it takes a measurement track first.
|
|
33
|
-
- Keep every plan at one root. A plan copied into each parallel working tree forks, and the copies answer the same question differently.
|
|
34
|
-
- Amend the plan in place when a decision changes mid-flight. Do not append a second passage narrating the change, which leaves a reader to work out which of two answers is current. An execution-time deviation from a suggestion is one such amendment, and the suggested-and-answer contract in `plan.md` fixes which line takes it.
|
|
35
|
-
- Move the plan to `.canon/plans/archive/` when the work it describes ships or is declined. Never delete it, because the plan is where the rejected alternative is written down. A flat `.claude/plans-archive/` sibling is the older layout.
|
|
36
33
|
- Write the plan in the same session that opens the task it serves. The session executing it later inherits reasoning it would otherwise re-derive.
|
|
34
|
+
- Keep every plan at one root. A plan copied into each parallel working tree forks, and the copies answer the same question differently.
|
|
35
|
+
|
|
36
|
+
### Amending and archiving
|
|
37
|
+
|
|
38
|
+
A plan changes in place and leaves only by a move.
|
|
39
|
+
|
|
40
|
+
- Amend the plan in place when a decision changes mid-flight, never appending a passage narrating the change, which leaves two answers to reconcile
|
|
41
|
+
- An execution-time deviation from a suggestion is one such amendment, and the suggested-and-answer contract in `plan.md` fixes which line takes it
|
|
42
|
+
- Move the plan to `.canon/plans/archive/` when its work ships or is declined, and never delete it, since it records the rejected alternative
|
|
43
|
+
- A flat `.claude/plans-archive/` sibling is the older layout.
|