@erclx/canon 5.49.0 → 5.51.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 +4024 -0
- package/claude/.claude-plugin/plugin.json +1 -1
- package/claude/skills/auto-ship/references/fan-in.md +20 -6
- package/claude/skills/canon-cli/SKILL.md +9 -7
- package/claude/skills/canvas-board/REQUIREMENT.md +4 -3
- package/claude/skills/canvas-board/SKILL.md +8 -9
- package/claude/skills/ci-workflow/REQUIREMENT.md +3 -3
- package/claude/skills/ci-workflow/SKILL.md +26 -1
- package/claude/skills/ci-workflow/references/workflows.md +28 -0
- package/claude/skills/context-fold/references/context.md +4 -3
- package/claude/skills/design-record/REQUIREMENT.md +33 -0
- package/claude/skills/design-record/SKILL.md +84 -0
- package/claude/skills/design-record/references/folder.md +69 -0
- package/claude/skills/design-taste/SKILL.md +3 -2
- package/claude/skills/git-followup/SKILL.md +1 -0
- package/claude/skills/git-pr/references/pr.md +1 -1
- package/claude/skills/markdown-craft/REQUIREMENT.md +1 -0
- package/claude/skills/markdown-craft/SKILL.md +6 -1
- package/claude/skills/markdown-craft/references/markdown.md +3 -3
- package/claude/skills/markdown-craft/references/tables.md +30 -0
- package/claude/skills/pick-by-eye/SKILL.md +10 -8
- package/claude/skills/plan-feature/SKILL.md +13 -1
- package/claude/skills/plan-feature/references/batches.md +1 -1
- package/claude/skills/session-worktree/SKILL.md +1 -1
- package/claude/skills/target-check/references/domains.md +8 -6
- package/docs/agents/index.md +2 -2
- package/docs/agents/markdown-audit.md +5 -2
- package/docs/agents/migrate.md +2 -0
- package/docs/agents/targets.md +8 -1
- package/docs/target/migrations.md +8 -1
- package/docs/target/projects.md +1 -1
- package/docs/workflow/parallel-features.md +1 -1
- package/docs/workflow/skill-map.md +2 -1
- package/docs/workflow/visual-design-workflow.md +2 -1
- package/governance/detect.toml +1 -1
- package/governance/ledger/tooling/ci-workflow.md +6 -0
- package/governance/ledger/ui/design-reference.md +8 -12
- package/governance/rules/tooling/ci-workflow.md +4 -0
- package/governance/rules/ui/design-reference.md +4 -6
- package/package.json +2 -1
- package/scripts/ci/check-browsers.sh +13 -0
- package/scripts/ci/delete-previews.sh +34 -0
- package/scripts/ci/publish-check.sh +29 -0
- package/scripts/ci/refresh-frames-pr.sh +63 -0
- package/scripts/ci/report-baseline.sh +23 -0
- package/scripts/ci/stack-issues.sh +24 -0
- package/scripts/ci/verify-npm-token.sh +14 -0
- package/src/claude/cases/misc.ts +5 -0
- package/src/cli/help.ts +1 -0
- package/src/cli.ts +2 -0
- package/src/commands/changelog.ts +146 -0
- package/src/commands/claude.ts +26 -1
- package/src/commands/gate.ts +57 -16
- package/src/commands/hooks.ts +7 -5
- package/src/commands/markdown.ts +98 -19
- package/src/commands/migrate.ts +77 -0
- package/src/commands/worktrees.ts +273 -0
- package/src/context/audit.ts +6 -5
- package/src/design/budget.ts +1 -1
- package/src/design/components.ts +1 -1
- package/src/design/document.ts +1 -1
- package/src/design/regen.ts +1 -1
- package/src/design/render.ts +1 -1
- package/src/gate/hand-suite.ts +52 -0
- package/src/gate/measures.ts +9 -2
- package/src/gate/sequencer.ts +17 -8
- package/src/gov/detect.ts +28 -10
- package/src/hooks/post-merge.ts +45 -6
- package/src/markdown/gated.ts +5 -7
- package/src/markdown/scope.ts +60 -10
- package/src/markdown/structure.ts +1 -1
- package/src/markdown/tables.ts +150 -0
- package/src/migrate/status.ts +128 -0
- package/src/tasks/validate.ts +15 -12
- package/src/version/changelog.ts +156 -0
- package/src/worktrees/members.ts +540 -0
- package/tooling/base/configs/.husky/post-merge +7 -6
- package/tooling/claude/reference.md +1 -0
- package/tooling/claude/seeds/.claude/hooks/standards-audit.sh +11 -1
- package/tooling/claude/seeds/CLAUDE.md +9 -0
- package/tooling/cloudflare/configs/.github/workflows/deploy.yml +10 -28
- package/tooling/cloudflare/configs/scripts/delete-previews.sh +36 -0
- package/tooling/cloudflare/reference.md +7 -4
- package/tooling/web/reference.md +5 -0
- package/tooling/web/seeds/canon/design/index.md +23 -0
- /package/claude/skills/{canvas-board → design-record}/references/design.md +0 -0
|
@@ -48,12 +48,26 @@ Continue Step 2 with the integrator plan's own `**Files to touch:**`, then the r
|
|
|
48
48
|
|
|
49
49
|
### What the pull request carries
|
|
50
50
|
|
|
51
|
-
Say in the pull request body that each member is one merge commit and name the members
|
|
51
|
+
Say in the pull request body that each member is one merge commit, and name the members on one line in `## Summary`, backticked, in merge order:
|
|
52
52
|
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
git worktree remove <member worktree>
|
|
56
|
-
git branch -D <member branch>
|
|
53
|
+
```markdown
|
|
54
|
+
Fan-in members: `feat/a`, `feat/b`, `feat/c`
|
|
57
55
|
```
|
|
58
56
|
|
|
59
|
-
|
|
57
|
+
The line names branches rather than plan stems, since the branch is what gets deleted. Nothing outside it is read, so a branch named in prose elsewhere in the body is never a candidate.
|
|
58
|
+
|
|
59
|
+
### After the merge
|
|
60
|
+
|
|
61
|
+
The post-merge hook runs `canon worktrees retire-members` for each merged pull request number, and the verb deletes each member's branch on origin, its worktree, and its local branch. No session runs a step.
|
|
62
|
+
|
|
63
|
+
No member opens a pull request, so neither head-branch deletion nor `canon worktrees reclaim` ever reads one as merged. The member line is what reaches them.
|
|
64
|
+
|
|
65
|
+
- A member half goes only when its tip is an ancestor of the integrator's merged head, so a commit added after the merge keeps that half
|
|
66
|
+
- A worktree a live session holds, or one with uncommitted work, stays with its local branch
|
|
67
|
+
- A line naming the trunk, the integrator's own branch, or a branch with an open pull request deletes nothing
|
|
68
|
+
|
|
69
|
+
Run the verb by hand for a merge the hook missed, reading the dry run first:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
canon worktrees retire-members --pull-request <number> --dry-run
|
|
73
|
+
```
|
|
@@ -18,13 +18,15 @@ Consult to pick the `canon` verb for a job, and before running a verb that write
|
|
|
18
18
|
|
|
19
19
|
## Project setup
|
|
20
20
|
|
|
21
|
-
| Job | Verb
|
|
22
|
-
| -------------------------------------------- |
|
|
23
|
-
| Bootstrap a project with toolkit domains | `canon init`
|
|
24
|
-
| Bring every installed domain current | `canon sync`
|
|
25
|
-
| Reinstall the CLI itself | `canon upgrade`
|
|
26
|
-
| Move a project off a retired name or layout | `canon migrate`
|
|
27
|
-
|
|
|
21
|
+
| Job | Verb |
|
|
22
|
+
| -------------------------------------------- | ---------------------- |
|
|
23
|
+
| Bootstrap a project with toolkit domains | `canon init` |
|
|
24
|
+
| Bring every installed domain current | `canon sync` |
|
|
25
|
+
| Reinstall the CLI itself | `canon upgrade` |
|
|
26
|
+
| Move a project off a retired name or layout | `canon migrate` |
|
|
27
|
+
| Read what a project still needs to migrate | `canon migrate status` |
|
|
28
|
+
| Read the releases since a target's install | `canon changelog` |
|
|
29
|
+
| List the projects the toolkit installed into | `canon targets` |
|
|
28
30
|
|
|
29
31
|
## Domains
|
|
30
32
|
|
|
@@ -9,7 +9,7 @@ description: Scope boundary for driving the local design canvas, and the line be
|
|
|
9
9
|
|
|
10
10
|
Without this skill, a session asked to draw on the canvas writes frames nothing is serving and reports them drawn. It trusts a passing capture, though a blank shell passes every capture while the operator sees an empty tab. From a linked worktree it writes a copy the canvas never serves, and it captures after every edit.
|
|
11
11
|
|
|
12
|
-
It reads "this one" from the conversation rather than the operator's selection, or acts on a stale element pick and edits the wrong element. It restyles through a class while the operator's inspector edit sits inline, so the change never shows. A picked frame stays on the canvas as the only record, and the design
|
|
12
|
+
It reads "this one" from the conversation rather than the operator's selection, or acts on a stale element pick and edits the wrong element. It restyles through a class while the operator's inspector edit sits inline, so the change never shows. A picked frame stays on the canvas as the only record, and the project's design record never learns it.
|
|
13
13
|
|
|
14
14
|
## Must
|
|
15
15
|
|
|
@@ -17,7 +17,7 @@ It reads "this one" from the conversation rather than the operator's selection,
|
|
|
17
17
|
- Pages and frames go through the verbs, so the session and the operator's drags share one writer, and a frame from a linked worktree takes the main-root route
|
|
18
18
|
- The operator's selection decides what "this one" means, and a stale element pick reads as unknown
|
|
19
19
|
- A frame's inline styles are read before a restyle, the run names which operator edits it kept and dropped, and capture runs once per finished frame or page
|
|
20
|
-
- A picked
|
|
20
|
+
- A picked frame is handed to `design-record` by page and frame, while a picked layout stays on the canvas for the plan that builds it
|
|
21
21
|
|
|
22
22
|
## Must not
|
|
23
23
|
|
|
@@ -31,4 +31,5 @@ It reads "this one" from the conversation rather than the operator's selection,
|
|
|
31
31
|
- Drafting candidates for a taste decision and taking the pick, which `pick-by-eye` owns
|
|
32
32
|
- What the canvas verbs do internally, which the CLI's own contract owns
|
|
33
33
|
- The content format a frame and a layout take, which the canvas standard owns
|
|
34
|
-
-
|
|
34
|
+
- Landing a pick in the reference folder and carrying its values into the design document, which `design-record` owns
|
|
35
|
+
- Tracing reference images into design values and backing up the canvas folder, which no skill owns
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: canvas-board
|
|
3
|
-
description: Drives the local design canvas, where pages hold HTML frames the operator sees, drags, selects, and edits in the browser. Starts the canvas when it is not running, confirms the live shell loads, makes pages and frames, edits a frame through its file, reads what the operator selected or restyled, captures finished frames, and
|
|
3
|
+
description: Drives the local design canvas, where pages hold HTML frames the operator sees, drags, selects, and edits in the browser. Starts the canvas when it is not running, confirms the live shell loads, makes pages and frames, edits a frame through its file, reads what the operator selected or restyled, captures finished frames, and hands a picked frame to `design-record`. Use when asked to "open the canvas", "put this on the canvas", "draw a frame for X", "change the one I selected", "what did I pick", "capture this frame", or "move that frame on the canvas". Do NOT use to draft candidates for a taste decision, which is `pick-by-eye`.
|
|
4
4
|
metadata:
|
|
5
5
|
family: decide
|
|
6
6
|
---
|
|
@@ -16,7 +16,7 @@ Every verb below is `canon canvas`. Run `canon canvas --help` for the verbs and
|
|
|
16
16
|
- If `canon` is not on PATH, stop: `❌ canon CLI not found.`
|
|
17
17
|
- If `canon canvas --help` reports no such command, stop: `❌ The installed canon carries no canvas command. Update the CLI and re-run.`
|
|
18
18
|
- Write no frame before the canvas is serving and the shell has loaded. A frame nobody can see is a draft reported as delivered.
|
|
19
|
-
- Never present a frame as the project's design. The canvas is a drafting surface and the project's design
|
|
19
|
+
- Never present a frame as the project's design. The canvas is a drafting surface and the project's design record holds what was decided.
|
|
20
20
|
- Never promise the canvas survives a lost checkout. Its folder is gitignored and nothing backs it up.
|
|
21
21
|
|
|
22
22
|
## Step 1: start the canvas and confirm the shell
|
|
@@ -122,13 +122,12 @@ Capture once per finished frame or page, not after every edit. The live canvas i
|
|
|
122
122
|
|
|
123
123
|
A capture refused because a font is not installed names the family it read off the frame's text. Set that text's `font-family` to a named family the machine has, never a generic keyword such as `sans-serif`, and capture again rather than reporting the frame as captured.
|
|
124
124
|
|
|
125
|
-
## Step 7:
|
|
125
|
+
## Step 7: hand a picked frame on
|
|
126
126
|
|
|
127
|
-
When the operator picks a frame, the decision leaves the canvas.
|
|
127
|
+
When the operator picks a frame, the decision leaves the canvas. Hand it to `canon:design-record`, which lands the frame in the project's reference folder and carries its values into the design document. Report it rather than proceeding silently when that skill does not resolve.
|
|
128
128
|
|
|
129
|
-
-
|
|
130
|
-
-
|
|
131
|
-
- Name the frame the decision came from in the reply, and leave the frame on the canvas until the operator clears it.
|
|
129
|
+
- Name the page and frame the decision came from in the handoff and the reply, and leave the frame on the canvas until the operator clears it
|
|
130
|
+
- Name the frame in the plan that builds a picked layout, since the layout reaches code through that plan
|
|
132
131
|
- Never cite a frame path from a tracked file. The folder is gitignored, so the citation resolves on this machine alone.
|
|
133
132
|
|
|
134
133
|
## Output
|
|
@@ -138,7 +137,7 @@ When the operator picks a frame, the decision leaves the canvas. Leave structure
|
|
|
138
137
|
Page: <page>, <n> frames
|
|
139
138
|
Selected: <page>/<frame>, element <index>, or none, or stale
|
|
140
139
|
Capture: <path of each capture written>
|
|
141
|
-
|
|
140
|
+
Handed: <the frame handed to design-record, the plan that cites it, or not yet>
|
|
142
141
|
```
|
|
143
142
|
|
|
144
|
-
Write the canvas line's URL as a markdown link. Omit the capture line when nothing was captured and the
|
|
143
|
+
Write the canvas line's URL as a markdown link. Omit the capture line when nothing was captured and the handed line when no frame was picked. Emit every path from the project root.
|
|
@@ -9,15 +9,15 @@ description: Scope boundary for pipeline structure against job contents, and the
|
|
|
9
9
|
|
|
10
10
|
Without this skill, a session chains jobs with `needs` to express reading order rather than a data dependency, so the pipeline costs the sum of its jobs. The same session splits a one-minute gate into parallel jobs, each repaying checkout, install, and toolchain setup, so the gate gets slower while reporting no earlier.
|
|
11
11
|
|
|
12
|
-
The rest surface as flakes.
|
|
12
|
+
The rest surface as flakes. A moving action ref changes under the project, a static cache key serves a stale toolchain, artifacts never expire, a broad default token grants unneeded writes, and a missing manual trigger leaves a run reproducible only by pushing a commit. A Linux-only pin also flags a supported macOS job as a departure.
|
|
13
13
|
|
|
14
14
|
## Must
|
|
15
15
|
|
|
16
16
|
- A job is gated only on a data dependency or a cost that justifies the wait, and checks sharing setup stay in one job until a run log puts the gate past roughly two minutes
|
|
17
17
|
- Every action is pinned to a tag that cannot cross a major version, and every cache is keyed on the version of what it caches
|
|
18
18
|
- Every workflow carries a manual trigger beside its primary one, except one that commits back
|
|
19
|
-
- The token defaults to read-only, with a write scope granted only on the job that needs it
|
|
20
|
-
-
|
|
19
|
+
- The token defaults to read-only, with a write scope granted only on the job that needs it, and artifact upload is bounded to failures and expires
|
|
20
|
+
- A job runs on Linux unless the project states a platform for a layer that differs by platform
|
|
21
21
|
|
|
22
22
|
## Must not
|
|
23
23
|
|
|
@@ -20,7 +20,17 @@ Generate GitHub Actions workflow files for CI pipelines. Enforce parallel job ex
|
|
|
20
20
|
- Include `workflow_dispatch` alongside the primary trigger, except on a commit-back workflow, where a manual run has no branch to commit onto and would pass while doing nothing.
|
|
21
21
|
- Set `permissions: contents: read` at the top level, and grant a write scope only on the job that needs it.
|
|
22
22
|
- Pin all actions to major version tags (`@v4`, never `@latest` or `@main`).
|
|
23
|
-
- Use `runs-on: ubuntu-latest` for
|
|
23
|
+
- Use `runs-on: ubuntu-latest` for every job, except one the runner platform rules below move to another platform.
|
|
24
|
+
|
|
25
|
+
## Runner platform
|
|
26
|
+
|
|
27
|
+
Linux stays the default. A job leaves it only for a layer whose result differs by platform, and only on a platform the project states.
|
|
28
|
+
|
|
29
|
+
- Read the stated platforms from the project's requirements record or README. A platform stated in neither keeps every job on Linux.
|
|
30
|
+
- Keep lint, build, and browser jobs on Linux, since their result does not differ by platform. Name the layers that may leave it and never the steps they run.
|
|
31
|
+
- Name another runner by its `-latest` label, such as `macos-latest`, matching the `ubuntu-latest` convention above.
|
|
32
|
+
- Resolve a macOS `$TMPDIR` or `mktemp` path with `realpath` before comparing it with a tool's output, since the `/var` to `/private/var` symlink hides the target. Treat `$RUNNER_TEMP` alike.
|
|
33
|
+
- Expect a macOS job to cost more per minute than a Linux one. GitHub bills the two differently, so read the rate from its billing page rather than quoting a multiplier.
|
|
24
34
|
|
|
25
35
|
## Job naming
|
|
26
36
|
|
|
@@ -59,6 +69,14 @@ A workflow that pushes a regenerated file onto the pull request branch takes the
|
|
|
59
69
|
- Set `HUSKY: 0` on the commit step when the runner lacks a tool a hook shells out to.
|
|
60
70
|
- Fail a template's first step while a path list still holds its placeholder, so an unfinished install fails loudly rather than never firing.
|
|
61
71
|
|
|
72
|
+
## Steps
|
|
73
|
+
|
|
74
|
+
- Keep an inline `run:` step to five lines and one guard that exits or writes an output. Move other branching, a loop, trap, or function to a script, which runs on a laptop and under shellcheck.
|
|
75
|
+
- Put the script at `scripts/<name>.sh`, or a `.ts` file for a Bun project, and call it after `actions/checkout`, since the runner holds no copy before that.
|
|
76
|
+
- Pass inputs as arguments or `env`, never spliced into the script text, so a branch name with a quote or `$(...)` in it cannot run.
|
|
77
|
+
- Keep `permissions` and secrets on the workflow step, with the script reading its token from `env`.
|
|
78
|
+
- Open the script with `set -e` at least, since the runner gives a `run:` step `bash -e` and a script called directly gets no flags.
|
|
79
|
+
|
|
62
80
|
## Template
|
|
63
81
|
|
|
64
82
|
Load `${CLAUDE_SKILL_DIR}/references/workflows.md` for the base workflow template. Adapt it to the project's stack, test commands, and build output. Add or remove jobs as needed. The template already carries the folded shape, and the split beside it applies once the granularity rule above calls for it.
|
|
@@ -79,5 +97,12 @@ Before responding, also verify:
|
|
|
79
97
|
|
|
80
98
|
- Artifacts upload on `if: failure()` only with `retention-days: 7`.
|
|
81
99
|
- Job names use emoji + title format.
|
|
100
|
+
- Every job runs on `ubuntu-latest`, except one that targets a platform the project states and runs a layer that differs by platform.
|
|
82
101
|
- Deploy, publish, and release jobs carry a placeholder step and a named handoff, never a guessed deploy command.
|
|
83
102
|
- Bun projects use `oven-sh/setup-bun@v2` with `bun install --frozen-lockfile`.
|
|
103
|
+
|
|
104
|
+
### Steps
|
|
105
|
+
|
|
106
|
+
Before responding, also verify:
|
|
107
|
+
|
|
108
|
+
- No `run:` step passes five lines or carries more than one exit-or-output guard, a loop, a trap, or a function. A step that does calls a script, with its inputs as arguments or `env`.
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# CI workflow template
|
|
2
2
|
|
|
3
|
+
## Contents
|
|
4
|
+
|
|
5
|
+
- [Base template](#base-template)
|
|
6
|
+
- [Splitting the check job](#splitting-the-check-job)
|
|
7
|
+
- [Targeting another platform](#targeting-another-platform)
|
|
8
|
+
|
|
9
|
+
## Base template
|
|
10
|
+
|
|
3
11
|
Copy this base template and adapt it to the project's stack, test commands, and build output. It carries the shape a new pipeline starts in, with the checks that share setup in one job, per the granularity rule in the skill body. `e2e` and anything gated on it stay separate jobs at either size.
|
|
4
12
|
|
|
5
13
|
```yaml
|
|
@@ -99,3 +107,23 @@ jobs:
|
|
|
99
107
|
name: build-output
|
|
100
108
|
path: dist/
|
|
101
109
|
```
|
|
110
|
+
|
|
111
|
+
## Targeting another platform
|
|
112
|
+
|
|
113
|
+
Add this job beside the Linux ones only when the project states macOS as a supported platform, per the runner platform rules in the skill body. It runs the unit layer, since that layer differs by platform, and the rest stay on `ubuntu-latest`.
|
|
114
|
+
|
|
115
|
+
```yaml
|
|
116
|
+
jobs:
|
|
117
|
+
unit-macos:
|
|
118
|
+
name: '🧪 Unit Tests (macOS)'
|
|
119
|
+
runs-on: macos-latest
|
|
120
|
+
steps:
|
|
121
|
+
- uses: actions/checkout@v7
|
|
122
|
+
- uses: oven-sh/setup-bun@v2
|
|
123
|
+
with:
|
|
124
|
+
bun-version: latest
|
|
125
|
+
- run: bun install --frozen-lockfile
|
|
126
|
+
- name: Resolve the temp folder
|
|
127
|
+
run: echo "TMPDIR=$(realpath "$RUNNER_TEMP")" >> "$GITHUB_ENV"
|
|
128
|
+
- run: bun run test
|
|
129
|
+
```
|
|
@@ -88,9 +88,10 @@ Entries get read top-down and often partially, so the boundary sits above the fo
|
|
|
88
88
|
|
|
89
89
|
## The development entry
|
|
90
90
|
|
|
91
|
-
Only the
|
|
91
|
+
Only the development entry carries this section, as an H3 under `## Layout`. That entry is the flat `development` entry or any entry directly under a `development/` folder, and the heading is not a general-purpose one for other domains.
|
|
92
92
|
|
|
93
|
-
- `### Scripts`:
|
|
93
|
+
- `### Scripts`: run commands as tables of command plus purpose. The single discoverable surface for how to run the project. Keep run commands here, not scattered across `CLAUDE.md`.
|
|
94
|
+
- Group a long set of commands into short tables, each under a lead sentence naming its group, since a table past 8 body rows breaks the table limits. This H3 alone may carry several lead paragraphs.
|
|
94
95
|
|
|
95
96
|
## What goes in
|
|
96
97
|
|
|
@@ -157,7 +158,7 @@ A domain outgrowing the ceiling splits into a folder, and small domains of one k
|
|
|
157
158
|
- Name an entry inside either folder per the `codebase-layout` skill, which never repeats the folder's name as the entry's stem or prefix
|
|
158
159
|
- Keep a split domain's `index.md` generated, since regen rewrites its body. The domain's own overview and layout go in a sibling file, which the `subtitle` names.
|
|
159
160
|
|
|
160
|
-
Author a catalog that grows a row per shipped thing as a bullet list, never a markdown table. A table pads its columns to a shared width, so one row outgrowing its column reflows every row and conflicts with any sibling branch.
|
|
161
|
+
Author a catalog that grows a row per shipped thing as a bullet list, never a markdown table. A table pads its columns to a shared width, so one row outgrowing its column reflows every row and conflicts with any sibling branch. The development entry's `### Scripts` is the one exception, kept small by grouping.
|
|
161
162
|
|
|
162
163
|
## Examples
|
|
163
164
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: design-record
|
|
3
|
+
description: What keeping the design record is for, the gaps it closes, and where it stops against the skills that pick and judge a design
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Design record requirement
|
|
7
|
+
|
|
8
|
+
## Gap
|
|
9
|
+
|
|
10
|
+
Without this skill, no surface sets up the design reference folder or keeps it. A pick reaches the folder only when the operator remembers the sync, or a session copies frames in by hand and they drift. A reference outlives the surface it showed, since nothing removes it.
|
|
11
|
+
|
|
12
|
+
Each project invents its own grouping, and its index restates the file tree rather than naming the code a group governs. A picked color reaches the stylesheet with no intent written down, or lands as a hand-typed value in the design document.
|
|
13
|
+
|
|
14
|
+
## Must
|
|
15
|
+
|
|
16
|
+
- The folder takes the groups, file names, support folder, and index row form the folder standard fixes, and a project without one gets it set up rather than refused
|
|
17
|
+
- A pick lands through the design sync after its index row, and a project with no sync is told before any write and still gets the design document half
|
|
18
|
+
- A redraw keeps the index row and leaves the files to the sync, and a retired surface takes its files and row out in the change that removes it
|
|
19
|
+
- The run looks at each landed picture in both themes before reporting it landed
|
|
20
|
+
- A picked value lands in the stylesheet and its intent in the design document under the design document standard, and a generated record changes through its module alone
|
|
21
|
+
|
|
22
|
+
## Must not
|
|
23
|
+
|
|
24
|
+
- Write, copy, or delete a reference file by hand, or capture frames in place of a missing sync
|
|
25
|
+
- Land a candidate the operator has not picked
|
|
26
|
+
- Restate when a pick lands against the build, which the design-reference rule states
|
|
27
|
+
- Be reached only by the author typing its name, since a pick from the picking or canvas skill should hand off to it
|
|
28
|
+
|
|
29
|
+
## Out of scope
|
|
30
|
+
|
|
31
|
+
- Drafting candidates and taking the pick, which `pick-by-eye` owns
|
|
32
|
+
- Drawing, selecting, and capturing frames on the canvas, which `canvas-board` owns
|
|
33
|
+
- Judging whether a design is good, which `design-taste` owns
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: design-record
|
|
3
|
+
description: Keeps the project's design record, being the design document at `canon/DESIGN.md` and the reference folder at `canon/design/` holding the accepted frames a build matches. Sets the folder up, lands a picked design through the project's design sync, keeps the index, redraws or retires a reference when its surface changes, and carries a pick's values into the stylesheet and its intent into the design document. Use whenever a picked frame or design moves into `canon/design/` or `canon/DESIGN.md`, before running the project's design sync or editing the index, including when asked to "land it in the design references", "add a design reference", "land this pick", "set up canon/design", "update the design index", "redraw the reference for X", "remove the reference for X", or "update DESIGN.md". Do NOT use to draft candidates or take a pick, which is `pick-by-eye`, to draw frames on the canvas, which is `canvas-board`, or to judge a design, which is `design-taste`.
|
|
4
|
+
metadata:
|
|
5
|
+
family: ship
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Design record
|
|
9
|
+
|
|
10
|
+
Keep the record of what the project's design is. The record has two halves, each with its own standard to read before writing it.
|
|
11
|
+
|
|
12
|
+
| Half | Path | Standard |
|
|
13
|
+
| ---------------- | ----------------- | ------------------------------------------ |
|
|
14
|
+
| Design document | `canon/DESIGN.md` | `${CLAUDE_SKILL_DIR}/references/design.md` |
|
|
15
|
+
| Reference folder | `canon/design/` | `${CLAUDE_SKILL_DIR}/references/folder.md` |
|
|
16
|
+
|
|
17
|
+
The document holds the rules and each role's intent, and the folder holds the pictures a build matches.
|
|
18
|
+
|
|
19
|
+
## Guards
|
|
20
|
+
|
|
21
|
+
- Write no reference file by hand, whether a copy, an edit, or a delete. The project's design sync writes the frames, so a hand-written file drifts from the frame it claims to show.
|
|
22
|
+
- Never land a candidate the operator has not picked. The folder holds accepted designs, and a draft lives on the canvas.
|
|
23
|
+
|
|
24
|
+
## Step 1: read the record
|
|
25
|
+
|
|
26
|
+
Read `canon/design/index.md` from the project root, and list the group folders beside it.
|
|
27
|
+
|
|
28
|
+
- A missing folder or index is set up at Step 3, once Step 2 has found the sync
|
|
29
|
+
- An index carrying a file list or a canvas mapping is an older shape. Leave its rows in place, add new rows in the form `folder.md` gives, and say the index predates the standard.
|
|
30
|
+
|
|
31
|
+
## Step 2: find the project's design sync
|
|
32
|
+
|
|
33
|
+
Find the sync before writing anything, since every folder step runs through it. Read the project's scripts, such as the `scripts` block of `package.json`, for the command that writes frames into `canon/design/`. Run its `--help` when it offers one, for its mapping file and its check.
|
|
34
|
+
|
|
35
|
+
When no sync resolves, skip Steps 3 to 5 and capture no frame in the sync's place. Report `⚠ No design sync found, so the pick did not land in canon/design/. Add one or name the command, then re-run.` and go on to Step 6, which needs no sync.
|
|
36
|
+
|
|
37
|
+
## Step 3: set up the folder
|
|
38
|
+
|
|
39
|
+
Skip this step when `canon/design/index.md` exists, even as a stub, since a stub the project's stack seeded is the setup.
|
|
40
|
+
|
|
41
|
+
1. Write `canon/design/index.md` from the template in `folder.md`, with one row per group the first pick needs.
|
|
42
|
+
2. Leave the group folders to the sync, since git tracks no empty folder and the sync creates each one as it writes.
|
|
43
|
+
|
|
44
|
+
## Step 4: land a pick
|
|
45
|
+
|
|
46
|
+
When the pick lands relative to the build is the design-reference rule's call, so follow it rather than choosing here.
|
|
47
|
+
|
|
48
|
+
1. Name the group the surface belongs to, by where a user meets it in the app, per `folder.md`.
|
|
49
|
+
2. Add or update the group's index row before running the sync, naming the code paths the surface governs and the states its frames show.
|
|
50
|
+
3. Add the surface to the sync's mapping file, in the form the sync's own help gives.
|
|
51
|
+
4. Run the sync, then its check, and report a missing or stray file the check names.
|
|
52
|
+
5. Open each written PNG, light and dark, before reporting it landed, since a frame captured blank or in one theme passes the sync.
|
|
53
|
+
|
|
54
|
+
## Step 5: redraw or retire a reference
|
|
55
|
+
|
|
56
|
+
A redraw follows an intentional design change and nothing else. Keep the index row, change the sync's mapping only where the frame moved on the canvas, and run the sync so it rewrites the files.
|
|
57
|
+
|
|
58
|
+
Retire a reference in the change that removes its surface from the app.
|
|
59
|
+
|
|
60
|
+
- Drop the surface from the sync's mapping and run the sync, so the sync removes its files
|
|
61
|
+
- Remove the group's index row when the group holds nothing else
|
|
62
|
+
- When the sync leaves the files and its check reports them stray, name each path and ask the operator, since no session deletes a reference by hand
|
|
63
|
+
|
|
64
|
+
## Step 6: carry a pick into the design document
|
|
65
|
+
|
|
66
|
+
A pick that settles color, type, spacing, or radius changes the design document as well as the folder. Skip this step when the pick changed layout or structure alone, since the reference carries that.
|
|
67
|
+
|
|
68
|
+
- Carry each value into the stylesheet the document's lead names, and its intent into the document's sections under `design.md`
|
|
69
|
+
- A project with no stylesheet yet takes the values under `.claude/design/project/` after `canon design install`, and the lead names that path
|
|
70
|
+
- A values record names in its lead the module it renders from and the command that renders it. Edit that module and run that command, never the document.
|
|
71
|
+
|
|
72
|
+
Never cite a canvas frame path from the document or the index. The canvas folder is gitignored, so the citation resolves on one machine alone.
|
|
73
|
+
|
|
74
|
+
## Output
|
|
75
|
+
|
|
76
|
+
```plaintext
|
|
77
|
+
✅ Design record: <landed, redrawn, retired, set up, or carried>
|
|
78
|
+
Group: <group>, <name>
|
|
79
|
+
Files: <each file the sync wrote or removed>
|
|
80
|
+
Index: <the row added, changed, or removed, or unchanged>
|
|
81
|
+
Design: <the stylesheet and design document the values went to, or unchanged>
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Emit every path from the project root. Omit the files line when nothing was written.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Design reference folder
|
|
3
|
+
description: Shape and content rules for canon/design, the tracked folder of accepted design frames a build matches
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Design reference folder
|
|
7
|
+
|
|
8
|
+
Applies to `canon/design/`. Each file is an accepted design a build matches, kept as a picture for a reader and as frame HTML for exact values. The folder holds what was picked, never a draft.
|
|
9
|
+
|
|
10
|
+
## Scope
|
|
11
|
+
|
|
12
|
+
Governs the folder's groups, the file names inside them, the support folder, and the index at `canon/design/index.md`.
|
|
13
|
+
|
|
14
|
+
Does not govern:
|
|
15
|
+
|
|
16
|
+
- The design document at `canon/DESIGN.md`, which `design.md` beside this file governs
|
|
17
|
+
- When a pick lands and how a build is held to a reference, which the design-reference governance rule states
|
|
18
|
+
- The canvas content format a frame is drawn in, which the canvas standard owns
|
|
19
|
+
|
|
20
|
+
## What a working folder looks like
|
|
21
|
+
|
|
22
|
+
A folder works when a builder opening it finds the reference for the surface they are changing without asking anyone:
|
|
23
|
+
|
|
24
|
+
- Does the group a surface sits in match where a user meets it in the app?
|
|
25
|
+
- Does each reference carry both themes, as a picture and as frame HTML?
|
|
26
|
+
- Does the index say which code each group governs?
|
|
27
|
+
|
|
28
|
+
## Groups
|
|
29
|
+
|
|
30
|
+
Group by app part, being the places a user sees, such as `home`, `inspector`, or `menus`. A component folder splits one screen across many folders, and a concern folder mixes surfaces a builder edits apart.
|
|
31
|
+
|
|
32
|
+
- Give each app part one plain kebab-case folder directly under `canon/design/`
|
|
33
|
+
- Put the inputs every app part draws on, such as tokens, colors, and the logo, under `foundations/`, so they read apart from places in the app
|
|
34
|
+
- Gather a surface shown on several app parts, such as a toast, under the part a user meets it in first
|
|
35
|
+
|
|
36
|
+
## Files
|
|
37
|
+
|
|
38
|
+
Each reference is one name in two themes, with a PNG and its frame HTML per theme.
|
|
39
|
+
|
|
40
|
+
- Name each file `<name>-dark` or `<name>-light`, as in `grid-dark.png` beside `grid-dark.html`
|
|
41
|
+
- Keep one HTML file without a theme suffix only for a frame that switches theme itself, beside both PNGs
|
|
42
|
+
- Put what every frame HTML loads, being its stylesheet, script, fonts, and vendored files, under `kit/`
|
|
43
|
+
|
|
44
|
+
## The index
|
|
45
|
+
|
|
46
|
+
`canon/design/index.md` is prose for a reader. It names the link a file listing lacks, from a group to the code it governs.
|
|
47
|
+
|
|
48
|
+
- Write one row per group, carrying the group, what the user sees there, the code paths it governs, and the states its frames show
|
|
49
|
+
- List no files, since the tree and the sync's own check already answer what exists
|
|
50
|
+
- Keep the sync's canvas mapping out of the index, in a file the sync owns beside it
|
|
51
|
+
|
|
52
|
+
### Template
|
|
53
|
+
|
|
54
|
+
The column headers stay verbatim. A row per group, `foundations` included.
|
|
55
|
+
|
|
56
|
+
```markdown
|
|
57
|
+
# Design references
|
|
58
|
+
|
|
59
|
+
Each group holds accepted frames a build matches, light and dark.
|
|
60
|
+
|
|
61
|
+
| Group | What the user sees | Code | States |
|
|
62
|
+
| ------------- | ------------------ | ------------------ | ---------------- |
|
|
63
|
+
| `home` | <the surface> | `<path in source>` | <states shown> |
|
|
64
|
+
| `foundations` | Tokens and colors | `<stylesheet>` | <themes covered> |
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Lifetime
|
|
68
|
+
|
|
69
|
+
The design-reference governance rule states how long a reference stays, when it is redrawn, and when it goes with its surface.
|
|
@@ -154,9 +154,10 @@ Run `${CLAUDE_SKILL_DIR}/references/preflight.md` against the output. It is the
|
|
|
154
154
|
|
|
155
155
|
### Other skills
|
|
156
156
|
|
|
157
|
-
|
|
157
|
+
Five neighbors own the rest.
|
|
158
158
|
|
|
159
159
|
- The candidate loop, the arm set, the render, and the pick: `pick-by-eye`
|
|
160
|
-
- The shape of the project's design document and where its values live: `${CLAUDE_SKILL_DIR}/../
|
|
160
|
+
- The shape of the project's design document and where its values live: `${CLAUDE_SKILL_DIR}/../design-record/references/design.md`
|
|
161
|
+
- The folder holding the accepted designs and how a reference lands in it: `${CLAUDE_SKILL_DIR}/../design-record/references/folder.md`
|
|
161
162
|
- Reading source for roughness: `ux-audit`. Measuring what a running interface costs to paint: `ux-measure`
|
|
162
163
|
- Prose on the surface being designed: the `write-human` skill
|
|
@@ -59,6 +59,7 @@ A missing tracking ref is not a guard, since an open pull request proves the bra
|
|
|
59
59
|
- A fix commit answering a review changes what shipped exactly as much as an ordinary followup does, so the sync cannot wait on the invocation or the comment count below.
|
|
60
60
|
- A body a person edited by hand between rounds gets no special handling: judge it against the tree the same way regardless of who wrote it last, since a hand-edit the fix commit has made stale is the exact drift this sync exists to close.
|
|
61
61
|
- Carry a `UI pass` line marked `<!-- pr-ui-pass -->` into any rewritten body unchanged, since `canon pr tick` owns it and a dropped marker defeats the reset on a new head.
|
|
62
|
+
- Carry a `Fan-in members:` line into any rewritten body unchanged, since the post-merge hook reads it to delete the members and a dropped line deletes nothing and says nothing.
|
|
62
63
|
8. Route on the invocation and the comment count for the reply alone.
|
|
63
64
|
- When invoked with `reply-owned`, skip this step: the caller posts its own reply.
|
|
64
65
|
- Otherwise, if the count is above zero, the followup addresses review feedback: write a one-line summary of the fix to `.canon/tmp/pr/followup/summary-<number>.md` in its own call, run `canon labels scan --body-file .canon/tmp/pr/followup/summary-<number>.md` against it, which applies the rule in `${CLAUDE_SKILL_DIR}/../git-pr/references/publish.md`, then post it with `gh api -X POST repos/{owner}/{repo}/issues/<number>/comments -F body=@.canon/tmp/pr/followup/summary-<number>.md --silent`. A hook on `Bash` runs the same scan on that body file and denies the post on a hit, and it refuses an inline `-f body=` value, so the body goes through a file. The `pull_request` check the git-pr surface carries triggers on a push or an open rather than a plain edit, so neither this comment nor the title and body step 7 synced reaches it.
|
|
@@ -66,7 +66,7 @@ Past 5 bullets, group Key changes under bold labels, 5 bullets a group at most.
|
|
|
66
66
|
|
|
67
67
|
### Closing lines
|
|
68
68
|
|
|
69
|
-
The closing lines end `## Summary`, one `Closes #NNN` per issue and no trailing period
|
|
69
|
+
The closing lines end `## Summary`, one `Closes #NNN` per issue and no trailing period, and a sliced task carries them on its last slice. `closing-issues.md` decides the list. A fan-in member line sits above them, per `${CLAUDE_SKILL_DIR}/../auto-ship/references/fan-in.md`.
|
|
70
70
|
|
|
71
71
|
### Context section
|
|
72
72
|
|
|
@@ -14,6 +14,7 @@ The rules also have three carriers, a standard, a generated rule pointing at it,
|
|
|
14
14
|
## Must
|
|
15
15
|
|
|
16
16
|
- Hold the format and structure reference in `references/markdown.md`, the one copy, read by sibling path from every skill that writes markdown
|
|
17
|
+
- Hold the table limits in `references/tables.md`, the one copy, since `markdown.md` sits at the document ceiling and points at it
|
|
17
18
|
- Send the session to `canon markdown audit` after an edit, since the audit reads the bans from the package and a restated list would drift
|
|
18
19
|
- Route voice to `write-human` and a Mermaid fence to `draw-figure` rather than restating either
|
|
19
20
|
|
|
@@ -7,10 +7,15 @@ metadata:
|
|
|
7
7
|
|
|
8
8
|
# Markdown craft
|
|
9
9
|
|
|
10
|
-
Read
|
|
10
|
+
Read the references below before a substantial markdown edit. Every rule in them is a fact a scan can settle, so do not work the banned characters from memory.
|
|
11
|
+
|
|
12
|
+
- `${CLAUDE_SKILL_DIR}/references/markdown.md`: headings, density, code spans, punctuation, and every other format rule
|
|
13
|
+
- `${CLAUDE_SKILL_DIR}/references/tables.md`: the four table limits and their fixes, read before writing a table or fixing a table finding
|
|
11
14
|
|
|
12
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.
|
|
13
16
|
|
|
17
|
+
A table finding reports without failing the run. Fix it the way `tables.md` gives for its limit.
|
|
18
|
+
|
|
14
19
|
## Routes
|
|
15
20
|
|
|
16
21
|
- Voice, rhythm, sentence construction, and information density: load `write-human`.
|
|
@@ -63,7 +63,7 @@ Two kinds of block are exempt from the 40-line checkpoint, since a subheading dr
|
|
|
63
63
|
- A block whose lines are all list items at one level averaging under roughly 130 characters, since a flat list of short peers is already navigable
|
|
64
64
|
- Weight decides rather than count, since a catalog of one-liners and a stack of paragraphs reach one count and read nothing alike. The cap on a bullet run is a separate rule.
|
|
65
65
|
- Mixing prose into that list, or nesting levels in it, ends the exemption at any weight
|
|
66
|
-
- A block
|
|
66
|
+
- A block of table rows, since a heading splits the table rather than the run
|
|
67
67
|
- Prose either side of the table ends that exemption, since the block has a seam and a heading breaks it there
|
|
68
68
|
|
|
69
69
|
### Bold section markers
|
|
@@ -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
|
|
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` beside this file. Open an H3 with a lead sentence or a table, then a few bullets or a short paragraph, since monotone text is the defect whether all prose or all bullets.
|
|
81
81
|
|
|
82
82
|
| Rule | Limit |
|
|
83
83
|
| ------------------- | ------------------------------------------------- |
|
|
@@ -88,7 +88,7 @@ Six limits keep a file scannable on sight, each a fact `canon markdown audit` me
|
|
|
88
88
|
| Heading depth | H3 at most, no H4 |
|
|
89
89
|
| H3 opening | First block under an H3 is a paragraph or a table |
|
|
90
90
|
|
|
91
|
-
Rules,
|
|
91
|
+
Rules, a requirements or design record, a changelog, examples, and `.canon/` records take no density finding, since each keeps its own shape. `CLAUDE.md` takes the run limit and the H3 opening inside `## Key paths` alone.
|
|
92
92
|
|
|
93
93
|
### How each limit counts
|
|
94
94
|
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Table limits
|
|
3
|
+
description: The four limits a markdown table takes, being cell length, row count, a list after a table, and a wide code token, with the fix each one takes
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Table limits
|
|
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, and reports each one without failing a push for now.
|
|
9
|
+
|
|
10
|
+
## Limits
|
|
11
|
+
|
|
12
|
+
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
|
+
|
|
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 |
|
|
20
|
+
|
|
21
|
+
A paragraph or a heading between a table and a list clears the third limit, and a blank line alone does not.
|
|
22
|
+
|
|
23
|
+
## Fixes
|
|
24
|
+
|
|
25
|
+
Each limit has its own fix, and none of them is trimming characters until the count passes.
|
|
26
|
+
|
|
27
|
+
- Move a long cell's overflow into a bullet under the table's lead sentence, or under a lead of its own
|
|
28
|
+
- Split a long table into groups, each under a lead sentence naming its group, since a heading inside a table splits it and H4 is banned
|
|
29
|
+
- Give a list that follows a table a lead sentence of its own
|
|
30
|
+
- Move a wide token out of the table into a bullet, since a preview either widens its column or splits it at a hyphen or a slash
|