@erclx/canon 5.37.0 → 5.39.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 +1 -1
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/api-design/SKILL.md +12 -9
- package/claude/skills/auto-ship/SKILL.md +43 -23
- package/claude/skills/backlog-triage/SKILL.md +62 -53
- package/claude/skills/backlog-triage/references/apply.md +69 -0
- package/claude/skills/build-in-slices/SKILL.md +8 -4
- package/claude/skills/canon-cli/SKILL.md +5 -1
- package/claude/skills/canon-feedback/SKILL.md +18 -8
- package/claude/skills/canon-feedback-triage/SKILL.md +10 -3
- package/claude/skills/canvas-board/SKILL.md +36 -17
- package/claude/skills/ci-workflow/SKILL.md +5 -4
- package/claude/skills/code-craft/SKILL.md +10 -6
- package/claude/skills/codebase-layout/SKILL.md +3 -5
- package/claude/skills/context-fold/REQUIREMENT.md +4 -4
- package/claude/skills/context-fold/SKILL.md +42 -23
- package/claude/skills/context-fold/references/context-refresh.md +4 -3
- package/claude/skills/context-fold/references/context.md +79 -64
- package/claude/skills/create-rule/SKILL.md +7 -3
- package/claude/skills/create-skill/SKILL.md +27 -7
- package/claude/skills/create-skill/references/skill-reference.md +41 -17
- package/claude/skills/decision-escalate/SKILL.md +8 -5
- package/claude/skills/deploy-app/SKILL.md +1 -1
- package/claude/skills/deprecation-migration/SKILL.md +12 -4
- package/claude/skills/design-taste/SKILL.md +17 -11
- package/claude/skills/docs-sync/REQUIREMENT.md +1 -0
- package/claude/skills/docs-sync/SKILL.md +17 -6
- package/claude/skills/docs-sync/references/docs.md +54 -21
- package/claude/skills/docs-sync/references/readme.md +32 -8
- package/claude/skills/document-health/SKILL.md +3 -4
- package/claude/skills/draft-and-pick/SKILL.md +73 -47
- package/claude/skills/draft-doc/SKILL.md +9 -4
- package/claude/skills/draft-doc/references/context.md +4 -4
- package/claude/skills/draft-doc/references/docs.md +1 -0
- package/claude/skills/draft-doc/references/wiki.md +3 -2
- package/claude/skills/draft-figure/SKILL.md +9 -7
- package/claude/skills/draft-identity/SKILL.md +24 -52
- package/claude/skills/draft-identity/references/card-route.md +46 -0
- package/claude/skills/draft-ready/SKILL.md +19 -7
- package/claude/skills/draft-screencast/SKILL.md +6 -112
- package/claude/skills/draft-screencast/references/beats-template.md +119 -0
- package/claude/skills/draft-slides/SKILL.md +7 -4
- package/claude/skills/git-branch/SKILL.md +3 -3
- package/claude/skills/git-commit/SKILL.md +5 -3
- package/claude/skills/git-followup/SKILL.md +16 -9
- package/claude/skills/git-issue/SKILL.md +6 -5
- package/claude/skills/git-issue/references/issue.md +11 -10
- package/claude/skills/git-pr/SKILL.md +56 -44
- package/claude/skills/git-ship/SKILL.md +43 -34
- package/claude/skills/git-ship/references/ci-watch.md +31 -0
- package/claude/skills/git-split/SKILL.md +28 -100
- package/claude/skills/git-split/references/independent.md +40 -0
- package/claude/skills/git-split/references/stacked.md +73 -0
- package/claude/skills/git-stage/SKILL.md +9 -7
- package/claude/skills/git-worktree/SKILL.md +27 -49
- package/claude/skills/git-worktree/references/cleanup.md +55 -0
- package/claude/skills/markdown-craft/SKILL.md +2 -2
- package/claude/skills/markdown-craft/references/markdown.md +82 -52
- package/claude/skills/plan-feature/SKILL.md +52 -46
- package/claude/skills/plan-feature/references/batches.md +46 -0
- package/claude/skills/plan-groundwork/SKILL.md +60 -74
- package/claude/skills/plan-groundwork/references/groundwork.md +53 -24
- package/claude/skills/plan-groundwork/references/output.md +48 -0
- package/claude/skills/plan-intake/SKILL.md +28 -21
- package/claude/skills/plan-intake-answer/SKILL.md +14 -13
- package/claude/skills/read-frames/SKILL.md +2 -0
- package/claude/skills/record-screencast/SKILL.md +31 -11
- package/claude/skills/review-address/SKILL.md +76 -158
- package/claude/skills/review-address/references/rebase-only.md +34 -0
- package/claude/skills/review-craft/SKILL.md +27 -11
- package/claude/skills/review-pr/SKILL.md +91 -40
- package/claude/skills/review-pr/references/post.md +1 -1
- package/claude/skills/review-ui/SKILL.md +62 -37
- package/claude/skills/review-ui/references/hosted-preview.md +30 -0
- package/claude/skills/role-orchestrator/SKILL.md +105 -74
- package/claude/skills/role-orchestrator/references/orchestrator-filing.md +26 -0
- package/claude/skills/role-orchestrator/references/orchestrator-parked.md +1 -1
- package/claude/skills/role-planner/SKILL.md +66 -64
- package/claude/skills/role-reviewer/SKILL.md +57 -46
- package/claude/skills/role-worker/SKILL.md +68 -63
- package/claude/skills/search-craft/SKILL.md +7 -5
- package/claude/skills/session-compact/SKILL.md +16 -11
- package/claude/skills/session-map/SKILL.md +31 -10
- package/claude/skills/session-relay/SKILL.md +32 -65
- package/claude/skills/session-resume/SKILL.md +18 -13
- package/claude/skills/session-worktree/SKILL.md +70 -42
- package/claude/skills/systematic-debugging/SKILL.md +6 -1
- package/claude/skills/target-check/SKILL.md +13 -6
- package/claude/skills/target-setup/SKILL.md +41 -30
- package/claude/skills/target-setup/references/verify.md +6 -5
- package/claude/skills/task-board/SKILL.md +68 -60
- package/claude/skills/task-board/references/create-report.md +36 -0
- package/claude/skills/task-board/references/tasks.md +3 -1
- package/claude/skills/task-complete/SKILL.md +20 -18
- package/claude/skills/teach-workspace/SKILL.md +61 -33
- package/claude/skills/test-craft/SKILL.md +2 -1
- package/claude/skills/test-first/SKILL.md +15 -9
- package/claude/skills/ui-checklist/SKILL.md +18 -16
- package/claude/skills/ux-audit/SKILL.md +9 -10
- package/claude/skills/ux-measure/SKILL.md +22 -18
- package/claude/skills/video-craft/SKILL.md +15 -7
- package/claude/skills/write-human/SKILL.md +9 -1
- package/claude/skills/youtube-transcripts/SKILL.md +2 -1
- package/docs/agents/context-audit-checks.md +19 -1
- package/docs/agents/context-audit.md +2 -2
- package/docs/agents/driver.md +1 -1
- package/docs/agents/hooks.md +21 -1
- package/docs/agents/index.md +10 -14
- package/docs/agents/indexes.md +25 -29
- package/docs/agents/install-and-sync.md +124 -235
- package/docs/agents/markdown-audit-density.md +39 -0
- package/docs/agents/markdown-audit-weight.md +9 -7
- package/docs/agents/markdown-audit.md +18 -14
- package/docs/agents/migrate.md +41 -16
- package/docs/agents/output-shape.md +60 -45
- package/docs/agents/overview.md +36 -12
- package/docs/agents/routing.md +1 -1
- package/docs/agents/rule-citations.md +1 -1
- package/docs/agents/skills-reach.md +1 -1
- package/docs/agents/targets.md +25 -77
- package/docs/target/migrations.md +1 -1
- package/docs/target/projects.md +3 -3
- package/docs/target/scenarios.md +1 -1
- package/docs/workflow/ai-workflow.md +2 -2
- package/docs/workflow/parallel-features.md +2 -2
- package/docs/workflow/skill-map.md +1 -1
- package/docs/workflow/visual-design-workflow.md +1 -1
- package/governance/detect.toml +6 -1
- package/package.json +6 -3
- package/scripts/core/install-check.sh +1 -1
- package/src/commands/claude.ts +1 -2
- package/src/commands/context.ts +106 -7
- package/src/commands/hooks.ts +63 -0
- package/src/commands/markdown.ts +169 -32
- package/src/commands/pr.ts +1 -1
- package/src/commands/records.ts +0 -1
- package/src/context/audit.ts +256 -5
- package/src/context/classify/prompts.ts +1 -1
- package/src/context/gate.ts +23 -7
- package/src/context/shape-gated.ts +28 -0
- package/src/design/document.ts +1 -1
- package/src/design/tokens.ts +1 -1
- package/src/docs/read.ts +15 -21
- package/src/gate/measures.ts +15 -190
- package/src/gate/stages.ts +21 -23
- package/src/hooks/reply-links.ts +110 -0
- package/src/markdown/density.ts +258 -0
- package/src/markdown/gate.ts +57 -18
- package/src/markdown/reference-shape.ts +103 -0
- package/src/markdown/scope.ts +174 -0
- package/src/markdown/structure.ts +10 -60
- package/src/sandbox/equivalence.ts +7 -9
- package/src/shipped/references.ts +1 -1
- package/src/teach/browser/head.ts +2 -2
- package/src/teach/browser/sidebar.ts +3 -3
- package/src/teach/browser/theme.ts +2 -2
- package/src/tooling/inject.ts +2 -2
- package/src/tooling/package.ts +15 -18
- package/src/tooling/verify-stack.ts +6 -3
- package/tooling/astro/configs/.oxfmtrc.json +8 -0
- package/tooling/astro/configs/.prettierrc +13 -0
- package/tooling/astro/manifest.toml +13 -0
- package/tooling/astro/reference.md +15 -5
- package/tooling/base/configs/.oxfmtrc.json +7 -0
- package/tooling/base/configs/scripts/verify.ts +1 -1
- package/tooling/base/manifest.toml +6 -6
- package/tooling/base/reference.md +12 -9
- package/tooling/base/seeds/.lintstagedrc +1 -3
- package/tooling/base/seeds/canon/context/ci.md +3 -3
- package/tooling/base/seeds/canon/context/development.md +2 -2
- package/tooling/claude/manifest.toml +5 -1
- package/tooling/claude/seeds/.claude/hooks/reply-links.sh +72 -0
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +22 -1
- package/tooling/claude/seeds/.claude/settings.json +4 -0
- package/tooling/go/reference.md +2 -2
- package/tooling/nextjs/configs/.oxlintrc.json +223 -0
- package/tooling/nextjs/manifest.toml +2 -5
- package/tooling/nextjs/reference.md +4 -4
- package/tooling/php/manifest.toml +6 -1
- package/tooling/php/reference.md +2 -2
- package/tooling/python/manifest.toml +6 -1
- package/tooling/python/reference.md +4 -4
- package/tooling/vite-react/manifest.toml +1 -4
- package/tooling/vite-react/reference.md +3 -3
- package/tooling/web/configs/.oxlintrc.json +213 -0
- package/tooling/web/manifest.toml +9 -13
- package/tooling/web/reference.md +14 -14
- package/docs/agents/commands.md +0 -154
- package/docs/agents/docs.md +0 -27
- package/docs/agents/drift-surfaces.md +0 -201
- package/docs/agents/gov-detect.md +0 -47
- package/docs/agents/scripting.md +0 -142
- package/src/markdown/growth.ts +0 -43
- package/tooling/base/configs/.prettierrc +0 -12
- package/tooling/base/seeds/.prettierignore +0 -0
- package/tooling/nextjs/configs/eslint.config.js +0 -91
- package/tooling/web/configs/eslint.config.js +0 -82
package/README.md
CHANGED
|
@@ -164,7 +164,7 @@ Each domain carries an entry written for someone maintaining the toolkit rather
|
|
|
164
164
|
- [Claude Code plugin](canon/context/claude-plugin/index.md)
|
|
165
165
|
- [Governance rules](canon/context/governance/index.md)
|
|
166
166
|
- [Tooling stacks](canon/context/tooling/index.md)
|
|
167
|
-
- [Design system](canon/context/design
|
|
167
|
+
- [Design system](canon/context/design.md)
|
|
168
168
|
- [Slides](canon/context/features/slides.md)
|
|
169
169
|
- [Transcripts](canon/context/features/transcripts.md)
|
|
170
170
|
- [Sandbox](canon/context/sandbox/index.md)
|
|
@@ -7,18 +7,16 @@ metadata:
|
|
|
7
7
|
|
|
8
8
|
# API design
|
|
9
9
|
|
|
10
|
-
A session changing a surface sees the one caller it is working for
|
|
10
|
+
A session changing a surface sees the one caller it is working for, so it renames a field in place, returns whatever record it had in hand, and ships. Every caller it did not open breaks on the next release. This skill carries the judgment at the moment the surface is drawn.
|
|
11
11
|
|
|
12
|
-
Load it before changing anything a caller outside the module reads, whether code, a script parsing output, or a stored file
|
|
13
|
-
|
|
14
|
-
Skip it when the change stays behind an existing boundary and alters nothing a caller can observe.
|
|
12
|
+
Load it before changing anything a caller outside the module reads, whether code, a script parsing output, or a stored file, since a surface is cheap to shape before its first caller and expensive after. Skip it when the change alters nothing a caller can observe.
|
|
15
13
|
|
|
16
14
|
## Decide what a caller can observe
|
|
17
15
|
|
|
18
16
|
Every observable behavior becomes a dependency once there are enough callers, whatever the contract promises, which is Hyrum's Law. Decide what is observable, and expose nothing by accident.
|
|
19
17
|
|
|
20
18
|
- Return a shape built for the caller over the internal record you had in hand. A storage type, an internal identifier, or a field kept for bookkeeping becomes a contract the moment it ships.
|
|
21
|
-
- Treat ordering, timing, default values, and the exact text of an error or a log line as observable. Sort output on purpose or say it is unordered,
|
|
19
|
+
- Treat ordering, timing, default values, and the exact text of an error or a log line as observable. Sort output on purpose or say it is unordered, never in whatever order the data arrived.
|
|
22
20
|
- Keep the surface as small as the first caller needs. A field or flag added later is free, and one removed later breaks someone.
|
|
23
21
|
- Keep one name for one concept across every surface the project exposes. A caller learning `id` in one output and `key` in the next has to guess which is which.
|
|
24
22
|
|
|
@@ -31,7 +29,8 @@ Every observable behavior becomes a dependency once there are enough callers, wh
|
|
|
31
29
|
|
|
32
30
|
## Keep one error shape per surface
|
|
33
31
|
|
|
34
|
-
- Give every failure on one surface the same shape,
|
|
32
|
+
- Give every failure on one surface the same shape, a stable code a caller can branch on and a message for the person, since branching on message text breaks at the first rewording
|
|
33
|
+
- Keep internal implementation details out of the message, since a caller reads it and cannot act on a stack frame
|
|
35
34
|
- Reuse the error type the project already throws or returns where one exists, rather than inventing a second error convention beside it.
|
|
36
35
|
|
|
37
36
|
## Validate at the boundary
|
|
@@ -44,10 +43,10 @@ Every observable behavior becomes a dependency once there are enough callers, wh
|
|
|
44
43
|
## Change additively
|
|
45
44
|
|
|
46
45
|
- Add a field, a flag, or a parameter as optional, with a default that keeps the old behavior.
|
|
47
|
-
- Never rename or remove anything in place. Add the new name beside the old
|
|
46
|
+
- Never rename or remove anything in place. Add the new name beside the old, keep both working, and remove the old only once no caller reads it, proven through `deprecation-migration`.
|
|
48
47
|
- Never change what an existing field means or what type it carries. A new meaning takes a new name.
|
|
49
|
-
- When a caller cannot pin a version, such as a module
|
|
50
|
-
- Record each deprecation where a caller looks, naming the replacement and what happens next,
|
|
48
|
+
- When a caller cannot pin a version, such as a module one repository imports, keep one version live and migrate every caller in the change, the One-Version Rule. Two live versions split the callers.
|
|
49
|
+
- Record each deprecation where a caller looks, naming the replacement and what happens next, never only in a commit message. Whether and when to deprecate is `deprecation-migration`.
|
|
51
50
|
|
|
52
51
|
## Make a retried write safe
|
|
53
52
|
|
|
@@ -82,6 +81,8 @@ Read `${CLAUDE_SKILL_DIR}/references/adopted.md` only when extending this guidan
|
|
|
82
81
|
|
|
83
82
|
### Changes, retries, and order
|
|
84
83
|
|
|
84
|
+
Changes to an existing surface carry their own signs.
|
|
85
|
+
|
|
85
86
|
- An existing field is changing type or meaning under the same name.
|
|
86
87
|
- A write that a client could retry carries no key, or checks for one with a read before the insert.
|
|
87
88
|
- Output order follows whatever the underlying data returned, and nothing states whether it is sorted.
|
|
@@ -97,6 +98,8 @@ Check each line against the surface the change produced. A line answering no is
|
|
|
97
98
|
|
|
98
99
|
### Input, writes, and contract
|
|
99
100
|
|
|
101
|
+
Check the input and the contract the same way.
|
|
102
|
+
|
|
100
103
|
- Input is checked once, at the boundary, and nowhere deeper.
|
|
101
104
|
- Every write a caller could retry takes a key, claims it atomically, and refuses a reused key with a different body.
|
|
102
105
|
- The contract states what the surface returns and what it refuses.
|
|
@@ -12,45 +12,62 @@ Chain the post-plan pipeline in a single run. Every step but the UI checklist ha
|
|
|
12
12
|
## Guards
|
|
13
13
|
|
|
14
14
|
- All `.canon/plans/` reads resolve at the main worktree root, not the current worktree. Resolve that root the way `session-worktree` does.
|
|
15
|
-
- Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../git-branch/references/slug.md
|
|
15
|
+
- Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../git-branch/references/slug.md`, taking the stop over the `latest` fallback, since this skill opens a pull request
|
|
16
|
+
- If the slug is empty, stop: `❌ Detached HEAD. Checkout the feature branch first.`
|
|
16
17
|
- Resolve `<plan>` in Step 1, ahead of any other read.
|
|
17
18
|
- If the working tree has uncommitted changes unrelated to the plan, stop: `❌ Uncommitted changes outside the plan. Commit or stash before autoshipping.`
|
|
18
19
|
|
|
20
|
+
Treat that slug as provisional. Once `session-worktree` runs, at Step 0 or before this chain began, every later step keys on the worktree and branch it resolved, whichever plan Step 1 reads.
|
|
21
|
+
|
|
19
22
|
## Step 0: take the role, then enter a worktree
|
|
20
23
|
|
|
21
24
|
Invoke `canon:role-worker` first, whatever the worktree state. That skill states the boundaries, the lifetime, and the channel obligations of a session building one branch under one plan, and a dispatched worker reaches the role here and nowhere else. Report it rather than proceeding silently when `canon:role-worker` does not resolve.
|
|
22
25
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
If neither command resolves, stop: `❌ Not a git repository. Autoship needs git or a WorktreeCreate hook.`
|
|
26
|
+
Then compare `git rev-parse --git-dir` with `git rev-parse --git-common-dir`. The `session-worktree` wrapper handles branch alignment, so never call `EnterWorktree` directly.
|
|
26
27
|
|
|
27
|
-
|
|
28
|
+
| Reading | Route |
|
|
29
|
+
| ---------------- | ---------------------------------------------------------------------------------------------- |
|
|
30
|
+
| Equal | The main worktree, so invoke `canon:session-worktree` with the argument the subsection derives |
|
|
31
|
+
| Different | Already in a linked worktree, so continue |
|
|
32
|
+
| Neither resolves | Stop: `❌ Not a git repository. Autoship needs git or a WorktreeCreate hook.` |
|
|
28
33
|
|
|
29
34
|
### Name the worktree from the plan rather than leaving it to be derived
|
|
30
35
|
|
|
31
|
-
When the invocation argument is a plan path or a bare slug, name the worktree from `canon tasks plan-branch <argument> --json` rather than from a reading of the plan.
|
|
36
|
+
When the invocation argument is a plan path or a bare slug, name the worktree from `canon tasks plan-branch <argument> --json` rather than from a reading of the plan. A task path or no argument at all invokes `canon:session-worktree` bare.
|
|
37
|
+
|
|
38
|
+
Read `${CLAUDE_SKILL_DIR}/references/worktree-name.md` before invoking `canon:session-worktree`, for how each record shape reaches its tier 0 argument.
|
|
32
39
|
|
|
33
40
|
## Step 1: read the plan
|
|
34
41
|
|
|
35
|
-
Resolve `<plan>` in this order, stopping at the first match
|
|
42
|
+
Resolve `<plan>` in this order, stopping at the first match. Only a path reaches tier 1, and a bare slug is read as a plan's throughout, since the two would collide on any similar name.
|
|
43
|
+
|
|
44
|
+
1. **Caller-supplied task.** A path under `.canon/tasks/`. Take what its first `Plan:` line names, per `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md`, after reading `tier-failures.md`.
|
|
45
|
+
2. **Caller-supplied plan.** Anything else, a plan path or a bare slug, as `session-worktree` tier 0 takes it. A slug resolves to `.canon/plans/feature-<slug>.md`, and a path is taken from the main root.
|
|
46
|
+
3. **Derived.** `.canon/plans/feature-<slug>.md`, from the `<slug>` the Guards derived.
|
|
36
47
|
|
|
37
|
-
|
|
38
|
-
2. **Caller-supplied plan.** The invocation carried something else. Accept it as a plan path or a bare slug, in the same position `session-worktree` tier 0 accepts its name. A bare slug resolves to `.canon/plans/feature-<slug>.md`, and a path is taken as given from the main worktree root. If it does not resolve to a file, stop: `❌ No plan at <path>. Path was supplied, not derived, so check it and re-run.`
|
|
39
|
-
3. **Derived.** `.canon/plans/feature-<slug>.md`, from the `<slug>` the Guards derived. If it does not exist, stop: `❌ No approved plan at .canon/plans/feature-<slug>.md, where <slug> was derived from the current branch, <branch>. The invocation carried no argument, so pass a plan or a task path, or run /plan-feature first.`
|
|
48
|
+
Each tier stops with its own message on a file that does not resolve.
|
|
40
49
|
|
|
41
|
-
|
|
50
|
+
| Tier | Stop |
|
|
51
|
+
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
52
|
+
| Task | `❌ No task at <path>. Path was supplied, not derived, so check it and re-run.` |
|
|
53
|
+
| Plan | `❌ No plan at <path>. Path was supplied, not derived, so check it and re-run.` |
|
|
54
|
+
| Derived | `❌ No approved plan at .canon/plans/feature-<slug>.md, where <slug> was derived from the current branch, <branch>. The invocation carried no argument, so pass a plan or a task path, or run /plan-feature first.` |
|
|
42
55
|
|
|
43
56
|
### When a tier fails
|
|
44
57
|
|
|
45
58
|
Tier 1 stops on a `Plan:` line linking several plans, on a task carrying none, and on a pointer into a plans archive or to no file. `${CLAUDE_SKILL_DIR}/references/tier-failures.md` carries the stop each one takes and the order the archive and existence tests run in.
|
|
46
59
|
|
|
47
|
-
Test the
|
|
60
|
+
### Test the plan's shape
|
|
48
61
|
|
|
49
|
-
|
|
62
|
+
Test the shape of whatever `<plan>` resolved to before reading it, after all three tiers, since a file resolving under any tier can be the wrong document. Look for a `**Files to touch:**` or `## Files to touch` marker per `${CLAUDE_SKILL_DIR}/../plan-feature/references/plan.md`, which a plan always carries and a task never does.
|
|
50
63
|
|
|
51
|
-
|
|
64
|
+
If neither form is present, stop: `❌ <path> carries no plan sections. A plan lives at .canon/plans/feature-<slug>.md, and a task reaches one through its Plan: line only from .canon/tasks/. Point autoship at either and re-run.` Otherwise read `<plan>` at the main worktree root, which is the scope for this run.
|
|
52
65
|
|
|
53
|
-
|
|
66
|
+
### Unanswered questions
|
|
67
|
+
|
|
68
|
+
The plan's sections and answer contract are fixed by `${CLAUDE_SKILL_DIR}/../plan-feature/references/plan.md`. A blank `- Answer:` accepts the `- Suggested:` line above it, so an unanswered question is a decision this run executes rather than a reason to stop.
|
|
69
|
+
|
|
70
|
+
When this run decides against a suggestion, rewrite its line as `overridden at execution to <pick>,` plus the measurement, leaving `- Answer:` blank. Put the same deviation in one line under the open task's `## Findings`, opening with the bold source-and-date label `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md` fixes.
|
|
54
71
|
|
|
55
72
|
## Step 2: implement
|
|
56
73
|
|
|
@@ -73,7 +90,7 @@ Run `canon gov test-order --json` from the worktree this chain is building in, n
|
|
|
73
90
|
The verb reads git history rather than the working tree, so it catches a violation that already reached this branch's history in an earlier session or round. It reports and never gates, so branch on the record's `kind` and its `findings` array rather than on the exit, which a shell function wrapping `canon` can flatten to zero.
|
|
74
91
|
|
|
75
92
|
- `kind: 'measured'`, `findings` empty. Nothing on the branch reached history ahead of its test. Continue to Step 5.
|
|
76
|
-
- `kind: 'measured'`, `findings` non-empty. Report each pair's `subject` and `reason`
|
|
93
|
+
- `kind: 'measured'`, `findings` non-empty. Report each pair's `subject` and `reason` and continue to Step 5 without a fix, since a rewrite here rewrites what an earlier run shipped.
|
|
77
94
|
- `kind: 'unreadable'`. Report the `message` and continue to Step 5, since a shallow clone or a repository with no trunk is no reason to stop shipping.
|
|
78
95
|
|
|
79
96
|
### When the verb is absent
|
|
@@ -82,17 +99,22 @@ Never read a missing subcommand as clean. Read `${CLAUDE_SKILL_DIR}/references/v
|
|
|
82
99
|
|
|
83
100
|
## Step 5: UI checklist (conditional)
|
|
84
101
|
|
|
85
|
-
If the diff touches UI files (JSX, TSX, Vue, Svelte, HTML, or CSS under `src/`), invoke `canon:ui-checklist`, then continue to Step 6 whatever it returns, in every run. The Step 6 draft mark holds the merge, so a stop here protects nothing.
|
|
102
|
+
If the diff touches UI files (JSX, TSX, Vue, Svelte, HTML, or CSS under `src/`), invoke `canon:ui-checklist`, then continue to Step 6 whatever it returns, in every run. The Step 6 draft mark holds the merge, so a stop here protects nothing.
|
|
103
|
+
|
|
104
|
+
When it produces a checklist, read `${CLAUDE_SKILL_DIR}/references/ui-checklist.md` for the counts to hold before `git-pr` removes the file.
|
|
86
105
|
|
|
87
106
|
## Step 6: ship
|
|
88
107
|
|
|
89
108
|
Invoke `canon:git-ship`. That body owns the sequence, being the verify gate, both doc syncs, staging, the commit grouping, the branch rename, the pull request, and the CI watch, along with the reason each step sits where it does. Read the order there and never here.
|
|
90
109
|
|
|
91
|
-
|
|
110
|
+
### The draft mark
|
|
92
111
|
|
|
93
|
-
|
|
112
|
+
This chain adds one thing. Mark the pull request as a draft as soon as `git-ship`'s pull request step returns, ahead of its CI watch, naming the number that step returned rather than one resolved by branch.
|
|
94
113
|
|
|
95
|
-
|
|
114
|
+
- Read `${CLAUDE_SKILL_DIR}/references/draft-mark.md` on reaching that point for the one command that proves the target, marks it, and reads the flag back
|
|
115
|
+
- A `false` read stops the chain, and never re-issue the mark on it
|
|
116
|
+
- Emit the Output block on the wake after `git-ship`'s background CI watch exits on `passing`, not when the turn ends on its watch line
|
|
117
|
+
- Keep `git-ship`'s own verify gate, which repeats Step 3 on a clean run, since a resumed run enters at that gate
|
|
96
118
|
|
|
97
119
|
## Output
|
|
98
120
|
|
|
@@ -103,9 +125,7 @@ Respond with up to two lines:
|
|
|
103
125
|
🖼️ <N> visual boxes unchecked (<M> taste), owed on the evidence comment of <PR url> to the operator, or to the UI reviewer for the boxes a driver can run
|
|
104
126
|
```
|
|
105
127
|
|
|
106
|
-
`<state>` is whatever the Step 6 read returned, being `draft` or `ready, unsupervised`, rather than the state the mark asked for.
|
|
107
|
-
|
|
108
|
-
Fill the second line from the counts Step 5 held, and omit it when no checklist was produced.
|
|
128
|
+
`<state>` is whatever the Step 6 read returned, being `draft` or `ready, unsupervised`, rather than the state the mark asked for. Fill the second line from the counts Step 5 held, and omit it when no checklist was produced.
|
|
109
129
|
|
|
110
130
|
This block replaces the one `git-ship` closes on rather than following it, since emitting both reports one run twice and buries the state under a `✅ Shipped` that does not name it.
|
|
111
131
|
|
|
@@ -9,25 +9,37 @@ metadata:
|
|
|
9
9
|
|
|
10
10
|
A backlog only grows while nothing can decline a row. This pass reads every row against the current tree, files one verdict per row for the operator, and later applies what they approved.
|
|
11
11
|
|
|
12
|
-
The record is an ordinary intake folder at `.canon/intake/<nn>-backlog-triage
|
|
12
|
+
The record is an ordinary intake folder at `.canon/intake/<nn>-backlog-triage/`, so three sibling references bind it.
|
|
13
|
+
|
|
14
|
+
- `${CLAUDE_SKILL_DIR}/../plan-intake/references/intake.md`, read before writing any file in the folder, holds the item format, the frontmatter, the index shape, and the answer contract
|
|
15
|
+
- `${CLAUDE_SKILL_DIR}/../task-board/references/board.md`, read before applying, holds the backlog and the ordering file
|
|
16
|
+
- `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md`, read before applying, holds the `Declined:` line
|
|
13
17
|
|
|
14
18
|
## Guards
|
|
15
19
|
|
|
16
|
-
- Resolve `.canon/tasks/` and `.canon/intake/` at the main worktree root,
|
|
20
|
+
- Resolve `.canon/tasks/` and `.canon/intake/` at the main worktree root, from `git worktree list --porcelain | grep -m 1 '^worktree ' | cut -d' ' -f2-`, falling back to `pwd` outside git
|
|
17
21
|
- If `.canon/tasks/backlog.md` does not exist at that root, stop: `❌ No backlog at .canon/tasks/backlog.md. Nothing to triage.`
|
|
18
|
-
- Never fill a `You:` slot, and never read an empty one as agreement. Answering runs through `plan-intake-answer` or the operator's own edit
|
|
22
|
+
- Never fill a `You:` slot, and never read an empty one as agreement, so silence never decides a row. Answering runs through `plan-intake-answer` or the operator's own edit.
|
|
19
23
|
- Branch on each `canon` record's `ok` and `reason` rather than on the exit code, which a shell function wrapping `canon` can flatten to zero.
|
|
20
24
|
|
|
21
25
|
## Step 1: detect the phase
|
|
22
26
|
|
|
23
|
-
Run `canon intake list --json` and
|
|
27
|
+
Run `canon intake list --json` and read the newest folder by ordinal whose slug ends in `-backlog-triage`. Where the binary carries no such subcommand, stop and report it, since a second folder would strand the first and apply needs the same verb.
|
|
28
|
+
|
|
29
|
+
| State of the newest folder | Route |
|
|
30
|
+
| ----------------------------------------- | ---------------------------------------------------------------------------------------------------------- |
|
|
31
|
+
| None, or fully applied | Run the file phase |
|
|
32
|
+
| Unread above zero | Stop: `❌ <n> items in <slug> are unread. Run /canon:plan-intake-answer, then re-run this skill to apply.` |
|
|
33
|
+
| Malformed above zero | Stop: `❌ <n> items in <slug> carry no answer slot. Repair them in the cluster files before applying.` |
|
|
34
|
+
| Every item answered, some not yet applied | Run the apply phase |
|
|
24
35
|
|
|
25
|
-
|
|
26
|
-
- **Unread above zero.** Stop: `❌ <n> items in <slug> are unread. Run /canon:plan-intake-answer, then re-run this skill to apply.`
|
|
27
|
-
- **Malformed above zero.** Stop: `❌ <n> items in <slug> carry no answer slot. Repair them in the cluster files before applying.`
|
|
28
|
-
- **Every item answered, some not yet applied.** Run the apply phase.
|
|
36
|
+
### When an item counts as applied
|
|
29
37
|
|
|
30
|
-
|
|
38
|
+
Test each item rather than trusting a count, since a run can stop partway. An item apply skipped for an unreadable answer stays unapplied until the operator rewrites it.
|
|
39
|
+
|
|
40
|
+
- Its task has moved under `.canon/tasks/declined/` or `.canon/tasks/archive/`
|
|
41
|
+
- Its live task file carries a `## Findings` line naming the folder slug
|
|
42
|
+
- Its task file sits in none of the three folders and `backlog.md` no longer names it, since the dangling line is all apply has left to remove
|
|
31
43
|
|
|
32
44
|
## File phase
|
|
33
45
|
|
|
@@ -35,7 +47,7 @@ Writes only inside `.canon/intake/<nn>-backlog-triage/`, so it runs under any ro
|
|
|
35
47
|
|
|
36
48
|
### Step 2: claim the folder
|
|
37
49
|
|
|
38
|
-
Run `canon records ordinal intake backlog-triage --claim --json` and take its `name`. The verb creates the folder in the same act, so two sessions opening at once never share one. Where the
|
|
50
|
+
Run `canon records ordinal intake backlog-triage --claim --json` and take its `name`. The verb creates the folder in the same act, so two sessions opening at once never share one. Where the binary carries no such subcommand, report it and stop rather than picking an ordinal by hand.
|
|
39
51
|
|
|
40
52
|
### Step 3: read every row
|
|
41
53
|
|
|
@@ -45,33 +57,51 @@ A row whose link resolves to no file gets an item anyway, carrying `decline` and
|
|
|
45
57
|
|
|
46
58
|
### Step 4: measure each row
|
|
47
59
|
|
|
48
|
-
Measure every claim the task makes against the tree and `git log` during this pass
|
|
60
|
+
Measure every claim the task makes against the tree and `git log` during this pass, never carrying a figure from the task file forward, since it states what was true when filed. Name the commit the pass measured against in the overview body.
|
|
61
|
+
|
|
62
|
+
- Grep for the construct its defect names and count the sites
|
|
63
|
+
- Check whether each open outcome's behavior exists
|
|
64
|
+
- Search the log for a commit or pull request that shipped it under another task
|
|
49
65
|
|
|
50
|
-
|
|
66
|
+
For each row that reproduces, gather the evidence Step 5 reads, and record each piece that is absent as absent rather than inferring it.
|
|
51
67
|
|
|
52
|
-
|
|
68
|
+
- An issue, a run, or a person it bit, named in its origin line or `## Findings`
|
|
69
|
+
- A commit or pull request that worked around it rather than fixing it
|
|
70
|
+
- The shipped path a defect sits on, being a route or page users call, or a rule, seed, scaffold, or verb other repositories copy or run
|
|
53
71
|
|
|
54
72
|
### Step 5: pick the verdict
|
|
55
73
|
|
|
56
|
-
Keep and promote carry the burden of proof, and a defect that still exists does not meet it. A row filed against the tree nearly always
|
|
74
|
+
Keep and promote carry the burden of proof, and a defect that still exists does not meet it. A row filed against the tree nearly always reproduces, so a reproduction test alone keeps almost every row. A row earns keep or promote only by naming a cost or a reach from Step 4's evidence.
|
|
75
|
+
|
|
76
|
+
| Ground | What it takes |
|
|
77
|
+
| ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
78
|
+
| Cost | A wrong result this pass observed by running the verb or reading committed output, or an issue, run, person, or workaround commit it hit, not measured fixed |
|
|
79
|
+
| Reach | The defect sits on a shipped path, so everyone reaching it receives a wrong instruction, a broken or unbounded behavior, or a wrong output, hit or not |
|
|
80
|
+
|
|
81
|
+
A plausible cost names nothing. A row arguing what could go wrong off a shipped path, with no observed output and no hit, is declined however likely it sounds.
|
|
82
|
+
|
|
83
|
+
### What is not a reach
|
|
57
84
|
|
|
58
|
-
|
|
85
|
+
Three things are not a reach, and a row resting on one needs a cost instead.
|
|
59
86
|
|
|
60
|
-
-
|
|
61
|
-
-
|
|
87
|
+
- A missing feature on a shipped surface, which leaves the path working and adds a capability, a document kind, or guidance
|
|
88
|
+
- A defect that changes nothing a user or a target receives, such as dead code on a shipped path
|
|
89
|
+
- A defect that shows only in this repository's own config, workflows, scripts, or fixtures
|
|
62
90
|
|
|
63
|
-
A
|
|
91
|
+
A missing protection is a defect, not a missing feature, and is a reach. Read a row that way when the shipped path lacks a run-time bound, check, or guard, such as a limit, a timeout, or input validation, so it can fail, run unbounded, or return a wrong output.
|
|
64
92
|
|
|
65
|
-
A missing
|
|
93
|
+
A missing feature earns keep through the cost arm when a user asked for it in an issue or a report, or worked around its absence. A feature nobody asked for is declined, and neither a passing mention nor a request the project's own planning filed with no user behind it counts.
|
|
66
94
|
|
|
67
|
-
|
|
95
|
+
### The four verdicts
|
|
68
96
|
|
|
69
|
-
|
|
70
|
-
- **promote**: it qualifies for keep, and the thing it was waiting on has cleared, naming what cleared it.
|
|
71
|
-
- **archive**: every open outcome is measured shipped, naming the commit or pull request per outcome position.
|
|
72
|
-
- **decline**: anything else, including a defect that reproduces but names no cost and no reach, a defect the tree no longer holds, work superseded by another task, and a row whose argument rests only on its original filing.
|
|
97
|
+
Age is evidence in neither direction. An old hit reads the same as a new one, by whether the pass measures it as still able to recur.
|
|
73
98
|
|
|
74
|
-
|
|
99
|
+
| Verdict | When |
|
|
100
|
+
| ------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
|
101
|
+
| keep | The defect reproduces this pass, with a count or a path, and the row names a cost or a reach with its observation, hit, or shipped path |
|
|
102
|
+
| promote | It qualifies for keep, and what it was waiting on has cleared, naming what cleared it |
|
|
103
|
+
| archive | Every open outcome is measured shipped, naming the commit or pull request per outcome position |
|
|
104
|
+
| decline | Anything else, including a reproduction naming no cost or reach, a defect the tree no longer holds, superseded work, or the filing alone |
|
|
75
105
|
|
|
76
106
|
### Step 6: write the items
|
|
77
107
|
|
|
@@ -79,9 +109,9 @@ Write one item per row in the intake item format, one cluster file per domain th
|
|
|
79
109
|
|
|
80
110
|
- **`Problem:`** states what this pass measured, with the count, path, or commit behind it
|
|
81
111
|
- **`Fix:`** states what applying the verdict does to the board
|
|
82
|
-
- **`Worth it:`** names the cost or
|
|
112
|
+
- **`Worth it:`** names the cost or reach the verdict rests on in one clause, or says the row names neither. A `yes` or `later` alone carries no verdict.
|
|
83
113
|
- **`Open:`** reads `decline, archive, keep, or promote?` on every item
|
|
84
|
-
- **`Suggested:`** opens with exactly one
|
|
114
|
+
- **`Suggested:`** opens with exactly one verdict token, then the reason. An archive lists every outcome position it closes, as `archive 1, 3: shipped in #NNN`.
|
|
85
115
|
- **`Overlaps:`** names a live board task that already carries the work, where one does
|
|
86
116
|
- **`You:`** ships empty
|
|
87
117
|
|
|
@@ -89,42 +119,21 @@ Write `00-overview.md` last, per the intake standard, with the verdict counts by
|
|
|
89
119
|
|
|
90
120
|
## Apply phase
|
|
91
121
|
|
|
92
|
-
Writes the board and task files
|
|
122
|
+
Writes the board and task files, so it refuses when this session's name starts with `planner-` or `worker-`. Read the name from `canon sessions list --self --json` before writing anything, and stop: `❌ Apply writes the board, which the <role> role bans. Run it from an operator or orchestrator session.`
|
|
93
123
|
|
|
94
|
-
Every write here is a main-root write
|
|
124
|
+
A refused or failed read proceeds, since it is indistinguishable from a solo project running no named sessions. Every write here is a main-root write, so route a change inside an existing file the way `session-worktree` states, and report it rather than proceeding silently when that skill does not resolve.
|
|
95
125
|
|
|
96
126
|
### Step 7: read the answers
|
|
97
127
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
- An answer of `ok` takes the suggested verdict. A `suggested` that opens with no verdict token is malformed: report the item and skip it, never treating it as keep.
|
|
101
|
-
- An answer opening with a verdict token overrides the suggestion. An override to archive names its own outcome positions, and one that names none is reported and skipped.
|
|
102
|
-
- Any other answer, such as a free-text note, is reported and skipped. Never guess a verdict from prose.
|
|
103
|
-
- An item already applied, by the test in Step 1, is skipped silently, which is what makes a re-run write nothing twice.
|
|
128
|
+
Read `${CLAUDE_SKILL_DIR}/references/apply.md` on reaching this step, for how each answer reads, what each verdict runs, and how a refusal routes. The file phase skips it.
|
|
104
129
|
|
|
105
130
|
### Step 8: run each verdict
|
|
106
131
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
- **decline**: `canon tasks decline <stem> --reason "<reason>, backlog triage <slug> item <cluster>#<n>" --json`. The verb clears the backlog line.
|
|
110
|
-
- **decline on a missing file**: when the stem resolves to no file in `.canon/tasks/`, `declined/`, or `archive/`, the verb would refuse as `no-match`, so skip it. Drop the dangling line from `backlog.md` directly and report it as removed with no task behind it. Any other verdict on such an item is reported and skipped, since there is no file to keep, archive, or promote.
|
|
111
|
-
- **archive**: `canon tasks outcome <stem> --close <p> ... --json` for the named positions, then `canon tasks archive <stem> --json`. Outcomes already closed report as closed rather than refusing, so archive still runs. Archive leaves `backlog.md` alone, so drop the task's backlog line once it succeeds, then append the `## Findings` line naming the evidence to the archived file.
|
|
112
|
-
- **keep**: append the `## Findings` line naming what reproduced. The backlog line stays.
|
|
113
|
-
- **promote**: move the backlog line to the bottom of `## Needs a plan` in `.canon/tasks/priority.md`, with a `Waiting on` cell stating what cleared and ending in `last`, then append the `## Findings` line.
|
|
114
|
-
|
|
115
|
-
Write the `## Findings` line as `- <YYYY-MM-DD>, backlog triage <slug>: <verdict>, <evidence>`. It is the last write on every verdict with a task file behind it, since Step 1 reads it as applied and a line written ahead of a refused move would mark a row done that never moved.
|
|
116
|
-
|
|
117
|
-
Before any promote, check the roster the way `task-board` step 4 does: a live session in this repository whose name starts with `orchestrator-` and whose `sessionId` is not this one. When one is found, write the `## Findings` line but not `priority.md` or `backlog.md`, and message that session with the row and its cell so it places the row itself.
|
|
132
|
+
Run each verdict through the task verbs the reference names, writing the `## Findings` line last on every verdict with a task file behind it.
|
|
118
133
|
|
|
119
134
|
### Step 9: route on a refusal
|
|
120
135
|
|
|
121
|
-
Report every refusal on its item and continue
|
|
122
|
-
|
|
123
|
-
- `decline` refusing with `no-match`: the task already moved elsewhere. Report and skip. A missing-file item never reaches the verb, per Step 8.
|
|
124
|
-
- `outcome` refusing, or `archive` refusing with `open-outcomes`: the verdict named too few positions. Report the positions still open and leave the row on the backlog. Never retry with guessed positions.
|
|
125
|
-
- A promote whose row already sits in `priority.md`: report it, skip the move, and still write the `## Findings` line.
|
|
126
|
-
|
|
127
|
-
Close with `canon tasks validate --json` and report every finding it raises against a row this run touched. After a shell write under `.canon/tasks/`, regenerate the index with `canon indexes regen --no-stage --root <main-root> <main-root>/.canon/tasks/index.md`, since no hook fires on `Bash`.
|
|
136
|
+
Report every refusal on its item and continue, then close with `canon tasks validate --json`, per the reference.
|
|
128
137
|
|
|
129
138
|
## Output
|
|
130
139
|
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Backlog triage apply reference
|
|
3
|
+
description: How the apply phase of a backlog triage reads the operator's answers, runs each verdict through the task verbs, writes the findings line, and routes a refusal
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Backlog triage apply reference
|
|
7
|
+
|
|
8
|
+
Applies to Steps 7 through 9 of `backlog-triage`, the phase that writes the board and task files once every item in a `<nn>-backlog-triage` intake folder carries an answer. The role guard and the main-root write route stay in the skill body.
|
|
9
|
+
|
|
10
|
+
## Step 7: read the answers
|
|
11
|
+
|
|
12
|
+
Run `canon intake list <slug> --json` and read each item's `answer` and `suggested`. Never guess a verdict from prose.
|
|
13
|
+
|
|
14
|
+
| Answer | Reading |
|
|
15
|
+
| ------------------------------------------- | -------------------------------------------------------------------- |
|
|
16
|
+
| `ok` | Takes the suggested verdict |
|
|
17
|
+
| `ok` on a `suggested` opening with no token | Malformed, so report the item and skip it, never treating it as keep |
|
|
18
|
+
| Opens with a verdict token | Overrides the suggestion |
|
|
19
|
+
| An archive override naming no positions | Reported and skipped |
|
|
20
|
+
| Any other answer, such as a free-text note | Reported and skipped |
|
|
21
|
+
|
|
22
|
+
An item already applied, by the test in the skill's Step 1, is skipped silently, which is what makes a re-run write nothing twice.
|
|
23
|
+
|
|
24
|
+
## Step 8: run each verdict
|
|
25
|
+
|
|
26
|
+
Take the task stem from the item heading. Every verdict leaves the folder slug on its task, which is how Step 1 and `task-board`'s unlinked-origin scan both see the folder as acted on.
|
|
27
|
+
|
|
28
|
+
| Verdict | Command and board write |
|
|
29
|
+
| ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
30
|
+
| decline | `canon tasks decline <stem> --reason "<reason>, backlog triage <slug> item <cluster>#<n>" --json`, which clears the backlog line |
|
|
31
|
+
| archive | `canon tasks outcome <stem> --close <p> ... --json` for the named positions, then `canon tasks archive <stem> --json` |
|
|
32
|
+
| keep | Append the `## Findings` line naming what reproduced, leaving the backlog line |
|
|
33
|
+
| promote | Move the backlog line to the bottom of `## Needs a plan` in `.canon/tasks/priority.md`, its `Waiting on` cell stating what cleared and ending in `last` |
|
|
34
|
+
|
|
35
|
+
### Archive and missing files
|
|
36
|
+
|
|
37
|
+
An archive treats outcomes already closed as closed rather than refusing, so it still runs. Archive leaves `backlog.md` alone, so drop the task's backlog line once it succeeds, then append the `## Findings` line naming the evidence to the archived file.
|
|
38
|
+
|
|
39
|
+
A decline whose stem resolves to no file in `.canon/tasks/`, `declined/`, or `archive/` would refuse as `no-match`, so skip the verb. Drop the dangling line from `backlog.md` directly and report it as removed with no task behind it. Any other verdict on such an item is reported and skipped, since there is no file to act on.
|
|
40
|
+
|
|
41
|
+
### The findings line
|
|
42
|
+
|
|
43
|
+
Write it as `- **<YYYY-MM-DD>, backlog triage <slug>:** <verdict>, <evidence>`, the bold label form `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md` fixes. It is the last write on every verdict with a task file behind it.
|
|
44
|
+
|
|
45
|
+
Step 1 reads the line as applied, so a line written ahead of a refused move would mark a row done that never moved.
|
|
46
|
+
|
|
47
|
+
### Promote and a live orchestrator
|
|
48
|
+
|
|
49
|
+
Before any promote, check the roster the way `task-board` step 4 does, for a live session in this repository whose name starts with `orchestrator-` and whose `sessionId` is not this one.
|
|
50
|
+
|
|
51
|
+
When one is found, write the `## Findings` line but not `priority.md` or `backlog.md`, and message that session with the row and its cell so it places the row itself.
|
|
52
|
+
|
|
53
|
+
## Step 9: route on a refusal
|
|
54
|
+
|
|
55
|
+
Report every refusal on its item and continue with the rest, since one row's refusal says nothing about another's.
|
|
56
|
+
|
|
57
|
+
| Refusal | Route |
|
|
58
|
+
| ----------------------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
59
|
+
| `decline` with `no-match` | The task already moved elsewhere, so report and skip |
|
|
60
|
+
| `outcome` refusing, or `archive` with `open-outcomes` | Too few positions named, so report those still open and leave the row, never guessing |
|
|
61
|
+
| A promote whose row already sits in `priority.md` | Report it, skip the move, and still write the `## Findings` line |
|
|
62
|
+
|
|
63
|
+
A missing-file item never reaches the verb, per Step 8.
|
|
64
|
+
|
|
65
|
+
### Closing the run
|
|
66
|
+
|
|
67
|
+
Close with `canon tasks validate --json` and report every finding it raises against a row this run touched.
|
|
68
|
+
|
|
69
|
+
After a shell write under `.canon/tasks/`, regenerate the index with `canon indexes regen --no-stage --root <main-root> <main-root>/.canon/tasks/index.md`, since no hook fires on `Bash`.
|
|
@@ -7,9 +7,9 @@ metadata:
|
|
|
7
7
|
|
|
8
8
|
# Build in slices
|
|
9
9
|
|
|
10
|
-
A session handed a plan tends to build all of it in one pass and test at the end. The diff grows past what anyone can read, a
|
|
10
|
+
A session handed a plan tends to build all of it in one pass and test at the end. The diff grows past what anyone can read, a late failure could have come from any change, and nothing in history marks a point that worked.
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
A defect it notices on the way gets fixed in the same diff, so the review reads two changes as one. This skill keeps each step small enough to verify and revert on its own. Load it before implementing a plan with more than one behavior or file, and skip it for one behavior in one place.
|
|
13
13
|
|
|
14
14
|
## Run the cycle per slice
|
|
15
15
|
|
|
@@ -26,7 +26,7 @@ Leave the build passing at every commit. A slice that cannot pass on its own is
|
|
|
26
26
|
|
|
27
27
|
- Prefer one path through every layer it needs, end to end, over one whole layer at a time. A finished path proves the layers fit, and a finished layer proves nothing until the next one meets it.
|
|
28
28
|
- Take the riskiest or least certain piece first. When it fails, the slices that would have rested on it are not built yet.
|
|
29
|
-
- Build the contract first when two sides are written against it, such as a command and the skill
|
|
29
|
+
- Build the contract first when two sides are written against it, such as a command and the skill calling it, or a format and its reader. Commit it as its own slice, then each side.
|
|
30
30
|
- Read the plan's file list as the scope of the whole branch, not as the order. Cut the order from the three rules above.
|
|
31
31
|
|
|
32
32
|
## Keep each commit safe to revert on its own
|
|
@@ -40,7 +40,7 @@ Leave the build passing at every commit. A slice that cannot pass on its own is
|
|
|
40
40
|
|
|
41
41
|
A defect outside the plan that turns up mid-build is a finding, not a slice. Fixing it on this branch widens a diff the plan scoped and hides the fix inside an unrelated review.
|
|
42
42
|
|
|
43
|
-
- Write it
|
|
43
|
+
- Write it as one line under the task's `## Findings`, naming the file and the fault when the build closes a task, opening with the label `${CLAUDE_SKILL_DIR}/../task-board/references/tasks.md` fixes
|
|
44
44
|
- Carry it in the handover message instead when no task exists, and never create a file to hold it.
|
|
45
45
|
- Leave the file as it is, even when the fix is one line.
|
|
46
46
|
- Fix it here only when the plan's own change cannot pass without it, and then say so in the commit that does.
|
|
@@ -74,6 +74,8 @@ Read `${CLAUDE_SKILL_DIR}/references/adopted.md` only when extending this guidan
|
|
|
74
74
|
|
|
75
75
|
### Scope and ordering
|
|
76
76
|
|
|
77
|
+
Scope and order carry their own signs.
|
|
78
|
+
|
|
77
79
|
- You opened a file the plan does not name and are about to edit it.
|
|
78
80
|
- A commit deletes code and adds its replacement in the same change.
|
|
79
81
|
- You are about to stage a test in a commit after the one that added its code.
|
|
@@ -89,6 +91,8 @@ Check each line against the branch the build produced. A line answering no is fi
|
|
|
89
91
|
|
|
90
92
|
### Tree and scope
|
|
91
93
|
|
|
94
|
+
Check the tree and the scope the same way.
|
|
95
|
+
|
|
92
96
|
- The working tree holds no uncommitted implementation work.
|
|
93
97
|
- Every file changed is in the plan's scope, or its commit says why the plan needed it.
|
|
94
98
|
- Every defect noticed outside the plan is written in the task's findings or the handover, and its file is unchanged.
|
|
@@ -88,6 +88,8 @@ Read the doc each line names before running one of these. `canon docs install-an
|
|
|
88
88
|
|
|
89
89
|
### Design, migrate, and indexes
|
|
90
90
|
|
|
91
|
+
Three more verbs rewrite files in place.
|
|
92
|
+
|
|
91
93
|
- `canon design sync` replaces the shipped design files and leaves `.claude/design/project/` alone.
|
|
92
94
|
- `canon migrate --write` rewrites files that cite a retired name or layout. It reports and writes nothing without the flag. See `canon docs migrate`.
|
|
93
95
|
- `canon indexes regen` rewrites each generated `index.md` from the folder's current state, so a hand edit there is lost. See `canon docs indexes`.
|
|
@@ -96,4 +98,6 @@ Read the doc each line names before running one of these. `canon docs install-an
|
|
|
96
98
|
|
|
97
99
|
## Source of truth
|
|
98
100
|
|
|
99
|
-
- `canon docs install-and-sync` states what each install and sync verb writes, refuses, or leaves alone
|
|
101
|
+
- `canon docs install-and-sync` states what each install and sync verb writes, refuses, or leaves alone
|
|
102
|
+
- `canon docs indexes` and `canon docs migrate` state the same for their verbs
|
|
103
|
+
- When a doc and this skill disagree, the doc wins
|