@erclx/canon 5.25.0 → 5.27.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/README.md +4 -3
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/SKILL.md +2 -0
- package/claude/skills/auto-ship/SKILL.md +3 -11
- package/claude/skills/auto-ship/references/review-findings.md +20 -0
- package/claude/skills/backlog-triage/SKILL.md +2 -0
- package/claude/skills/bash-cli-script/SKILL.md +2 -0
- package/claude/skills/build-in-slices/SKILL.md +2 -0
- package/claude/skills/canon-cli/SKILL.md +2 -0
- package/claude/skills/canon-feedback/SKILL.md +2 -0
- package/claude/skills/canon-feedback-triage/SKILL.md +2 -0
- package/claude/skills/canon-operator/SKILL.md +2 -0
- package/claude/skills/canon-rollout/SKILL.md +3 -11
- package/claude/skills/canon-rollout/references/failure-recovery.md +20 -0
- package/claude/skills/canvas/SKILL.md +14 -1
- package/claude/skills/ci-workflow/SKILL.md +2 -0
- package/claude/skills/code-craft/SKILL.md +2 -0
- package/claude/skills/codebase-layout/SKILL.md +2 -0
- package/claude/skills/context-fold/REQUIREMENT.md +6 -2
- package/claude/skills/context-fold/SKILL.md +9 -21
- package/claude/skills/context-fold/references/anchor-sweep.md +2 -2
- package/claude/skills/context-fold/references/completion-report.md +26 -0
- package/claude/skills/create-rule/SKILL.md +2 -0
- package/claude/skills/create-skill/SKILL.md +2 -0
- package/claude/skills/create-standard/SKILL.md +2 -0
- package/claude/skills/decision-escalate/SKILL.md +2 -0
- package/claude/skills/deploy-app/SKILL.md +2 -0
- package/claude/skills/deprecation-migration/SKILL.md +2 -0
- package/claude/skills/design-extract/SKILL.md +2 -0
- package/claude/skills/design-taste/REQUIREMENT.md +1 -1
- package/claude/skills/design-taste/SKILL.md +6 -2
- package/claude/skills/design-taste/references/adopted.md +40 -0
- package/claude/skills/design-taste/references/kinds.md +1 -1
- package/claude/skills/design-taste/references/systems.md +1 -7
- package/claude/skills/design-taste/references/tells.md +2 -24
- package/claude/skills/docs-sync/REQUIREMENT.md +2 -1
- package/claude/skills/docs-sync/SKILL.md +2 -0
- package/claude/skills/document-health/REQUIREMENT.md +2 -0
- package/claude/skills/document-health/SKILL.md +23 -0
- package/claude/skills/document-health/references/axes.md +12 -0
- package/claude/skills/draft-and-pick/SKILL.md +3 -1
- package/claude/skills/draft-doc/SKILL.md +2 -0
- package/claude/skills/draft-doc/references/wiki.md +1 -1
- package/claude/skills/draft-figure/SKILL.md +2 -0
- package/claude/skills/draft-identity/SKILL.md +3 -1
- package/claude/skills/draft-ready/SKILL.md +2 -0
- package/claude/skills/draft-screencast/SKILL.md +11 -7
- package/claude/skills/draft-slides/REQUIREMENT.md +17 -12
- package/claude/skills/draft-slides/SKILL.md +33 -20
- package/claude/skills/git-branch/SKILL.md +2 -0
- package/claude/skills/git-commit/SKILL.md +2 -0
- package/claude/skills/git-followup/SKILL.md +2 -0
- package/claude/skills/git-issue/SKILL.md +2 -0
- package/claude/skills/git-issue/references/issue.md +10 -0
- package/claude/skills/git-pr/SKILL.md +2 -0
- package/claude/skills/git-pr/references/evidence.md +14 -6
- package/claude/skills/git-pr/references/labels.md +12 -0
- package/claude/skills/git-ship/SKILL.md +2 -0
- package/claude/skills/git-split/SKILL.md +21 -8
- package/claude/skills/git-stage/SKILL.md +2 -0
- package/claude/skills/git-worktree/SKILL.md +2 -0
- package/claude/skills/index-lookup/SKILL.md +2 -0
- package/claude/skills/markdown-propose/SKILL.md +2 -0
- package/claude/skills/markdown-propose/references/format.md +9 -0
- package/claude/skills/memory-capture/SKILL.md +2 -0
- package/claude/skills/memory-review/SKILL.md +2 -0
- package/claude/skills/memory-review/references/later-phases.md +7 -0
- package/claude/skills/plan-feature/SKILL.md +2 -0
- package/claude/skills/plan-groundwork/SKILL.md +2 -0
- package/claude/skills/plan-intake/SKILL.md +2 -0
- package/claude/skills/plan-intake-answer/SKILL.md +2 -0
- package/claude/skills/project-commands/SKILL.md +2 -0
- package/claude/skills/read-frames/SKILL.md +2 -0
- package/claude/skills/record-screencast/SKILL.md +2 -0
- package/claude/skills/repo-metadata/SKILL.md +2 -0
- package/claude/skills/restate-plainly/SKILL.md +2 -0
- package/claude/skills/review-address/SKILL.md +3 -7
- package/claude/skills/review-address/references/post-review-findings.md +16 -0
- package/claude/skills/review-branch/SKILL.md +2 -0
- package/claude/skills/review-craft/SKILL.md +2 -0
- package/claude/skills/review-craft/references/ui.md +2 -2
- package/claude/skills/review-pr/SKILL.md +4 -8
- package/claude/skills/review-pr/references/body-variants.md +52 -0
- package/claude/skills/review-pr/references/key-changes.md +16 -0
- package/claude/skills/review-pr/references/post.md +15 -43
- package/claude/skills/review-ui/SKILL.md +3 -1
- package/claude/skills/review-ui/references/post.md +4 -2
- package/claude/skills/role-orchestrator/SKILL.md +5 -14
- package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +8 -0
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +13 -0
- package/claude/skills/role-orchestrator/references/orchestrator-handback.md +1 -1
- package/claude/skills/role-orchestrator/references/orchestrator-inbound.md +23 -0
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +5 -33
- package/claude/skills/role-orchestrator/references/orchestrator-poll.md +1 -21
- package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +1 -1
- package/claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md +38 -0
- package/claude/skills/role-orchestrator/references/orchestrator-watch.md +26 -0
- package/claude/skills/role-planner/SKILL.md +2 -0
- package/claude/skills/role-reviewer/REQUIREMENT.md +1 -1
- package/claude/skills/role-reviewer/SKILL.md +2 -0
- package/claude/skills/role-worker/SKILL.md +2 -0
- package/claude/skills/search-craft/REQUIREMENT.md +1 -1
- package/claude/skills/search-craft/SKILL.md +5 -1
- package/claude/skills/search-craft/references/adopted.md +30 -0
- package/claude/skills/seed-sync/SKILL.md +2 -0
- package/claude/skills/session-compact/SKILL.md +2 -0
- package/claude/skills/session-map/SKILL.md +2 -0
- package/claude/skills/session-relay/SKILL.md +2 -0
- package/claude/skills/session-resume/SKILL.md +2 -0
- package/claude/skills/session-worktree/SKILL.md +3 -11
- package/claude/skills/session-worktree/references/install-command.md +20 -0
- package/claude/skills/sketch-design/SKILL.md +2 -0
- package/claude/skills/systematic-debugging/SKILL.md +2 -0
- package/claude/skills/target-check/SKILL.md +2 -0
- package/claude/skills/target-setup/SKILL.md +2 -0
- package/claude/skills/target-setup/references/detect.md +8 -0
- package/claude/skills/target-setup/references/indexes.md +13 -0
- package/claude/skills/target-setup/references/verify.md +8 -0
- package/claude/skills/task-board/SKILL.md +2 -0
- package/claude/skills/teach-workspace/SKILL.md +5 -15
- package/claude/skills/teach-workspace/references/lesson-build.md +75 -0
- package/claude/skills/teach-workspace/references/lesson-craft.md +13 -69
- package/claude/skills/teach-workspace/references/revisit.md +22 -0
- package/claude/skills/test-craft/SKILL.md +2 -0
- package/claude/skills/test-first/SKILL.md +4 -0
- package/claude/skills/test-first/references/adopted.md +36 -0
- package/claude/skills/ui-checklist/SKILL.md +2 -0
- package/claude/skills/ux-audit/SKILL.md +2 -0
- package/claude/skills/ux-measure/SKILL.md +2 -0
- package/claude/skills/ux-walkthrough/SKILL.md +2 -0
- package/claude/skills/video-craft/SKILL.md +2 -0
- package/claude/skills/write-human/SKILL.md +3 -1
- package/claude/skills/write-human/references/machine-tells.md +13 -0
- package/claude/skills/youtube-transcripts/SKILL.md +2 -0
- package/docs/agents/canvas.md +24 -6
- package/docs/agents/capture.md +6 -6
- package/docs/agents/commands.md +5 -5
- package/docs/agents/index.md +5 -5
- package/docs/agents/install-and-sync.md +7 -0
- package/docs/agents/key-changes.md +1 -1
- package/docs/agents/pr-evidence.md +38 -15
- package/docs/agents/pr-local.md +19 -13
- package/docs/agents/pr-preview.md +44 -21
- package/docs/agents/records-stale.md +22 -9
- package/docs/agents/records.md +1 -1
- package/docs/agents/sandbox.md +29 -5
- package/docs/agents/scripting.md +8 -1
- package/docs/agents/skills-audit.md +11 -3
- package/docs/agents/slides.md +15 -3
- package/docs/workflow/ai-workflow.md +1 -1
- package/docs/workflow/index.md +1 -0
- package/docs/workflow/operating-model.md +5 -6
- package/docs/workflow/parallel-features.md +23 -2
- package/docs/workflow/skill-map-on-request.md +42 -0
- package/docs/workflow/skill-map.md +3 -34
- package/docs/workflow/zshrc-aliases.md +1 -1
- package/package.json +1 -1
- package/scripts/core/regen-hero.ts +1 -1
- package/scripts/lib/sandbox-git.sh +1 -9
- package/scripts/lib/sandbox-path.sh +6 -162
- package/scripts/sandbox-hook.sh +99 -0
- package/src/audits/run.ts +1 -1
- package/src/canvas/address.ts +12 -3
- package/src/canvas/capture.ts +1 -9
- package/src/canvas/client/inspector/align-grid.tsx +162 -0
- package/src/canvas/client/inspector/color-field.tsx +398 -0
- package/src/canvas/client/inspector/color-inputs.tsx +139 -0
- package/src/canvas/client/inspector/color-picker.tsx +668 -0
- package/src/canvas/client/inspector/color-space.ts +240 -0
- package/src/canvas/client/inspector/field.tsx +5 -1
- package/src/canvas/client/inspector/fields.css +547 -17
- package/src/canvas/client/inspector/size-field.tsx +69 -0
- package/src/canvas/client/inspector/values.ts +166 -1
- package/src/canvas/client/inspector.tsx +236 -73
- package/src/canvas/client/selection.tsx +197 -0
- package/src/canvas/client/shell.css +104 -12
- package/src/canvas/client/state.ts +69 -9
- package/src/canvas/client/surface.tsx +147 -22
- package/src/canvas/content.ts +50 -1
- package/src/canvas/edit.ts +37 -4
- package/src/canvas/editing.ts +203 -0
- package/src/canvas/global.d.ts +15 -0
- package/src/canvas/server.ts +149 -12
- package/src/canvas/tokens.ts +59 -17
- package/src/capture/render.ts +45 -7
- package/src/capture/sources.ts +43 -0
- package/src/census/count.ts +2 -2
- package/src/claude/cases/workflow.ts +5 -0
- package/src/claude/seeds.ts +2 -2
- package/src/claude/skills-audit.ts +96 -14
- package/src/claude/skills-drift.ts +1 -1
- package/src/claude/skills-families.ts +36 -0
- package/src/claude/skills-list.ts +76 -15
- package/src/commands/audits.ts +2 -2
- package/src/commands/canvas.ts +179 -2
- package/src/commands/claude.ts +94 -11
- package/src/commands/design.ts +142 -2
- package/src/commands/feedback.ts +3 -3
- package/src/commands/gov.ts +1 -1
- package/src/commands/hooks.ts +1 -1
- package/src/commands/indexes.ts +1 -1
- package/src/commands/init.ts +1 -1
- package/src/commands/intake.ts +1 -1
- package/src/commands/migrate.ts +1 -1
- package/src/commands/pr.ts +105 -58
- package/src/commands/records.ts +89 -7
- package/src/commands/repo.ts +1 -1
- package/src/commands/sandbox.ts +103 -11
- package/src/commands/sessions.ts +1 -1
- package/src/commands/slides.ts +31 -77
- package/src/commands/sync.ts +1 -1
- package/src/commands/tasks.ts +2 -2
- package/src/commands/teach.ts +1 -1
- package/src/commands/transcripts.ts +1 -1
- package/src/commands/worktrees.ts +1 -1
- package/src/comments/scan.ts +1 -1
- package/src/comments/trend.ts +1 -1
- package/src/context/audit.ts +1 -1
- package/src/context/citations.ts +1 -1
- package/src/context/classify/extract.ts +2 -2
- package/src/design/project-fonts.ts +392 -0
- package/src/design/tokens.ts +2 -18
- package/src/docs/read.ts +1 -1
- package/src/{github.ts → feedback/github.ts} +2 -2
- package/src/{client-commands.ts → gate/client-commands.ts} +1 -1
- package/src/gate/measures.ts +53 -13
- package/src/gate/sequencer.ts +1 -1
- package/src/gate/stages.ts +9 -0
- package/src/{git-files.ts → git/files.ts} +2 -2
- package/src/{git-ignore.ts → git/ignore.ts} +1 -1
- package/src/{worktree.ts → git/worktree.ts} +1 -1
- package/src/gov/citations.ts +2 -2
- package/src/gov/install.ts +1 -1
- package/src/gov/payload.ts +1 -1
- package/src/gov/superseded.ts +3 -3
- package/src/gov/test-order.ts +2 -2
- package/src/help.ts +1 -1
- package/src/hooks/post-merge.ts +1 -1
- package/src/indexes/walk.ts +1 -1
- package/src/labels/audit.ts +1 -1
- package/src/markdown/ceiling.ts +1 -1
- package/src/markdown/files.ts +1 -1
- package/src/migrate/apply.ts +1 -1
- package/src/pr/bijection.ts +1 -1
- package/src/pr/evidence.ts +96 -43
- package/src/pr/local.ts +16 -10
- package/src/pr/preview.ts +78 -2
- package/src/record-root.ts +1 -0
- package/src/records/backup.ts +2 -1
- package/src/records/push-guard.ts +1 -1
- package/src/records/stale-canonical.ts +146 -0
- package/src/records/stale.ts +1 -1
- package/src/sandbox/headless/dispatch.ts +264 -0
- package/src/sandbox/headless/run.ts +653 -0
- package/src/sandbox/headless/watch.ts +145 -0
- package/src/sandbox/hooks.ts +128 -0
- package/src/sandbox/provision.ts +607 -0
- package/src/sandbox/tree.ts +99 -4
- package/src/secrets/marker.ts +2 -2
- package/src/secrets/scan.ts +2 -2
- package/src/sessions/claim.ts +1 -1
- package/src/sessions/resolve.ts +1 -1
- package/src/sessions/transfer/bundle.ts +1 -1
- package/src/shipped/references.ts +2 -2
- package/src/slides/convert/export.ts +2 -16
- package/src/slides/decks.ts +110 -0
- package/src/slides/package/fonts.ts +6 -2
- package/src/standards/audit.ts +2 -2
- package/src/standards/read.ts +1 -1
- package/src/sync/check.ts +2 -2
- package/src/sync/engine.ts +2 -2
- package/src/sync/git.ts +1 -1
- package/src/sync/history.ts +1 -1
- package/src/sync/reverse.ts +1 -1
- package/src/sync/seeds-report.ts +1 -1
- package/src/sync/target.ts +1 -1
- package/src/sync/workflow.ts +1 -1
- package/src/targets/pulls.ts +2 -2
- package/src/targets/sweep.ts +2 -2
- package/src/tasks/answers.ts +1 -1
- package/src/tasks/archive.ts +1 -1
- package/src/tasks/reach.ts +1 -1
- package/src/tasks/trunk.ts +1 -1
- package/src/teach/nav.ts +1 -1
- package/src/tooling/inject.ts +2 -2
- package/src/tooling/subfolder.ts +1 -1
- package/src/web/readme-citations.ts +2 -2
- package/src/worktrees/bare-flag.ts +1 -1
- package/src/worktrees/reclaim.ts +2 -2
- package/src/worktrees/remove.ts +1 -1
- package/standards/architecture.md +1 -0
- package/standards/canvas.md +3 -2
- package/standards/requirements.md +2 -0
- package/standards/skill-practice.md +2 -1
- package/standards/skill.md +2 -0
- package/standards/wiki.md +12 -3
- package/tooling/base/configs/.github/workflows/pr-local-preview.yml +2 -2
- package/scripts/lib/sandbox-dispatch.sh +0 -190
- package/scripts/manage-sandbox.sh +0 -472
- package/src/slides/layouts.ts +0 -478
- package/src/slides/parse.ts +0 -84
- package/src/slides/render.ts +0 -110
- package/src/slides/styles.ts +0 -96
- /package/claude/skills/write-human/references/{source-material.md → adopted.md} +0 -0
- /package/src/{commands/feedback-format.ts → feedback/body.ts} +0 -0
- /package/src/{github-format.ts → feedback/github-format.ts} +0 -0
- /package/src/{git-base.ts → git/base.ts} +0 -0
- /package/src/{git-env.ts → git/env.ts} +0 -0
- /package/src/{frontmatter.ts → markdown/frontmatter.ts} +0 -0
- /package/src/{binary.ts → sweep/binary.ts} +0 -0
- /package/src/{exempt-marker.ts → sweep/exempt-marker.ts} +0 -0
- /package/src/{copy.ts → sync/copy.ts} +0 -0
- /package/src/{target.ts → targets/validate.ts} +0 -0
- /package/src/{paths.ts → tasks/paths.ts} +0 -0
- /package/src/{seed-marker.ts → tooling/seed-marker.ts} +0 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: git-split
|
|
3
3
|
description: Splits a mixed-commit branch into focused branches off main using cherry-pick. Use when a branch has unrelated commits, asking "split this branch", or needing to separate concerns into reviewable PRs.
|
|
4
|
+
metadata:
|
|
5
|
+
family: after-pr
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Git split
|
|
@@ -86,7 +88,8 @@ git switch -c <branch> main && git cherry-pick <sha> <sha> \
|
|
|
86
88
|
&& (cat <<'BODY' > .canon/tmp/pr/split/<branch>.md
|
|
87
89
|
<body following pr.md template, written from the cherry-picked commits>
|
|
88
90
|
BODY
|
|
89
|
-
) && gh
|
|
91
|
+
) && gh api -X POST 'repos/{owner}/{repo}/pulls' -f title="<title>" -f head=<branch> -f base=main -F body=@.canon/tmp/pr/split/<branch>.md --jq .html_url \
|
|
92
|
+
&& printf 'opened=true\n' \
|
|
90
93
|
&& rm .canon/tmp/pr/split/<branch>.md
|
|
91
94
|
|
|
92
95
|
# Return to primary branch, push, and open its PR
|
|
@@ -94,13 +97,18 @@ git checkout <new_name> && git push -u origin <new_name> \
|
|
|
94
97
|
&& (cat <<'BODY' > .canon/tmp/pr/split/<new_name>.md
|
|
95
98
|
<body following pr.md template, written from the primary's commits>
|
|
96
99
|
BODY
|
|
97
|
-
) && gh
|
|
100
|
+
) && gh api -X POST 'repos/{owner}/{repo}/pulls' -f title="<title>" -f head=<new_name> -f base=main -F body=@.canon/tmp/pr/split/<new_name>.md --jq .html_url \
|
|
101
|
+
&& printf 'opened=true\n' \
|
|
98
102
|
&& rm .canon/tmp/pr/split/<new_name>.md
|
|
99
103
|
|
|
100
104
|
# Clean up the body-file dir if all PRs succeeded (no-op when non-empty)
|
|
101
105
|
rmdir .canon/tmp/pr/split 2>/dev/null || true
|
|
102
106
|
```
|
|
103
107
|
|
|
108
|
+
Every pull request opens through the REST pulls endpoint rather than the `gh pr` create subcommand, which runs on GraphQL and fails where a cloud session's GitHub proxy refuses it. The endpoint requires `base`, so each call names the branch its layer sits on. `-F` reads the body file, where `-f` would post the path itself.
|
|
109
|
+
|
|
110
|
+
A create the endpoint refuses, such as one for a head that already has an open pull request, exits non-zero and stops the chain before `opened=true` prints and before the body file is removed. The `opened=true` line is what a pull request creation log reads to count the opening, since the REST call prints a URL and never names itself.
|
|
111
|
+
|
|
104
112
|
For stacked mode, base each branch on the previous and cherry-pick only that group's commits:
|
|
105
113
|
|
|
106
114
|
```bash
|
|
@@ -115,7 +123,8 @@ git switch -c <branch-1> main && git cherry-pick <g1-sha> <g1-sha> \
|
|
|
115
123
|
&& (cat <<'BODY' > .canon/tmp/pr/split/<branch-1>.md
|
|
116
124
|
<body following pr.md template, written from the cherry-picked commits>
|
|
117
125
|
BODY
|
|
118
|
-
) && gh
|
|
126
|
+
) && gh api -X POST 'repos/{owner}/{repo}/pulls' -f title="<title>" -f head=<branch-1> -f base=main -F body=@.canon/tmp/pr/split/<branch-1>.md --jq .html_url \
|
|
127
|
+
&& printf 'opened=true\n' \
|
|
119
128
|
&& rm .canon/tmp/pr/split/<branch-1>.md
|
|
120
129
|
|
|
121
130
|
# Group 2: based on <branch-1>, this group's commits only
|
|
@@ -124,15 +133,17 @@ git checkout -b <branch-2> && git cherry-pick <g2-sha> <g2-sha> \
|
|
|
124
133
|
&& (cat <<'BODY' > .canon/tmp/pr/split/<branch-2>.md
|
|
125
134
|
<body following pr.md template, written from the cherry-picked commits>
|
|
126
135
|
BODY
|
|
127
|
-
) && gh
|
|
136
|
+
) && gh api -X POST 'repos/{owner}/{repo}/pulls' -f title="<title>" -f head=<branch-2> -f base=<branch-1> -F body=@.canon/tmp/pr/split/<branch-2>.md --jq .html_url \
|
|
137
|
+
&& printf 'opened=true\n' \
|
|
128
138
|
&& rm .canon/tmp/pr/split/<branch-2>.md
|
|
129
139
|
|
|
130
|
-
# Return to primary branch, push, and open its PR
|
|
140
|
+
# Return to primary branch, push, and open its PR on the last group's branch
|
|
131
141
|
git checkout <new_name> && git push -u origin <new_name> \
|
|
132
142
|
&& (cat <<'BODY' > .canon/tmp/pr/split/<new_name>.md
|
|
133
143
|
<body following pr.md template, written from the primary's commits>
|
|
134
144
|
BODY
|
|
135
|
-
) && gh
|
|
145
|
+
) && gh api -X POST 'repos/{owner}/{repo}/pulls' -f title="<title>" -f head=<new_name> -f base=<branch-2> -F body=@.canon/tmp/pr/split/<new_name>.md --jq .html_url \
|
|
146
|
+
&& printf 'opened=true\n' \
|
|
136
147
|
&& rm .canon/tmp/pr/split/<new_name>.md
|
|
137
148
|
|
|
138
149
|
# Clean up the body-file dir if all PRs succeeded (no-op when non-empty)
|
|
@@ -145,6 +156,8 @@ Respond with exactly one line:
|
|
|
145
156
|
|
|
146
157
|
`✅ Renamed: <old> → <new> | PRs: <primary-url>, <url1>, <url2>`
|
|
147
158
|
|
|
159
|
+
Read each URL off the line its create printed through `--jq .html_url`.
|
|
160
|
+
|
|
148
161
|
Do not add any other text.
|
|
149
162
|
|
|
150
163
|
## Stacked merge loop
|
|
@@ -153,10 +166,10 @@ When the user signals the previous stacked PR has merged, restack the next one.
|
|
|
153
166
|
|
|
154
167
|
1. Rebase and push. The own-commit-count comes from the original split table.
|
|
155
168
|
`git fetch origin main && git checkout <branch> && git rebase --onto origin/main HEAD~<own-commit-count> && git push --force-with-lease`
|
|
156
|
-
2. Verify the PR's base auto-retargeted to main with `gh api repos/{owner}/{repo}/pulls/<num> --jq .base.ref`, a REST read a cloud session's GitHub proxy serves where it refuses GraphQL. If not, `gh
|
|
169
|
+
2. Verify the PR's base auto-retargeted to main with `gh api repos/{owner}/{repo}/pulls/<num> --jq .base.ref`, a REST read a cloud session's GitHub proxy serves where it refuses GraphQL. If not, retarget it with `gh api -X PATCH repos/{owner}/{repo}/pulls/<num> -f base=main --silent`.
|
|
157
170
|
3. Reply: `✅ <branch> rebased onto main. Ready for squash-merge.`
|
|
158
171
|
|
|
159
172
|
Edge cases:
|
|
160
173
|
|
|
161
174
|
- If this branch's commits modify a file added by an unmerged upstream PR, wait for that PR to merge before rebasing.
|
|
162
|
-
- If the PR was orphaned by base-branch deletion, recreate it with
|
|
175
|
+
- If the PR was orphaned by base-branch deletion, recreate it with the same create the final commands run, passing `-f head=<branch> -f base=main` and a regenerated body, and print `opened=true` after it.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: git-stage
|
|
3
3
|
description: Groups staged files by concern and generates one conventional commit per group. Use when asked to "group these changes into commits", or when staged changes span multiple concerns and need to ship as separate commits. Do NOT use on a single-concern staged set. That is `git-commit`, which also preserves a hunk-level selection this skill's unstage and restage over whole files would widen.
|
|
4
|
+
metadata:
|
|
5
|
+
family: ship
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Git stage
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: git-worktree
|
|
3
3
|
description: Lists linked worktrees with PR state and cleans up merged ones. Use when asked to "list worktrees", "clean up worktrees", or after shipping a PR to reclaim slots. Do NOT use to enter a worktree from scratch (use `session-worktree`).
|
|
4
|
+
metadata:
|
|
5
|
+
family: after-pr
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Git worktree
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: index-lookup
|
|
3
3
|
description: Answers a topic search over every tracked index.md catalog in the project by running `canon indexes list --json` and matching the topic against each entry's title, description, and path, then reports the hits or names why there are none. Names the gitignored task and memory catalogs and the groundwork and intake record folders as pointers outside its walked corpus, so it never claims a topic is undocumented when the topic only sits there. Use when asked "where is X documented", "is there a page about X", "search the docs for X", "find the index entry for X", or "what covers X". Do NOT use to grep source code, browse a file whose path is already known, or regenerate an index, which is `canon indexes regen`.
|
|
4
|
+
metadata:
|
|
5
|
+
family: answer
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Index lookup
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: markdown-propose
|
|
3
3
|
description: Reviews a named markdown surface against a named concern, drafts a per-file proposal under `.canon/proposals/<nn>-<slug>/` carrying a diff and a reason for each change, and stops without editing a source file. Takes the concern and the surface as inputs, such as a claim stated stronger than the record, a fact gone stale, two files disagreeing, or a passage duplicated without derivation. A later invocation applies what the operator answered. Use when asked to "propose a change to CLAUDE.md", "draft a rewrite of this standard", "propose fixes to this doc", "draft alternatives for this passage", or "apply the answered proposals". Do NOT use to report without drafting a replacement (`canon markdown audit`), to review a diff already made (`review-branch`), or to file a raw brain dump as findings (`plan-intake`).
|
|
4
|
+
metadata:
|
|
5
|
+
family: check
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Markdown propose
|
|
@@ -2,6 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Governs the proposal `markdown-propose` writes before it edits anything. The concern being screened is an input and does not change the format.
|
|
4
4
|
|
|
5
|
+
## Contents
|
|
6
|
+
|
|
7
|
+
- [Folder](#folder)
|
|
8
|
+
- [Change format](#change-format)
|
|
9
|
+
- [The answer contract](#the-answer-contract)
|
|
10
|
+
- [Applying](#applying)
|
|
11
|
+
- [After](#after)
|
|
12
|
+
- [Retrieval](#retrieval)
|
|
13
|
+
|
|
5
14
|
## Folder
|
|
6
15
|
|
|
7
16
|
- One folder per screening pass at `.canon/proposals/<nn>-<slug>/`, where the slug names the subject rather than the activity
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: memory-capture
|
|
3
3
|
description: Extracts durable patterns from the current session, routes a domain fact to the context entry that owns it, and writes the residue to `.canon/memory/` as feedback, project, user, or reference files. Use when asked to "capture memory", "capture lessons", "wrap up the session", "end of session memory", or as a step in autoship. Do NOT use to curate existing memory. Use `memory-review` for that.
|
|
4
|
+
metadata:
|
|
5
|
+
family: ship
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Memory capture
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: memory-review
|
|
3
3
|
description: Reviews `.canon/memory/` and proposes per-entry actions (promote to an always-loaded rule, move into a skill body, route to a context entry, hand off to governance, or retire as stale). Also runs the discuss, challenge, apply, and cleanup phases on an existing review file. Use when asked to "review memory", "discuss memory questions", "challenge the promotes", "apply memory decisions", "cleanup memory review", "promote memory", or "consolidate memories". Do NOT auto-apply. Output a grouped proposal and wait for block-by-block approval.
|
|
4
|
+
metadata:
|
|
5
|
+
family: ship
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Memory review
|
|
@@ -7,6 +7,13 @@ description: The Challenge, Discuss, Apply, and Cleanup phases of memory-review,
|
|
|
7
7
|
|
|
8
8
|
The phases of `memory-review` after Propose. The session reads this file when the phase table in the skill picks Challenge, Discuss, Apply, or Cleanup, and reads only the section for that phase. The skill's Guards still hold for every phase here.
|
|
9
9
|
|
|
10
|
+
## Contents
|
|
11
|
+
|
|
12
|
+
- [Challenge phase](#challenge-phase)
|
|
13
|
+
- [Discuss phase](#discuss-phase)
|
|
14
|
+
- [Apply phase](#apply-phase)
|
|
15
|
+
- [Cleanup phase](#cleanup-phase)
|
|
16
|
+
|
|
10
17
|
## Challenge phase
|
|
11
18
|
|
|
12
19
|
Trigger: user says "challenge the promotes", "challenge before apply", or asks for a high-bar pass. Run before Apply. No mutations to memory files or promotion targets. Review file only.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: plan-feature
|
|
3
3
|
description: Plans a feature by reading the project's Claude setup and scanning relevant source files. Outputs which files to touch, risks, and ambiguities, then stops. Use before implementing anything, or when asked to "implement X", "add X", "build X", or "I want to add X". Do NOT implement. Plan only.
|
|
4
|
+
metadata:
|
|
5
|
+
family: decide
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Plan feature
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: plan-groundwork
|
|
3
3
|
description: Opens and runs a numbered groundwork folder under `.canon/groundwork/<nn>-<slug>/` for a topic that has to be measured before it can be planned. Detects open, resume, and close from the folder itself. Use when asked to "research X", "dig into X", "work out what we should do about X", "measure this before we commit", or "open a groundwork folder". Do NOT use to write a feature plan or to implement. That is `plan-feature`.
|
|
4
|
+
metadata:
|
|
5
|
+
family: decide
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Plan groundwork
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: plan-intake
|
|
3
3
|
description: Files a raw brain dump into a numbered intake folder under `.canon/intake/<nn>-<slug>/`, one item per finding carrying a measured problem, a proposed fix, and a verdict. Use when asked to "file this dump", "triage my notes", "work through this list", "sort out this brain dump", or "run an intake pass". Do NOT use for one question that has to be measured before anyone can plan it. That is `plan-groundwork`.
|
|
4
|
+
metadata:
|
|
5
|
+
family: decide
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Plan intake
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
name: plan-intake-answer
|
|
3
3
|
description: Walks an intake folder's unread items and puts them as batched questions in chat, writing each selection back onto the item it answers. Use when asked to "answer the intake", "work through the open items", "answer my intake questions", "go through the dump", or "let me answer these from here". Do NOT use to file a dump or write new items, which is `plan-intake`.
|
|
4
4
|
disable-model-invocation: true
|
|
5
|
+
metadata:
|
|
6
|
+
family: decide
|
|
5
7
|
---
|
|
6
8
|
|
|
7
9
|
# Plan intake answer
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: project-commands
|
|
3
3
|
description: Runs a command the project documents in its development context entry and stops there. Use when asked to "start the app", "start the dev server", "run the checks", "run the build", "spin it up", or "what commands does this project have". Do NOT use to confirm a change works in a running app, which needs verification past the launch. Do NOT use to deploy, publish, or release.
|
|
4
|
+
metadata:
|
|
5
|
+
family: build
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Project commands
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: read-frames
|
|
3
3
|
description: Pulls numbered still frames from any video, a raw take or a composed render, through `canon demo frames`, reads each one with the Read tool, and reports one plain description per frame. Never judges the recording, since a frame read is evidence rather than a verdict. Use when asked to "check the recording", "read the demo frames", "see what the video shows", or right after `canon demo run` writes a take or a composition renders and nobody has opened the video yet. Do NOT use to record the video, which is `record-screencast`, or to state whether the recording looks correct or broken, which is out of scope for every surface in the toolkit today.
|
|
4
|
+
metadata:
|
|
5
|
+
family: answer
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Read frames
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: record-screencast
|
|
3
3
|
description: Drives a screencast draft through to a recording. Compiles it with `canon demo compile` when no plan exists yet at the default path, skipping compile when one is already there, runs `canon demo run` once nothing is unresolved, then composes the take into a finished mp4 through HyperFrames when the draft's wrap section asks for anything. Reports every unresolved field from the compile or run record and stops rather than guessing one. Use when asked to "record the screencast", "run the demo", "compile and record this draft", or right after `draft-screencast` prints its next-step line. Do NOT use to draft the beats, which is `draft-screencast`, or to fill in a plan's target or URL, which is the operator's own edit.
|
|
4
|
+
metadata:
|
|
5
|
+
family: generate
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Record screencast
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: repo-metadata
|
|
3
3
|
description: Proposes a GitHub About description, homepage, and topic set computed from the README's opening line and package.json, reports the difference against what the repository's remote already carries, and stops without writing. A later invocation, carrying the operator's answered fields, writes the change through gh repo edit. Use when asked to "propose repo metadata", "check the github description", "does our github about text match the readme", "sync github topics", "update the repo homepage", or "apply the repo metadata answers". Do NOT use to edit README.md itself, or to change a repository setting other than description, homepage, or topics.
|
|
4
|
+
metadata:
|
|
5
|
+
family: setup
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Repo metadata
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: restate-plainly
|
|
3
3
|
description: Restates a dense answer or a named markdown document in plain language, cutting jargon and keeping only what changes a decision. Use when asked to "restate that in plain language", "say that plainly", "what does this actually mean", "cut the jargon", "give me the plain version", or "restate this document". Do NOT use to draft or revise prose, which is `write-human`, and do NOT fire on the model's own judgment that its own output was dense.
|
|
4
|
+
metadata:
|
|
5
|
+
family: answer
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Restate plainly
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: review-address
|
|
3
3
|
description: Pulls review findings and CI status on the current branch's open PR, fixes each in the working tree, refreshes any stale `.claude/` docs, replies with a summary comment, and pushes a follow-up commit. The worker's return leg after `review-pr`. Use when asked to "address the review", "fix the PR comments", "respond to review", or after an orchestrator posts findings. Do NOT use to write a review. That is `review-pr`.
|
|
4
|
+
metadata:
|
|
5
|
+
family: after-pr
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Review address
|
|
@@ -240,10 +242,4 @@ Do not merge. Hand back to the orchestrator for re-review.
|
|
|
240
242
|
|
|
241
243
|
## Post-review findings
|
|
242
244
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
Open with `## Post-review findings` rather than `## Review response`, since nothing on the thread is being answered. `review-pr` states the full heading set this belongs to and routes it the same as a response: `role-orchestrator`'s poll picks it up and sends the reviewing session back for a pass. Close the body with `🤖 Addressed by Claude Code` on its own line, matching the reply's footer.
|
|
246
|
-
|
|
247
|
-
```bash
|
|
248
|
-
gh api -X POST 'repos/{owner}/{repo}/issues/<number>/comments' -F body=@.canon/tmp/pr/reply/reply-<number>.md --silent
|
|
249
|
-
```
|
|
245
|
+
Something worth reaching the reviewing session can surface after Step 7 already closed the review. Read `${CLAUDE_SKILL_DIR}/references/post-review-findings.md` before posting it, for the heading it opens with, the voice and scan its body takes, and the call that posts it.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Post-review findings
|
|
3
|
+
description: How review-address posts something worth reporting after Step 7 closed the review, being the heading, the voice and scan the body takes, the footer, and the one REST call that posts it
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Post a finding after the review closed
|
|
7
|
+
|
|
8
|
+
Outside the numbered flow of `review-address`. The session reads this file when it has something worth reaching the reviewing session after Step 7 already closed the review.
|
|
9
|
+
|
|
10
|
+
Not everything worth reaching the reviewing session surfaces inside the numbered flow in `SKILL.md`. A worker that settled a risk, filed a follow-up, or found something else worth reporting after Step 7 already closed the review posts it directly rather than waiting on a review pass that has nothing left to trigger it. Write the body the way Step 6 writes a reply: load `write-human` for voice and word choice, follow `${CLAUDE_SKILL_DIR}/../../standards/markdown.md` for punctuation, and run the `${CLAUDE_SKILL_DIR}/../../standards/publish.md` scan before posting with `canon labels scan --body-file .canon/tmp/pr/reply/reply-<number>.md`.
|
|
11
|
+
|
|
12
|
+
Open with `## Post-review findings` rather than `## Review response`, since nothing on the thread is being answered. `review-pr` states the full heading set this belongs to and routes it the same as a response: `role-orchestrator`'s poll picks it up and sends the reviewing session back for a pass. Close the body with `🤖 Addressed by Claude Code` on its own line, matching the reply's footer.
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
gh api -X POST 'repos/{owner}/{repo}/issues/<number>/comments' -F body=@.canon/tmp/pr/reply/reply-<number>.md --silent
|
|
16
|
+
```
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: review-branch
|
|
3
3
|
description: Reviews all changes since main for bugs, edge cases, and logic flaws. Reads CLAUDE.md, REQUIREMENTS.md, and ARCHITECTURE.md for context, then applies a structured review to the full diff and outputs a findings report. Coding standards from `.claude/rules/` are auto-loaded by Claude Code. Use when asked to review changes, run a code review, or check the current branch. Do NOT auto-trigger on vague signals like "looks good" or "can you check this". Require an explicit review request or an autoship invocation.
|
|
4
|
+
metadata:
|
|
5
|
+
family: check
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Review branch
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: review-craft
|
|
3
3
|
description: Carries what a code review looks for and how much evidence a finding needs, from design and scope through breakage outside the diff, a test or check the change weakens to pass, performance, developer experience, executable prose, stale docs, security classes, and rendered output checked against the screenshots a pull request carries. Use when reviewing a change, when a review procedure loads it for its axes, or when asked "what should a review look for", "what does a good review check", "how sure do I need to be before flagging this", or "did the review look at the screenshots". Do NOT use to run a review, post it, or grade its findings, which is `review-branch` for local work and `review-pr` for a pull request, and do NOT use for a deliberate full security audit, which is the built-in `security-review`.
|
|
4
|
+
metadata:
|
|
5
|
+
family: build
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Review craft
|
|
@@ -18,9 +18,9 @@ Read the thread over REST, which a cloud session's GitHub proxy serves where it
|
|
|
18
18
|
gh api --paginate 'repos/{owner}/{repo}/issues/<number>/comments?per_page=100' --jq '.[] | select((.body // "") | contains("<!-- pr-evidence: head=")) | .body'
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-
Take the comment whose body carries a `<!-- pr-evidence: head=<sha> -->` marker. Match the marker, never the first line, since the body opens with a
|
|
21
|
+
Take the comment whose body carries a `<!-- pr-evidence: head=<sha> -->` marker. Match the marker, never the first line, since the body opens with `## Evidence` and a comment posted before that layout opens with a `**Preview:**` line instead.
|
|
22
22
|
|
|
23
|
-
Flag the change as shipping no screenshot when it paints and the pull request carries no marked comment, carries one with no
|
|
23
|
+
Flag the change as shipping no screenshot when it paints and the pull request carries no marked comment, carries one with no comparison, meaning no `**Base:**` line and no `<details>` table, or carries only a checklist posted alone. The `## Evidence` heading opens every marked comment, a checklist-only one included, so the heading alone never means screenshots are present. Then decide how to raise it by whether the project keeps captures, which is the same test `canon pr evidence` applies:
|
|
24
24
|
|
|
25
25
|
```bash
|
|
26
26
|
git ls-tree -r --name-only <base> | grep -E '(^|/)evidence/.*\.(png|jpe?g|gif|webp|avif|svg)$' | head -1
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: review-pr
|
|
3
3
|
description: Reviews an open pull request from an independent session and posts findings as a review comment on the PR. Posts a first pass against the whole change and every later pass against only the commits added since, under `## Review` while any finding is open and `## Review closed` once a pass carries none. Reads project docs and the task board for cross-feature context a self-review lacks. Use when asked to "review the PR", "review this feature's PR", "post a PR review", "re-review the PR", "close out the review", "confirm the findings are fixed", or acting as the orchestrator reviewing a worker's PR. Do NOT use to review local uncommitted changes. That is `review-branch`.
|
|
4
|
+
metadata:
|
|
5
|
+
family: after-pr
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Review PR
|
|
@@ -83,13 +85,7 @@ Test every unchecked box against the testing discipline in `${CLAUDE_SKILL_DIR}/
|
|
|
83
85
|
|
|
84
86
|
Test every ticked box too, bounded to one naming a file or a command. Confirm what it names still exists at `<headRefOid>`, `git show <headRefOid>:<path>` for a file or `git grep <command> <headRefOid>` for a command, rather than re-running what it claims. A box naming neither stays untested, since nothing here can confirm a claim carrying no artifact. A box ticked before a later commit removed or replaced what it names is a `should-fix` finding on the body itself, filed under a `**PR body**` block ahead of the file blocks, since what it corrupts is the merge record rather than a file in the diff.
|
|
85
87
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
Read `unmet` as a `should-fix` finding under the same `**PR body**` block the stale box takes, one entry per path, quoting the bullet the record carries on `preview` and naming the `head` the comparison ran at. Read the bullet before filing it, since one class survives the reader: a bullet citing where something is defined while claiming an edit elsewhere, which puts a real path in the claim region and points the change at a locative the path does not name. Report that as the class rather than as a stale claim. A body is edited between pushes, so the reading is true at that commit and can be false a minute later. Read `unnamed` for yourself and raise nothing off the count. The class still covers a real omission and equally a generated asset or a regenerated index that earns no bullet, and the entries the reader can name as owing none are already held apart under `incidental`. Open the section and confirm no bullet names the file before putting a single one to the author, because this instruction has sent the question to three pull requests in one day over bullets that had named the files all along, and one of those authors added bullets nobody needed. Report `unresolved` and `incidental` nowhere: the first was judged in neither direction and the second owes no bullet, so neither says anything about the body.
|
|
89
|
-
|
|
90
|
-
A `reason` of `no-claims` means the reader resolved no path out of a section that exists, which is the extractor failing over prose rather than the body being wrong. Say so and raise nothing. `no-section` is the body carrying no such heading, which is a finding only where the pull request template asks for one.
|
|
91
|
-
|
|
92
|
-
Compose this on the body read Step 4 already performs rather than opening a second one. That step scans the title and body for a leaked phase label, and both reads answer from the same text at the same head.
|
|
88
|
+
Then test what `## Key Changes` claims against the diff it describes. Read `${CLAUDE_SKILL_DIR}/references/key-changes.md` for the verb that compares them, which field of its record becomes a finding, and which ones raise nothing.
|
|
93
89
|
|
|
94
90
|
Ask rather than grade. Whether a human is genuinely required is a reading the branch author may hold a reason this session cannot see, so the question carries no severity and enters no count. What it does carry is the heading and the dispatch, on the rule the opening states, because a question the author never receives corrects nothing and the author is the only party who can answer it. Answering it closes it, and the answer may be that the requirement holds.
|
|
95
91
|
|
|
@@ -109,7 +105,7 @@ Use severity: `critical` (blocks merge), `should-fix` (fix before merge), `minor
|
|
|
109
105
|
|
|
110
106
|
## Step 4: post to the PR
|
|
111
107
|
|
|
112
|
-
Read `${CLAUDE_SKILL_DIR}/references/post.md` for the body file name, the body shape
|
|
108
|
+
Read `${CLAUDE_SKILL_DIR}/references/post.md` for the body file name, the body shape, the PR body block, the marker every body carries, and the scans ahead of the post, and `${CLAUDE_SKILL_DIR}/references/body-variants.md` for the Testing and reviewer blocks and the close-out bodies. That file sends a pass repeating a standing close-out on to `${CLAUDE_SKILL_DIR}/references/close-out.md`, which rewrites the comment in place.
|
|
113
109
|
|
|
114
110
|
## Step 5: output
|
|
115
111
|
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Body variants for the review comment
|
|
3
|
+
description: The Testing and reviewer blocks a pass may carry, and the close-out bodies for a pass carrying nothing, only minors, a withdrawal, or only answered reviewer requests
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Body variants
|
|
7
|
+
|
|
8
|
+
Step 4 of `review-pr`, beside `post.md`. That file names the body file and gives the shape a finding-carrying pass takes, and this one holds the blocks and close-outs that vary it.
|
|
9
|
+
|
|
10
|
+
A Testing box the Step 3 check raised goes in a `**Testing**` block placed after the file blocks, one bullet per box, each quoting the box and naming what would drive it. It carries no severity and enters no count, and it is still something owed, so a pass carrying one takes `## Review` and the full body rather than either ✅ line. Say so on the summary line as `plus N testing question(s)`, since the three counts read as zero and would otherwise report the pass as silent.
|
|
11
|
+
|
|
12
|
+
```markdown
|
|
13
|
+
**Testing**
|
|
14
|
+
|
|
15
|
+
- `- [ ] <the box as written>` names no capability the agent lacks. `sandbox/run.sh <arm>` drives it. Was there a reason to leave it?
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Keep it to the boxes the check raised. Restating a box whose stated requirement holds teaches the branch author to skip the block.
|
|
19
|
+
|
|
20
|
+
Every `## For the reviewer` bullet Step 3 read goes in a `**For the reviewer**` block placed after the Testing block, one bullet per request, each followed by its answer or, where the pass could not answer it, by what would settle it. It carries no severity and enters no count.
|
|
21
|
+
|
|
22
|
+
An unanswered bullet is owed the same way an unanswered Testing box is, so a pass carrying one takes `## Review` and the full body rather than either ✅ line. A bullet the pass answered is not owed, since the answer is discharged in the same comment that carries it. A pass still posting a numeric summary line, because a finding, a Testing question, or an unanswered bullet already forces one, says so there as `plus N reviewer request(s)`. The all-answered close-out below carries the block in place of that line and needs no addition to it.
|
|
23
|
+
|
|
24
|
+
```markdown
|
|
25
|
+
**For the reviewer**
|
|
26
|
+
|
|
27
|
+
- Confirm the 401 and 403 split reads correctly for the public API. Confirmed — `AuthService.authenticate()` returns 401 for an expired token and 403 for a missing scope, and both paths are covered under `## Testing`.
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
A pass carrying nothing at all takes `## Review closed` and a short body, with the footer line included either way. On a first pass, post `✅ No findings. Reviewed against project docs and the board.` On a later pass, post `✅ Prior findings addressed. Re-reviewed <short-sha>, N commits since the prior pass.`
|
|
31
|
+
|
|
32
|
+
A pass carrying only minors is an ordinary finding-carrying pass, so it takes the open heading and the full shape rather than either short line, since the minors have to be readable and neither line reports them. A pass carrying only Testing questions, or only an unanswered reviewer request, takes the same route for the same reason. Keep whichever scope sentence the pass owes on the summary line:
|
|
33
|
+
|
|
34
|
+
```markdown
|
|
35
|
+
## Review
|
|
36
|
+
|
|
37
|
+
0 critical, 0 should-fix, Z minor. Reviewed against project docs and the board.
|
|
38
|
+
|
|
39
|
+
**`path/to/file.ext`**
|
|
40
|
+
|
|
41
|
+
- **minor** ([line 12](<repo-url>/blob/<headRefOid>/path/to/file.ext#L12)): finding, and the fix it wants.
|
|
42
|
+
|
|
43
|
+
🤖 Reviewed by Claude Code
|
|
44
|
+
|
|
45
|
+
<!-- review-pr: commit=<headRefOid> read-at=<read-at> -->
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
A pass that closed by withdrawing a finding rather than by reading its fix takes neither ✅ line, per the withdrawal rule in Step 3. Both claim a fix landed, and the second names it, so posting either over a withdrawal credits work nobody did on the one comment a reader treats as the verdict. Write the withdrawal and the fact that settled it in place of the canned line, keeping the heading and the footer.
|
|
49
|
+
|
|
50
|
+
A pass whose only content is a `## For the reviewer` block with every bullet answered, and that owes nothing else, takes the same shape: `## Review closed`, the block in place of the canned line, and the footer. The heading reports what the branch author still owes rather than what the pass did, and an answer discharged in the same comment owes nothing back.
|
|
51
|
+
|
|
52
|
+
Post a close-out even when there is nothing to report. A review left with no closing comment reads as one nobody answered.
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Key changes check
|
|
3
|
+
description: How review-pr Step 3 tests what the pull request body's Key Changes section claims against the diff, reading each field the canon pr key-changes record carries and which one becomes a finding
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Test the Key Changes claims
|
|
7
|
+
|
|
8
|
+
Part of Step 3 of `review-pr`. The session reads this file after the `## Testing` boxes and before the `## For the reviewer` bullets.
|
|
9
|
+
|
|
10
|
+
Test what `## Key Changes` claims against the diff it describes, with `canon pr key-changes <number> --json`. This repository squash-merges, so that section becomes the commit message and the record on the trunk once the branch is gone, which is the same thing a stale ticked box corrupts. Branch on the record rather than on the exit code, which a shell function wrapping `canon` can flatten to zero.
|
|
11
|
+
|
|
12
|
+
Read `unmet` as a `should-fix` finding under the same `**PR body**` block the stale box takes, one entry per path, quoting the bullet the record carries on `preview` and naming the `head` the comparison ran at. Read the bullet before filing it, since one class survives the reader: a bullet citing where something is defined while claiming an edit elsewhere, which puts a real path in the claim region and points the change at a locative the path does not name. Report that as the class rather than as a stale claim. A body is edited between pushes, so the reading is true at that commit and can be false a minute later. Read `unnamed` for yourself and raise nothing off the count. The class still covers a real omission and equally a generated asset or a regenerated index that earns no bullet, and the entries the reader can name as owing none are already held apart under `incidental`. Open the section and confirm no bullet names the file before putting a single one to the author, because this instruction has sent the question to three pull requests in one day over bullets that had named the files all along, and one of those authors added bullets nobody needed. Report `unresolved` and `incidental` nowhere: the first was judged in neither direction and the second owes no bullet, so neither says anything about the body.
|
|
13
|
+
|
|
14
|
+
A `reason` of `no-claims` means the reader resolved no path out of a section that exists, which is the extractor failing over prose rather than the body being wrong. Say so and raise nothing. `no-section` is the body carrying no such heading, which is a finding only where the pull request template asks for one.
|
|
15
|
+
|
|
16
|
+
Compose this on the body read Step 4 already performs rather than opening a second one. That step scans the title and body for a leaked phase label, and both reads answer from the same text at the same head.
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Post the review to the pull request
|
|
3
|
-
description: Step 4 of review-pr, which names the body file, gives the body shape for
|
|
3
|
+
description: Step 4 of review-pr, which names the body file, gives the body shape for a pass carrying findings, places the PR body block, carries the read-time marker, and runs the scans and the post
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Post to the PR
|
|
7
7
|
|
|
8
8
|
Step 4 of `review-pr`. The threshold that picks the heading and decides the dispatch sits in the skill body's opening, and this file applies it.
|
|
9
9
|
|
|
10
|
+
## Contents
|
|
11
|
+
|
|
12
|
+
- [The body file and finding links](#the-body-file-and-finding-links)
|
|
13
|
+
- [The body shapes](#the-body-shapes)
|
|
14
|
+
- [The marker, the scans, and the post](#the-marker-the-scans-and-the-post)
|
|
15
|
+
|
|
16
|
+
## The body file and finding links
|
|
17
|
+
|
|
10
18
|
Write the comment to `.canon/tmp/pr/review/body-<number>-<short-sha>.md` at the main worktree root, not the current worktree, which the rest of this step calls `<body-file>`. Resolve that root and send the write as a heredoc, both the way `session-worktree` states. The PR number stops two sessions reviewing different pull requests from overwriting each other between the write and the post, and the head commit stops a second pass overwriting the first one's body.
|
|
11
19
|
|
|
12
20
|
Derive both segments from Step 1. Never pick a suffix by hand, and never reuse a name the folder already holds.
|
|
@@ -23,6 +31,8 @@ A finding that spans lines anchors to the span as `#L12-L14`, with no spaces and
|
|
|
23
31
|
|
|
24
32
|
Four findings take the plain bullet with no link: a `**PR body**` entry, a finding on a file the head deleted, a finding on a line the diff removed from a file that survives, since the head holds no number for it, and a finding about a whole file with no one line. A path holding a character a URL needs encoded, such as a space or `#`, is percent-encoded in the link or keeps the plain bullet. Keep the file block header a bare backticked path, so the section-marker reading in `${CLAUDE_SKILL_DIR}/../../standards/markdown.md` does not change.
|
|
25
33
|
|
|
34
|
+
## The body shapes
|
|
35
|
+
|
|
26
36
|
The comment is a rendered-for-human GitHub surface, so load the `write-human` skill for voice and word choice and follow `${CLAUDE_SKILL_DIR}/../../standards/markdown.md` for punctuation: cut editorializing, and keep every sentence load-bearing. Match this shape on a first pass:
|
|
27
37
|
|
|
28
38
|
```markdown
|
|
@@ -64,25 +74,7 @@ Re-reviewed `<short-sha>`, N commits since the prior pass. X critical, Y should-
|
|
|
64
74
|
<!-- review-pr: commit=<headRefOid> read-at=<read-at> -->
|
|
65
75
|
```
|
|
66
76
|
|
|
67
|
-
A Testing
|
|
68
|
-
|
|
69
|
-
```markdown
|
|
70
|
-
**Testing**
|
|
71
|
-
|
|
72
|
-
- `- [ ] <the box as written>` names no capability the agent lacks. `sandbox/run.sh <arm>` drives it. Was there a reason to leave it?
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
Keep it to the boxes the check raised. Restating a box whose stated requirement holds teaches the branch author to skip the block.
|
|
76
|
-
|
|
77
|
-
Every `## For the reviewer` bullet Step 3 read goes in a `**For the reviewer**` block placed after the Testing block, one bullet per request, each followed by its answer or, where the pass could not answer it, by what would settle it. It carries no severity and enters no count.
|
|
78
|
-
|
|
79
|
-
An unanswered bullet is owed the same way an unanswered Testing box is, so a pass carrying one takes `## Review` and the full body rather than either ✅ line. A bullet the pass answered is not owed, since the answer is discharged in the same comment that carries it. A pass still posting a numeric summary line, because a finding, a Testing question, or an unanswered bullet already forces one, says so there as `plus N reviewer request(s)`. The all-answered close-out below carries the block in place of that line and needs no addition to it.
|
|
80
|
-
|
|
81
|
-
```markdown
|
|
82
|
-
**For the reviewer**
|
|
83
|
-
|
|
84
|
-
- Confirm the 401 and 403 split reads correctly for the public API. Confirmed — `AuthService.authenticate()` returns 401 for an expired token and 403 for a missing scope, and both paths are covered under `## Testing`.
|
|
85
|
-
```
|
|
77
|
+
A Testing question or a `## For the reviewer` bullet Step 3 read takes its own block after the file blocks, per `${CLAUDE_SKILL_DIR}/references/body-variants.md`.
|
|
86
78
|
|
|
87
79
|
Keying either half of the opening's threshold on the grade was measured wrong: across 8 findings on one archived pass, 3 were posted as minor and 2 of those were defects a worker fixed rather than recorded, so a floor at should-fix loses real fixes to a grade that runs low. Splitting the two halves so the dispatch fired lower than the heading was the other candidate, and it left a thread reading closed while work was owed on it. The Testing question was first written to sit outside both, which is that same split reached from the other side, and it left the one party who could answer the question with no route to it.
|
|
88
80
|
|
|
@@ -104,6 +96,8 @@ The `What is right` section is optional, capped at three bullets, and included o
|
|
|
104
96
|
|
|
105
97
|
Close the body with `🤖 Reviewed by Claude Code` on its own line so the review reads as an independent machine pass, not a human sign-off.
|
|
106
98
|
|
|
99
|
+
## The marker, the scans, and the post
|
|
100
|
+
|
|
107
101
|
### The marker every body carries
|
|
108
102
|
|
|
109
103
|
End every body with this line, carrying `<headRefOid>` and `<read-at>` from Step 1 verbatim:
|
|
@@ -132,26 +126,4 @@ gh api -X POST 'repos/{owner}/{repo}/pulls/<number>/reviews' -f event=COMMENT -F
|
|
|
132
126
|
|
|
133
127
|
The post goes through the REST reviews endpoint rather than the `gh pr` review subcommand, which runs on GraphQL and fails where a cloud session's GitHub proxy refuses it. `event=COMMENT` submits the review as a comment, the same state the old `--comment` flag produced.
|
|
134
128
|
|
|
135
|
-
A pass carrying nothing at all
|
|
136
|
-
|
|
137
|
-
A pass carrying only minors is an ordinary finding-carrying pass, so it takes the open heading and the full shape rather than either short line, since the minors have to be readable and neither line reports them. A pass carrying only Testing questions, or only an unanswered reviewer request, takes the same route for the same reason. Keep whichever scope sentence the pass owes on the summary line:
|
|
138
|
-
|
|
139
|
-
```markdown
|
|
140
|
-
## Review
|
|
141
|
-
|
|
142
|
-
0 critical, 0 should-fix, Z minor. Reviewed against project docs and the board.
|
|
143
|
-
|
|
144
|
-
**`path/to/file.ext`**
|
|
145
|
-
|
|
146
|
-
- **minor** ([line 12](<repo-url>/blob/<headRefOid>/path/to/file.ext#L12)): finding, and the fix it wants.
|
|
147
|
-
|
|
148
|
-
🤖 Reviewed by Claude Code
|
|
149
|
-
|
|
150
|
-
<!-- review-pr: commit=<headRefOid> read-at=<read-at> -->
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
A pass that closed by withdrawing a finding rather than by reading its fix takes neither ✅ line, per the withdrawal rule in Step 3. Both claim a fix landed, and the second names it, so posting either over a withdrawal credits work nobody did on the one comment a reader treats as the verdict. Write the withdrawal and the fact that settled it in place of the canned line, keeping the heading and the footer.
|
|
154
|
-
|
|
155
|
-
A pass whose only content is a `## For the reviewer` block with every bullet answered, and that owes nothing else, takes the same shape: `## Review closed`, the block in place of the canned line, and the footer. The heading reports what the branch author still owes rather than what the pass did, and an answer discharged in the same comment owes nothing back.
|
|
156
|
-
|
|
157
|
-
Post a close-out even when there is nothing to report. A review left with no closing comment reads as one nobody answered.
|
|
129
|
+
A pass carrying nothing at all, a withdrawal, or only answered reviewer requests takes a close-out body, and a pass carrying only minors keeps the full shape, both per `${CLAUDE_SKILL_DIR}/references/body-variants.md`.
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: review-ui
|
|
3
3
|
description: Drives an open pull request's visual checklist in the running app, one box at a time through a pinned agent browser, and posts one verdict per box as its own review comment under `## UI review` while the branch owes a fix, being a failed box, a sweep finding, or a box the page kept from being driven, and `## UI review closed` once it owes none. Never reads the diff, never builds the head, and never judges a box marked as taste. Use when asked to "drive the checklist", "run the UI review", "check the running app against the checklist", "review the PR in the browser", or launched as the UI reviewer beside a code review. Do NOT use to review the code or the screenshots, which is `review-pr`, to inspect a running app with the operator present, which is `ux-walkthrough`, or to write the checklist, which is `ui-checklist`.
|
|
4
|
+
metadata:
|
|
5
|
+
family: after-pr
|
|
4
6
|
---
|
|
5
7
|
|
|
6
8
|
# Review UI
|
|
@@ -70,7 +72,7 @@ When the hosted rung answers, check that it was built from the head before drivi
|
|
|
70
72
|
canon pr preview <number> --check --json
|
|
71
73
|
```
|
|
72
74
|
|
|
73
|
-
Branch on the record's `reason`. Only `fresh` continues. Any other stops with nothing posted, naming `built`, `tip`, and the next act: `stale` and `no-build` ask the dispatcher to run `canon pr preview <number> --json`, and `building` asks it to wait, since a mint is already running for the tip. This pass never mints. A `canon` that rejects `--check` predates the verb. Report that this pass needs a `canon` whose `pr preview` takes `--check`, naming the installed `canon --version`, and stop rather than reading the missing flag as `fresh`, the way Step 2 does for its own older binaries. A `reason` of `no-deploy`, `unfenced`, or `no-alias` means the project has no fenced deploy to read, so the hosted build cannot be verified. Stop on the hosted address then too, and say so.
|
|
75
|
+
Branch on the record's `reason`. Only `fresh` continues. Any other stops with nothing posted, naming `built`, `tip`, and the next act: `stale` and `no-build` ask the dispatcher to run `canon pr preview <number> --json`, and `building` asks it to wait, since a mint is already running for the tip. This pass never mints. A `canon` that rejects `--check` predates the verb. Report that this pass needs a `canon` whose `pr preview` takes `--check`, naming the installed `canon --version`, and stop rather than reading the missing flag as `fresh`, the way Step 2 does for its own older binaries. A `reason` of `no-deploy`, `unfenced`, or `no-alias` means the project has no fenced deploy to read, so the hosted build cannot be verified. Stop on the hosted address then too, and say so. A `reason` of `unserved` means the deploy builds from nothing this pull request changed, so the hosted address shows none of the change. Treat it as no hosted address and fall to the local rung.
|
|
74
76
|
|
|
75
77
|
The check covers the hosted address only. The local rung and an address the launch names have no deploy run to read, so say in the comment that they were driven unverified rather than implying the same coverage.
|
|
76
78
|
|
|
@@ -68,7 +68,9 @@ Record the instant just before the post, in UTC, as `<posted-at>`. Step 8 keeps
|
|
|
68
68
|
|
|
69
69
|
```bash
|
|
70
70
|
date -u +%Y-%m-%dT%H:%M:%SZ
|
|
71
|
-
gh
|
|
71
|
+
gh api -X POST 'repos/{owner}/{repo}/pulls/<number>/reviews' -f event=COMMENT -F body=@.canon/tmp/pr/review-ui/body-<number>-<short-sha>.md --jq .html_url
|
|
72
72
|
```
|
|
73
73
|
|
|
74
|
-
|
|
74
|
+
The post goes through the REST reviews endpoint rather than the `gh pr` review subcommand, which runs on GraphQL and fails where a cloud session's GitHub proxy refuses it. `-F` reads the file into the body, where `-f` would post the path itself.
|
|
75
|
+
|
|
76
|
+
Never pass `event=APPROVE` or `event=REQUEST_CHANGES`, which carry a state the poll does not read and a weight this pass has not earned.
|