@erclx/canon 5.19.0 → 5.21.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.
Files changed (135) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/auto-ship/references/verb-absent.md +1 -1
  3. package/claude/skills/create-skill/SKILL.md +1 -0
  4. package/claude/skills/docs-sync/REQUIREMENT.md +1 -1
  5. package/claude/skills/document-health/REQUIREMENT.md +1 -1
  6. package/claude/skills/draft-ready/REQUIREMENT.md +2 -1
  7. package/claude/skills/draft-ready/SKILL.md +6 -4
  8. package/claude/skills/markdown-propose/REQUIREMENT.md +3 -3
  9. package/claude/skills/markdown-propose/SKILL.md +1 -1
  10. package/claude/skills/plan-feature/SKILL.md +1 -1
  11. package/claude/skills/plan-groundwork/SKILL.md +1 -1
  12. package/claude/skills/record-screencast/REQUIREMENT.md +2 -1
  13. package/claude/skills/record-screencast/SKILL.md +2 -2
  14. package/claude/skills/role-worker/REQUIREMENT.md +3 -1
  15. package/claude/skills/role-worker/SKILL.md +5 -3
  16. package/claude/skills/session-resume/SKILL.md +1 -1
  17. package/claude/skills/task-board/REQUIREMENT.md +1 -0
  18. package/claude/skills/task-board/SKILL.md +6 -0
  19. package/claude/skills/task-board/references/decline.md +2 -0
  20. package/claude/skills/video-craft/REQUIREMENT.md +48 -0
  21. package/claude/skills/video-craft/SKILL.md +80 -0
  22. package/claude/skills/video-craft/references/adopted.md +66 -0
  23. package/docs/agents/canvas.md +4 -0
  24. package/docs/agents/commands.md +1 -0
  25. package/docs/agents/demo.md +1 -1
  26. package/docs/agents/index.md +1 -0
  27. package/docs/agents/install-and-sync.md +17 -3
  28. package/docs/agents/markdown-audit.md +1 -3
  29. package/docs/agents/rule-citations.md +4 -4
  30. package/docs/agents/sandbox.md +8 -7
  31. package/docs/agents/slides.md +120 -0
  32. package/docs/agents/tasks-validate.md +1 -1
  33. package/docs/agents/tasks.md +1 -1
  34. package/docs/target/migrations.md +1 -1
  35. package/docs/workflow/ai-workflow.md +1 -1
  36. package/docs/workflow/operating-model.md +9 -9
  37. package/docs/workflow/parallel-features.md +1 -1
  38. package/docs/workflow/skill-map.md +12 -13
  39. package/governance/renames.toml +24 -0
  40. package/governance/rules/lib/330-testing-py.md +1 -1
  41. package/governance/rules/lib/336-testing-php.md +1 -1
  42. package/governance/rules/{canon/640-architecture.md → standards/architecture.md} +3 -2
  43. package/governance/rules/standards/context.md +15 -0
  44. package/governance/rules/standards/design.md +13 -0
  45. package/governance/rules/standards/diagrams.md +17 -0
  46. package/governance/rules/standards/groundwork.md +13 -0
  47. package/governance/rules/standards/intake.md +12 -0
  48. package/governance/rules/standards/markdown.md +15 -0
  49. package/governance/rules/standards/memory.md +12 -0
  50. package/governance/rules/standards/mermaid.md +15 -0
  51. package/governance/rules/{canon/658-plan.md → standards/plan.md} +5 -9
  52. package/governance/rules/standards/readme.md +12 -0
  53. package/governance/rules/standards/ready.md +13 -0
  54. package/governance/rules/standards/requirements.md +13 -0
  55. package/governance/rules/standards/rule.md +13 -0
  56. package/governance/rules/standards/session.md +13 -0
  57. package/governance/rules/{claude/570-skill.md → standards/skill.md} +6 -10
  58. package/governance/rules/standards/standard.md +13 -0
  59. package/governance/rules/standards/tasks.md +15 -0
  60. package/governance/rules/{canon/661-teach.md → standards/teach.md} +3 -2
  61. package/governance/rules/standards/wiki.md +13 -0
  62. package/governance/rules/standards/wireframes.md +14 -0
  63. package/governance/rules/writing/800-prose.md +1 -1
  64. package/governance/stacks/base.toml +4 -2
  65. package/package.json +1 -1
  66. package/src/canvas/capture.ts +228 -15
  67. package/src/claude/cases/misc.ts +5 -0
  68. package/src/claude/cases/workflow.ts +4 -20
  69. package/src/claude/routing.ts +1 -1
  70. package/src/commands/canvas.ts +76 -2
  71. package/src/commands/gov.ts +19 -4
  72. package/src/commands/sandbox.ts +7 -0
  73. package/src/commands/slides.ts +13 -3
  74. package/src/commands/tasks.ts +46 -2
  75. package/src/gate/stages.ts +7 -1
  76. package/src/gov/citations.ts +1 -1
  77. package/src/gov/standard-rules.ts +179 -0
  78. package/src/migrate/skill-names.ts +0 -7
  79. package/src/sandbox/equivalence.ts +43 -14
  80. package/src/sandbox/stub-remote.ts +140 -0
  81. package/src/slides/convert/chart.ts +165 -0
  82. package/src/slides/convert/deck.ts +164 -0
  83. package/src/slides/convert/export.ts +217 -7
  84. package/src/slides/convert/master.ts +195 -0
  85. package/src/slides/convert/shapes.ts +1 -1
  86. package/src/slides/convert/walk.ts +187 -2
  87. package/src/tasks/record.ts +11 -1
  88. package/src/tasks/validate.ts +14 -0
  89. package/standards/architecture.md +5 -0
  90. package/standards/context.md +6 -0
  91. package/standards/design.md +3 -0
  92. package/standards/diagrams.md +8 -0
  93. package/standards/groundwork-spikes.md +66 -0
  94. package/standards/groundwork.md +5 -25
  95. package/standards/index.md +6 -2
  96. package/standards/intake.md +2 -0
  97. package/standards/markdown.md +6 -0
  98. package/standards/memory.md +2 -0
  99. package/standards/mermaid.md +6 -0
  100. package/standards/plan-lifecycle.md +36 -0
  101. package/standards/plan.md +13 -11
  102. package/standards/readme.md +2 -0
  103. package/standards/ready.md +4 -0
  104. package/standards/requirements.md +3 -0
  105. package/standards/rule.md +6 -1
  106. package/standards/session.md +4 -0
  107. package/standards/skill-paths.md +50 -0
  108. package/standards/skill.md +15 -23
  109. package/standards/standard.md +7 -1
  110. package/standards/tasks-decline.md +38 -0
  111. package/standards/tasks.md +9 -14
  112. package/standards/teach.md +5 -0
  113. package/standards/wiki.md +4 -0
  114. package/standards/wireframes.md +5 -0
  115. package/tooling/astro/configs/card-src/pages/og-card.astro +2 -2
  116. package/claude/skills/docs-fold/REQUIREMENT.md +0 -25
  117. package/claude/skills/docs-fold/SKILL.md +0 -9
  118. package/claude/skills/standards-audit/REQUIREMENT.md +0 -33
  119. package/claude/skills/standards-audit/SKILL.md +0 -99
  120. package/governance/rules/canon/610-context.md +0 -17
  121. package/governance/rules/canon/620-wireframes.md +0 -13
  122. package/governance/rules/canon/630-requirements.md +0 -12
  123. package/governance/rules/canon/650-design.md +0 -12
  124. package/governance/rules/canon/655-tasks.md +0 -13
  125. package/governance/rules/canon/656-groundwork.md +0 -11
  126. package/governance/rules/canon/657-intake.md +0 -11
  127. package/governance/rules/canon/659-memory.md +0 -11
  128. package/governance/rules/canon/660-diagrams.md +0 -19
  129. package/governance/rules/canon/662-session.md +0 -15
  130. package/governance/rules/canon/663-ready.md +0 -15
  131. package/governance/rules/claude/590-rule-authoring.md +0 -12
  132. package/governance/rules/writing/801-markdown.md +0 -14
  133. package/governance/rules/writing/802-mermaid.md +0 -14
  134. package/governance/rules/writing/880-readme.md +0 -11
  135. package/governance/rules/writing/891-standard-authoring.md +0 -12
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "canon",
3
3
  "description": "Runs your agent's work and keeps its code good, on one setup for every repo.",
4
- "version": "5.19.0",
4
+ "version": "5.21.0",
5
5
  "author": {
6
6
  "name": "Eric Le",
7
7
  "url": "https://github.com/erclx"
@@ -29,7 +29,7 @@ Behavior paths carry two spellings, the one a surface authors at and the one it
29
29
 
30
30
  Markdown under one of them states what an agent does, so a change there is a behavior change wearing a prose extension. Everything outside them is informational, which keeps `docs/`, `README.md`, and `CHANGELOG.md` skipping without naming them. One behavior file sends the whole branch to review, since documentation shipped beside a behavior change does not cancel it.
31
31
 
32
- Informational prose is already gated by `docs-sync`, `standards-audit`, and pre-push hooks. Running a code-style review on it burns tokens with no signal.
32
+ Informational prose is already gated by `docs-sync`, `canon markdown audit`, and pre-push hooks. Running a code-style review on it burns tokens with no signal.
33
33
 
34
34
  The list covers this toolkit's authoring layout and the layout it installs, which is not every layout. A project keeping executable prose where neither spelling reaches adds the path, and until it does every branch touching it skips review silently.
35
35
 
@@ -9,6 +9,7 @@ Read these files in parallel:
9
9
 
10
10
  - `${CLAUDE_SKILL_DIR}/../../standards/skill.md`: skill structure, skill types, frontmatter fields, invocation rules
11
11
  - `${CLAUDE_SKILL_DIR}/../../standards/skill-requirement.md`: what `REQUIREMENT.md` must answer, its sections, and its template
12
+ - `${CLAUDE_SKILL_DIR}/../../standards/skill-paths.md`: which root a path in the body resolves against, and how the body cites a standard
12
13
  - `${CLAUDE_SKILL_DIR}/../../standards/markdown.md`: punctuation and formatting for skill body text
13
14
  - The `write-human` skill: voice, rhythm, and sentence construction for skill body text
14
15
 
@@ -38,4 +38,4 @@ The quiet one is the baseline. A diff resolved against a bare local ref equals H
38
38
  - The context entries, requirements, architecture, wireframes, and task board: `context-fold`, which runs immediately before this skill in the ship chain and resolves the same baseline. The split is by audience, so a file's location decides which skill owns it rather than its subject.
39
39
  - `CLAUDE.md` and the installed seed docs: `seed-sync`, which reconciles them per section against the toolkit source
40
40
  - Changelog entries, which release tooling generates from commit messages
41
- - Whether the prose conforms to its standards. `standards-audit` reports violations and fixes none, and this skill writes prose it does not audit.
41
+ - Whether the prose conforms to its standards. `canon markdown audit` reports violations and fixes none, and this skill writes prose it does not audit.
@@ -40,7 +40,7 @@ The third is silence on an unread axis. Both measured verbs resolve their folder
40
40
  ## Out of scope
41
41
 
42
42
  - Whether a document exists or holds its required sections, which is the structural question `target-check` answers across six domains
43
- - Conformance of changed markdown to the authoring standards declaring jurisdiction over its paths, which is `standards-audit`. That skill is diff-scoped and standard-declared, taking a changed file and reporting which stated rule it breaks with a line number. This one is corpus-scoped and reads rot in documents nobody changed, which is the case a diff-scoped audit never reaches. The two sit beside each other rather than one absorbing the other.
43
+ - Banned tokens and structural checkpoints in markdown, which `canon markdown audit` measures from package data. This skill reads rot a ban set cannot state.
44
44
  - Rewriting a stale claim once this run has named it, which is `markdown-propose`
45
45
  - Running the toolkit's own checks as one gating set over its own corpus, which is `canon audits run`. That set gates a push and this reports to a reader.
46
46
  - Repairing anything an axis names. Each routes to the command or skill that owns it.
@@ -13,6 +13,7 @@ Without this skill, a session holding finished files that hands them to a worker
13
13
  - Lists a destination in the overview that the plan's `**Files to touch:**` omits, or the reverse. The omitted path is invisible to `plan-reach`, so a second track writes the same file and neither side finds out.
14
14
  - Picks the next ordinal by reading only the live folder, and reuses a number an archived folder already spent, which the pull request that shipped it cites by name.
15
15
  - Picks a phase label by scanning the live board alone, which is the scan that let two sessions hand out one label within minutes of each other.
16
+ - Reads the label bare, which reserves nothing and returns one a live claim already holds until that claim's task file lands.
16
17
  - Leaves the plan's `**Constraints:**` without a line naming the folder as the verbatim source, so the worker reads the files as inspiration and writes its own version.
17
18
  - Leaves a note, an alternate, or a draft passage in the folder beside the real files, so the worker guesses which one is the source.
18
19
  - Writes into the main worktree root from a linked worktree with `Edit` or `Write`, which the isolation guard refuses, and takes the refusal's redirect into a second gitignored copy no later session reads.
@@ -22,7 +23,7 @@ Without this skill, a session holding finished files that hands them to a worker
22
23
 
23
24
  - Refuse before writing when the operator has named no finished file, since a folder assembled from a description is a plan with extra steps.
24
25
  - Read the ordinal from the live folder and its archive together, so a spent number is never reused.
25
- - Take the phase label from `canon tasks next-label` rather than from a scan of its own.
26
+ - Take the phase label from `canon tasks next-label --claim` rather than from a scan of its own or a bare read, and stop on a binary that predates the flag rather than falling back.
26
27
  - Derive the overview's `destinations` and the plan's `**Files to touch:**` from one list, and compare the two before reporting, so neither can name a path the other lacks.
27
28
  - Write the plan's `**Constraints:**` line naming the folder as the verbatim source.
28
29
  - Copy each finished file whole to its destination path inside the folder, and carry nothing else into it.
@@ -31,13 +31,15 @@ Read these in parallel before writing:
31
31
 
32
32
  Read `<main-root>/.canon/ready/` and `<main-root>/.canon/ready/archive/` together and take the highest `<nn>` across both, plus one. A folder set with no entry takes `01`. Keep this skill-local. No verb allocates a ready ordinal, and two writers running at once can claim one number, so re-read the folder immediately before Step 3 writes.
33
33
 
34
- Take the label from the verb rather than from a scan:
34
+ Claim the label through the verb rather than reading it bare or scanning for it:
35
35
 
36
36
  ```bash
37
- canon tasks next-label --json
37
+ canon tasks next-label --claim --json
38
38
  ```
39
39
 
40
- Branch on the record's `label` rather than on the exit code. Report the verb as unavailable and stop when the installed binary carries no `next-label` subcommand, since a label picked by hand is the collision the verb exists to prevent.
40
+ The claim reserves the label under `.canon/ordinal-locks/`, so a second session allocating at the same moment gets the next one. A bare read reserves nothing and can return a label a live claim already holds.
41
+
42
+ Branch on the record's `reason` rather than on the exit code, taking `label` from a record that carries one. `label-contended` means re-run the claim. Report the verb as unavailable and stop when the installed binary carries no `next-label` subcommand, or when an unknown `--claim` prints no record, since that binary predates the flag. Never fall back to a bare read or a label picked by hand, which reopens the collision the claim exists to prevent.
41
43
 
42
44
  ## Step 3: write the overview
43
45
 
@@ -67,7 +69,7 @@ Run the match check in `${CLAUDE_SKILL_DIR}/references/assembly.md` before going
67
69
 
68
70
  ## Step 6: write the task
69
71
 
70
- Write `<main-root>/.canon/tasks/<label>-<slug>.md` by heredoc, from the label Step 2 read. Its frontmatter, H1, and `## Outcomes` follow `${CLAUDE_SKILL_DIR}/../../standards/tasks.md`. Write a `Ready:` line beside the `Plan:` line pointing at the folder, then point the task at the plan through the verb:
72
+ Write `<main-root>/.canon/tasks/<label>-<slug>.md` by heredoc, from the label Step 2 claimed, without calling the verb again, since a second call would claim a different label. Its frontmatter, H1, and `## Outcomes` follow `${CLAUDE_SKILL_DIR}/../../standards/tasks.md`. Write a `Ready:` line beside the `Plan:` line pointing at the folder, then point the task at the plan through the verb:
71
73
 
72
74
  ```bash
73
75
  canon tasks plan-link <task-stem> .canon/plans/feature-<slug>.md --json
@@ -7,9 +7,9 @@ description: Why a markdown rewrite is proposed per file and answered before any
7
7
 
8
8
  ## Gap
9
9
 
10
- Rewriting a passage in a governing document today means editing it live or arguing in chat, and three surfaces sit near this moment without covering it. `standards-audit` maps changed markdown to the standards claiming it and reports violations, ending on its own description: `Do NOT fix violations. Reporting only.` `canon markdown audit` measures bans and structural checkpoints from package data.
10
+ Rewriting a passage in a governing document today means editing it live or arguing in chat, and two surfaces sit near this moment without covering it. `canon markdown audit` measures bans and structural checkpoints from package data.
11
11
 
12
- `review-branch` reports findings on a diff someone already wrote. None of the three drafts a replacement, carries an answer slot, or waits.
12
+ `review-branch` reports findings on a diff someone already wrote. Neither drafts a replacement, carries an answer slot, or waits.
13
13
 
14
14
  A review delivered in chat gets applied from memory across files nobody reopened, and nothing records which changes the operator approved. A change nobody agreed to either lands unreviewed, because the session acting on a chat review cannot tell an approved line from an inferred one, or never gets written down at all, because a finding with no draft behind it hands the rewrite back to whoever reads it next.
15
15
 
@@ -41,7 +41,7 @@ A second failure compounds the first. A claim copied across several files is cor
41
41
 
42
42
  ## Out of scope
43
43
 
44
- - Reporting a violation with no drafted replacement, which `standards-audit` and `canon markdown audit` already own
44
+ - Reporting a violation with no drafted replacement, which `canon markdown audit` already owns
45
45
  - Reviewing a diff someone already wrote, which `review-branch` owns
46
46
  - Filing a raw brain dump as findings, which `plan-intake` owns
47
47
  - Reviewing `.canon/memory/` and proposing promote-or-retire actions per entry, which `memory-review` owns on a different subject with a different answer contract
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: markdown-propose
3
- description: Reviews a named markdown surface against a named concern, drafts a per-file proposal under `.canon/proposals/<nn>-<slug>/` carrying a diff and a reason for each change, and stops without editing a source file. Takes the concern and the surface as inputs, such as a claim stated stronger than the record, a fact gone stale, two files disagreeing, or a passage duplicated without derivation. A later invocation applies what the operator answered. Use when asked to "propose a change to CLAUDE.md", "draft a rewrite of this standard", "propose fixes to this doc", "draft alternatives for this passage", or "apply the answered proposals". Do NOT use to report without drafting a replacement (`standards-audit` or `canon markdown audit`), to review a diff already made (`review-branch`), or to file a raw brain dump as findings (`plan-intake`).
3
+ description: Reviews a named markdown surface against a named concern, drafts a per-file proposal under `.canon/proposals/<nn>-<slug>/` carrying a diff and a reason for each change, and stops without editing a source file. Takes the concern and the surface as inputs, such as a claim stated stronger than the record, a fact gone stale, two files disagreeing, or a passage duplicated without derivation. A later invocation applies what the operator answered. Use when asked to "propose a change to CLAUDE.md", "draft a rewrite of this standard", "propose fixes to this doc", "draft alternatives for this passage", or "apply the answered proposals". Do NOT use to report without drafting a replacement (`canon markdown audit`), to review a diff already made (`review-branch`), or to file a raw brain dump as findings (`plan-intake`).
4
4
  ---
5
5
 
6
6
  # Markdown propose
@@ -40,7 +40,7 @@ Open each file before describing what is in it. A count or a claim carried from
40
40
 
41
41
  ## Step 3: build the plan
42
42
 
43
- The section list, what each section holds, the suggested-and-answer contract, and the lifecycle are fixed by `${CLAUDE_SKILL_DIR}/../../standards/plan.md`. Read it before writing the file and follow it rather than working the shape from memory.
43
+ The section list, what each section holds, and the suggested-and-answer contract are fixed by `${CLAUDE_SKILL_DIR}/../../standards/plan.md`, and the lifecycle by `${CLAUDE_SKILL_DIR}/../../standards/plan-lifecycle.md`. Read it before writing the file and follow it rather than working the shape from memory.
44
44
 
45
45
  What this skill adds on top of the standard:
46
46
 
@@ -33,7 +33,7 @@ Read `${CLAUDE_SKILL_DIR}/../../standards/groundwork.md` before writing any file
33
33
  A track may run an experiment to settle an open question without stopping to ask. What it takes depends on what the experiment does.
34
34
 
35
35
  - Reading or computing: run it. Unrestricted reading already covers this, and it is what most spikes turn out to be.
36
- - Anything that processes an input: start against a sample and scale up after it works, per the sample rule in the standard's spikes section, which bounds it on size, duration, and spend.
36
+ - Anything that processes an input: start against a sample and scale up after it works, per the sample rule in `${CLAUDE_SKILL_DIR}/../../standards/groundwork-spikes.md`, which bounds it on size, duration, and spend.
37
37
  - Writing a fixture this session reads or provisions itself: run it, under the fixtures path above. Provisioning is the usual blocker rather than spend, and it costs nothing.
38
38
  - Spawning a billed headless session: run up to three, then ask before spawning more. The bound is a run count rather than a budget, because a headless run reports its total cost only after it finishes, so a dollar ceiling is reportable and not enforceable while a run count is checkable before spawning.
39
39
 
@@ -14,7 +14,8 @@ Without this skill, `draft-screencast` writes a draft and names `canon demo comp
14
14
  - Resolve the default plan path the same way `canon demo compile` does, so a caller passing only the draft path reaches the plan without naming it
15
15
  - Skip compiling when a plan already exists at that path, since its timing may be tuned by hand and a draft cannot reproduce that
16
16
  - Report every unresolved field from the compile or run record and stop rather than filling one in
17
- - Report every path a run wrote, video, mp4, gif, still, skipping any the record carries as null
17
+ - Report every path a run wrote, video, mp4, gif, still, and timeline, skipping any the record carries as null
18
+ - Load the video craft guidance before composing, so a composition applies sourced judgment on captions, zoom, pointer, and audio rather than the defaults an unguided session reaches for
18
19
  - Compose the take into a finished mp4 through HyperFrames when the draft's wrap section asks for anything, check the composition before rendering, and hand the render to `read-frames`
19
20
  - Stop at the take when the wrap section says `none` throughout, and stop with the install command when HyperFrames is absent
20
21
 
@@ -57,7 +57,7 @@ Read the draft's `## Wrap` section. When intro, outro, and music all say `none`,
57
57
 
58
58
  Otherwise confirm HyperFrames' `hyperframes` skill resolves. `bunx` would fetch the package on a machine without it, which installs by the back door, so the skill is the presence test. When it does not resolve, stop and report the install command, `bunx -y hyperframes init`, with the warning that init installs its skills machine-wide without asking, and report the take's paths as Step 6 does so the operator still holds the recording the run wrote. Never install it from here.
59
59
 
60
- When it resolves, load it and build `demos/<slug>/index.html` around the take, with the intro, outro, and music the wrap section names. That skill owns the composition rules, so this body states none of them. Then run both from `demos/<slug>/`:
60
+ When it resolves, load it, then load `canon:video-craft` for the captions, zoom, pointer, and audio judgment a video of software needs, reporting it rather than proceeding silently when it does not resolve. Build `demos/<slug>/index.html` around the take, with the intro, outro, and music the wrap section names, aiming each zoom from the timeline the run wrote beside the take. Those two skills own the composition rules, so this body states none of them. Then run both from `demos/<slug>/`:
61
61
 
62
62
  ```bash
63
63
  bunx -y hyperframes check
@@ -72,6 +72,6 @@ Hand the render to `read-frames` as its video path, so the composed result is ch
72
72
 
73
73
  ## Step 6: output
74
74
 
75
- The record carries `video`, `mp4`, `gif`, and `still`, each a path or `null`. Report each one that is not `null`, one per line, skipping the rest, and add the render path when Step 4 wrote one. Name the mp4 as the deliverable, the webm as the raw take, and the gif as the form for a host that strips video.
75
+ The record carries `video`, `mp4`, `gif`, `still`, and `timeline`, each a path or `null`. Report each one that is not `null`, one per line, skipping the rest, and add the render path when Step 4 wrote one. Name the mp4 as the deliverable, the webm as the raw take, the gif as the form for a host that strips video, and the timeline as the per-step timing a composition aims its zooms from.
76
76
 
77
77
  Say so plainly if `canon demo compile` or `canon demo run` is not available, rather than driving the application some other way. Both ship with the CLI and this skill ships with the plugin, so a project carrying one and not the other is a real state.
@@ -25,8 +25,9 @@ The draft mark fails from both ends. On 2026-08-31 four sessions re-drafted a pu
25
25
 
26
26
  - Assert what a building session is, what it may not do, and how long the role lasts, since the three step-owning skills each carry a procedure and none carries a role
27
27
  - State that session scratch resolves at the main worktree root, since a linked worktree holds none of those folders and their absence reads as a missing artifact rather than as a wrong vantage
28
- - State the shared board as read-only for a building session and name what it does instead when a row is owed, since a worker cannot pick a free label without reading every task file and every archive entry
28
+ - State the shared board as read-only for a building session and name what it does instead when a row is owed, since a task file with no row is a dropped task and placing the row is the controlling session's call
29
29
  - Owe an announcement the moment the pull request opens, carrying the number, the branch, and the task, since that transition is the one interval only the worker can observe
30
+ - Carry a row the build turned up in the pull request announcement, and send it alone only when the session ends before a pull request opens, since the worker files no task file of its own and the channel is the row's only route
30
31
  - Owe a message before a block becomes an interactive prompt, since a session already waiting on input never reaches the tool round an inbound message drains at
31
32
  - Defer the addressee resolution to `session-relay` and keep only the operator ask and the last-rung inference, which discriminates here because a worker holds a feature branch and a controller does not, and which falls back to the roster and says so, since an operator's own launch names nobody
32
33
  - Keep refusing a dispatcher a first-class move carrying its evidence, since the halts measured so far were correct and the cost of each fell where it belonged
@@ -39,6 +40,7 @@ The draft mark fails from both ends. On 2026-08-31 four sessions re-drafted a pu
39
40
  - Restate a boundary the orchestrator already states about itself
40
41
  - Report progress through the channel, which rebuilds on the sender's side the poll the announcement exists to retire
41
42
  - Write the priority board or the backlog, at any size
43
+ - Create a task file for work the build turns up, through `task-board` or by hand, since the file lands with no row and the placement is not the worker's to make
42
44
  - Be a skill nothing invokes but its author typing the name. `auto-ship` Step 0 invokes it on every build, dispatched or hand-launched, so a stretch where only a typed invocation reaches it is the signal that the role never took.
43
45
 
44
46
  ## Guards
@@ -37,16 +37,18 @@ which `auto-ship` Step 2 loads.
37
37
  ## The board is read-only
38
38
 
39
39
  - Never write `.canon/tasks/priority.md` or `.canon/tasks/backlog.md`. The controlling session is their only writer apart from `canon tasks archive`, and both are gitignored, so an overwrite drops a row with no history to recover it from.
40
- - Report a row this build turns up rather than adding it. Picking a free label means reading every task file and every archive entry, which this session has not done, so a label it invents collides with one already taken.
40
+ - Create no file under `.canon/tasks/`, including through `task-board`, when this build turns up new work. A task file with no row is a dropped task, and where the row lands is the controlling session's call, so a file this session writes is either orphaned or a placement it had no standing to make.
41
+ - Report the row upward instead, through the channel below.
41
42
  - Write the task file this build closes and the plan it ran under. The ban covers the shared board rather than the artifacts of the row in hand.
42
43
 
43
44
  ## The channel
44
45
 
45
- The controlling session cannot watch this one build, so three messages are owed
46
- and nothing else.
46
+ The controlling session cannot watch this one build, so the messages below are
47
+ owed and nothing else.
47
48
 
48
49
  - Announce the pull request as the ship chain's pull request step returns, carrying the number, the branch, and the task it closes. That transition is the one moment only this session knows, and the controller's review poll no longer starts on a dispatch because of it.
49
50
  - Carry the reach in that same message: the paths this branch wrote that another live plan or `## Run now` row holds, and who holds each, which `canon tasks plan-reach` reports as `claimed`. The gate cleared this branch against a prediction it has since outgrown, so the controller holds a disjointness reading that stopped being true hours ago and nothing else tells it. Say the reach was unread rather than clear when the installed binary carries no such subcommand, and leave the undeclared list to the pull request.
51
+ - Carry a row this build turned up in that same message, with its title, its origin, and the surface it would take. Send it as its own message only when the session will end before a pull request opens, since the row has no other way to reach the controller.
50
52
  - Announce when an address-review pass finishes, as `review-address` Step 8 returns, carrying what was addressed and the PR's new CI state. That transition is the other moment only this session knows, and it is what tells the controller to re-review rather than leaving it to poll for an answer nothing marks as landed.
51
53
  - Send a block out as a message before it becomes an interactive prompt.
52
54
  - Send nothing on progress. A worker reporting progress rebuilds, on this side of the channel, the poll the announcement retired on the other.
@@ -41,7 +41,7 @@ End with one line: `Start with: <first Up next item>` and note whether it has a
41
41
 
42
42
  When the board is empty and a handoff was found, name what the handoff leaves open instead: `Start with: <the open thread the handoff names>`. A recommendation slot filled with nothing reads as a failed run, and a handoff on an empty board is the shape a session leaves when it was reasoning rather than shipping.
43
43
 
44
- Do not offer to remove entries. A completed task is archived out of `.canon/tasks/` when work ships. The git log is the authoritative record of shipped work. Plan files are archived per the lifecycle rule in `${CLAUDE_SKILL_DIR}/../../standards/plan.md`.
44
+ Do not offer to remove entries. A completed task is archived out of `.canon/tasks/` when work ships. The git log is the authoritative record of shipped work. Plan files are archived per the lifecycle rule in `${CLAUDE_SKILL_DIR}/../../standards/plan-lifecycle.md`.
45
45
 
46
46
  Memory is updated only when a recorded fact becomes wrong, never on resume. A domain fact reaches a session through `canon/context/`, which `memory-capture` routes to and the three-tier model loads on demand, so the memory folder read here is the residue no context entry owns.
47
47
 
@@ -31,6 +31,7 @@ Placing a row without checking for another writer collides the same way. Two ses
31
31
  - Write a pull request line at creation, when any number is a guess at someone else's work
32
32
  - Archive around a refusal
33
33
  - Split the legacy single-file archive into per-task files nobody wrote
34
+ - Claim a label or write a task file for a session holding the worker role, since that role reports a row upward and the controlling session places it
34
35
  - Fall through to a direct write when no orchestrator is found and this session's own name starts with `worker-` or `planner-`, since those role bodies ban the write with no exception
35
36
 
36
37
  ## Guards
@@ -27,6 +27,12 @@ A task with no origin is either lost context or work nobody decided to do. This
27
27
 
28
28
  Accept work whose origin is the conversation itself only when the user says so explicitly, and record what it was in the intro paragraph instead of writing a link line to a file that does not exist.
29
29
 
30
+ ### Stop a worker before it claims a label
31
+
32
+ A session that asserted `canon:role-worker` this run, or whose own name in `canon sessions list --self --json` starts with `worker-`, stops here. It claims no label and writes no file. Report the row's title, its origin, and the surface it would take to the controlling session instead, since a task file with no row is a dropped task and placing the row is that session's call.
33
+
34
+ The guard sits ahead of Step 2 because `--claim` reserves a label on disk, so a stop after it leaves a reservation nothing uses. It names the worker role alone. A planner closing a groundwork track still writes its task file here and reaches Step 4's roster check as before.
35
+
30
36
  ### Step 2: allocate the phase label
31
37
 
32
38
  Run `canon tasks next-label --claim --json` and take its `label` field. The verb reads the live board and its `archive/` sibling together, so the label it returns accounts for what the board alone no longer shows, and `--claim` reserves it under `.canon/ordinal-locks/` so a second session filing at the same moment gets the next one. Branch on the record's `reason` rather than the exit: `label-contended` means re-run the claim, and a usage error from an unknown `--claim` means the installed binary predates the flag, so report the verb as unavailable rather than falling back to a bare read, which reopens the race.
@@ -7,6 +7,8 @@ description: How task-board gathers the reason a task is decided against, runs c
7
7
 
8
8
  The Decline mode of `task-board`. The session reads this file when the request names a task decided against.
9
9
 
10
+ Read `${CLAUDE_SKILL_DIR}/../../standards/tasks-decline.md` first. It holds the declined folder, the `Declined:` line, and what the move does to a plan and a board row.
11
+
10
12
  A task decided against carries no `post-merge` hook of its own, so every decline request arrives here directly rather than through work the hook already did.
11
13
 
12
14
  Do not move the file, edit `priority.md` or `backlog.md`, or regenerate the index by hand. `canon tasks decline` owns all three as one unit.
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: video-craft
3
+ description: Why a session composing a video of software needs sourced judgment on captions, zoom, pointer, and audio beyond what HyperFrames' own skills carry, and why every number in it has to trace to a source
4
+ ---
5
+
6
+ # Video craft requirement
7
+
8
+ ## Gap
9
+
10
+ Without this skill, a session composing a video applies no judgment specific to a video of software. HyperFrames' own skills carry general motion craft, being ease and speed variety, anchoring, and click timing, and nothing carries what a demo needs on top: what a caption says, which moment earns a zoom, how a recorded pointer behaves, and how far music sits under a voice.
11
+
12
+ The miss is measured. Two unguided renders of one demo in October 2026 pushed in over 2.2 and 1.4 seconds, used one ease on every move, centered the caption in a pill, and opened on a card holding the product name and a slogan over a gradient. The operator watched both and judged them generic, naming the zoom as too slow, and added that a caption has to name what the frame shows at that moment rather than narrate the whole flow. Rendering the first again with HyperFrames' creative and animation skills loaded fixed the general motion and left the four points above untouched.
13
+
14
+ Numbers from recall are the second gap. HyperFrames' zoom rule states 1.0 to 2.0 seconds with no source, and its default music bed sits about 18 dB under a voice where the accessibility guideline asks for 20. A session taking either as given reproduces the defaults the operator rejected.
15
+
16
+ ## Must
17
+
18
+ - State that a caption names only what its frame shows, with its on-screen time, line count, line length, and reading rate traced to published subtitle guidelines
19
+ - State which moment earns a zoom, aim it from the timeline `canon demo run` writes beside the take, and give a sourced duration for a push onto an action
20
+ - State how a recorded pointer behaves on a real interface: one pointer, and each click inside its recorded target. Smoothing and hiding the pointer are recorder settings a composition cannot change, so they stay out
21
+ - Cover choosing music or silence, the level music sits under a voice, and the pace of a captioned voiceover, each number sourced
22
+ - State that a checker finding is dismissed only after the frame it names is read
23
+ - Record the source behind every number in `references/adopted.md`, and name each conflict between sources with its pick rather than averaging
24
+ - Close with the practice skill's excuses, red flags, and closing checklist
25
+ - Be loaded by `record-screencast` before it composes, reporting when the skill does not resolve
26
+
27
+ ## Must not
28
+
29
+ - Restate a rule HyperFrames' own skills carry, such as ease variety, anchoring, click timing, the scale and dwell of a zoom, safe margins, or the carve that sits music under a voice. Point at the skill that owns it.
30
+ - State a number that `references/adopted.md` does not trace to a source
31
+ - Fetch, generate, or install a media file or HyperFrames itself
32
+ - Name this repository's demos, branches, or render files, since the body ships to targets holding none of them
33
+
34
+ ## Guards
35
+
36
+ - Two sources disagreeing on a number are named together with the side the body takes, never averaged
37
+
38
+ ## Out of scope
39
+
40
+ - General motion and composition rules: `hyperframes-animation` and `hyperframes-creative`
41
+ - Sourcing media: `media-use`
42
+ - Recording the take: `record-screencast`
43
+ - Vertical 9:16 framing, until a project asks for it
44
+ - Whether loading the skill improves a render, which needs a with-and-without comparison rather than a rule here
45
+
46
+ ## Measured
47
+
48
+ Not yet measured. The comparison owed is a demo composed with the skill loaded, judged by the operator against the unguided renders described under Gap. Whether the result reads designed is a taste call, so a pattern check cannot stand in for it.
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: video-craft
3
+ description: Carries what makes a composed video of software read as designed rather than generic, being captions that name only what the frame shows, which moment earns a zoom and how fast it lands, how a real pointer behaves on a real interface, music or silence and how far under a voice the music sits, and reading a frame before dismissing a checker finding. Every number traces to a source. Use before composing or judging any video, whether a product demo, an explainer, a pull request walkthrough, or a launch clip, when a render reads generic or slow, or when asked "make this video look designed", "is this zoom too slow", "what should this caption say", "should this have music", or "the checker flagged a frame, is it real". Do NOT use for general motion such as easing, speed variety, and click timing, which HyperFrames' `hyperframes-animation` and `hyperframes-creative` carry, to fetch or generate a media file, which is `media-use`, or to record the take, which is `record-screencast`.
4
+ ---
5
+
6
+ # Video craft
7
+
8
+ A session composing a video with no stated direction reaches for the defaults: a push-in of over two seconds, one ease on every move, a caption centered in a pill, and an intro card holding the product name and a slogan. Each default is reasonable alone, and together they read as generic. This skill carries the judgment specific to a video of software, which HyperFrames' own skills leave out.
9
+
10
+ Load `hyperframes-creative` and `hyperframes-animation` first. They own general motion, being ease and speed variety, anchoring, and click timing, and this body names none of their rules. Read `${CLAUDE_SKILL_DIR}/references/adopted.md` for the source behind every number below, and only when extending this guidance or arguing against a rule in it.
11
+
12
+ The guidance covers landscape 16:9 video. Vertical 9:16 framing is not covered yet.
13
+
14
+ ## Captions name what the frame shows
15
+
16
+ - Write each caption about the frame on screen while it shows, never about the step before or the one after. A caption narrating the whole flow describes a frame the viewer is not looking at.
17
+ - Name the visible change, such as the card landing or the field filling, rather than the feature's pitch. The pitch belongs in an intro card or the voiceover.
18
+ - Start a caption on the first frame of the action it names, and keep it on screen for at least 5/6 of a second and at most 7 seconds.
19
+ - Hold a caption to two lines of at most 42 characters, read at no more than 20 characters per second, or 17 for an audience of children. Cut words rather than shorten the hold.
20
+ - Place a caption where it covers nothing the frame is about. Move it off the element the step acts on, rather than centering it by default. HyperFrames' studio skill owns the title-safe margins.
21
+
22
+ ## A zoom is earned by an action
23
+
24
+ - Zoom only on a click, fill, or hover whose result is too small to read at full frame. A navigate, a wait, or a hold has nothing to aim at.
25
+ - Aim the zoom at the action's own place and moment. `canon demo run` writes a timeline beside the take carrying each step's start, end, and target box, so read the zoom's target and its start off that file rather than adding up holds by hand.
26
+ - Run a push that lands on an action no faster than the floor HyperFrames' `viewport-change` rule states, and never past 1 second. That rule's own range suits an ambient reveal with no action to land on, and reads slow on a push onto a click.
27
+ - Leave the scale and the dwell after a zoom settles to the `viewport-change` rule, which states both.
28
+
29
+ ## A real pointer on a real interface
30
+
31
+ - Keep the pointer the take recorded. Never draw a second, synthetic cursor over a real interface, since two pointers on one frame leave the viewer guessing which one acted.
32
+ - Check that each click lands inside the target box the timeline records for it. A pointer arriving beside the button it claims to press reads as a fake.
33
+
34
+ ## Music, silence, and a voice
35
+
36
+ - Choose silence over a music bed that competes with a voiceover. A bed earns its place on a video with no voice, where it carries the pacing between beats.
37
+ - Sit music at least 20 dB under the voice. Check `media-use`'s narrated bed default against that floor rather than take it as given, since it has sat short of it. The mechanism, a carve rather than a flat duck, is `hyperframes-audio`'s.
38
+ - Keep a captioned voiceover at or under 160 words a minute, since captions follow the voice and a faster voice forces captions past their reading limit. `hyperframes-creative`'s narration pace sits under that ceiling.
39
+
40
+ ## Read the frame before dismissing a finding
41
+
42
+ - Open the frame at the timestamp a checker names before calling its finding a false positive, whether the checker is `hyperframes check`, `canon demo frames`, or `read-frames`.
43
+ - Report what the frame shows beside the dismissal. A dismissal with no frame read is a guess about the render, and the viewer sees the render.
44
+
45
+ ## Excuses and rebuttals
46
+
47
+ | Excuse | Rebuttal |
48
+ | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
49
+ | A slow zoom feels cinematic | A push onto an action is interface motion. Past 1 second the viewer waits on the camera instead of watching the action land. |
50
+ | The caption explains the whole feature, so it is more useful | A caption about anything but the frame on screen makes the viewer read one thing and watch another. |
51
+ | The checker flagged a frame I already know is fine | Knowing is a memory of the composition, not of the render. Open the frame. |
52
+ | Music makes it feel finished | Music under a voice that is not 20 dB down masks the words, and the words carry the explanation. |
53
+ | A drawn cursor looks cleaner than the recorded one | The recorded pointer is the one that pressed the button. A drawn one is a claim about an action the take already shows. |
54
+
55
+ ## Red flags
56
+
57
+ - A push onto a click runs longer than 1 second.
58
+ - Every move in the composition shares one duration.
59
+ - A caption is centered on screen and covers the element the step acts on.
60
+ - A caption names a step the frame is not showing.
61
+ - The zoom's start time was added up by hand while a timeline file sits beside the take.
62
+ - Two pointers appear on one frame.
63
+ - A checker finding was dismissed and no frame was opened.
64
+
65
+ ## Before handing over
66
+
67
+ - Every caption names what its frame shows, starts on its action's first frame, and holds within its time and length limits.
68
+ - Every zoom aims at a click, fill, or hover read from the timeline, and lands within its duration.
69
+ - One pointer is on screen, and each click lands inside its recorded box.
70
+ - Music, when present, sits at least 20 dB under any voice, and a captioned voice stays at or under 160 words a minute.
71
+ - Every checker finding was either fixed or dismissed with the frame it names read and reported.
72
+
73
+ ## What this delegates
74
+
75
+ - Easing, speed variety, anchoring, click timing, and every other general motion rule: `hyperframes-animation` and `hyperframes-creative`
76
+ - Title-safe margins and timeline layout: `hyperframes-studio`
77
+ - The carve that sits music under a voice: `hyperframes-audio`
78
+ - Fetching or generating music, effects, voice, and imagery: `media-use`
79
+ - Recording the take and writing its timeline: `record-screencast` through `canon demo run`
80
+ - Reading a render frame by frame: `read-frames`
@@ -0,0 +1,66 @@
1
+ ---
2
+ title: Adopted and declined
3
+ description: The source behind every number in the video-craft body, by field, which conflicts between sources were picked and why, and what was declined
4
+ ---
5
+
6
+ # Adopted and declined
7
+
8
+ Each number in the body traces to a source here, read through the `search-craft` method: the field named first, its authorities derived from the kind of body it trusts, and each question searched scoped to those authorities and open beside it. A later session extending the skill adds to this file rather than re-arguing an item settled here.
9
+
10
+ ## Captions
11
+
12
+ Field: subtitling and captioning. Authorities: broadcasters' and streamers' published subtitle guidelines, and the captioning program that sets educational practice.
13
+
14
+ **On screen for 5/6 of a second to 7 seconds, two lines, 42 characters a line.** Netflix's [Timed Text Style Guide: General Requirements](https://partnerhelp.netflixstudios.com/hc/en-us/articles/215758617-Timed-Text-Style-Guide-General-Requirements) states a minimum of 5/6 of a second (20 frames at 24 fps) and a maximum of 7 seconds per event, and its [English (USA) guide](https://partnerhelp.netflixstudios.com/hc/en-us/articles/217350977-English-USA-Timed-Text-Style-Guide) states 42 characters a line and two lines at most.
15
+
16
+ **20 characters per second, 17 for children.** The same English (USA) guide, adult and children's programs respectively.
17
+
18
+ **Start on the first frame of the action.** Netflix's [Subtitle Timing Guidelines](https://partnerhelp.netflixstudios.com/hc/en-us/articles/360051554394-Timed-Text-Style-Guide-Subtitle-Timing-Guidelines) put a subtitle's in-time on the first frame of its audio. A software video's caption names an action rather than a line of speech, so the body keys the in-time on the action's first frame.
19
+
20
+ **Never over what the frame is about.** The DCMP [Captioning Tip Sheet](https://dcmp.org/learn/225-captioning-tip-sheet): "Placement must not interfere with existing visuals/graphics."
21
+
22
+ **Captions name what the frame shows.** No source states this for a software video. It is the operator's read of an unguided render whose caption narrated the whole flow, kept because the timing rules above already assume a caption tied to one moment.
23
+
24
+ ## Zoom
25
+
26
+ Fields: interface motion design, and screen recording practice. Authorities: design systems that publish motion specs, and the reference documentation of a screen recording tool.
27
+
28
+ **A push onto an action no faster than HyperFrames' floor, never past 1 second.** HyperFrames' `viewport-change` rule states a zoom of 1.0 to 2.0 seconds and gives its reason beside the value: "under 0.8s teleports, over 2.5s drags". The body keeps that floor by pointing at the rule rather than restating it. The 1 second ceiling has two grounds. Measured: an unguided render pushed in over 2.2 seconds and a second over 1.4 seconds, and the operator judged both slow, so the range's lower half already reads slow on a push onto a click. Published: Material Design 3's [easing and duration tokens](https://m3.material.io/styles/motion/easing-and-duration/tokens-specs) end their scale at 1000 ms, the top of the extra-long band they reserve for ambient transitions, so no input-driven transition in that system runs longer.
29
+
30
+ **Zoom on a click.** Screen Studio's [auto zoom guide](https://screen.studio/guide/auto-zoom) keys its zoom on click positions and zooms nowhere a click did not occur.
31
+
32
+ **Conflict, and the pick.** HyperFrames' range and the measured renders disagree on the push onto an action, and the body takes the overlap: HyperFrames' teleport floor below, and 1 second above, which sits inside HyperFrames' range at its fast end. HyperFrames' full range stays with an ambient reveal, which matches Material's own split between input-driven and ambient motion. A tighter band was considered and declined. Material puts large expressive transitions at 450 to 600 ms, and Nielsen Norman Group's [animation duration article](https://www.nngroup.com/articles/animation-duration/) calls 400 ms "very slow", but both write for an interface a user waits on, which a video viewer is not, and that band sits below HyperFrames' stated teleport floor with nothing measured to show it reads right. Narrow the band once a composed demo is compared against the unguided renders.
33
+
34
+ ## Pointer
35
+
36
+ The two pointer rules in the body carry no number. One pointer on a frame and a click landing inside its recorded box both follow from the take recording the real pointer and the timeline recording each target's box.
37
+
38
+ ## Audio
39
+
40
+ Fields: web accessibility, and audio post-production. Authorities: the W3C's accessibility guidelines, and the audio engineering society's streaming recommendation.
41
+
42
+ **Music at least 20 dB under the voice.** WCAG 2.1 [Success Criterion 1.4.7](https://www.w3.org/WAI/WCAG21/Understanding/low-or-no-background-audio.html): "The background sounds are at least 20 decibels lower than the foreground speech content, with the exception of occasional sounds that last for only one or two seconds."
43
+
44
+ **Conflict, and the pick.** HyperFrames' `media-use` sets its narrated bed at a volume of 0.12, about 18 dB under a voice at full scale. The body takes WCAG's 20 dB, since it is the published floor and the bed default sits 2 dB short of it.
45
+
46
+ **Overall loudness is delegated.** The AES [TD1008](https://aes.org/wp-content/uploads/2024/01/20210924_TD1008_v3.13.pdf) streaming recommendation normalizes speech to -18 LUFS with a true peak no higher than -1 dBTP, while `media-use` ships -14 and -16 LUFS targets for social and podcast delivery. The body states no overall target, since the right one depends on where the video is published and `media-use` owns that operation.
47
+
48
+ ## Voiceover
49
+
50
+ Field: captioning, for the reading ceiling a voiceover's captions inherit. Authority: the captioning program's presentation rate guidance.
51
+
52
+ **At or under 160 words a minute when captioned.** The DCMP [Captioning Key: Presentation Rate](https://dcmp.org/learn/601-captioning-key---presentation-rate) caps upper-level captions at 160 words a minute. `hyperframes-creative`'s narration reference states 2.5 words a second, 150 a minute, which sits under the ceiling, so the two do not conflict. An open search of voiceover practitioners put explainers at 140 to 160 words a minute, which agrees.
53
+
54
+ Narration has no standards body for pace, and the scoped search found none, so the body sets only the ceiling captions impose and points at HyperFrames for the pace itself.
55
+
56
+ ## Declined
57
+
58
+ **Restating HyperFrames' motion rules.** Ease variety, anchoring, click timing, the scale and dwell of a zoom, and title-safe margins are stated in HyperFrames' own skills, which update on their own cadence. A copy here goes stale on theirs.
59
+
60
+ **A loudness target in the body.** See Audio above.
61
+
62
+ **Pointer smoothing and hiding at rest.** Screen Studio's [cursor guide](https://screen.studio/guide/cursor) smooths the pointer and hides it when idle, and its [guide to disabling smooth movement](https://screen.studio/guide/disable-smooth-mouse-movement) turns smoothing off for a dropdown menu. Declined because both are recorder settings. A take is composed with its pointer already baked into the frames, so a session composing from it cannot change either. They belong to whatever records the take.
63
+
64
+ **Zoom out before a cut, and a sound effect only on a click that changes something.** Neither has a source, and no operator read stands behind either, so both stay out until one does.
65
+
66
+ **Vertical 9:16 framing.** Every video measured when this skill was written was landscape. Add it when a project asks for vertical video, with its safe areas sourced from the platform's own creator documentation.
@@ -46,3 +46,7 @@ The Theme tab in the shell lists what the token stylesheet defines, grouped as c
46
46
  `canvas capture <page>/<frame>` renders one frame as a PNG, and `canvas capture <page>` renders every frame on the page. Each goes through a server started for the call, so the injected tokens are in the image, and renders at the frame's own width from the layout, so a media query resolves there. It never captures the file on disk.
47
47
 
48
48
  `--out` is the PNG for a frame and a folder for a page, defaulting to session scratch. `--json` emits `{ ok, captures }` with the path and pixel size of each frame. Each PNG is the frame's whole document, so its height follows the document and not the frame's box. The font check `canon capture` makes applies, so a frame naming a font the machine lacks fails with that reason. A refused capture reports `no-page` or `no-frame` for a target that does not exist, `no-server` when the server for the call cannot start, and `capture-failed` for an error the engine throws, such as a browser that will not launch.
49
+
50
+ `canvas capture <page> --composite` renders the whole page as one PNG, with every frame at its layout position and its own width. The image is the union of the frame boxes with no padding, transparent where no frame sits, and frames that overlap paint in the board's order. It shows the frames only, with no captions and no selection outline. Each frame is clipped to its box as it is on the board, so its height can differ from the per-frame PNG, and each shows in its default theme, since the board's theme toggle is client state the capture never sees. The font check covers the composite page and not the documents inside its frames.
51
+
52
+ Under `--composite`, `--out` is the PNG itself, defaulting to `<page>.png` beside the per-frame folder in session scratch. `--json` emits `{ ok, composite }` carrying the page, the path, and the pixel size. The flag takes a page alone, and a `<page>/<frame>` target is refused as `invalid-name`. For the length of the call the generated page sits at `.canon/canvas/.composite/`, so it shares an origin with the frames, and the capture removes it after.
@@ -130,6 +130,7 @@ Subcommands no other page describes:
130
130
  - `design regen` rewrites this repository's `canon/DESIGN.md` from `src/design/tokens.ts` and `src/design/base.css` from `src/design/neutral.ts`. `design css` emits the tokens and components as CSS on stdout, with `--no-components` for properties alone, and `design render` declares each vendored face the typography table names under `--embed-fonts`.
131
131
  - `slides render` renders a `.claude/SLIDES.md` source into a PowerPoint deck and reports any unrecognized layout name on stderr, and `slides list --json` emits the layout catalog.
132
132
  - `slides render --source <folder>` lays out each `.html` file in filename order in Chromium at 1280 by 720 and rebuilds it as editable shapes. Each element drawn as a picture prints one `✗` line on stderr naming the slide, the selector, and the properties that forced it. A link left out, being a `#slide-N` past the deck's end or any target that is neither that nor an absolute URL, prints one too, and the exit stays 0.
133
+ - A deck folder's `deck.json`, its per-slide `<body>` attributes, speaker notes, and charts are described in `slides.md`.
133
134
  - `canvas`, with its verbs, content format, and write routes, is described in `canvas.md`.
134
135
  - `labels scan` fails a pull request or a posted review whose title, body, or review comment carries a phase label, a label a code span quotes, a gitignored record path, a session link, a title word no dictionary holds, or a title breaking `standards/pr.md`'s format, casing, or length rule (`--event`, `--body-file`, `--json`).
135
136
  - `repo metadata propose` compares a description, homepage, and topic set computed from the README and `package.json` against what the remote carries, writing nothing, and `repo metadata apply` writes an explicitly supplied set through `gh repo edit` (`--description`, `--homepage`, `--topics`).
@@ -123,7 +123,7 @@ The cost is stated rather than hidden: the browser binary installs separately, s
123
123
 
124
124
  ## Composing the take into a finished video
125
125
 
126
- The take is raw. When the draft's `## Wrap` section asks for an intro, an outro, or music, `record-screencast` composes the take into `demos/<slug>/index.html` through [HyperFrames](https://hyperframes.heygen.com) and renders `renders/<slug>.mp4`, the deliverable. The skill loads HyperFrames' own `hyperframes` skill for the composition rules and runs `bunx -y hyperframes check` and `render`, then hands the render to `read-frames`. A wrap section reading `none` throughout stops at the take. The webm is only the raw take, and a gif is for a host that strips video.
126
+ The take is raw. When the draft's `## Wrap` section asks for an intro, an outro, or music, `record-screencast` composes the take into `demos/<slug>/index.html` through [HyperFrames](https://hyperframes.heygen.com) and renders `renders/<slug>.mp4`, the deliverable. The skill loads HyperFrames' own `hyperframes` skill for the composition rules and `canon:video-craft` for the captions, zoom, pointer, and audio judgment a video of software needs, aims each zoom from the take's timeline, and runs `bunx -y hyperframes check` and `render`, then hands the render to `read-frames`. A wrap section reading `none` throughout stops at the take. The webm is only the raw take, and a gif is for a host that strips video.
127
127
 
128
128
  Canon neither ships nor installs HyperFrames, and there is no `canon` verb for composing, since the render is one command already. The operator installs it once per machine:
129
129
 
@@ -55,6 +55,7 @@ CLI catalog and invocation rules for agents, split by command domain. Start with
55
55
  - [Sessions](sessions.md): Resolving live peer sessions to the worktree and branch each holds, reading which row is the caller, the liveness confidence field, what each session surface can see, and where moving a session to another machine is described
56
56
  - [Skill audit](skills-audit.md): Measuring both skill corpora against the skill standards, the checks it reads, the requirement gate that is the only failing one, and the drift verb that names bodies rewritten since a ref
57
57
  - [Citation reach](skills-reach.md): Reporting the skill bodies that cite a path no target project receives, which corpus the verb reads, the ownership key that decides what counts, the one-word qualifier that marks a citation as decided, and why the verb reports instead of gating
58
+ - [Slides](slides.md): What a folder of HTML slides declares for the whole deck in deck.json, what each slide declares on its own body, the master built from the project's tokens, speaker notes, charts, and what each refusal reports
58
59
  - [Standard success criteria](standards-audit.md): Reading the corpus against the success-criterion gate, the two headings it accepts, why the check scopes to arrival rather than the whole corpus, and the exit codes it sets
59
60
  - [State-scoped risk](state-scoped-risk.md): Reading committed state rather than an arriving change, the shipped-tree corpus the secret scan reads, what it keys on and how a deliberate value is exempted, the advisory check and its network failure mode, and why one gates while the other reports
60
61
  - [Superseded values](superseded.md): Reading where the tree still asserts a value a changed convention no longer produces, why the sweep keys on the value rather than the file, the family stem behind a templated citation, the exemption marker, the blind spots it cannot reach, and why it reports rather than gates
@@ -25,7 +25,16 @@ installs the rule under its new name and deletes the old file, whether or not
25
25
  the target's stamp records a stack. Local edits to the old file are not
26
26
  carried, and the sync says so. The sync lists each change by path before it
27
27
  applies, and the target's git diff is the record afterwards. `canon sync
28
- --check` lists the same file as `retired` or `renamed` before any sync runs. A project's own rules belong under `.claude/rules/project/`, where
28
+ --check` lists the same file as `retired` or `renamed` before any sync runs.
29
+
30
+ The `standards` band is the largest such move. Each rule that only routed a
31
+ path to a standard now ships under that standard's name at
32
+ `.claude/rules/canon/standards/<standard>.md`, so a target holding
33
+ `canon/658-plan.md` or `writing/801-markdown.md` syncs onto `standards/plan.md`
34
+ and `standards/markdown.md`. Those rules carry no number, and their globs and
35
+ bullets come from the standard's own frontmatter.
36
+
37
+ A project's own rules belong under `.claude/rules/project/`, where
29
38
  `canon standards rule` reserves `900-999` for them, and a rule placed under
30
39
  `canon/` instead is lost on the next sync.
31
40
 
@@ -130,7 +139,12 @@ runs the verb again for that name.
130
139
 
131
140
  `canon gov regen` is the one governance verb that runs against the toolkit root,
132
141
  because the `.claude/rules/` it writes there is produced output rather than an
133
- operator's working copy. It reads the stack recorded in `internal/governance.toml`
142
+ operator's working copy. It first writes `governance/rules/standards/`, one rule
143
+ per standard under `standards/` whose frontmatter carries `paths:`, clearing the
144
+ folder so a standard that drops the field loses its rule. A standard named like
145
+ a band folder or an authored rule, or a `paths:` or `rule:` that is not a list
146
+ of strings, refuses the whole run before anything is written. It then reads the
147
+ stack recorded in `internal/governance.toml`
134
148
  into `.claude/rules/canon/`, installs anything under `internal/rules/` into a
135
149
  separate `.claude/rules/internal/`, and clears both destinations first so a
136
150
  rule the record stopped naming disappears. `internal/` is what this repository
@@ -140,7 +154,7 @@ since a target has no rule source of its own that ships nowhere.
140
154
  It takes `--root <path>` and defaults to the toolkit root, prints nothing on success, and
141
155
  reports the reason on stderr with exit 1 when the record names a stack or rule
142
156
  that does not resolve. The Consumed copies stage of `bun run check` calls it and
143
- asserts the result is committed.
157
+ asserts both the generated band and the consumed copy are committed.
144
158
 
145
159
  ## Whole-project sync
146
160