@erclx/canon 5.45.0 → 5.47.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/REQUIREMENT.md +15 -31
- package/claude/skills/auto-ship/REQUIREMENT.md +14 -25
- package/claude/skills/backlog-triage/REQUIREMENT.md +12 -23
- package/claude/skills/build-in-slices/REQUIREMENT.md +15 -25
- package/claude/skills/canon-cli/REQUIREMENT.md +15 -27
- package/claude/skills/canon-feedback/REQUIREMENT.md +10 -18
- package/claude/skills/canon-feedback-triage/REQUIREMENT.md +10 -15
- package/claude/skills/canvas-board/REQUIREMENT.md +14 -28
- package/claude/skills/ci-workflow/REQUIREMENT.md +12 -21
- package/claude/skills/code-craft/REQUIREMENT.md +14 -28
- package/claude/skills/codebase-layout/REQUIREMENT.md +14 -31
- package/claude/skills/context-fold/REQUIREMENT.md +15 -39
- package/claude/skills/context-fold/references/context.md +3 -3
- package/claude/skills/create-rule/REQUIREMENT.md +10 -24
- package/claude/skills/create-rule/SKILL.md +3 -0
- package/claude/skills/create-skill/REQUIREMENT.md +10 -21
- package/claude/skills/decision-escalate/REQUIREMENT.md +12 -24
- package/claude/skills/deploy-app/REQUIREMENT.md +12 -22
- package/claude/skills/deprecation-migration/REQUIREMENT.md +14 -42
- package/claude/skills/design-identity/REQUIREMENT.md +14 -20
- package/claude/skills/design-taste/REQUIREMENT.md +16 -57
- package/claude/skills/docs-sync/REQUIREMENT.md +14 -23
- package/claude/skills/document-health/REQUIREMENT.md +15 -29
- package/claude/skills/document-health/SKILL.md +2 -2
- package/claude/skills/document-repair/REQUIREMENT.md +32 -0
- package/claude/skills/document-repair/SKILL.md +76 -0
- package/claude/skills/document-repair/references/batches.md +44 -0
- package/claude/skills/draft-and-pick/REQUIREMENT.md +4 -3
- package/claude/skills/draft-doc/REQUIREMENT.md +4 -3
- package/claude/skills/draft-figure/REQUIREMENT.md +4 -3
- package/claude/skills/draft-identity/REQUIREMENT.md +4 -3
- package/claude/skills/draft-ready/REQUIREMENT.md +4 -3
- package/claude/skills/draft-screencast/REQUIREMENT.md +4 -3
- package/claude/skills/draft-slides/REQUIREMENT.md +4 -3
- package/claude/skills/draw-figure/REQUIREMENT.md +15 -39
- package/claude/skills/git-branch/REQUIREMENT.md +12 -26
- package/claude/skills/git-commit/REQUIREMENT.md +11 -15
- package/claude/skills/git-followup/REQUIREMENT.md +11 -22
- package/claude/skills/git-followup/SKILL.md +1 -0
- package/claude/skills/git-issue/REQUIREMENT.md +9 -15
- package/claude/skills/git-pr/REQUIREMENT.md +13 -32
- package/claude/skills/git-pr/SKILL.md +11 -2
- package/claude/skills/git-pr/references/closing-issues.md +47 -0
- package/claude/skills/git-pr/references/pr.md +62 -7
- package/claude/skills/git-ship/REQUIREMENT.md +13 -26
- package/claude/skills/git-split/REQUIREMENT.md +10 -17
- package/claude/skills/git-stage/REQUIREMENT.md +12 -18
- package/claude/skills/git-worktree/REQUIREMENT.md +15 -19
- package/claude/skills/make-deck/REQUIREMENT.md +13 -21
- package/claude/skills/markdown-craft/REQUIREMENT.md +9 -3
- package/claude/skills/plan-feature/REQUIREMENT.md +15 -24
- package/claude/skills/plan-groundwork/REQUIREMENT.md +12 -28
- package/claude/skills/plan-groundwork/SKILL.md +5 -2
- package/claude/skills/plan-groundwork/references/output.md +47 -1
- package/claude/skills/plan-intake/REQUIREMENT.md +11 -26
- package/claude/skills/plan-intake/references/intake.md +2 -2
- package/claude/skills/plan-intake-answer/REQUIREMENT.md +14 -29
- package/claude/skills/plan-intake-answer/SKILL.md +7 -1
- package/claude/skills/plan-ready/REQUIREMENT.md +17 -36
- package/claude/skills/pr-evidence/REQUIREMENT.md +11 -17
- package/claude/skills/read-frames/REQUIREMENT.md +3 -8
- package/claude/skills/record-screencast/REQUIREMENT.md +14 -17
- package/claude/skills/review-address/REQUIREMENT.md +14 -38
- package/claude/skills/review-address/SKILL.md +18 -6
- package/claude/skills/review-address/references/post-review-findings.md +4 -1
- package/claude/skills/review-address/references/rebase-only.md +14 -2
- package/claude/skills/review-craft/REQUIREMENT.md +14 -32
- package/claude/skills/review-pr/REQUIREMENT.md +15 -34
- package/claude/skills/review-pr/SKILL.md +9 -2
- package/claude/skills/review-pr/references/body-variants.md +29 -8
- package/claude/skills/review-pr/references/post.md +29 -10
- package/claude/skills/review-ui/REQUIREMENT.md +14 -39
- package/claude/skills/review-ui/SKILL.md +1 -0
- package/claude/skills/review-ui/references/post.md +2 -0
- package/claude/skills/review-ui/references/tick.md +3 -0
- package/claude/skills/role-orchestrator/REQUIREMENT.md +2 -2
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +5 -0
- package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +9 -0
- package/claude/skills/role-reviewer/REQUIREMENT.md +15 -65
- package/claude/skills/role-reviewer/SKILL.md +8 -1
- package/claude/skills/role-worker/REQUIREMENT.md +2 -2
- package/claude/skills/role-worker/SKILL.md +3 -0
- package/claude/skills/script-screencast/REQUIREMENT.md +10 -16
- package/claude/skills/search-craft/REQUIREMENT.md +12 -36
- package/claude/skills/search-craft/SKILL.md +1 -1
- package/claude/skills/search-craft/references/adopted.md +2 -2
- package/claude/skills/session-compact/REQUIREMENT.md +13 -23
- package/claude/skills/session-map/REQUIREMENT.md +13 -29
- package/claude/skills/session-relay/REQUIREMENT.md +14 -58
- package/claude/skills/session-relay/SKILL.md +6 -0
- package/claude/skills/session-resume/REQUIREMENT.md +13 -27
- package/claude/skills/session-worktree/REQUIREMENT.md +14 -43
- package/claude/skills/systematic-debugging/REQUIREMENT.md +13 -34
- package/claude/skills/target-check/REQUIREMENT.md +16 -23
- package/claude/skills/target-setup/REQUIREMENT.md +11 -34
- package/claude/skills/task-board/REQUIREMENT.md +13 -22
- package/claude/skills/task-board/SKILL.md +7 -0
- package/claude/skills/task-board/references/decline.md +2 -2
- package/claude/skills/task-board/references/tasks.md +1 -1
- package/claude/skills/task-complete/REQUIREMENT.md +11 -24
- package/claude/skills/task-complete/references/archive.md +4 -2
- package/claude/skills/teach-workspace/REQUIREMENT.md +14 -45
- package/claude/skills/test-craft/REQUIREMENT.md +15 -46
- package/claude/skills/test-first/REQUIREMENT.md +14 -20
- package/claude/skills/ui-checklist/REQUIREMENT.md +14 -29
- package/claude/skills/ui-checklist/SKILL.md +3 -3
- package/claude/skills/ux-audit/REQUIREMENT.md +3 -7
- package/claude/skills/ux-measure/REQUIREMENT.md +14 -28
- package/claude/skills/video-craft/REQUIREMENT.md +14 -27
- package/claude/skills/write-doc/REQUIREMENT.md +14 -24
- package/claude/skills/write-human/REQUIREMENT.md +15 -27
- package/claude/skills/youtube-transcripts/REQUIREMENT.md +9 -15
- package/docs/agents/context-audit.md +19 -12
- package/docs/agents/markdown-audit.md +15 -10
- package/docs/target/projects.md +2 -0
- package/docs/workflow/skill-map.md +6 -5
- package/docs/workflow/zshrc-aliases.md +3 -0
- package/governance/renames.toml +0 -2
- package/governance/rules/claude/output.md +5 -1
- package/governance/rules/code/routing.md +5 -1
- package/governance/stacks/base.toml +0 -1
- package/package.json +1 -1
- package/scripts/core/bootstrap.sh +1 -0
- package/src/claude/cases/workflow.ts +12 -0
- package/src/commands/context.ts +57 -3
- package/src/commands/labels.ts +149 -4
- package/src/commands/markdown.ts +188 -21
- package/src/commands/pr.ts +113 -4
- package/src/commands/sessions.ts +58 -11
- package/src/commands/tasks.ts +182 -0
- package/src/commands/worktrees.ts +2 -0
- package/src/context/coverage.ts +210 -0
- package/src/context/gate.ts +12 -3
- package/src/gate/stages.ts +1 -1
- package/src/init/steps.ts +45 -0
- package/src/intake/items.ts +14 -0
- package/src/labels/closing.ts +46 -0
- package/src/labels/density.ts +363 -0
- package/src/markdown/gated.ts +250 -0
- package/src/markdown/scope.ts +115 -2
- package/src/migrate/rename.ts +6 -0
- package/src/pr/evidence.ts +1 -1
- package/src/pr/rest.ts +2 -0
- package/src/pr/tick.ts +89 -0
- package/src/sessions/claim.ts +7 -0
- package/src/sessions/live.ts +79 -6
- package/src/sessions/registry.ts +11 -0
- package/src/sessions/resolve.ts +85 -7
- package/src/tasks/archive.ts +15 -4
- package/src/tasks/closes.ts +136 -0
- package/src/tasks/record.ts +1 -1
- package/src/worktrees/reclaim.ts +16 -1
- package/tooling/base/configs/scripts/verify.ts +1 -1
- package/tooling/base/seeds/.github/pull_request_template.md +1 -1
- package/tooling/claude/seeds/.claude/hooks/board-validate.sh +1 -1
- package/tooling/claude/seeds/CLAUDE.md +2 -2
- package/governance/rules/canon/task-scope.md +0 -12
|
@@ -7,17 +7,18 @@ description: Why a pointer answers under the old `draft-slides` name, and the te
|
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
10
|
-
Without this skill, a person typing the old name after the rename to `make-deck` meets an unknown command
|
|
10
|
+
Without this skill, a person typing the old name after the rename to `make-deck` meets an unknown command that names no successor. A target that has not run `canon migrate skill-names` still tells people to type it, and so does a live gitignored record, which the sweep never reads.
|
|
11
11
|
|
|
12
12
|
## Must
|
|
13
13
|
|
|
14
14
|
- Name `make-deck` as the skill to run, so a typed invocation of the old name reaches the new one in one step
|
|
15
|
-
- Carry `disable-model-invocation: true`, so routing never matches the old description against a request
|
|
15
|
+
- Carry `disable-model-invocation: true`, so routing never matches the old description against a request `make-deck` owns
|
|
16
|
+
- Retire once `canon migrate skill-names --json` reports zero citations in every target the rollout reaches and no live `.canon/` record names the old name
|
|
16
17
|
|
|
17
18
|
## Must not
|
|
18
19
|
|
|
19
20
|
- Carry any part of the deck draft, which would give one behavior two bodies that drift apart
|
|
20
|
-
- Retire on a release number
|
|
21
|
+
- Retire on a release number, which retires it on a date nothing measured
|
|
21
22
|
|
|
22
23
|
## Out of scope
|
|
23
24
|
|
|
@@ -7,53 +7,29 @@ description: Why a figure decides between Mermaid, an architecture view, and fre
|
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
10
|
-
Without this skill, a session asked for a figure
|
|
10
|
+
Without this skill, a session asked for a figure takes the first path it thinks of. A graph gets SVG coordinates nobody checked against a render, and a subject that is not a graph gets forced through Mermaid. In a teach lesson the renderer cannot load the hand font, so labels clip, and a check reading the standalone image passes them.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
An architecture view asked for one at a time fails its own way. A session asked to refresh one view redraws every view beside it, so pictures nobody checked change in the same commit and the reviewer cannot tell which one the pass was about. It reaches for C4, state, or class diagrams that render differently in every viewer. A Mermaid source can satisfy every rule in the standard and still render as a picture asserting something false about the system, so a session that judges the source and calls it verified has spent the only signal a reader has on a picture nobody looked at.
|
|
15
|
-
|
|
16
|
-
The color failure is the quiet one. Mermaid's own theme writes literal hex values, and a figure carrying one stops re-coloring itself the moment the host page switches its palette, which the figure standard's own accessibility bar rules out.
|
|
12
|
+
Asked to refresh one architecture view, it redraws every view beside it. It judges the source and calls the figure verified, though a valid source can render a picture asserting something false. Mermaid's theme writes literal hex values, so the figure stops re-coloring when the page switches palette.
|
|
17
13
|
|
|
18
14
|
## Must
|
|
19
15
|
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
-
|
|
24
|
-
-
|
|
25
|
-
- Verify a figure bound for a rendered page by capturing it inside that page, and fall back to the standalone render only where the destination has no page to load
|
|
26
|
-
- Keep the scoped overflow style as the documented fallback for a clipped group title wherever the Mermaid path still runs
|
|
27
|
-
- Render the Mermaid path with the hand-drawn look and the figure font stack, never with Mermaid's default look
|
|
28
|
-
- Rewrite every literal color the renderer wrote into the custom property the host stylesheet defines
|
|
29
|
-
- Read the Mermaid render back and judge it against what the figure means to say, rather than judging the source
|
|
30
|
-
- Read the node labels by hand, since no hook checks inside a fence
|
|
31
|
-
- Cite only code paths that exist in an architecture view's caption or prose
|
|
32
|
-
- Wrap either path in a `<figure>` and `<figcaption>` and give it an accessible name
|
|
16
|
+
- The figure clears the standard's earn-its-place bar, and its path follows whether the subject reduces to a graph, with a teach lesson drawn freehand whatever its shape
|
|
17
|
+
- An architecture view is drawn from its named source signal in `flowchart` or `sequenceDiagram`, and only the view the request names changes
|
|
18
|
+
- The Mermaid render uses the hand-drawn look and the figure font stack, with every literal color rewritten to the host's custom property
|
|
19
|
+
- The render is read back against what the figure means to say, and a figure bound for a rendered page is verified by a capture inside that page
|
|
20
|
+
- Either path lands in a `<figure>` with a `<figcaption>` and an accessible name, and an architecture view's caption cites only code paths that exist
|
|
33
21
|
|
|
34
22
|
## Must not
|
|
35
23
|
|
|
36
|
-
-
|
|
37
|
-
- Report a figure
|
|
38
|
-
- Ship a literal hex color
|
|
39
|
-
- Report a clean verification when the Mermaid render was skipped or a defect survived
|
|
24
|
+
- Draw with no subject or no destination, an architecture view with no planning file or folder structure to anchor it, or decoration for a subject that fails the bar
|
|
25
|
+
- Report a figure verified from the standalone render alone, or report a clean check when the render was skipped or a defect survived
|
|
26
|
+
- Ship a literal hex color, or commit a scratch render
|
|
40
27
|
- Loop past two correction passes on a surviving defect
|
|
41
|
-
-
|
|
42
|
-
- Redraw a figure the request did not name, or report one as drawn when it was left alone
|
|
43
|
-
- Leave an architecture view as an unrendered fence
|
|
44
|
-
|
|
45
|
-
## Guards
|
|
46
|
-
|
|
47
|
-
- No subject given: stop, since nothing states what the figure has to show
|
|
48
|
-
- No destination document given: stop, since the figure has nowhere to land
|
|
49
|
-
- Subject does not clear the earn-its-place bar: stop rather than drawing decoration
|
|
50
|
-
- An architecture view with no planning file and no folder structure to scan: stop, because nothing anchors it
|
|
51
|
-
- Render fails for any reason: continue to the output and name the skipped check. A missing renderer degrades the loop rather than failing it.
|
|
28
|
+
- Redraw a figure the request did not name, or leave an architecture view as an unrendered fence
|
|
52
29
|
|
|
53
30
|
## Out of scope
|
|
54
31
|
|
|
55
|
-
- Mermaid's
|
|
56
|
-
- A UI screen mockup
|
|
57
|
-
-
|
|
58
|
-
- Implementation detail behind an architecture view, which
|
|
59
|
-
- Which lesson needs a figure and where it sits among the lesson's blocks: `teach-workspace`, which calls this skill to draw one
|
|
32
|
+
- Mermaid's layout, budgets, and label rules inside the fence, which the mermaid standard owns
|
|
33
|
+
- A UI screen mockup, and design tokens or the visual system, which `canvas-board` owns
|
|
34
|
+
- Which lesson needs a figure and where it sits, which `teach-workspace` owns
|
|
35
|
+
- Implementation detail behind an architecture view, which the context entry the caption points at owns
|
|
@@ -7,43 +7,29 @@ description: What branch naming is for, the gaps it closes, and where the family
|
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
10
|
-
Without this skill, a branch name is invented once per session. The type prefix drifts from
|
|
10
|
+
Without this skill, a branch name is invented once per session. The type prefix drifts from the history's convention, the name runs past the width a pull request list renders, and a rename lands on a branch the remote already carries, which detaches every open pull request pointing at it.
|
|
11
11
|
|
|
12
|
-
A session standing on `main` has no route
|
|
12
|
+
A session standing on `main` has no route to its first act either. Every git operation goes through a `git-*` skill, so creating a feature's branch needs one that creates as well as renames, and that agrees with the name a dispatcher already checked.
|
|
13
13
|
|
|
14
14
|
## Must
|
|
15
15
|
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
- Read the remote itself with `git ls-remote` before creating, since `origin/<name>` sees only the last fetch
|
|
22
|
-
- Show the name and its length against the limit before renaming or creating
|
|
23
|
-
- Execute immediately after the preview. The tool permission dialog is the confirmation gate.
|
|
16
|
+
- The name follows the branch format reference, and the user sees it with its length before the branch changes
|
|
17
|
+
- One skill creates on `main` or `master` and renames anywhere else
|
|
18
|
+
- A created name for a plan comes from `canon tasks plan-branch`, and a rename with no description derives from the commits ahead of main
|
|
19
|
+
- Remote existence is read before any rename or create, from the remote itself rather than the last fetch
|
|
20
|
+
- A conforming name passes through as a success, so a chained caller continues
|
|
24
21
|
|
|
25
22
|
## Must not
|
|
26
23
|
|
|
27
|
-
- Rename `main` or
|
|
28
|
-
-
|
|
29
|
-
-
|
|
30
|
-
- Create a branch from anywhere but `main` or `master`, or create one whose name exists locally or on the remote
|
|
31
|
-
- Invent a name when the plan verb refuses, since a name the skill calls non-conforming strands the rename at ship
|
|
24
|
+
- Rename `main`, `master`, or a branch that exists on the remote
|
|
25
|
+
- Create from anywhere but `main` or `master`, or onto a name that exists locally or on the remote
|
|
26
|
+
- Invent a name when the plan verb refuses
|
|
32
27
|
- Fetch or stash while creating
|
|
33
28
|
- Emit anything after the result line
|
|
34
29
|
|
|
35
|
-
## Guards
|
|
36
|
-
|
|
37
|
-
- Create with no plan and no name: stop and name both missing inputs
|
|
38
|
-
- Create with a name breaking the branch standard: stop and name the cap
|
|
39
|
-
- Create with a name existing locally or on the remote: stop and say which
|
|
40
|
-
- Rename name already conforms: stop with a success marker, not a failure, since a chained caller continues past it
|
|
41
|
-
- Rename with no commits and no description: stop and name both missing inputs
|
|
42
|
-
- Rename of a branch existing on the remote: stop and route to the surface that preserves the pull request link
|
|
43
|
-
|
|
44
30
|
## Out of scope
|
|
45
31
|
|
|
46
32
|
- The commit message, which `git-commit` owns
|
|
47
|
-
- Pushing and opening the pull request, which `git-pr` owns
|
|
33
|
+
- Pushing and opening the pull request, which `git-pr` owns and which refuses a non-conforming name
|
|
48
34
|
- Splitting a branch whose commits span concerns, which `git-split` owns
|
|
49
|
-
- Entering a worktree, which `session-worktree` owns
|
|
35
|
+
- Entering a worktree and naming its branch, which `session-worktree` owns
|
|
@@ -7,30 +7,26 @@ description: What commit generation is for, the gaps it closes, and where the fa
|
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
10
|
-
Without this skill, a commit message takes whatever shape the session
|
|
10
|
+
Without this skill, a commit message takes whatever shape the session picks. The type and scope drift from the history's convention, the subject runs past the log's width, and a lockfile diff crowds out the change the message should describe.
|
|
11
11
|
|
|
12
|
-
A
|
|
12
|
+
A plain request to commit also reaches the grouping sibling, which restages whole files, so a hunk-level selection ships wider than the user reviewed.
|
|
13
13
|
|
|
14
14
|
## Must
|
|
15
15
|
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
16
|
+
- The message follows the commit format and versioning references
|
|
17
|
+
- The message describes the staged diff with lockfiles excluded
|
|
18
|
+
- The user sees the message and its length before the commit runs
|
|
19
|
+
- The committed set is exactly the staged set
|
|
20
|
+
- The description claims single-concern and hunk-level staged sets, and names `git-stage` for a mixed one
|
|
21
21
|
|
|
22
22
|
## Must not
|
|
23
23
|
|
|
24
|
-
- Stage
|
|
24
|
+
- Stage or unstage anything
|
|
25
25
|
- Commit when nothing is staged
|
|
26
|
-
- Emit anything after the result line
|
|
27
|
-
|
|
28
|
-
## Guards
|
|
29
|
-
|
|
30
|
-
- Nothing staged: stop and name the command that stages
|
|
26
|
+
- Emit anything after the result line
|
|
31
27
|
|
|
32
28
|
## Out of scope
|
|
33
29
|
|
|
34
|
-
- Splitting a mixed diff
|
|
35
|
-
- Naming
|
|
30
|
+
- Splitting a mixed diff into several commits, which `git-stage` owns
|
|
31
|
+
- Naming a branch, which `git-branch` owns
|
|
36
32
|
- Pushing or opening a pull request, which `git-pr` owns
|
|
@@ -7,38 +7,27 @@ description: What the follow-up push is for, the gaps it closes, and how it spli
|
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
10
|
-
Without this skill, an edit made after a pull request
|
|
10
|
+
Without this skill, an edit made after a pull request opens ships as a bare push. The body still describes the scope from before the edit, and a review fix always changes what shipped, so the description a merge records is false by the time review ends. A reviewer who left comments gets no reply, or a second one under the caller's own.
|
|
11
11
|
|
|
12
|
-
A caller that rebased
|
|
13
|
-
|
|
14
|
-
A fix commit answering a review is the sharpest case of the first paragraph, since it always changes what shipped. The routing that once picked whether to sync the body keyed off the same branch that decides whether to reply, so reaching `reply-owned` or a nonzero comment count meant the sync never ran at all. The description a merge record carries was true when the pull request opened and false by the time review finished, with nothing between the two that read it back.
|
|
12
|
+
The push itself fails on two branch shapes. A caller that rebased before handing over hits a rejected push, and a branch entered through a worktree carries an open pull request with no tracking ref, which reads as a branch never pushed.
|
|
15
13
|
|
|
16
14
|
## Must
|
|
17
15
|
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
- Suppress the reply when the caller owns it, and still run the push and the body sync
|
|
24
|
-
- Post the evidence through `pr-evidence` and read `canon pr evidence <number> --check --json` after it, since a followup that posts the evidence and stops leaves the preview for a relay
|
|
25
|
-
- Force the push under a lease when the tracking branch no longer reaches the head, so a caller's rebase lands and a commit this session never read is not overwritten
|
|
16
|
+
- Every follow-up commit syncs the body when it moves the scope, and the title when the shift makes it inaccurate, whether or not a reply runs
|
|
17
|
+
- The message comes from `git-commit`, so a follow-up reads like every other commit
|
|
18
|
+
- A pull request carrying review comments gets one reply, scanned for banned characters and phase labels and posted through a file, and none when the caller owns it
|
|
19
|
+
- The push lands on a branch with no tracking ref, and on a rebased one under a lease that protects a commit this session never read
|
|
20
|
+
- The evidence is posted through `pr-evidence` and read back with `canon pr evidence <number> --check --json`
|
|
26
21
|
|
|
27
22
|
## Must not
|
|
28
23
|
|
|
29
|
-
- Run on `main
|
|
30
|
-
- Open a pull request. A missing one is the stop
|
|
24
|
+
- Run on `main`, or with nothing changed
|
|
25
|
+
- Open a pull request. A missing one is the stop.
|
|
31
26
|
- Post a second reply when the caller has already replied
|
|
32
27
|
- Emit anything after the result line
|
|
33
28
|
|
|
34
|
-
## Guards
|
|
35
|
-
|
|
36
|
-
- On `main`: stop and say to switch to a pull request branch
|
|
37
|
-
- Nothing changed: stop
|
|
38
|
-
- No open pull request: stop and route to the skill that opens one
|
|
39
|
-
|
|
40
29
|
## Out of scope
|
|
41
30
|
|
|
42
31
|
- Opening the pull request, which `git-pr` owns and `git-ship` chains
|
|
43
|
-
- Deciding what to fix from a review, which `review-address` owns
|
|
44
|
-
- Grouping a multi-concern diff, which `git-stage` owns
|
|
32
|
+
- Deciding what to fix from a review, which `review-address` owns
|
|
33
|
+
- Grouping a multi-concern diff, which `git-stage` owns
|
|
@@ -58,6 +58,7 @@ A missing tracking ref is not a guard, since an open pull request proves the bra
|
|
|
58
58
|
- Read the live title and body with `gh api repos/{owner}/{repo}/pulls/<number> --jq '{html_url, title, body}'`. Update the body with `gh api -X PATCH repos/{owner}/{repo}/pulls/<number> -F body=@<file> --silent` when the new commit changes scope, writing the new body to `<file>` first, and the title with `gh api -X PATCH repos/{owner}/{repo}/pulls/<number> -f title="<title>" --silent` when the scope shifted enough to make it inaccurate.
|
|
59
59
|
- A fix commit answering a review changes what shipped exactly as much as an ordinary followup does, so the sync cannot wait on the invocation or the comment count below.
|
|
60
60
|
- A body a person edited by hand between rounds gets no special handling: judge it against the tree the same way regardless of who wrote it last, since a hand-edit the fix commit has made stale is the exact drift this sync exists to close.
|
|
61
|
+
- Carry a `UI pass` line marked `<!-- pr-ui-pass -->` into any rewritten body unchanged, since `canon pr tick` owns it and a dropped marker defeats the reset on a new head.
|
|
61
62
|
8. Route on the invocation and the comment count for the reply alone.
|
|
62
63
|
- When invoked with `reply-owned`, skip this step: the caller posts its own reply.
|
|
63
64
|
- Otherwise, if the count is above zero, the followup addresses review feedback: write a one-line summary of the fix to `.canon/tmp/pr/followup/summary-<number>.md` in its own call, run `canon labels scan --body-file .canon/tmp/pr/followup/summary-<number>.md` against it, which applies the rule in `${CLAUDE_SKILL_DIR}/../git-pr/references/publish.md`, then post it with `gh api -X POST repos/{owner}/{repo}/issues/<number>/comments -F body=@.canon/tmp/pr/followup/summary-<number>.md --silent`. A hook on `Bash` runs the same scan on that body file and denies the post on a hit, and it refuses an inline `-f body=` value, so the body goes through a file. The `pull_request` check the git-pr surface carries triggers on a push or an open rather than a plain edit, so neither this comment nor the title and body step 7 synced reaches it.
|
|
@@ -7,32 +7,26 @@ description: What issue filing is for, the gaps it closes, and which reporting p
|
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
10
|
-
Without this skill, an issue takes the shape of whatever the session was saying. It arrives with no label, so triage cannot filter it, and without the sections a triage pass reads, so the reader
|
|
10
|
+
Without this skill, an issue takes the shape of whatever the session was saying. It arrives with no label, so triage cannot filter it, and without the sections a triage pass reads, so the reader reconstructs the problem from narrative.
|
|
11
|
+
|
|
12
|
+
Prose bans hold on files the hook watches and not on text leaving through `gh`, so a banned character survives into a published issue that then has to be edited on the remote. A missing remote or an unauthenticated `gh` surfaces only after the body is written.
|
|
11
13
|
|
|
12
14
|
## Must
|
|
13
15
|
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
-
|
|
17
|
-
-
|
|
18
|
-
- Ask once when the type is ambiguous between a bug and a task, since the label follows from it and a wrong label buries the issue
|
|
19
|
-
- Pass the body through a file and remove it afterward, so shell quoting cannot mangle it
|
|
16
|
+
- The title and body follow the issue reference and are scanned for banned characters and phase labels before filing
|
|
17
|
+
- Each issue carries exactly one label mapped from its type, asked once when the type is ambiguous between a bug and a task
|
|
18
|
+
- A remote and an authenticated `gh` are confirmed before any body is composed
|
|
19
|
+
- The body passes through a file that is removed afterward
|
|
20
20
|
|
|
21
21
|
## Must not
|
|
22
22
|
|
|
23
|
-
- Invent an issue from a thin session
|
|
23
|
+
- Invent an issue from a thin session
|
|
24
24
|
- File anywhere other than the current origin
|
|
25
25
|
- Open a pull request
|
|
26
26
|
- Emit anything after the result line
|
|
27
27
|
|
|
28
|
-
## Guards
|
|
29
|
-
|
|
30
|
-
- No concrete bug or task in session context: stop and say what to provide
|
|
31
|
-
- No remote: stop and name what `gh issue create` needs
|
|
32
|
-
- `gh` not authenticated: stop and name the command that authenticates
|
|
33
|
-
|
|
34
28
|
## Out of scope
|
|
35
29
|
|
|
36
|
-
- Reporting a toolkit defect from a target project, which `canon-feedback` owns
|
|
30
|
+
- Reporting a toolkit defect from a target project, which `canon-feedback` owns
|
|
37
31
|
- Triaging issues already filed, which `canon-feedback-triage` owns
|
|
38
32
|
- Opening a pull request, which `git-pr` owns
|
|
@@ -7,47 +7,28 @@ description: What pull request generation is for, the gaps it closes, and what i
|
|
|
7
7
|
|
|
8
8
|
## Gap
|
|
9
9
|
|
|
10
|
-
Without this skill, a pull request body is written from memory
|
|
10
|
+
Without this skill, a pull request body is written from memory rather than the diff, so it describes the intent and omits what the work became. Testing boxes get ticked from intent, a second push errors or opens a duplicate, and banned characters survive into a body the hook never sees. The body grows into a wall nothing measures.
|
|
11
11
|
|
|
12
|
-
Every pull request
|
|
13
|
-
|
|
14
|
-
A lookup that resolves by head branch alone carries its own failure. A branch name reused after an earlier pull request merged resolves to the closed one, so the run rewrites a merged pull request's title and body and reports its URL as the one it opened. Both fields are recoverable only through the issue timeline and the edit history, and nothing reports that the write landed on the wrong object.
|
|
12
|
+
Every pull request lands unlabelled, so a merged list cannot be filtered by surface. A head-branch lookup resolves a reused name to the merged pull request and rewrites it. A pull request changing a rendered surface reaches review with no screenshots, and a hand-written `Closes` line closes an issue on a middle slice or misses one the task names.
|
|
15
13
|
|
|
16
14
|
## Must
|
|
17
15
|
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
- Detect an open pull request and edit it in place, so a follow-up push keeps the body in sync instead of failing
|
|
24
|
-
- Scope that detection to an open pull request on the current head and the default base, so neither a reused branch name nor a second base resolves the wrong one
|
|
25
|
-
- Resolve the pull request once and reuse what that resolution returned, so the number recorded never depends on how a lookup ranks two pull requests sharing a head
|
|
26
|
-
- Prove before every write to an existing pull request that its head is the current branch and its state is open, and refuse with nothing written on a mismatch, so a wrong number reaching a write never lands on another branch's pull request
|
|
27
|
-
- Print the head branch beside the number, so a caller writing to the pull request later has a value to check the number against
|
|
28
|
-
- Label from the paths the branch changed, against a map the project declares, so the label set belongs to the project rather than to the skill
|
|
29
|
-
- Apply labels after the pull request exists, so a label the remote does not carry costs a warning rather than the pull request
|
|
30
|
-
- Report a refused label, since a warning nothing surfaces leaves the run indistinguishable from one that labelled
|
|
31
|
-
- End every pull request it opens or edits by invoking `pr-evidence` with the number it resolved, since a pull request changing a rendered surface otherwise reaches review with no screenshots, checklist, or address
|
|
16
|
+
- The title and body come from the commits and the lockfile-free diff against main, scanned for banned characters, phase labels, and density, and every ticked box records a check this run executed
|
|
17
|
+
- A follow-up run edits the one open pull request on the current head and default base, resolved once, and every write first proves that pull request's head and open state
|
|
18
|
+
- Closing lines come from `canon tasks closes`, one `Closes #NNN` per issue on the task's last slice only, with the scan failing a body that disagrees
|
|
19
|
+
- Labels come from the paths the branch changed against a map the project declares, applied after the pull request exists, with a refused label reported
|
|
20
|
+
- The run closes by invoking `pr-evidence` with the number it resolved, and prints the head branch beside that number
|
|
32
21
|
|
|
33
22
|
## Must not
|
|
34
23
|
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
- Create a second pull request
|
|
38
|
-
-
|
|
39
|
-
- Name a domain of any one project in the skill body or its references
|
|
40
|
-
- Create a label the map names and the remote lacks
|
|
24
|
+
- Run on a non-conforming branch name or with no commits ahead of main
|
|
25
|
+
- Tick a testing box from intent, or put a request for the reviewer in the Testing list
|
|
26
|
+
- Create a second pull request, or edit one that is not open
|
|
27
|
+
- Name a domain of any one project in the body or its references, or create a label the remote lacks
|
|
41
28
|
- Emit anything after the result line
|
|
42
29
|
|
|
43
|
-
## Guards
|
|
44
|
-
|
|
45
|
-
- Branch name does not conform: stop and route to the skill that renames
|
|
46
|
-
- No commits ahead of main: stop
|
|
47
|
-
- No label map in the project: label nothing and warn nothing, since an absent map is a decision rather than a gap
|
|
48
|
-
|
|
49
30
|
## Out of scope
|
|
50
31
|
|
|
51
|
-
- Naming the branch, which `git-branch` owns
|
|
32
|
+
- Naming the branch, which `git-branch` owns
|
|
52
33
|
- Grouping the diff into commits, which `git-stage` owns
|
|
53
|
-
- Pushing a later edit onto
|
|
34
|
+
- Pushing a later edit onto a pull request already under review, which `git-followup` owns
|
|
@@ -75,6 +75,10 @@ Follow Testing discipline in `${CLAUDE_SKILL_DIR}/references/pr.md`. Run each ch
|
|
|
75
75
|
|
|
76
76
|
Leave a box unchecked only for the human-only cases the reference defines, and name which human and why on the same line. A request for the reviewer is not a test result, so it belongs under `## For the reviewer` rather than in the Testing list.
|
|
77
77
|
|
|
78
|
+
### Name the issues the pull request closes
|
|
79
|
+
|
|
80
|
+
Ask `canon tasks closes` which issues this pull request closes before writing the body, and put one `Closes #NNN` line per issue last in `## Summary`. Read `${CLAUDE_SKILL_DIR}/references/closing-issues.md` on reaching this step for the invocation, the refusals it skips silently, and why an earlier slice of a sliced task carries none.
|
|
81
|
+
|
|
78
82
|
### Pre-publish scan
|
|
79
83
|
|
|
80
84
|
Before running the final command, run the scan in `${CLAUDE_SKILL_DIR}/references/publish.md` against the PR title and body, on top of the banned phrases in `${CLAUDE_SKILL_DIR}/references/pr.md`. The title and body go straight to the remote, so run it whatever backs it downstream.
|
|
@@ -94,12 +98,14 @@ BODY
|
|
|
94
98
|
Then run:
|
|
95
99
|
|
|
96
100
|
```bash
|
|
97
|
-
canon labels scan --title "<title>" --body-file .canon/tmp/pr/body.md --json
|
|
101
|
+
canon labels scan --title "<title>" --body-file .canon/tmp/pr/body.md --closes <numbers|none> --json
|
|
98
102
|
```
|
|
99
103
|
|
|
104
|
+
Drop `--closes` when the closes step skipped a refusal, since no list was decided to grade against.
|
|
105
|
+
|
|
100
106
|
### Reading the scan
|
|
101
107
|
|
|
102
|
-
Branch on the JSON record rather than the exit code, since a shell function wrapping `canon` can flatten a non-zero exit to 0. Stop and fix the title or body on any key below, and do not proceed to `### Final command` until a re-run comes back clean on all
|
|
108
|
+
Branch on the JSON record rather than the exit code, since a shell function wrapping `canon` can flatten a non-zero exit to 0. Stop and fix the title or body on any key below, and do not proceed to `### Final command` until a re-run comes back clean on all nine.
|
|
103
109
|
|
|
104
110
|
| Key | Fix |
|
|
105
111
|
| ------------------- | ------------------------------------------------------------------------------------ |
|
|
@@ -109,6 +115,9 @@ Branch on the JSON record rather than the exit code, since a shell function wrap
|
|
|
109
115
|
| `titleFormatIssues` | Fix the `## Title` rule in `pr.md` it names, being structure, casing, or length |
|
|
110
116
|
| `bannedCharacters` | Restructure the sentence around the named character |
|
|
111
117
|
| `sections` | Rename or drop each heading in `outside`, and add each required heading in `missing` |
|
|
118
|
+
| `missingClosures` | Add a `Closes #NNN` line for each number listed |
|
|
119
|
+
| `strayClosures` | Delete the closing keyword for each number listed |
|
|
120
|
+
| `density` | Regroup or split the named section per `## Formatting` in `pr.md`, keeping each path |
|
|
112
121
|
|
|
113
122
|
Leave `cutsRelease` and `semverTags` alone, since a release-please pull request legitimately carries version references its own fixed shape explains.
|
|
114
123
|
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Close the task's issues
|
|
3
|
+
description: How git-pr asks canon tasks closes which issues the pull request closes, the Closes line it writes into the body, the refusals it skips silently, and why an earlier slice carries none
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Close the task's issues
|
|
7
|
+
|
|
8
|
+
Reached before the body is written. A task that cites `Issue: #NNN` ships and archives while its issue stays open unless the pull request body carries a closing keyword, and GitHub closes the issue only when that pull request merges into the default branch. `git-pr` always bases on the default branch, so no handling for another base is needed.
|
|
9
|
+
|
|
10
|
+
## Ask the verb
|
|
11
|
+
|
|
12
|
+
The plan is the one `task-number.md` names, so reuse the filename an earlier step already read.
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
canon tasks closes --plan feature-<slug> --json
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The verb reads the current branch itself and counts the names it carried before a rename, so pass nothing else. Branch on the record rather than the exit code.
|
|
19
|
+
|
|
20
|
+
| Record | Route |
|
|
21
|
+
| --------------------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
22
|
+
| `ok: true`, `closing: true` | Write one `Closes #NNN` line per number in `issues`, and pass the list to the scan |
|
|
23
|
+
| `ok: true`, `closing: false` | Write no closing line, and pass `--closes none` to the scan |
|
|
24
|
+
| `ok: false`, `no-board`, `no-match`, or `ambiguous` | Write nothing and run the scan without `--closes` |
|
|
25
|
+
| Any other refusal | Report it rather than swallowing it |
|
|
26
|
+
|
|
27
|
+
The three skipped refusals are the ones `task-number.md` skips, and for the same reason. A guessed task would close the wrong issue.
|
|
28
|
+
|
|
29
|
+
## The line
|
|
30
|
+
|
|
31
|
+
- Put the lines last in `## Summary`, after its sentences, one per issue
|
|
32
|
+
- Write `Closes #NNN` with no trailing period, since GitHub reads the keyword and the number and a period adds nothing
|
|
33
|
+
- Write one keyword per issue, because GitHub reads a keyword followed by a comma list as closing the first number alone
|
|
34
|
+
|
|
35
|
+
The scan takes the same list, so a missing line or a closing keyword the verb did not name fails the body:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
canon labels scan --title "<title>" --body-file .canon/tmp/pr/body.md --closes <numbers|none> --json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Why an earlier slice carries none
|
|
42
|
+
|
|
43
|
+
The verb applies the condition the merge-time archive applies, being no open outcome and no other branch on the task's `Pending branch:` line. The issue then closes exactly when the task archives. An earlier slice merging with a closing keyword would close the issue while later slices are still to ship.
|
|
44
|
+
|
|
45
|
+
A re-run on an earlier slice's branch reads the same way. The verb looks up the branch's own pull request numbers, and one that is on the task's `Pull request:` line without being last reports `earlier-slice` and no closing line. The lookup runs over REST, and a failed one reports `lookup-failed` and no closing line once the task lists a pull request, since a failure cannot rule an earlier slice out.
|
|
46
|
+
|
|
47
|
+
`git-ship` ticks the outcomes before `git-pr` runs, so the condition holds at body time. A run with outcomes not yet ticked reads as an earlier slice and writes no line. That is the safe side, since the issue stays open, and the record's `reason` names why.
|