@erclx/canon 5.54.0 → 5.56.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/CHANGELOG.md +16 -0
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/SKILL.md +8 -10
- package/claude/skills/auto-ship/SKILL.md +4 -5
- package/claude/skills/auto-ship/references/failure-recovery.md +37 -17
- package/claude/skills/auto-ship/references/tier-failures.md +9 -7
- package/claude/skills/auto-ship/references/worktree-name.md +8 -5
- package/claude/skills/backlog-triage/SKILL.md +10 -10
- package/claude/skills/backlog-triage/references/apply.md +6 -6
- package/claude/skills/context-fold/references/classify.md +17 -4
- package/claude/skills/create-rule/references/rule.md +4 -0
- package/claude/skills/create-skill/SKILL.md +3 -3
- package/claude/skills/deploy-app/SKILL.md +2 -0
- package/claude/skills/deprecation-migration/SKILL.md +7 -9
- package/claude/skills/document-health/SKILL.md +6 -6
- package/claude/skills/document-health/references/axes.md +1 -1
- package/claude/skills/document-repair/SKILL.md +5 -5
- package/claude/skills/git-followup/SKILL.md +16 -5
- package/claude/skills/git-issue/references/issue.md +9 -11
- package/claude/skills/git-pr/references/publish.md +4 -5
- package/claude/skills/git-split/SKILL.md +11 -4
- package/claude/skills/markdown-craft/SKILL.md +1 -1
- package/claude/skills/markdown-craft/references/markdown.md +2 -2
- package/claude/skills/markdown-craft/references/tables.md +9 -7
- package/claude/skills/plan-feature/SKILL.md +2 -0
- package/claude/skills/plan-feature/references/plan.md +2 -0
- package/claude/skills/review-address/SKILL.md +9 -7
- package/claude/skills/review-craft/SKILL.md +7 -9
- package/claude/skills/review-craft/references/adopted.md +10 -8
- package/claude/skills/review-pr/SKILL.md +2 -0
- package/claude/skills/review-pr/references/key-changes.md +8 -6
- package/claude/skills/review-ui/references/driving.md +10 -8
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +6 -4
- package/claude/skills/role-orchestrator/references/orchestrator-refill.md +9 -3
- package/claude/skills/role-reviewer/SKILL.md +5 -5
- package/claude/skills/search-craft/SKILL.md +5 -7
- package/claude/skills/session-worktree/SKILL.md +2 -0
- package/claude/skills/session-worktree/references/main-root-writes.md +2 -0
- package/claude/skills/systematic-debugging/SKILL.md +9 -9
- package/claude/skills/systematic-debugging/references/adopted.md +1 -1
- package/claude/skills/target-check/SKILL.md +6 -8
- package/claude/skills/target-check/references/domains.md +1 -4
- package/claude/skills/target-setup/SKILL.md +8 -8
- package/claude/skills/target-update/SKILL.md +5 -5
- package/claude/skills/task-board/SKILL.md +2 -4
- package/claude/skills/task-board/references/tasks.md +5 -5
- package/claude/skills/task-complete/references/archive.md +5 -2
- package/claude/skills/test-craft/SKILL.md +2 -0
- package/claude/skills/test-craft/references/adopted.md +2 -0
- package/claude/skills/ui-checklist/SKILL.md +8 -9
- package/claude/skills/write-doc/SKILL.md +8 -8
- package/claude/skills/write-doc/references/readme.md +2 -0
- package/claude/skills/write-doc/references/wiki-kind.md +11 -4
- package/docs/agents/context-audit.md +16 -14
- package/docs/agents/install-and-sync.md +2 -2
- package/docs/agents/markdown-audit.md +11 -4
- package/docs/agents/migrate.md +15 -13
- package/docs/agents/output-shape.md +13 -10
- package/docs/target/migrations.md +3 -3
- package/docs/target/sync.md +1 -1
- package/docs/workflow/operating-model.md +2 -0
- package/package.json +1 -1
- package/scripts/core/install-check.sh +1 -1
- package/scripts/lib/ui.sh +12 -65
- package/src/audits/run.ts +1 -1
- package/src/claude/routing.ts +1 -1
- package/src/cli/run.ts +5 -6
- package/src/cli/ui.ts +87 -28
- package/src/cli.ts +6 -0
- package/src/commands/claude.ts +2 -3
- package/src/commands/design.ts +8 -13
- package/src/commands/gate.ts +5 -3
- package/src/commands/gov.ts +11 -21
- package/src/commands/labels.ts +1 -1
- package/src/commands/markdown.ts +25 -29
- package/src/commands/pr.ts +1 -1
- package/src/commands/sync.ts +1 -1
- package/src/commands/tooling.ts +5 -8
- package/src/commands/transcripts.ts +6 -11
- package/src/gate/sequencer.ts +1 -1
- package/src/gate/stages.ts +0 -10
- package/src/hooks/post-merge.ts +2 -5
- package/src/labels/density.ts +5 -46
- package/src/markdown/density.ts +41 -6
- package/src/markdown/scope.ts +6 -1
- package/src/markdown/structure.ts +18 -9
- package/src/markdown/tables.ts +32 -18
- package/src/process/harness.ts +11 -4
- package/src/process/seeded-package.ts +21 -0
- package/src/sandbox/equivalence.ts +0 -1
- package/src/sandbox/provision.ts +8 -13
- package/src/sandbox/scenario.ts +6 -12
- package/src/serve/static.ts +2 -60
- package/src/sync/engine.ts +3 -8
- package/src/sync/workflow.ts +3 -5
- package/src/tooling/verify-stack.ts +1 -1
- package/tooling/base/configs/.husky/post-merge +6 -10
- package/tooling/base/reference.md +7 -6
- package/tooling/claude/reference.md +7 -5
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +7 -6
- package/scripts/core/check-color-source.sh +0 -51
- package/src/serve/live.ts +0 -113
|
@@ -74,10 +74,17 @@ Classify the groups before generating commands, since the mode decides each bran
|
|
|
74
74
|
|
|
75
75
|
Append the line for the run's mode to the preview.
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
77
|
+
Stacked mode appends this line:
|
|
78
|
+
|
|
79
|
+
```plaintext
|
|
80
|
+
🔁 Sequential squash-merge loop. Squash-merge each PR bottom-up with --delete-branch. After each merge, signal me so I can restack the next branch onto main before you merge it.
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Independent mode appends this line:
|
|
84
|
+
|
|
85
|
+
```plaintext
|
|
86
|
+
🔁 Squash-merge secondaries first, primary last. The primary keeps every cherry-picked commit, so merging it first lands every secondary's content on main and leaves the secondary PRs empty after rebase.
|
|
87
|
+
```
|
|
81
88
|
|
|
82
89
|
After outputting the preview, execute the final commands immediately. Claude Code's tool permission dialog is the confirmation gate. Do not wait for user input.
|
|
83
90
|
|
|
@@ -14,7 +14,7 @@ Read the references below before a substantial markdown edit. Every rule in them
|
|
|
14
14
|
|
|
15
15
|
Run `canon markdown audit <path>` after the edit, and fix every ban and density finding it reports before moving on. Rewrite the sentence carrying a ban hit rather than swapping the token for a near-synonym, and fix a density finding by its shape rather than trimming characters.
|
|
16
16
|
|
|
17
|
-
A table
|
|
17
|
+
A table cell past its cap and a list after a table gate where density does, and the row count and the wide token report without failing the run. Fix each the way `tables.md` gives for its limit.
|
|
18
18
|
|
|
19
19
|
## Routes
|
|
20
20
|
|
|
@@ -77,7 +77,7 @@ A bold section marker holding its line alone breaks a run the way a heading does
|
|
|
77
77
|
|
|
78
78
|
## Density
|
|
79
79
|
|
|
80
|
-
Six limits keep a file scannable on sight, each a fact `canon markdown audit` measures that fails the push where the surface's gate is on. A table takes four more
|
|
80
|
+
Six limits keep a file scannable on sight, each a fact `canon markdown audit` measures that fails the push where the surface's gate is on. A table takes four more in `tables.md`, two of them gating. Open an H3 with a lead sentence or a table, then a few bullets or a short paragraph, since monotone text is the defect.
|
|
81
81
|
|
|
82
82
|
| Rule | Limit |
|
|
83
83
|
| ------------------- | ------------------------------------------------- |
|
|
@@ -95,7 +95,7 @@ Rules, a requirements or design record, a changelog, examples, and `.canon/` rec
|
|
|
95
95
|
A paragraph is read straight through and a bullet is scanned, so the paragraph limit sits above the bullet one. Four sentences to a paragraph stays advice rather than a limit.
|
|
96
96
|
|
|
97
97
|
- A paragraph's length folds in the lines that wrap it. A paragraph inside a list item counts toward its bullet, never as a paragraph or toward a run.
|
|
98
|
-
- A bullet's length counts its continuation lines and excludes any bullet nested under it
|
|
98
|
+
- A bullet's length counts its continuation lines and excludes any bullet nested under it, and a nested bullet is measured on its own
|
|
99
99
|
- A heading, list, table, fence, or bold section marker ends a run of paragraphs
|
|
100
100
|
- A blank line, a continuation, and a nested item do not break a run of bullets, and a paragraph or a heading does
|
|
101
101
|
- A run whose every item opens with a bold label or a link is exempt from the run limit, since each item names its own subject. A task box is not a link, so a checklist counts as plain.
|
|
@@ -5,18 +5,20 @@ description: The four limits a markdown table takes, being cell length, row coun
|
|
|
5
5
|
|
|
6
6
|
# Table limits
|
|
7
7
|
|
|
8
|
-
None of the density limits in `markdown.md` reads inside a table, so content too long for a bullet tends to move into a cell. Four table limits close that gap. `canon markdown audit` measures them on the paths density covers, outside fences
|
|
8
|
+
None of the density limits in `markdown.md` reads inside a table, so content too long for a bullet tends to move into a cell. Four table limits close that gap. `canon markdown audit` measures them on the paths density covers, outside fences.
|
|
9
|
+
|
|
10
|
+
Cell length and a list after a table fail a push where density gates. Rows and a wide token report without failing one.
|
|
9
11
|
|
|
10
12
|
## Limits
|
|
11
13
|
|
|
12
14
|
Each limit is a count or a shape a scan settles, read the way a renderer draws the table. An escaped pipe stays inside its cell, and pipe lines with no delimiter row are not a table.
|
|
13
15
|
|
|
14
|
-
| Rule | Limit |
|
|
15
|
-
| ---------------- | ----------------------------------------------------- |
|
|
16
|
-
| Cell length | 120 visible characters, counting a link by its label |
|
|
17
|
-
| Rows | 8 body rows, not counting the header |
|
|
18
|
-
| List after table | A list is never the next block after a table |
|
|
19
|
-
| Wide token | No code span in a cell holds a run past 30 characters |
|
|
16
|
+
| Rule | Limit | Effect |
|
|
17
|
+
| ---------------- | ----------------------------------------------------- | ------------ |
|
|
18
|
+
| Cell length | 120 visible characters, counting a link by its label | Gates |
|
|
19
|
+
| Rows | 8 body rows, not counting the header | Reports only |
|
|
20
|
+
| List after table | A list is never the next block after a table | Gates |
|
|
21
|
+
| Wide token | No code span in a cell holds a run past 30 characters | Reports only |
|
|
20
22
|
|
|
21
23
|
A paragraph or a heading between a table and a list clears the third limit, and a blank line alone does not.
|
|
22
24
|
|
|
@@ -163,6 +163,8 @@ Pick the `Next:` line from the roster check `${CLAUDE_SKILL_DIR}/../task-board/S
|
|
|
163
163
|
| **Not found**, and this session's name starts with `worker-` or `planner-` | `Hand <task> to a worker`, naming no session, since none is live and the operator dispatches by hand |
|
|
164
164
|
| **Not found otherwise**, or the read fails | `/session-worktree` |
|
|
165
165
|
|
|
166
|
+
Three rules apply to the `Next:` choice:
|
|
167
|
+
|
|
166
168
|
- With a live orchestrator and no planner role held, send the plan path to it through `canon:session-relay`, resolved from its `sessionId`
|
|
167
169
|
- A session holding `canon:role-planner` already owes that announcement through its own channel, so it sends none
|
|
168
170
|
- Say which row fired in one clause, since a line with no stated reason is one the next reader re-derives.
|
|
@@ -81,6 +81,8 @@ The document opens with `# Feature: <short title>` and one paragraph stating wha
|
|
|
81
81
|
| `## Questions` | numbered open decisions, each with a suggestion and an answer slot | Always |
|
|
82
82
|
| `## Sources` | the outside sources a decision rests on, each with its quoted passage | When a decision rests on an outside source |
|
|
83
83
|
|
|
84
|
+
Four rules govern how a section is written:
|
|
85
|
+
|
|
84
86
|
- Write each section as the H2 the table gives, so a reader scans the plan by its outline
|
|
85
87
|
- A section written as a bold label, the spelling before this one, is still that section to every parser. Leave an existing plan's spelling alone.
|
|
86
88
|
- Write `None identified.` under a required section with nothing to report rather than dropping the marker. A dropped section and an unconsidered one read identically.
|
|
@@ -90,13 +90,15 @@ Once the fixes are commits, re-run step 5's staleness test against the new head.
|
|
|
90
90
|
|
|
91
91
|
Write a summary reply to `.canon/tmp/pr/reply/reply-<number>.md`, keyed on the PR number so two sessions addressing different pull requests never overwrite each other. Load `write-human` for voice, follow `${CLAUDE_SKILL_DIR}/../markdown-craft/references/markdown.md`, and keep each mapping to one line.
|
|
92
92
|
|
|
93
|
-
| Part | Content
|
|
94
|
-
| -------- |
|
|
95
|
-
| Heading | `## Review response`, distinct from human threads and subordinate to the review's own `## Review`
|
|
96
|
-
| Summary | One sentence
|
|
97
|
-
| Findings | One line per finding under 200 characters, naming its outcome and the commit that carries it, in the shape below
|
|
98
|
-
| Docs | Any `.claude/` docs refreshed as a result of the fixes
|
|
99
|
-
| Close | `🤖 Addressed by Claude Code` on its own line, so the reply reads as a machine pass rather than a human sign-off
|
|
93
|
+
| Part | Content |
|
|
94
|
+
| -------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
95
|
+
| Heading | `## Review response`, distinct from human threads and subordinate to the review's own `## Review` |
|
|
96
|
+
| Summary | One sentence, plus the rebase note below |
|
|
97
|
+
| Findings | One line per finding under 200 characters, naming its outcome and the commit that carries it, in the shape below |
|
|
98
|
+
| Docs | Any `.claude/` docs refreshed as a result of the fixes |
|
|
99
|
+
| Close | `🤖 Addressed by Claude Code` on its own line, so the reply reads as a machine pass rather than a human sign-off |
|
|
100
|
+
|
|
101
|
+
After a step 5 rebase, the summary says so and names the files resolved by hand and those the regen rebuilt, since the next review is a full pass.
|
|
100
102
|
|
|
101
103
|
```markdown
|
|
102
104
|
- **<severity>**, `<file>` line <n>: fixed in `<sha>`. <What now holds, in one sentence.>
|
|
@@ -87,15 +87,13 @@ Three scope checks follow the walk:
|
|
|
87
87
|
|
|
88
88
|
## Excuses and rebuttals
|
|
89
89
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
| The description says it is faster | A claimed speedup with no measurement, or one run each side, is asserted. Ask for runs that beat the noise. |
|
|
98
|
-
| The change only touches styles, so the screenshots can wait | A stylesheet diff says what changed and only the image says what a user sees. Open them, or say none exist. |
|
|
90
|
+
- **The tests pass, so the change works.** Read what the diff did to the tests first. A test skipped, deleted, or stripped of its assertions passes by proving nothing.
|
|
91
|
+
- **The hunk reads clean, so the review is done.** The hunk is where the author looked. A consumer, a doc a section away, and the commit that added a removed guard are not in it.
|
|
92
|
+
- **The checker passes on the branch.** Read the checker's config and the inline suppressions in the diff. A path excluded from the run passes by not being read.
|
|
93
|
+
- **It was split into smaller functions, so it is simpler.** Count the concepts a reader holds before and after. Moved complexity reads as simpler only to the person who moved it.
|
|
94
|
+
- **Nothing calls it, so deleting it is safe.** Read why it was added. Code nobody calls today can still be guarding a path nobody exercised in the change.
|
|
95
|
+
- **The description says it is faster.** A claimed speedup with no measurement, or one run each side, is asserted. Ask for runs that beat the noise.
|
|
96
|
+
- **The change only touches styles, so the screenshots can wait.** A stylesheet diff says what changed and only the image says what a user sees. Open them, or say none exist.
|
|
99
97
|
|
|
100
98
|
## Red flags
|
|
101
99
|
|
|
@@ -13,14 +13,16 @@ The `addyosmani/agent-skills` citations below all pin commit `addyosmani/agent-s
|
|
|
13
13
|
|
|
14
14
|
### Design and scope
|
|
15
15
|
|
|
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.
|
|
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. Each source below carries the step it backs.
|
|
17
17
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
- Ousterhout's deep modules, information hiding, and pass-through methods, [A Philosophy of Software Design](https://web.stanford.edu/~ouster/cgi-bin/book.php)
|
|
19
|
+
- Backs asking what each unit hides, and flagging a unit that passes its arguments straight through
|
|
20
|
+
- 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)
|
|
21
|
+
- Backs 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)
|
|
23
|
+
- Backs the one-place step, and matching each pattern to a problem the code has today
|
|
24
|
+
- 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)
|
|
25
|
+
- Backs the frame for the whole walk, and the reason a speculative abstraction is a finding
|
|
24
26
|
|
|
25
27
|
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.
|
|
26
28
|
|
|
@@ -55,7 +57,7 @@ From `skills/security-and-hardening/SKILL.md`, the threat model first and the de
|
|
|
55
57
|
|
|
56
58
|
### Closing sections
|
|
57
59
|
|
|
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
|
|
60
|
+
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 rebuts a reason a review stops at the hunk, such as passing tests against a test the diff skipped.
|
|
59
61
|
|
|
60
62
|
## Declined
|
|
61
63
|
|
|
@@ -33,6 +33,8 @@ Both headings anchor as a section distinct from human threads. The full set is e
|
|
|
33
33
|
| Evidence | `## Evidence` | `canon pr evidence`, through `pr-evidence` from `git-pr` and `git-followup` |
|
|
34
34
|
| UI | `## UI review`, `## UI review closed` | `review-ui`, posted as a review beside this one and read by nothing here |
|
|
35
35
|
|
|
36
|
+
Three notes qualify the table.
|
|
37
|
+
|
|
36
38
|
- 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
39
|
- `## 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
|
|
38
40
|
- A comment under any other heading reaches the poll as unclassified rather than as silence, so an invented ninth heading is a gap the next run reports
|
|
@@ -13,12 +13,14 @@ Test what `## Key changes` claims against the diff it describes, with `canon pr
|
|
|
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
15
|
|
|
16
|
-
| Field | Reading
|
|
17
|
-
| ------------ |
|
|
18
|
-
| `unmet` | a `should-fix` finding under the `**PR body**` block the stale box takes, one per path
|
|
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
|
|
16
|
+
| Field | Reading |
|
|
17
|
+
| ------------ | -------------------------------------------------------------------------------------- |
|
|
18
|
+
| `unmet` | a `should-fix` finding under the `**PR body**` block the stale box takes, one per path |
|
|
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
|
+
Each `unmet` finding quotes the `preview` bullet and the `head`.
|
|
22
24
|
|
|
23
25
|
### Before filing an unmet path
|
|
24
26
|
|
|
@@ -45,14 +45,16 @@ A taste box takes the shot twice, once per theme, naming the theme in the file a
|
|
|
45
45
|
|
|
46
46
|
## The four verdicts
|
|
47
47
|
|
|
48
|
-
Each box takes exactly one.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
Each box takes exactly one, keyed here by the state it answers.
|
|
49
|
+
|
|
50
|
+
- **pass or fail, read.** The result is a fact the page reports.
|
|
51
|
+
- The evidence is the value read, quoted, such as `scrollWidth 436 against clientWidth 320`.
|
|
52
|
+
- **pass or fail, frame.** The result has a stated criterion only an image settles.
|
|
53
|
+
- The evidence is the matching evidence stem or the pushed frame's link, inline under the failed box's heading, and what the frame shows, in words.
|
|
54
|
+
- **needs eyes.** The box ends in `(taste)`.
|
|
55
|
+
- The evidence is the dark and the light shot as a pair, each the matching evidence stem or a pushed frame's link, and what the frames showed, with nothing about whether it looks right.
|
|
56
|
+
- **not driven.** The state could not be reached.
|
|
57
|
+
- The evidence is the reason, such as an unreachable address, a `(local only)` box on a hosted preview, or a target the snapshot does not hold.
|
|
56
58
|
|
|
57
59
|
A fail names what was expected beside what was read. A not driven never reads as a fail, since it says the pass could not look rather than that the page is wrong. Its reason says whether the cause sits on the page or off it, since only a cause on the page opens the heading Step 7 picks.
|
|
58
60
|
|
|
@@ -9,10 +9,12 @@ Re-test every parked row as orchestrator. A blocker cell is a measurement taken
|
|
|
9
9
|
|
|
10
10
|
Two triggers start this pass, and they differ in scope rather than in procedure.
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
- **Sweep.** `orchestrator-sweep.md` sends the rows `canon tasks validate` listed untested.
|
|
13
|
+
- Scope: those rows alone, since a merge changes the tree under every parked row and the validator already re-took the two kinds it settles
|
|
14
|
+
- **Idle.** The session has nothing merged, workers building, and no pull request awaiting a first pass.
|
|
15
|
+
- Scope: every parked row, since no event narrowed them, plus every `backlog.md` row, which carries no blocker cell for the validator to name
|
|
16
|
+
|
|
17
|
+
Three points hold for both triggers.
|
|
16
18
|
|
|
17
19
|
- Neither trigger is a scheduler. `orchestrator-poll.md` owns the one recurring trigger, and a second loop firing into a static board is the always-on failure it warns about.
|
|
18
20
|
- The sweep asks which parked row to promote next, taking the blocker cell as read, and this pass asks whether the cell is still true
|
|
@@ -25,10 +25,14 @@ The third trigger reaches a window the first two cannot. A session with three wo
|
|
|
25
25
|
- Run `task-complete` to archive one the hook left in place
|
|
26
26
|
- A task whose outcomes are standing policy never closes, so hand it to a worker to encode the policy where it is enforced, then cut the outcomes with the reason and archive once that branch merges
|
|
27
27
|
- Encoding it from this session would write a tracked file, which `## Boundaries` in the skill body forbids
|
|
28
|
-
- An outcome marked `- [ ] Operator check: <outcome>` never blocks the archive
|
|
29
|
-
-
|
|
28
|
+
- An outcome marked `- [ ] Operator check: <outcome>` never blocks the archive, so leave it unticked
|
|
29
|
+
- The hook prints no record, so read the archived file's `Operator check:` lines into the report's `Operator checks:` line
|
|
30
|
+
- A merged task whose only open outcomes another repository owes, or that an operator owns and nobody marked, never archives, since `canon tasks archive` refuses `open-outcomes`
|
|
31
|
+
- Strike each one on the task file as `- ~~<outcome>~~ <reason>` with the reason on the same line, then archive. The task files are gitignored scratch, so this session may edit them.
|
|
30
32
|
- Strike only an outcome the operator or another repository owes. An open outcome this repository owes stays on the board, and the task stays with it.
|
|
31
|
-
- Send a struck outcome that another repository owes to that repository's orchestrator through `session-relay`, which resolves the address
|
|
33
|
+
- Send a struck outcome that another repository owes to that repository's orchestrator through `session-relay`, which resolves the address
|
|
34
|
+
- Let the receiver file it with `task-board` on its own board, since `task-board` here would file it on this board
|
|
35
|
+
- Name it in the report for the operator when no such session is live
|
|
32
36
|
- List every struck outcome in the report's `Struck:` line, so the work is carried by a named owner rather than lost to the strike
|
|
33
37
|
4. Read `.canon/tasks/priority.md` and count the `## Up next` rows whose `Waiting on` has cleared, since a blocked row is no reserve. `## Run now` is what is running, so keep one in reserve beyond it.
|
|
34
38
|
5. Promote from the top of `## Needs a plan`, where the last sweep recorded what to plan next.
|
|
@@ -69,6 +73,8 @@ Write `.canon/tasks/priority.md` through the `canon tasks` verbs alone, each rea
|
|
|
69
73
|
| A row up or down inside its group | `canon tasks move <stem> --before <stem>` |
|
|
70
74
|
| What a row waits on, or why it sits there | `canon tasks block <stem> "<reason>"` |
|
|
71
75
|
|
|
76
|
+
The points below govern writing the board through those verbs.
|
|
77
|
+
|
|
72
78
|
- `place` removes the task's backlog line in the same call, so a row never sits on both surfaces or on neither
|
|
73
79
|
- Demoting a row to `backlog.md` has no verb yet. Add the backlog line first, then delete the row with the file-editing tool, which errors on a non-match.
|
|
74
80
|
- Put the reason a row sits where it does in its Waiting on cell through `block`, since a row promoted with the cell left alone carries an order the next sweep cannot check
|
|
@@ -19,11 +19,11 @@ This body states the role, the reads, the boundaries, and the channel, and start
|
|
|
19
19
|
|
|
20
20
|
The session writes its comment and nothing tracked. Each kind of reviewer writes only these:
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
- **Code:** the comment through `review-pr` and the body file it names under `.canon/tmp/pr/review/`
|
|
23
|
+
- **UI:** the comment `review-ui` posts, its body file, and the browser's snapshots and frames under `.canon/tmp/pr/review-ui/`, plus `canon pr tick` on boxes it passed
|
|
24
|
+
- **Either:** the draft flag, through `canon pr lift` and no other way
|
|
25
|
+
|
|
26
|
+
The rules below close off everything else.
|
|
27
27
|
|
|
28
28
|
- A tracked file, a branch, a worktree, a board file, and a commit all sit outside what this session may touch
|
|
29
29
|
- Never enter a worktree or check the branch out. The pass reads a change, and a checkout is the first step toward editing it.
|
|
@@ -54,13 +54,11 @@ Read `${CLAUDE_SKILL_DIR}/references/adopted.md` only when extending this guidan
|
|
|
54
54
|
|
|
55
55
|
## Excuses and rebuttals
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
| I scoped it, so every result is in scope | The domain filter is not strict, so a scoped search can return results from outside its list. |
|
|
63
|
-
| The summary already answers it | A summary paraphrases. Fetch the page when two summaries disagree, since that is where the error sits. |
|
|
57
|
+
- **The model already knows the good sites.** It does, and it does not use that knowledge unprompted. Left to rank, a search puts guides written to rank above a field's reference pages.
|
|
58
|
+
- **One search was enough.** One search gives nothing to check a wrong fact against. The scoped search is what catches the open summary's error.
|
|
59
|
+
- **The open results look authoritative.** Ranking rewards pages written to rank, so advocates and thin guides sit beside the field's own record and tilt the summary.
|
|
60
|
+
- **I scoped it, so every result is in scope.** The domain filter is not strict, so a scoped search can return results from outside its list.
|
|
61
|
+
- **The summary already answers it.** A summary paraphrases. Fetch the page when two summaries disagree, since that is where the error sits.
|
|
64
62
|
|
|
65
63
|
## Red flags
|
|
66
64
|
|
|
@@ -73,6 +73,8 @@ Resolve `<type>` here too, since Step 3 previews it and Step 5 renames onto it,
|
|
|
73
73
|
| A plan, through tier 1 or tier 2 | The `type` field of `canon tasks plan-branch <plan> --json` |
|
|
74
74
|
| A branch, a bare user name, or anything else | `feat` |
|
|
75
75
|
|
|
76
|
+
The points below govern how the type is read.
|
|
77
|
+
|
|
76
78
|
- The verb is the reading because a type read off a plan's sections is a judgment two sessions can grade differently, and the verb answers the same for both
|
|
77
79
|
- Branch on the record rather than on the exit code, which a shell function wrapping `canon` can flatten to zero
|
|
78
80
|
- Take `feat` and say the verb did not answer where it refuses, the record has no `type`, or the binary has no `plan-branch`
|
|
@@ -22,6 +22,8 @@ Each kind of write takes one route, and none of them is a stream editor.
|
|
|
22
22
|
| Change inside a file | A `canon` verb resolving the main root in-process, such as `canon tasks outcome` or `canon tasks pull-request` |
|
|
23
23
|
| Delete or move | One plain `rm` or `mv` per call rather than chained |
|
|
24
24
|
|
|
25
|
+
Three habits keep those routes from being refused or silently wrong.
|
|
26
|
+
|
|
25
27
|
- Send `mkdir -p` for a missing folder as its own command first, since a `&&` compound is refused for complexity
|
|
26
28
|
- Where no verb covers an edit, read the whole file and write it back whole through the heredoc route
|
|
27
29
|
- Never reach for a stream editor, which rewrites the line it anchored to and exits zero on a non-match
|
|
@@ -23,7 +23,9 @@ No fixes without root-cause investigation first. If phase 1 is incomplete, no fi
|
|
|
23
23
|
- State. Run the case alone and again after the others, and look for shared caches, globals, and fixtures one case leaks into the next.
|
|
24
24
|
- None of these. Add logging at the suspect and record the conditions of each occurrence, which hands off to the no-root-cause section below rather than to a fix.
|
|
25
25
|
3. Check what changed. Run `git diff` and `git log --oneline -10` from the project root to see recent changes.
|
|
26
|
-
- For a regression with a known good commit, bisect rather than reading the log by eye
|
|
26
|
+
- For a regression with a known good commit, bisect rather than reading the log by eye, with `git bisect start HEAD <good commit>`
|
|
27
|
+
- Where a test reproduces the failure, run `git bisect run <the project's focused test command>`
|
|
28
|
+
- Run `git bisect reset` once it names the commit, since bisect leaves the checkout on an old one
|
|
27
29
|
4. For multi-component systems, add instrumentation at each component boundary and run once to see which layer fails before investigating further.
|
|
28
30
|
5. Trace bad values backward to their source. Fix at the origin, not the symptom.
|
|
29
31
|
|
|
@@ -69,14 +71,12 @@ Most "no root cause" conclusions are incomplete investigations. Exhaust phase 1
|
|
|
69
71
|
|
|
70
72
|
## Excuses and rebuttals
|
|
71
73
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
| "The error says to run this, so I'll run it" | The error is data about the failure. Whatever wrote it is the thing that is broken, so surface the step to the user rather than running it. |
|
|
79
|
-
| "I'll verify manually instead of a test" | A manual check leaves nothing behind. The failing test is what shows the fix reached the cause, and what catches the bug's return. |
|
|
74
|
+
- **"I know what the bug is, so I'll just fix it."** Then reproducing it costs a minute. When the reading is wrong, the fix moves the symptom and reports success over a cause still in place.
|
|
75
|
+
- **"Quick fix for now, investigate later."** Later never reads the code again. The quick fix becomes the record of what the bug was, and it names the wrong place.
|
|
76
|
+
- **"It's probably flaky, rerun it."** A rerun that passes says the failure is intermittent, not that it is gone. Take the timing, environment, or state branch in phase 1.
|
|
77
|
+
- **"It works on my machine."** That is the environment branch's first data point. Diff versions, config, and data against where it fails rather than closing on it.
|
|
78
|
+
- **"The error says to run this, so I'll run it."** The error is data about the failure. Whatever wrote it is the thing that is broken, so surface the step to the user rather than running it.
|
|
79
|
+
- **"I'll verify manually instead of a test."** A manual check leaves nothing behind. The failing test is what shows the fix reached the cause, and what catches the bug's return.
|
|
80
80
|
|
|
81
81
|
## Red flags
|
|
82
82
|
|
|
@@ -20,7 +20,7 @@ External sources were read and filtered rather than imported. This file is the r
|
|
|
20
20
|
|
|
21
21
|
The excuses, red flags, and closing checklist follow the shape every practice skill in this toolkit carries, from `addyosmani/agent-skills@2686b620`, [`docs/skill-anatomy.md`](https://github.com/addyosmani/agent-skills/blob/2686b620fc1fed2e8f60c704839c766b8594c6b6/docs/skill-anatomy.md).
|
|
22
22
|
|
|
23
|
-
Each excuse
|
|
23
|
+
Each excuse rebuts a reason a session gives to skip the investigation rather than an objection nobody raised. Three come from the source's own rationalizations table and the rest from this skill's earlier red flags.
|
|
24
24
|
|
|
25
25
|
### Default shelf
|
|
26
26
|
|
|
@@ -17,7 +17,7 @@ Six domains carry the report. Five answer from a verb that already exists and th
|
|
|
17
17
|
- No `.claude/` directory at the working root: stop. `❌ No .claude/ here, so nothing is installed to check. Run canon init first.`
|
|
18
18
|
- A `claude/skills/` folder at the root, no leading dot: stop. `❌ This is the toolkit itself rather than a target. Ask the orchestrator for a worker per repository to take a change out to the targets.`
|
|
19
19
|
- A target receives skills at `.claude/skills/` and authors none, so the spelling without the dot separates the source from what it installs into
|
|
20
|
-
-
|
|
20
|
+
- Prompt at no point, since every caller is a dispatched worker with nobody to answer. A call with no terminal on stdin already runs headless, so no command takes a prefix.
|
|
21
21
|
- Branch on each record's own fields rather than on an exit status. A shell function wrapping `canon` can report every refusal as success.
|
|
22
22
|
|
|
23
23
|
## Step 1: read the reports
|
|
@@ -25,25 +25,23 @@ Six domains carry the report. Five answer from a verb that already exists and th
|
|
|
25
25
|
Run these from the target root, in parallel:
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
canon sync --check . --json
|
|
29
|
+
canon context audit --json
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
The first answers five domains from one read, being `skew`, `domains`, `seeds`, `tooling`, and the layout fields `unmigrated`, `superseded`, `unmovedSurfaces`, and `reverse`. The second deepens a domain that first read only counts.
|
|
33
33
|
|
|
34
|
-
Then run `
|
|
34
|
+
Then run `canon records validate <kind> --json` once per record folder the target carries, taking `<kind>` from what is present under the record root rather than from a list held here.
|
|
35
35
|
|
|
36
36
|
### The tooling read takes a stack, always
|
|
37
37
|
|
|
38
38
|
The tooling comparison runs last, because it needs a value the first read returns. Take `<stack>` from the first name in the report's `tooling.chain`, which records the stack nearest the target, and pass it:
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
-
|
|
41
|
+
canon tooling sync --check <stack>
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
Refuse the domain and report it unread when `chain` names nothing, rather than running the command bare. A bare call reaches the stack prompt, which
|
|
45
|
-
|
|
46
|
-
Every target would then be compared against whichever stack sorts first, on every run, and the drift reported would be an artifact of the wrong comparison rather than anything the target did.
|
|
44
|
+
Refuse the domain and report it unread when `chain` names nothing, rather than running the command bare. A bare call reaches the stack prompt, which refuses a headless caller, so it would report nothing about the domain.
|
|
47
45
|
|
|
48
46
|
### Domains come from the report
|
|
49
47
|
|
|
@@ -72,10 +72,7 @@ Read the `tooling` block off the report first, because the comparison command ne
|
|
|
72
72
|
|
|
73
73
|
### The comparison
|
|
74
74
|
|
|
75
|
-
On a measured report, take `<stack>` from the first name in `chain` and run `canon tooling sync --check <stack>`. Never run it bare.
|
|
76
|
-
|
|
77
|
-
- Omitting the stack reaches a prompt the non-interactive variable resolves to the catalog's first entry rather than refusing
|
|
78
|
-
- That compares the target against a stack it does not use and reports the difference as drift
|
|
75
|
+
On a measured report, take `<stack>` from the first name in `chain` and run `canon tooling sync --check <stack>`. Never run it bare, since omitting the stack reaches a prompt that refuses a headless caller and compares nothing.
|
|
79
76
|
|
|
80
77
|
### Verdicts
|
|
81
78
|
|
|
@@ -33,9 +33,9 @@ rather than a step within it, so the full chain never runs it separately.
|
|
|
33
33
|
|
|
34
34
|
## Non-interactive path
|
|
35
35
|
|
|
36
|
-
Every phase runs
|
|
37
|
-
otherwise pause, and each takes an
|
|
38
|
-
time:
|
|
36
|
+
Every phase runs headless with no prefix, since a call with no terminal on
|
|
37
|
+
stdin is already headless. Three phases otherwise pause, and each takes an
|
|
38
|
+
argument that answers its prompt ahead of time:
|
|
39
39
|
|
|
40
40
|
| Phase | Pauses to | Answered ahead by | With neither and no TTY |
|
|
41
41
|
| ------------------- | ------------------------------------------ | ---------------------------------------------------------- | ----------------------------------------------------- |
|
|
@@ -91,7 +91,7 @@ target project's current directory. Do not cd into the toolkit source tree. The
|
|
|
91
91
|
Step 1: `canon init` installs base tooling, claude seeds, and governance rules.
|
|
92
92
|
|
|
93
93
|
```bash
|
|
94
|
-
|
|
94
|
+
canon init \
|
|
95
95
|
--stack <stack> \
|
|
96
96
|
--add <rules> \
|
|
97
97
|
<target>
|
|
@@ -106,7 +106,7 @@ Step 2: `canon tooling sync <tooling-stack> --write` installs stack deps, script
|
|
|
106
106
|
- A fresh target has nothing to lose, so pass `--write` directly rather than reading a report first
|
|
107
107
|
|
|
108
108
|
```bash
|
|
109
|
-
|
|
109
|
+
canon tooling sync <tooling-stack> <target> --write
|
|
110
110
|
```
|
|
111
111
|
|
|
112
112
|
### Monorepo with multiple language roots
|
|
@@ -114,8 +114,8 @@ CANON_NON_INTERACTIVE=1 canon tooling sync <tooling-stack> <target> --write
|
|
|
114
114
|
Run `canon init` once at the repo root so `base` (husky, oxfmt, commitlint, CI) lands once, then sync each subtree with `--skip base`. Take the subtree commands from the preview's per-root rows rather than picking folders by hand.
|
|
115
115
|
|
|
116
116
|
```bash
|
|
117
|
-
|
|
118
|
-
|
|
117
|
+
canon tooling sync vite-react ./frontend --skip base --write
|
|
118
|
+
canon tooling sync python ./backend --skip base --write
|
|
119
119
|
```
|
|
120
120
|
|
|
121
121
|
- Without `--skip base`, each subtree re-drops husky, and git honors only one `core.hooksPath`, so the extra hook dirs silently break
|
|
@@ -139,7 +139,7 @@ Resolve exactly as the detect reference states, confirm the proposed extras
|
|
|
139
139
|
there, then run:
|
|
140
140
|
|
|
141
141
|
```bash
|
|
142
|
-
|
|
142
|
+
canon gov install <stack> --add <extras> <target>
|
|
143
143
|
```
|
|
144
144
|
|
|
145
145
|
Report the rule count installed, the target path, and any rules that failed to
|
|
@@ -24,7 +24,7 @@ Stop with the line beside each state.
|
|
|
24
24
|
|
|
25
25
|
Then hold two rules for every verb this body runs.
|
|
26
26
|
|
|
27
|
-
- Run it
|
|
27
|
+
- Run it from the target root with no prefix, since a call with no terminal on stdin already runs headless
|
|
28
28
|
- Branch on its record's fields rather than its exit, which a shell function wrapping `canon` can flatten
|
|
29
29
|
|
|
30
30
|
## Step 1: bring the binary and plugin forward
|
|
@@ -38,12 +38,12 @@ Both write to the machine rather than the target, and the preview needs the verb
|
|
|
38
38
|
Run these in parallel from the target root:
|
|
39
39
|
|
|
40
40
|
```bash
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
canon changelog --json
|
|
42
|
+
canon migrate status --json
|
|
43
|
+
canon sync --check . --json
|
|
44
44
|
```
|
|
45
45
|
|
|
46
|
-
Then take `<stack>` from the first name in the report's `tooling.chain` and run `canon tooling diff <stack> . --json`. Never run it bare, since the stack prompt
|
|
46
|
+
Then take `<stack>` from the first name in the report's `tooling.chain` and run `canon tooling diff <stack> . --json`. Never run it bare, since the stack prompt refuses a headless caller. Report tooling unmeasured when `tooling.measured` is false or `chain` names nothing.
|
|
47
47
|
|
|
48
48
|
### When a read refuses
|
|
49
49
|
|
|
@@ -74,10 +74,8 @@ Write `.canon/tasks/vXX.Y-<slug>.md` under the claimed label, reading the file f
|
|
|
74
74
|
|
|
75
75
|
A task file with no row is a dropped task, so name its surface in the same pass that creates it. The test and both file shapes are in `${CLAUDE_SKILL_DIR}/references/board.md`.
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
| Plausibly planned within the next few waves | A row under `## Needs a plan` in `.canon/tasks/priority.md`, through `canon tasks place <stem> --group needs-a-plan --waiting "<reason>"` |
|
|
80
|
-
| Anything else | A line in `.canon/tasks/backlog.md`, which is unordered |
|
|
77
|
+
- A task plausibly planned within the next few waves takes a row under `## Needs a plan` in `.canon/tasks/priority.md`, through `canon tasks place <stem> --group needs-a-plan --waiting "<reason>"`.
|
|
78
|
+
- Any other task takes a line in `.canon/tasks/backlog.md`, which is unordered.
|
|
81
79
|
|
|
82
80
|
Position the row against its siblings with `--before <stem>` or `--after <stem>`, and state what it ranks against in the reason.
|
|
83
81
|
|