@erclx/canon 5.41.0 → 5.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/references/adopted.md +34 -14
- package/claude/skills/auto-ship/REQUIREMENT.md +1 -0
- package/claude/skills/auto-ship/SKILL.md +24 -4
- package/claude/skills/auto-ship/references/draft-mark.md +32 -6
- package/claude/skills/auto-ship/references/failure-recovery.md +15 -13
- package/claude/skills/auto-ship/references/tier-failures.md +31 -10
- package/claude/skills/auto-ship/references/ui-checklist.md +9 -4
- package/claude/skills/auto-ship/references/worktree-name.md +9 -3
- package/claude/skills/build-in-slices/references/adopted.md +35 -21
- package/claude/skills/canvas-board/references/canvas.md +17 -6
- package/claude/skills/canvas-board/references/design.md +26 -7
- package/claude/skills/ci-workflow/REQUIREMENT.md +2 -1
- package/claude/skills/ci-workflow/SKILL.md +12 -2
- package/claude/skills/ci-workflow/references/workflows.md +12 -9
- package/claude/skills/code-craft/references/adopted.md +58 -20
- package/claude/skills/codebase-layout/references/adopted.md +49 -16
- package/claude/skills/codebase-layout/references/frontend.md +11 -4
- package/claude/skills/codebase-layout/references/tests.md +4 -2
- package/claude/skills/context-fold/references/classify.md +10 -15
- package/claude/skills/context-fold/references/completion-report.md +11 -9
- package/claude/skills/context-fold/references/context-refresh.md +26 -9
- package/claude/skills/context-fold/references/unusable-baseline.md +5 -3
- package/claude/skills/create-rule/REQUIREMENT.md +5 -0
- package/claude/skills/create-rule/SKILL.md +10 -1
- package/claude/skills/create-rule/references/checklist.md +26 -0
- package/claude/skills/create-rule/references/rule.md +98 -20
- package/claude/skills/create-skill/SKILL.md +1 -0
- package/claude/skills/create-skill/references/skill-disclosure.md +10 -2
- package/claude/skills/create-skill/references/skill-frontmatter.md +43 -0
- package/claude/skills/create-skill/references/skill-paths.md +7 -4
- package/claude/skills/create-skill/references/skill-practice.md +6 -3
- package/claude/skills/create-skill/references/skill-requirement.md +4 -2
- package/claude/skills/create-skill/references/skill.md +67 -44
- package/claude/skills/decision-escalate/SKILL.md +1 -2
- package/claude/skills/deploy-app/references/vercel.md +2 -1
- package/claude/skills/deprecation-migration/references/adopted.md +44 -25
- package/claude/skills/design-taste/references/adopted.md +9 -1
- package/claude/skills/design-taste/references/craft.md +3 -1
- package/claude/skills/design-taste/references/kinds.md +8 -7
- package/claude/skills/design-taste/references/preflight.md +12 -0
- package/claude/skills/design-taste/references/systems.md +7 -6
- package/claude/skills/design-taste/references/tells.md +24 -25
- package/claude/skills/design-taste/references/vocabulary.md +7 -5
- package/claude/skills/document-health/references/axes.md +55 -30
- package/claude/skills/draft-and-pick/references/live-arms.md +2 -2
- package/claude/skills/draft-doc/references/context.md +4 -3
- package/claude/skills/draft-doc/references/docs.md +6 -3
- package/claude/skills/draft-doc/references/readme/agent-facing.md +6 -0
- package/claude/skills/draft-doc/references/readme/application.md +8 -2
- package/claude/skills/draft-doc/references/readme/cli.md +5 -1
- package/claude/skills/draft-doc/references/readme/library.md +4 -0
- package/claude/skills/draft-doc/references/readme/plugin.md +9 -1
- package/claude/skills/draft-doc/references/readme.md +30 -13
- package/claude/skills/draft-doc/references/requirements.md +17 -4
- package/claude/skills/draft-doc/references/wiki-kind.md +20 -10
- package/claude/skills/draft-doc/references/wiki.md +1 -1
- package/claude/skills/draft-figure/references/architecture-set.md +7 -3
- package/claude/skills/draft-figure/references/figures.md +8 -6
- package/claude/skills/draft-figure/references/hand-drawn.md +3 -1
- package/claude/skills/draft-figure/references/mermaid-path.md +19 -9
- package/claude/skills/draft-figure/references/mermaid.md +10 -5
- package/claude/skills/draft-ready/references/ready.md +22 -15
- package/claude/skills/git-branch/references/branch.md +11 -1
- package/claude/skills/git-branch/references/slug.md +17 -5
- package/claude/skills/git-commit/references/commit.md +9 -5
- package/claude/skills/git-commit/references/versioning.md +23 -17
- package/claude/skills/git-followup/REQUIREMENT.md +1 -1
- package/claude/skills/git-followup/SKILL.md +5 -6
- package/claude/skills/git-issue/references/issue.md +29 -16
- package/claude/skills/git-pr/REQUIREMENT.md +1 -5
- package/claude/skills/git-pr/SKILL.md +11 -22
- package/claude/skills/git-pr/references/final-command.md +21 -8
- package/claude/skills/git-pr/references/labels.md +45 -28
- package/claude/skills/git-pr/references/pr.md +29 -9
- package/claude/skills/git-pr/references/publish.md +42 -28
- package/claude/skills/git-pr/references/task-number.md +20 -8
- package/claude/skills/git-ship/SKILL.md +1 -1
- package/claude/skills/plan-feature/SKILL.md +1 -1
- package/claude/skills/plan-feature/references/plan-lifecycle.md +10 -3
- package/claude/skills/plan-feature/references/plan.md +58 -21
- package/claude/skills/plan-groundwork/references/groundwork-spikes.md +4 -1
- package/claude/skills/plan-groundwork/references/groundwork.md +14 -16
- package/claude/skills/plan-intake/references/intake.md +29 -24
- package/claude/skills/pr-evidence/REQUIREMENT.md +40 -0
- package/claude/skills/pr-evidence/SKILL.md +53 -0
- package/claude/skills/pr-evidence/references/evidence.md +150 -0
- package/claude/skills/review-address/references/post-review-findings.md +10 -3
- package/claude/skills/review-address/references/rebase-conflicts.md +15 -7
- package/claude/skills/review-address/references/rest-reads.md +3 -1
- package/claude/skills/review-craft/references/adopted.md +35 -18
- package/claude/skills/review-craft/references/security.md +42 -7
- package/claude/skills/review-craft/references/ui.md +23 -8
- package/claude/skills/review-pr/SKILL.md +6 -6
- package/claude/skills/review-pr/references/body-variants.md +29 -9
- package/claude/skills/review-pr/references/close-out.md +20 -5
- package/claude/skills/review-pr/references/key-changes.md +27 -3
- package/claude/skills/review-pr/references/post.md +83 -31
- package/claude/skills/review-pr/references/scope.md +54 -19
- package/claude/skills/review-ui/references/close-out.md +7 -5
- package/claude/skills/review-ui/references/driving.md +24 -4
- package/claude/skills/review-ui/references/post.md +43 -15
- package/claude/skills/role-orchestrator/SKILL.md +2 -0
- package/claude/skills/role-orchestrator/references/orchestrator-cloud-launch.md +67 -17
- package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +80 -40
- package/claude/skills/role-orchestrator/references/orchestrator-handback.md +52 -15
- package/claude/skills/role-orchestrator/references/orchestrator-handoff.md +48 -26
- package/claude/skills/role-orchestrator/references/orchestrator-inbound.md +12 -13
- package/claude/skills/role-orchestrator/references/orchestrator-launch.md +72 -36
- package/claude/skills/role-orchestrator/references/orchestrator-output.md +16 -4
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +64 -24
- package/claude/skills/role-orchestrator/references/orchestrator-poll.md +80 -26
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +41 -18
- package/claude/skills/role-orchestrator/references/orchestrator-resume.md +19 -7
- package/claude/skills/role-orchestrator/references/orchestrator-review-dispatch.md +22 -12
- package/claude/skills/role-orchestrator/references/orchestrator-reviewer-launch.md +15 -6
- package/claude/skills/role-orchestrator/references/orchestrator-sweep.md +25 -7
- package/claude/skills/role-orchestrator/references/orchestrator-watch.md +34 -8
- package/claude/skills/role-orchestrator/scripts/poll.ts +16 -24
- package/claude/skills/role-planner/REQUIREMENT.md +1 -1
- package/claude/skills/role-planner/SKILL.md +3 -3
- package/claude/skills/role-worker/REQUIREMENT.md +3 -0
- package/claude/skills/role-worker/SKILL.md +34 -2
- package/claude/skills/search-craft/REQUIREMENT.md +1 -1
- package/claude/skills/search-craft/SKILL.md +2 -2
- package/claude/skills/search-craft/references/adopted.md +18 -6
- package/claude/skills/session-map/references/session.md +26 -7
- package/claude/skills/session-worktree/references/main-root-writes.md +25 -8
- package/claude/skills/systematic-debugging/references/adopted.md +30 -16
- package/claude/skills/target-check/references/domains.md +39 -11
- package/claude/skills/target-setup/references/detect.md +80 -65
- package/claude/skills/target-setup/references/indexes.md +8 -6
- package/claude/skills/task-board/references/board.md +86 -30
- package/claude/skills/task-board/references/decline.md +29 -13
- package/claude/skills/task-board/references/tasks-decline.md +12 -5
- package/claude/skills/task-board/references/tasks.md +65 -33
- package/claude/skills/task-complete/references/archive.md +41 -17
- package/claude/skills/task-complete/references/receipt-sweep.md +23 -9
- package/claude/skills/task-complete/references/unusable-baseline.md +10 -3
- package/claude/skills/teach-workspace/references/glossary.md +6 -2
- package/claude/skills/teach-workspace/references/lesson-build.md +44 -16
- package/claude/skills/teach-workspace/references/lesson-craft.md +12 -7
- package/claude/skills/teach-workspace/references/pedagogy.md +6 -3
- package/claude/skills/teach-workspace/references/promotion-fold.md +17 -11
- package/claude/skills/teach-workspace/references/promotion.md +31 -8
- package/claude/skills/teach-workspace/references/revisit.md +8 -2
- package/claude/skills/teach-workspace/references/teach.md +17 -9
- package/claude/skills/test-craft/references/adopted.md +48 -14
- package/claude/skills/test-craft/references/component.md +7 -4
- package/claude/skills/test-craft/references/e2e.md +25 -7
- package/claude/skills/test-craft/references/unit.md +3 -1
- package/claude/skills/test-first/references/adopted.md +12 -4
- package/claude/skills/ui-checklist/REQUIREMENT.md +1 -1
- package/claude/skills/ui-checklist/SKILL.md +1 -1
- package/claude/skills/video-craft/references/adopted.md +62 -18
- package/claude/skills/write-human/references/adopted.md +21 -8
- package/docs/agents/audits.md +1 -0
- package/docs/agents/migrate.md +11 -8
- package/docs/target/migrations.md +11 -0
- package/docs/workflow/parallel-features.md +1 -1
- package/docs/workflow/skill-map.md +1 -0
- package/governance/detect.toml +4 -0
- package/governance/rules/canon/context.md +2 -1
- package/governance/rules/canon/plan.md +3 -5
- package/governance/rules/canon/scratch.md +3 -1
- package/governance/rules/canon/task-scope.md +2 -1
- package/governance/rules/canon/tasks.md +2 -1
- package/governance/rules/canon/worktrees.md +5 -2
- package/governance/rules/claude/output.md +7 -4
- package/governance/rules/claude/skill.md +6 -4
- package/governance/rules/tooling/ci-workflow.md +6 -39
- package/governance/rules/ui/design-reference.md +37 -0
- package/governance/rules/writing/markdown.md +2 -1
- package/package.json +6 -6
- package/src/audits/catalog.ts +42 -0
- package/src/claude/cases/workflow.ts +5 -0
- package/src/claude/settings.ts +8 -4
- package/src/commands/claude.ts +11 -1
- package/src/commands/gov.ts +198 -0
- package/src/commands/migrate.ts +121 -2
- package/src/commands/pr.ts +146 -105
- package/src/commands/tooling.ts +3 -3
- package/src/commands/worktrees.ts +49 -0
- package/src/gate/stages.ts +15 -0
- package/src/gov/audit.ts +440 -0
- package/src/listeners/belongs.ts +21 -0
- package/src/listeners/machine.ts +93 -0
- package/src/listeners/parse.ts +41 -0
- package/src/markdown/scope.ts +144 -0
- package/src/migrate/session-defaults.ts +138 -0
- package/src/pr/lift.ts +6 -3
- package/src/pr/local.ts +4 -69
- package/src/pr/review-state.ts +182 -0
- package/src/sync/check.ts +15 -0
- package/src/tooling/stamp.ts +56 -12
- package/src/worktrees/stop.ts +92 -0
- package/tooling/base/configs/.github/workflows/phase-label-gate.yml +6 -2
- package/tooling/base/configs/commitlint.config.js +0 -20
- package/tooling/base/reference.md +1 -1
- package/tooling/base/seeds/.github/workflows/verify.yml +4 -1
- package/tooling/claude/reference.md +13 -7
- package/tooling/claude/seeds/.claude/settings.json +4 -0
- package/tooling/claude/user/settings.template.json +0 -4
- package/tooling/cloudflare/configs/.github/workflows/deploy.yml +5 -5
- package/tooling/public/configs/.github/dependabot.yml +12 -0
- package/tooling/public/configs/.github/workflows/release-please.yml +30 -0
- package/tooling/public/manifest.toml +8 -0
- package/tooling/public/reference.md +53 -0
- package/tooling/public/seeds/.github/ISSUE_TEMPLATE/bug.yml +48 -0
- package/tooling/public/seeds/.github/ISSUE_TEMPLATE/config.yml +5 -0
- package/tooling/public/seeds/.github/ISSUE_TEMPLATE/feature.yml +16 -0
- package/tooling/public/seeds/.release-please-manifest.json +3 -0
- package/tooling/public/seeds/CONTRIBUTING.md +50 -0
- package/tooling/public/seeds/LICENSE +21 -0
- package/tooling/public/seeds/SECURITY.md +13 -0
- package/tooling/public/seeds/release-please-config.json +12 -0
- package/tooling/shell/configs/.github/workflows/shell.yml +4 -1
- package/tooling/web/configs/.github/workflows/readme-screenshot.yml +6 -3
- package/tooling/web/configs/.github/workflows/verify.yml +15 -12
- package/claude/skills/git-pr/references/evidence.md +0 -124
|
@@ -5,11 +5,18 @@ description: How review-address posts something worth reporting after Step 7 clo
|
|
|
5
5
|
|
|
6
6
|
# Post a finding after the review closed
|
|
7
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.
|
|
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, such as a settled risk, a filed follow-up, or another finding. It posts directly rather than waiting on a review pass that has nothing left to trigger it.
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
## The body
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
Write the body the way Step 6 writes a reply.
|
|
13
|
+
|
|
14
|
+
- Load `write-human` for voice and word choice, and follow `${CLAUDE_SKILL_DIR}/../markdown-craft/references/markdown.md` for punctuation
|
|
15
|
+
- Run the `${CLAUDE_SKILL_DIR}/../git-pr/references/publish.md` scan before posting, with `canon labels scan --body-file .canon/tmp/pr/reply/reply-<number>.md`
|
|
16
|
+
- Open with `## Post-review findings` rather than `## Review response`, since nothing on the thread is being answered
|
|
17
|
+
- Close the body with `🤖 Addressed by Claude Code` on its own line, matching the reply's footer
|
|
18
|
+
|
|
19
|
+
`review-pr` states the full heading set this belongs to and routes it the same as a response, so `role-orchestrator`'s poll picks it up and sends the reviewing session back for a pass.
|
|
13
20
|
|
|
14
21
|
```bash
|
|
15
22
|
gh api -X POST 'repos/{owner}/{repo}/issues/<number>/comments' -F body=@.canon/tmp/pr/reply/reply-<number>.md --silent
|
|
@@ -33,15 +33,23 @@ A branch carrying merge commits of its own, such as a fan-in integrator's, rebas
|
|
|
33
33
|
These rules apply to a hunk from the rebase and a hunk from the stash pop alike:
|
|
34
34
|
|
|
35
35
|
- Never take one side wholesale with `--ours` or `--theirs`. Both sides are valid content, so the drop is silent and passes every check.
|
|
36
|
-
- Never resolve a generated file by hand
|
|
37
|
-
- Where two branches wrote prose into one file, keep both sides and rewrite what the merge broke
|
|
38
|
-
-
|
|
39
|
-
- A hunk raised by the rebase takes `git rebase --abort`, which restores the old base: `❌ Conflict needs a decision at <file>. Branch left on its old base.`
|
|
40
|
-
- A hunk raised by the stash pop arrives after the rebase already landed, so no abort applies and the conflict stays in the tree: `❌ Conflict needs a decision at <file>. Branch rebased, fixes left conflicted in the tree.`
|
|
36
|
+
- Never resolve a generated file by hand, such as an `index.md` carrying no `auto: false`. Take either side and let the regen below rebuild it.
|
|
37
|
+
- Where two branches wrote prose into one file, keep both sides and rewrite what the merge broke, such as a count opening a section
|
|
38
|
+
- Both sides of every hunk sit in the conflict and `git log origin/main` names what landed, so never wait on the orchestrator for context
|
|
41
39
|
|
|
42
|
-
|
|
40
|
+
### A hunk needing a decision
|
|
43
41
|
|
|
44
|
-
|
|
42
|
+
When a hunk needs a decision the tree does not carry, stop rather than guessing and name where the branch was left, since a guess that compiles is the failure this stage would introduce. Either case reaches the operator as an ordinary finding on the next review pass. The two sources recover differently.
|
|
43
|
+
|
|
44
|
+
- A hunk raised by the rebase takes `git rebase --abort`, which restores the old base: `❌ Conflict needs a decision at <file>. Branch left on its old base.`
|
|
45
|
+
- A hunk raised by the stash pop arrives after the rebase landed, so the conflict stays in the tree: `❌ Conflict needs a decision at <file>. Branch rebased, fixes left conflicted in the tree.`
|
|
46
|
+
|
|
47
|
+
### The stop message
|
|
48
|
+
|
|
49
|
+
The stop still owes a message, since the next review pass never starts on a branch nobody pushed. When the launch named a controlling session, send it the stop line through `canon:session-relay` before halting, per the worker channel the `role-worker` skill states.
|
|
50
|
+
|
|
51
|
+
- Add the commit on `main` that wrote the other side of the hunk
|
|
52
|
+
- With nobody named, print the two lines above and stop
|
|
45
53
|
|
|
46
54
|
## After the rebase
|
|
47
55
|
|
|
@@ -5,7 +5,9 @@ description: The reads review-address runs over REST, being the findings on the
|
|
|
5
5
|
|
|
6
6
|
# REST reads
|
|
7
7
|
|
|
8
|
-
The guard and Step 1 of `review-address`. The session reads this file on reaching Step 1, and from the guard when `canon pr head --json` hands back no `number`.
|
|
8
|
+
The guard and Step 1 of `review-address`. The session reads this file on reaching Step 1, and from the guard when `canon pr head --json` hands back no `number`.
|
|
9
|
+
|
|
10
|
+
Every read runs on REST, since the `gh pr` subcommands run on GraphQL and a cloud session's GitHub proxy refuses it. A cloud worker answering a review runs this skill, so one GraphQL call breaks the whole leg.
|
|
9
11
|
|
|
10
12
|
## The findings
|
|
11
13
|
|
|
@@ -7,51 +7,68 @@ description: Which external review patterns this skill adopted, which it decline
|
|
|
7
7
|
|
|
8
8
|
External sources were read and filtered rather than imported. This file is the record. A later session extending the skill adds to it rather than re-arguing an item already settled here.
|
|
9
9
|
|
|
10
|
+
The `addyosmani/agent-skills` citations below all pin commit `addyosmani/agent-skills@2686b620`.
|
|
11
|
+
|
|
10
12
|
## Adopted
|
|
11
13
|
|
|
12
14
|
### Design and scope
|
|
13
15
|
|
|
14
16
|
**The design procedure.** The nine ordered steps under the design axis draw on four sources, each restated without a language, a framework, or a transport so the walk holds on any stack.
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
| Source | Step it backs |
|
|
19
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- |
|
|
20
|
+
| Ousterhout's deep modules, information hiding, and pass-through methods, [A Philosophy of Software Design](https://web.stanford.edu/~ouster/cgi-bin/book.php) | Asking what each unit hides, and flagging a unit that passes its arguments straight through |
|
|
21
|
+
| Parnas's criterion that a boundary hides a decision likely to change, [On the Criteria To Be Used in Decomposing Systems into Modules](https://dl.acm.org/doi/10.1145/361598.361623) | The opening step, naming the next likely change and counting what it touches |
|
|
22
|
+
| Beck's design rules as Fowler records them, especially no duplication and fewest elements, [BeckDesignRules](https://martinfowler.com/bliki/BeckDesignRules.html) | The one-place step, and matching each pattern to a problem the code has today |
|
|
23
|
+
| Google's reviewer guide on design, complexity, and over-engineering, [What to look for in a code review](https://google.github.io/eng-practices/review/reviewer/looking-for.html) | The frame for the whole walk, and the reason a speculative abstraction is a finding |
|
|
20
24
|
|
|
21
25
|
The procedure stays in the body rather than a reference, since every review reads the design axis and a reference would cost a read on every run.
|
|
22
26
|
|
|
23
|
-
|
|
27
|
+
### Scope checks
|
|
24
28
|
|
|
25
|
-
|
|
29
|
+
Three scope checks come from outside sources, each adopted as one check.
|
|
26
30
|
|
|
27
|
-
**
|
|
31
|
+
- **Change sizing as a split.** Google's [small CLs](https://google.github.io/eng-practices/review/developer/small-cls.html) and `skills/code-review-and-quality/SKILL.md` ask for one self-contained change, so the check names a split when two concerns could land apart.
|
|
32
|
+
- **Relocate versus reduce.** The same `code-review-and-quality` skill counts the concepts a reader holds before and after a refactor, so moved complexity reports as moved.
|
|
33
|
+
- **Chesterton's Fence.** `skills/code-simplification/SKILL.md` reads why code exists before removing it, so the check reads `git blame` and the adding commit before calling a path dead.
|
|
28
34
|
|
|
29
35
|
### Guard the bar
|
|
30
36
|
|
|
31
|
-
From `
|
|
37
|
+
From `skills/constraint-driven-development/SKILL.md`, a change must not pass by weakening the constraint it has to meet. Adopted as its own axis after tests.
|
|
38
|
+
|
|
39
|
+
- It lists the moved threshold, the skipped or hollowed test, the inline suppression, the excluded path, the throwing stub, the empty catch, and the new config exception
|
|
40
|
+
- The clause accepting a suppression whose stated reason holds is this skill's own, since a legitimate one would otherwise report noise the procedures then drop
|
|
32
41
|
|
|
33
42
|
### Performance
|
|
34
43
|
|
|
35
|
-
|
|
44
|
+
The axis itself, a call inside a loop and an unbounded fetch, comes from `skills/code-review-and-quality/SKILL.md`. Keep or revert comes from `skills/performance-optimization/SKILL.md`.
|
|
45
|
+
|
|
46
|
+
- Measure before and after the same way, and a neutral result argues for removing the added complexity
|
|
47
|
+
- The repeated-run requirement against noise is stated here, so one run on each side reads as an anecdote
|
|
36
48
|
|
|
37
49
|
### Security additions
|
|
38
50
|
|
|
39
|
-
From `
|
|
51
|
+
From `skills/security-and-hardening/SKILL.md`, the threat model first and the derived-path rule. Both stay stack-neutral, and no red run measures them, so they ship as lifts rather than as an answer to a miss.
|
|
52
|
+
|
|
53
|
+
- The threat model is the opening step of `references/security.md`, naming who supplies each input and what the code can reach before any class is read
|
|
54
|
+
- The derived-path rule is the destructive-operations class, asking for the empty-value collapse, the glob or symlink escape, the missing root check, and no read before the call
|
|
40
55
|
|
|
41
56
|
### Closing sections
|
|
42
57
|
|
|
43
|
-
The excuses, red flags, and closing checklist follow the
|
|
58
|
+
The excuses, red flags, and closing checklist follow the shape every practice skill in this toolkit carries, from [`docs/skill-anatomy.md`](https://github.com/addyosmani/agent-skills/blob/2686b620fc1fed2e8f60c704839c766b8594c6b6/docs/skill-anatomy.md). Each excuse row rebuts a reason a review stops at the hunk, such as passing tests against a test the diff skipped.
|
|
44
59
|
|
|
45
60
|
## Declined
|
|
46
61
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
**A fixed line count for sizing.** Google's small-CL page sets no hard limit, and one concern regularly runs past a hundred lines here. A number would fire on nearly every branch, so the split is stated by concern instead.
|
|
62
|
+
Each item names what was declined and the reason it stays out.
|
|
50
63
|
|
|
51
|
-
**
|
|
64
|
+
- **Google's approval standard.** "Approve a change once it definitely improves the overall code health" is a grading rule, and grading belongs to the procedures that load this skill.
|
|
65
|
+
- **A fixed line count for sizing.** Google's page sets no hard limit, and one concern regularly runs past a hundred lines here, so the split is stated by concern.
|
|
66
|
+
- **Named structural remedies as a catalog.** A list of refactorings reads as a menu a session fills in. A design finding states the cost, and the remedy is the author's.
|
|
67
|
+
- **STRIDE and abuse-case tests as a procedure.** They belong to a design session, and the threat-model opening takes the one step a diff supports.
|
|
68
|
+
- **The web and database tables from `performance-optimization`.** They name a stack, and the axis stays stack-neutral until a target asks for one.
|
|
52
69
|
|
|
53
|
-
|
|
70
|
+
### A dependency upgrade reference
|
|
54
71
|
|
|
55
|
-
|
|
72
|
+
`skills/code-review-and-quality/SKILL.md` reads the changelog across the range, one dependency per change, and the lockfile diff. Declined because the seeded upgrade is not a miss. The body without such a reference reported the planted major bump and the lockfile install script on the second of two runs, passing the assertion.
|
|
56
73
|
|
|
57
|
-
|
|
74
|
+
Revisit when a run on a changed lockfile misses what a reference would have named.
|
|
@@ -8,13 +8,48 @@ Before the classes, name from the diff who supplies each input and what the code
|
|
|
8
8
|
|
|
9
9
|
## Classes to check
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
-
|
|
11
|
+
Each class names the sink, the path in, and the fix to look for.
|
|
12
|
+
|
|
13
|
+
### Shell and command injection
|
|
14
|
+
|
|
15
|
+
A value from an argument, an environment variable, a file, or a network response reaches a shell.
|
|
16
|
+
|
|
17
|
+
- The paths in are `eval`, an unquoted expansion, a string built into a command, and a subprocess call taking a single command string
|
|
18
|
+
- Quoting the variable at the call site is the fix to look for
|
|
19
|
+
|
|
20
|
+
### Path traversal in a file write
|
|
21
|
+
|
|
22
|
+
A path built from outside input is written without being resolved and checked against the directory it must stay inside. A `..` segment, an absolute path, and a symlink inside the target each escape a naive join.
|
|
23
|
+
|
|
24
|
+
### Destructive operation on a derived path
|
|
25
|
+
|
|
26
|
+
A delete, overwrite, move, or clean takes a path built from a variable, a config value, or a listing. The fix to look for is resolve, require the root, then act.
|
|
27
|
+
|
|
28
|
+
- An empty or unset value that collapses the path to a root
|
|
29
|
+
- A glob or a symlink that carries it outside the folder it was meant for
|
|
30
|
+
- No check that the resolved path sits at least one level below an expected root
|
|
31
|
+
- No read of what is there, owned by this tool or not, before the call
|
|
32
|
+
- A write escaping its folder is path traversal. When a finding fits both, name the class whose fix applies.
|
|
33
|
+
|
|
34
|
+
### Secrets and personal data leaving the process
|
|
35
|
+
|
|
36
|
+
A token, a key, a password, or personal data reaches a log line, an error message, a session transcript, a published page, a pull request comment, or a sync to a remote. Check what a debug line prints and what a verbose flag adds.
|
|
37
|
+
|
|
38
|
+
### Supply chain
|
|
39
|
+
|
|
40
|
+
Three shapes bring in code nobody reviewed.
|
|
41
|
+
|
|
42
|
+
- One-shot package execution of an unpinned version, which runs whatever the registry serves that day
|
|
43
|
+
- A new dependency, and what its install scripts run
|
|
44
|
+
- A lockfile that changes without a manifest change
|
|
45
|
+
|
|
46
|
+
### Time of check to time of use on a file write
|
|
47
|
+
|
|
48
|
+
An existence or permission check is followed by a write to the same path in a later step, or a predictable name sits in a shared temporary directory. Another process can swap the path in between.
|
|
49
|
+
|
|
50
|
+
### Insecure defaults a consumer installs
|
|
51
|
+
|
|
52
|
+
A config, a scaffold, or a seed turns a check off, opens a port on every interface, grants a broad permission, or ships a placeholder secret. The consumer inherits the default without reading it.
|
|
18
53
|
|
|
19
54
|
## Excluded
|
|
20
55
|
|
|
@@ -20,7 +20,13 @@ gh api --paginate 'repos/{owner}/{repo}/issues/<number>/comments?per_page=100' -
|
|
|
20
20
|
|
|
21
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
|
|
23
|
+
Flag the change as shipping no screenshot when it paints and the pull request carries any of three comment shapes.
|
|
24
|
+
|
|
25
|
+
- No marked comment at all
|
|
26
|
+
- A marked comment with no comparison, meaning no `**Base:**` line and no `<details>` table
|
|
27
|
+
- Only a checklist posted alone, since `## Evidence` opens every marked comment and the heading alone never means screenshots are present
|
|
28
|
+
|
|
29
|
+
Then decide how to raise it by whether the project keeps captures, the same test `canon pr evidence` applies:
|
|
24
30
|
|
|
25
31
|
```bash
|
|
26
32
|
git ls-tree -r --name-only <base> | grep -E '(^|/)evidence/.*\.(png|jpe?g|gif|webp|avif|svg)$' | head -1
|
|
@@ -45,7 +51,11 @@ mkdir -p .canon/tmp/pr/review/evidence/<number>
|
|
|
45
51
|
git show <sha>:<path> > .canon/tmp/pr/review/evidence/<number>/<side>-<name>.png
|
|
46
52
|
```
|
|
47
53
|
|
|
48
|
-
Take the sha from the row, so the base and head sides are exactly what the comment shows. Then open each file with the file-reading tool.
|
|
54
|
+
Take the sha from the row, so the base and head sides are exactly what the comment shows. Then open each file with the file-reading tool.
|
|
55
|
+
|
|
56
|
+
- Read the URL out of the `src=` of each `<img>`, or out of `*` base cell has no before image, and a view or flat block whose cases are all added has no base column at all
|
|
58
|
+
- A view row holds one case per theme cell, so a width row names two images where a flat row names one
|
|
49
59
|
|
|
50
60
|
## How many to open
|
|
51
61
|
|
|
@@ -59,21 +69,26 @@ A second theme earns a read only when the diff touches a color token. Name the s
|
|
|
59
69
|
|
|
60
70
|
## Comparing
|
|
61
71
|
|
|
62
|
-
Check each opened image against the layout its checklist box claims
|
|
72
|
+
Check each opened image against the layout its checklist box claims. A finding names the checklist box or design-file line the image breaks, never a taste.
|
|
63
73
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
74
|
+
- Check the visible tokens, being color, type scale, and spacing, against the stylesheet `canon/DESIGN.md`'s lead names
|
|
75
|
+
- Check its component rules against the record itself, and skip the design file comparison silently when the project has none
|
|
76
|
+
- Read the width and theme from whatever the image path carries, and fix no width list, since which widths matter belongs to the project
|
|
67
77
|
|
|
68
78
|
## The checklist
|
|
69
79
|
|
|
70
80
|
The `## What to look at` block between the `pr-checklist` markers holds what was claimed as verified. A tick stamped `passed at` the current head is the UI reviewer's pass, and an unstamped tick is an author's or operator's claim.
|
|
71
81
|
|
|
72
|
-
- Test each ticked box against an opened image showing the state and width it names, a stamped one included, since the UI reviewer drove the
|
|
82
|
+
- Test each ticked box against an opened image showing the state and width it names, a stamped one included, since the UI reviewer drove the app and not the stills
|
|
83
|
+
- Flag a box whose image contradicts it, quoting the box
|
|
73
84
|
- A ticked box no image covers is untested rather than confirmed, and the finding says so.
|
|
74
85
|
- Test only the rows the current comment shows. The next render clears a tick whose stamp names another head, so a tick not stamped at the current head may describe images the comment no longer carries.
|
|
75
86
|
- Leave unchecked boxes to the procedure's own read of the description.
|
|
76
87
|
|
|
77
88
|
## With no pull request
|
|
78
89
|
|
|
79
|
-
A local review has no comment to read
|
|
90
|
+
A local review has no comment to read, so it reads the tree.
|
|
91
|
+
|
|
92
|
+
- Read each changed image under an `evidence/` path segment from the working tree, and its base side with `git show <base>:<path>`
|
|
93
|
+
- Read the checklist handoff at `.canon/tmp/handoff/ui-checklist/<slug>.md` at the main worktree root when it exists
|
|
94
|
+
- A painting change with no changed evidence image takes the flag from the first section, decided by the same `git ls-tree` test
|
|
@@ -26,12 +26,12 @@ A thread then reads as `## Review`, the worker's `## Review response` from `revi
|
|
|
26
26
|
|
|
27
27
|
Both headings anchor as a section distinct from human threads. The full set is eight headings across four families, stated here once so `role-orchestrator`'s poll and every reply-posting skill cite it rather than carry a copy.
|
|
28
28
|
|
|
29
|
-
| Family | Headings | Owner
|
|
30
|
-
| -------- | ------------------------------------------------------------ |
|
|
31
|
-
| Review | `## Review`, `## Review closed` | This skill alone
|
|
32
|
-
| Reply | `## Review response`, `## Rebase`, `## Post-review findings` | `review-address`
|
|
33
|
-
| Evidence | `## Evidence` | `canon pr evidence`, through `git-pr` and `git-followup`
|
|
34
|
-
| UI | `## UI review`, `## UI review closed` | `review-ui`, posted as a review beside this one and read by nothing here
|
|
29
|
+
| Family | Headings | Owner |
|
|
30
|
+
| -------- | ------------------------------------------------------------ | --------------------------------------------------------------------------- |
|
|
31
|
+
| Review | `## Review`, `## Review closed` | This skill alone |
|
|
32
|
+
| Reply | `## Review response`, `## Rebase`, `## Post-review findings` | `review-address` |
|
|
33
|
+
| Evidence | `## Evidence` | `canon pr evidence`, through `pr-evidence` from `git-pr` and `git-followup` |
|
|
34
|
+
| UI | `## UI review`, `## UI review closed` | `review-ui`, posted as a review beside this one and read by nothing here |
|
|
35
35
|
|
|
36
36
|
- The reply headings in order answer a finding, report a stale branch resolved without one, and carry a finding a worker produced after a close-out
|
|
37
37
|
- `## Evidence` answers no comment on the thread, so the poll leaves it out of the unclassified count rather than reading it as a reply owing a re-review
|
|
@@ -7,7 +7,13 @@ description: The Testing and reviewer blocks a pass may carry, and the close-out
|
|
|
7
7
|
|
|
8
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
9
|
|
|
10
|
-
|
|
10
|
+
## The testing block
|
|
11
|
+
|
|
12
|
+
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.
|
|
13
|
+
|
|
14
|
+
- It carries no severity and enters no count, and it is still owed, so the pass takes `## Review` and the full body rather than either ✅ line
|
|
15
|
+
- Say so on the summary line as `plus N testing question(s)`, since the three counts read as zero and would otherwise report a silent pass
|
|
16
|
+
- Keep it to the boxes the check raised, since restating a box whose stated requirement holds teaches the author to skip the block
|
|
11
17
|
|
|
12
18
|
```markdown
|
|
13
19
|
**Testing**
|
|
@@ -15,11 +21,14 @@ A Testing box the Step 3 check raised goes in a `**Testing**` block placed after
|
|
|
15
21
|
- `- [ ] <the box as written>` names no capability the agent lacks. `canon sandbox run <arm>` drives it. Was there a reason to leave it?
|
|
16
22
|
```
|
|
17
23
|
|
|
18
|
-
|
|
24
|
+
## The reviewer block
|
|
19
25
|
|
|
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
|
|
26
|
+
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 is followed by its answer, or by what would settle it where the pass could not answer. It carries no severity and enters no count.
|
|
21
27
|
|
|
22
|
-
An unanswered bullet is owed
|
|
28
|
+
- An unanswered bullet is owed like an unanswered Testing box, so the pass takes `## Review` and the full body
|
|
29
|
+
- An answered bullet is not owed, since the answer is discharged in the same comment that carries it
|
|
30
|
+
- A pass already posting a numeric summary line adds `plus N reviewer request(s)` to it
|
|
31
|
+
- The all-answered close-out below carries the block in place of that line and needs no addition
|
|
23
32
|
|
|
24
33
|
```markdown
|
|
25
34
|
**For the reviewer**
|
|
@@ -27,9 +36,16 @@ An unanswered bullet is owed the same way an unanswered Testing box is, so a pas
|
|
|
27
36
|
- 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
37
|
```
|
|
29
38
|
|
|
30
|
-
|
|
39
|
+
## Close-out bodies
|
|
40
|
+
|
|
41
|
+
A pass carrying nothing at all takes `## Review closed` and a short body, with the footer line included either way. Post a close-out even with nothing to report, since a review left with no closing comment reads as one nobody answered.
|
|
42
|
+
|
|
43
|
+
- On a first pass, post `✅ No findings. Reviewed against project docs and the board.`
|
|
44
|
+
- On a later pass, post `✅ Prior findings addressed. Re-reviewed <short-sha>, N commits since the prior pass.`
|
|
31
45
|
|
|
32
|
-
|
|
46
|
+
### Only minors
|
|
47
|
+
|
|
48
|
+
A pass carrying only minors is an ordinary finding-carrying pass, so it takes the open heading and the full shape, since neither short line reports the minors. A pass carrying only Testing questions or only an unanswered reviewer request takes the same route. Keep whichever scope sentence the pass owes on the summary line:
|
|
33
49
|
|
|
34
50
|
```markdown
|
|
35
51
|
## Review
|
|
@@ -45,8 +61,12 @@ A pass carrying only minors is an ordinary finding-carrying pass, so it takes th
|
|
|
45
61
|
<!-- review-pr: commit=<headRefOid> read-at=<read-at> -->
|
|
46
62
|
```
|
|
47
63
|
|
|
48
|
-
A
|
|
64
|
+
### A withdrawal
|
|
65
|
+
|
|
66
|
+
A pass that closed by withdrawing a finding rather than reading its fix takes neither ✅ line, per the withdrawal rule in Step 3. Both claim a fix landed, so either credits work nobody did on the comment a reader treats as the verdict.
|
|
67
|
+
|
|
68
|
+
Write the withdrawal and the fact that settled it in place of the canned line, keeping the heading and the footer.
|
|
49
69
|
|
|
50
|
-
|
|
70
|
+
### Only answered reviewer requests
|
|
51
71
|
|
|
52
|
-
|
|
72
|
+
A pass whose only content is a `## For the reviewer` block with every bullet answered, owing nothing else, takes `## Review closed`, the block in place of the canned line, and the footer. The heading reports what the author still owes, and an answer discharged in the same comment owes nothing back.
|
|
@@ -9,22 +9,37 @@ Part of Step 4 of `review-pr`, reached only on the branch `post.md` names. Every
|
|
|
9
9
|
|
|
10
10
|
When `<prior-heading>` from Step 2 reads `## Review closed` and this pass carries nothing owed, the thread already holds this verdict. Replace the standing close-out rather than posting a second one beside it.
|
|
11
11
|
|
|
12
|
+
## The rewrite
|
|
13
|
+
|
|
12
14
|
Resolve its numeric id off the REST listing, keeping the newest match across every page:
|
|
13
15
|
|
|
14
16
|
```bash
|
|
15
17
|
gh api --paginate 'repos/{owner}/{repo}/pulls/<number>/reviews?per_page=100' --jq '.[] | select((.body // "") | split("\n")[0] | rtrimstr("\r") == "## Review closed") | .id' | tail -n 1
|
|
16
18
|
```
|
|
17
19
|
|
|
18
|
-
Write the replacement body to `<body-file>`, the name `post.md` already derived at the top of Step 4
|
|
20
|
+
Write the replacement body to `<body-file>`, the name `post.md` already derived at the top of Step 4. Keep the heading and the footer, and name what this pass covered on the scope line in place of what the old one covered.
|
|
21
|
+
|
|
22
|
+
- Derive that name the same way whichever path reached here, since the guard reads `<prior-heading>` alone and a repeated head resolves the third segment as usual
|
|
23
|
+
- The folder then gains a record of every covered head rather than losing the one the standing comment named
|
|
19
24
|
|
|
20
25
|
```bash
|
|
21
26
|
gh api -X PUT repos/{owner}/{repo}/pulls/<number>/reviews/<review-id> -F body=@<body-file>
|
|
22
27
|
```
|
|
23
28
|
|
|
24
|
-
`PUT` keeps the comment's timestamp and its position in the thread, so the verdict stays where a reader already found it
|
|
29
|
+
`PUT` keeps the comment's timestamp and its position in the thread, so the verdict stays where a reader already found it. A submitted review cannot be deleted, which is why this rewrites the standing comment rather than posting a fresh one.
|
|
30
|
+
|
|
31
|
+
## When the guard fires
|
|
32
|
+
|
|
33
|
+
The guard fires on `## Review closed` alone.
|
|
34
|
+
|
|
35
|
+
- Two open passes carry different findings and both are worth reading, so a repeated `## Review` posts normally
|
|
36
|
+
- A pass carrying anything owed posts normally under `## Review`, so a finding raised after a close-out is never swallowed by the guard
|
|
37
|
+
|
|
38
|
+
## What the PUT leaves pinned
|
|
25
39
|
|
|
26
|
-
|
|
40
|
+
`PUT` leaves the review's `commit.oid` pinned at the commit the close-out was first submitted against. Step 2's `<prior-oid>` and the prior commit `poll.ts` derives would read too wide a range from it, and the poll's `SEEN` branch, firing on `prior` equalling the head, could never be reached.
|
|
27
41
|
|
|
28
|
-
The
|
|
42
|
+
The marker answers both, because `PUT` replaces the body and the marker is in it. It carries the commit this pass read, and every reader takes it in preference to the pinned field.
|
|
29
43
|
|
|
30
|
-
|
|
44
|
+
- `submittedAt` still stays at the original submission, and the poll's age test reads it
|
|
45
|
+
- A rewritten close-out therefore ages from when it first landed, which is the right reading for a thread waiting on a human
|
|
@@ -7,10 +7,34 @@ description: How review-pr Step 3 tests what the pull request body's Key changes
|
|
|
7
7
|
|
|
8
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
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
|
|
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 on the trunk once the branch is gone, the same record a stale ticked box corrupts.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
## Reading each field
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Branch on the record rather than on the exit code, which a shell function wrapping `canon` can flatten to zero. Each field the record carries takes its own reading.
|
|
15
|
+
|
|
16
|
+
| Field | Reading |
|
|
17
|
+
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
|
|
18
|
+
| `unmet` | a `should-fix` finding under the `**PR body**` block the stale box takes, one per path, quoting the `preview` bullet and the `head` |
|
|
19
|
+
| `unnamed` | read for yourself and raise nothing off the count |
|
|
20
|
+
| `unresolved` | reported nowhere, since it was judged in neither direction |
|
|
21
|
+
| `incidental` | reported nowhere, since it owes no bullet |
|
|
22
|
+
|
|
23
|
+
### Before filing an unmet path
|
|
24
|
+
|
|
25
|
+
Read the bullet before filing it, since one class survives the reader. A bullet citing where something is defined while claiming an edit elsewhere puts a real path in the claim region, so report that as the class rather than as a stale claim.
|
|
26
|
+
|
|
27
|
+
A body is edited between pushes, so the reading is true at the `head` it names and can be false a minute later.
|
|
28
|
+
|
|
29
|
+
### Before raising an unnamed path
|
|
30
|
+
|
|
31
|
+
The `unnamed` class covers a real omission and equally a generated asset or a regenerated index that earns no bullet. Open the section and confirm no bullet names the file before putting one to the author.
|
|
32
|
+
|
|
33
|
+
This instruction once sent the question to three pull requests in one day over bullets that had named the files all along, and one author added bullets nobody needed.
|
|
34
|
+
|
|
35
|
+
## Refusals
|
|
36
|
+
|
|
37
|
+
- `no-claims` means the reader resolved no path out of a section that exists, the extractor failing over prose, so say so and raise nothing
|
|
38
|
+
- `no-section` means the body carries no such heading, a finding only where the pull request template asks for one
|
|
15
39
|
|
|
16
40
|
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.
|