@erclx/aitk 3.6.0 → 3.7.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 (44) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/claude-autoship/SKILL.md +5 -5
  3. package/claude/skills/claude-docs/SKILL.md +15 -10
  4. package/claude/skills/claude-memory-review/SKILL.md +7 -7
  5. package/claude/skills/claude-memory-review/references/receipt-format.md +1 -1
  6. package/claude/skills/claude-orchestrate/SKILL.md +2 -2
  7. package/claude/skills/claude-pr-review/SKILL.md +25 -7
  8. package/claude/skills/claude-review/SKILL.md +5 -3
  9. package/claude/skills/claude-screencast/SKILL.md +9 -4
  10. package/claude/skills/claude-tasks/SKILL.md +2 -2
  11. package/claude/skills/git-pr/references/pr.md +3 -0
  12. package/claude/skills/git-ship/SKILL.md +1 -1
  13. package/claude/skills/git-split/references/pr.md +3 -0
  14. package/claude/skills/toolkit-feedback/SKILL.md +2 -2
  15. package/docs/agents/capture.md +3 -1
  16. package/docs/agents/commands.md +4 -1
  17. package/docs/agents/demo.md +82 -0
  18. package/docs/agents/index.md +1 -0
  19. package/docs/agents/records.md +2 -2
  20. package/docs/agents/tasks.md +1 -1
  21. package/docs/ai-workflow.md +7 -5
  22. package/docs/operating-model.md +13 -4
  23. package/governance/rules/claude/558-plan.md +1 -2
  24. package/governance/rules/lib/300-testing-ts.md +1 -0
  25. package/package.json +3 -2
  26. package/src/cli.ts +4 -1
  27. package/src/commands/demo.ts +373 -0
  28. package/src/commands/feedback.ts +10 -3
  29. package/src/commands/tasks.ts +1 -1
  30. package/src/demo/beats.ts +135 -0
  31. package/src/demo/compile.ts +295 -0
  32. package/src/demo/cursors.ts +55 -0
  33. package/src/demo/drive.ts +256 -0
  34. package/src/demo/pointer.ts +178 -0
  35. package/src/demo/theme.ts +112 -0
  36. package/src/records/backup.ts +34 -8
  37. package/src/tasks/archive.ts +11 -4
  38. package/standards/bundled/pr.md +3 -0
  39. package/standards/plan.md +1 -1
  40. package/standards/tasks.md +4 -4
  41. package/tooling/claude/manifest.toml +1 -1
  42. package/tooling/claude/reference.md +6 -5
  43. package/tooling/claude/seeds/.claude/hooks/tasks-index.sh +4 -1
  44. package/tooling/claude/seeds/CLAUDE.md +1 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "aitk",
3
3
  "description": "Automated governance, versioning, and discovery tools for Claude Code.",
4
- "version": "3.6.0",
4
+ "version": "3.7.0",
5
5
  "author": {
6
6
  "name": "Eric Le",
7
7
  "url": "https://github.com/erclx"
@@ -92,15 +92,15 @@ The list covers this toolkit's authoring layout and the layout it installs, whic
92
92
 
93
93
  ## Step 6: evaluate findings
94
94
 
95
- Skip this step when Step 5 skipped review. Otherwise read `.claude/review/review-<slug>.md` at the main worktree root. Split every finding by origin before parsing the summary line (`X critical, Y should-fix, Z minor`), since the stop exists for a defect the branch inherited rather than for one this run introduced.
95
+ Skip this step when Step 5 skipped review. Otherwise read `.claude/review/branch/review-<slug>.md` at the main worktree root. Split every finding by origin before parsing the summary line (`X critical, Y should-fix, Z minor`), since the stop exists for a defect the branch inherited rather than for one this run introduced.
96
96
 
97
97
  - **This run caused it, at any severity.** Fix it, re-run the Step 3 verify commands, re-read the fixed file against what the finding claimed, and continue. Do not report it as a stop and do not offer the fix as a choice, which is the same stop wearing a proposal.
98
- - **It predates this run, critical or should-fix.** Stop: `❌ Review found non-minor issues that predate this run. See .claude/review/review-<slug>.md. Fix and run /git-ship.`
98
+ - **It predates this run, critical or should-fix.** Stop: `❌ Review found non-minor issues that predate this run. See .claude/review/branch/review-<slug>.md. Fix and run /git-ship.`
99
99
  - **It predates this run, minor only.** Continue. The minor findings stay in the on-disk review receipt. Fold any a reviewer needs into the PR's `## Technical Context`. Do not add a separate review-notes section to the PR body.
100
100
 
101
101
  Read origin as causation rather than authorship. Staleness this run induced in a file it never opened is a finding it caused, and the plan's "Files to touch" list scopes what the run builds rather than what it may repair.
102
102
 
103
- Bound the repair at one pass, the way Step 3 bounds verify. When that re-read shows the finding still standing, stop: `❌ A self-introduced finding survived one fix pass. See .claude/review/review-<slug>.md. Fix and run /git-ship.`
103
+ Bound the repair at one pass, the way Step 3 bounds verify. When that re-read shows the finding still standing, stop: `❌ A self-introduced finding survived one fix pass. See .claude/review/branch/review-<slug>.md. Fix and run /git-ship.`
104
104
 
105
105
  ## Step 7: ship
106
106
 
@@ -138,10 +138,10 @@ Respond with up to five lines:
138
138
 
139
139
  ```plaintext
140
140
  ✅ Autoshipped (draft): <PR url>
141
- <N minor findings kept in .claude/review/review-<slug>.md>
141
+ <N minor findings kept in .claude/review/branch/review-<slug>.md>
142
142
  <N facts routed to context entries>
143
143
  <N memories captured in .claude/memory/>
144
- <Memory proposal at .claude/review/memory-review-<slug>.md>
144
+ <Memory proposal at .claude/review/memory/memory-review-<slug>.md>
145
145
  ```
146
146
 
147
147
  Omit the second line if there were no minor findings, and the third if nothing routed. Omit the fourth and fifth if `claude-memory-capture` wrote no memory file this session, since an empty pen means no scoped review and no proposal. A run that routes every fact and writes none is the shape to expect, and it reports three lines.
@@ -238,30 +238,34 @@ Board-wide scope is the one place this sweep reaches past Step 3's rule against
238
238
 
239
239
  Before moving anything, count the other citations. Scan every `.claude/tasks/*.md` file except the one being processed for a `Plan:` line naming the same plan. Compare the resolved target from the parse above, never the raw target string and never the filename alone.
240
240
 
241
- A board carrying one task written `../plans/x.md` and another written `.claude/plans/x.md` cites one plan, and a raw string comparison reads two, counts zero, and archives the file out from under a live task. Comparing filenames swaps that for the opposite error, since a live plan and an archived one share a basename whenever a closed task still points into `.claude/plans-archive/`, and the count then reads a citation that does not exist and archives nothing.
241
+ A board carrying one task written `../plans/x.md` and another written `.claude/plans/x.md` cites one plan, and a raw string comparison reads two, counts zero, and archives the file out from under a live task. Comparing filenames swaps that for the opposite error, since a live plan and an archived one share a basename whenever a closed task still points into `.claude/plans/archive/`, and the count then reads a citation that does not exist and archives nothing.
242
242
 
243
243
  Exclude the closing task explicitly. It sits on the board and cites the plan itself, so a scan that counts it never reaches zero and no plan is ever archived.
244
244
 
245
- `aitk tasks plan-citations <stem> --json` answers this same question, and the archive gate already reads it. This body states the rule anyway rather than calling the verb, because a plugin skill reaches a target the moment it merges while the CLI reaches one only when a release publishes, so a target whose installed `aitk` predates the verb gets no record back and routes on nothing. Measured against the `claude:docs` `board-sweep` arm, where calling the verb archived neither plan and created no `.claude/plans-archive/`.
245
+ `aitk tasks plan-citations <stem> --json` answers this same question, and the archive gate already reads it. This body states the rule anyway rather than calling the verb, because a plugin skill reaches a target the moment it merges while the CLI reaches one only when a release publishes, so a target whose installed `aitk` predates the verb gets no record back and routes on nothing. Measured against the `claude:docs` `board-sweep` arm, where calling the verb archived neither plan and created no `.claude/plans/archive/`.
246
246
 
247
247
  Nothing in the exit code reports that. Branch on the record's `ok` and `reason` fields and never on the exit, which is the rule every task verb already carries: an operator's shell profile may wrap `aitk` in a function that runs the binary and then another command, taking its status from the second, and one measured here masks every non-zero exit rather than only an absent verb. The binary itself exits 1 for an unknown subcommand and 1 for an ordinary refusal alike. Switching this body to the verb needs a release that carries it and a read of the record rather than the exit, which together retire the duplication.
248
248
 
249
249
  A plan can serve more than one task, and archiving on the first task to close strands every other task's pointer at a path that has moved. `.claude/plans/` is gitignored, so that retarget would be the only record and there is nothing to recover it from.
250
250
 
251
- - Target resolves inside `.claude/plans/`, the file exists, and no other task file cites it: create `.claude/plans-archive/`, move the file there under its original name, overwriting any file already sitting at that name. Then rewrite the task file's `Plan:` line to the archive path, so a completed task still leads to the reasoning behind it.
251
+ - Target resolves inside `.claude/plans/`, the file exists, and no other task file cites it: create `.claude/plans/archive/`, move the file there under its original name, overwriting any file already sitting at that name. Then rewrite the task file's `Plan:` line to the archive path, so a completed task still leads to the reasoning behind it.
252
252
  - Target resolves inside `.claude/plans/` and at least one other task file cites it: leave the plan where it is and retarget nothing. Report the shared citation.
253
- - Target resolves inside `.claude/plans-archive/`: skip silently. The plan was archived by an earlier pass and the task file is already correct.
253
+ - Target resolves inside `.claude/plans/archive/`: skip silently. The plan was archived by an earlier pass and the task file is already correct.
254
254
  - Any other resolved target outside `.claude/plans/`: warn and skip.
255
255
 
256
- Write the retarget as a markdown link, `Plan: [feature-<slug>](../plans-archive/feature-<slug>.md)`, updating both halves so the text and the target stay in step. This branch is the only writer that produces a `Plan:` line nobody authored by hand, so a retarget that emits a bare path converts every task to the old form as it closes and drifts the board back to two shapes on its own.
256
+ Write the retarget as a markdown link, `Plan: [feature-<slug>](../plans/archive/feature-<slug>.md)`, updating both halves so the text and the target stay in step. This branch is the only writer that produces a `Plan:` line nobody authored by hand, so a retarget that emits a bare path converts every task to the old form as it closes and drifts the board back to two shapes on its own.
257
257
 
258
258
  ### Reviews
259
259
 
260
260
  Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../../standards/slug.md`. Fall back to `latest` on an empty result.
261
261
 
262
- If `.claude/review/review-<slug>.md` exists, delete it. `claude-review` writes with this convention.
262
+ If `.claude/review/branch/review-<slug>.md` exists, delete it. `claude-review` writes with this convention.
263
263
 
264
- Memory receipts sweep board-wide, like plans above and unlike the review receipt. Scan every `.claude/review/memory-review-*.md`, not only the one matching this slug. `claude-memory-review` writes its receipt after this skill has run in every ship chain, so a sweep keyed on the current slug looks for a file that does not exist yet, and no later branch looks for it either because a slug is unique per feature. Scanning the folder is what makes the sweep fire at all.
264
+ Then sweep the branch reports this session never opened. List `.claude/review/branch/review-*.md`, run the same slug transform over every name `git branch --format='%(refname:short)'` prints, and delete a report whose slug matches none of them. Take the names from that format rather than from `git branch --list`, which marks the current branch with `* ` and a branch checked out in another worktree with `+ `, so a transform reading the marked lines as written turns a live branch into a slug nothing matches and sweeps a report a sibling worktree is still working from. A branch report is read once, by the session addressing it, and the durable record of what a review found is the comment `claude-pr-review` posts on the pull request, so a report outliving its branch is holding nothing. Skipping this leaves them accumulating for the life of the checkout, since a slug is unique per feature and no later branch ever looks for one.
265
+
266
+ What that removes is a local-only review on a branch deleted before it opened a pull request. `claude-review` says so where a reader meets the report, and the sweep runs anyway rather than keeping every report against the one case, since nothing else ever clears them.
267
+
268
+ Memory receipts sweep board-wide, like plans above and unlike the current slug's review report. Scan every `.claude/review/memory/memory-review-*.md`, not only the one matching this slug. `claude-memory-review` writes its receipt after this skill has run in every ship chain, so a sweep keyed on the current slug looks for a file that does not exist yet, and no later branch looks for it either because a slug is unique per feature. Scanning the folder is what makes the sweep fire at all.
265
269
 
266
270
  For each receipt, count the H2 items still marked 📝 pending:
267
271
 
@@ -270,13 +274,14 @@ For each receipt, count the H2 items still marked 📝 pending:
270
274
 
271
275
  That standard owns what a fold writes and which entry types take one. `claude-memory-review` collects a receipt on the same rule, so neither body restates it.
272
276
 
273
- Do not sweep `ui-checklist-*.md` (pending human verification), `ux-audit-*.md`, or `ux-measure-*.md` (standalone deliverables), or any other `review-*.md` file.
277
+ Do not sweep `ui-checklist-*.md` (pending human verification), `ux-audit-*.md`, or `ux-measure-*.md` (standalone deliverables). Those sit at `.claude/review/` itself rather than under a producer folder, so the two globs above never reach them.
274
278
 
275
279
  Output one line per file swept:
276
280
 
277
- - `📦 Archived: <path>` for a plan moved into `.claude/plans-archive/`
281
+ - `📦 Archived: <path>` for a plan moved into `.claude/plans/archive/`
278
282
  - `⏭ Kept: <path>, still cited by <task-file>` for a plan another live task shares
279
- - `🧹 Deleted: <path>` for a swept review
283
+ - `🧹 Deleted: <path>` for a swept branch report
284
+ - `🧹 Deleted: <path>, branch gone` for a branch report whose branch no longer exists
280
285
  - `🧹 Deleted: <path>, folded <n> skips` for a swept memory receipt
281
286
  - `⏭ Kept: <path>, <n> items pending` for a memory receipt still holding decisions
282
287
 
@@ -5,7 +5,7 @@ description: Reviews `.claude/memory/` and proposes per-entry actions (promote t
5
5
 
6
6
  # Claude memory review
7
7
 
8
- This skill drives the full memory review lifecycle in five phases. Pick the phase from what the user said and whether a review receipt already exists at `<main-root>/.claude/review/memory-review-*.md`.
8
+ This skill drives the full memory review lifecycle in five phases. Pick the phase from what the user said and whether a review receipt already exists at `<main-root>/.claude/review/memory/memory-review-*.md`.
9
9
 
10
10
  What an entry looks like and why a retired one is moved rather than deleted are fixed by `${CLAUDE_SKILL_DIR}/../../standards/memory.md`. Read it before rewriting an entry, since a promotion rewrites the rule and a rewrite has to leave the entry conforming.
11
11
 
@@ -89,11 +89,11 @@ Rules that resist crisp one-line phrasing default to **Retire** over promote. Ne
89
89
 
90
90
  Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../../standards/slug.md`. Fall back to `latest` on an empty result.
91
91
 
92
- Write the full proposal to `.claude/review/memory-review-<slug>.md` at the main worktree root. Do not print it inline. Read `${CLAUDE_SKILL_DIR}/references/receipt-format.md` for the file structure, the item template, and how each action type varies the body. The four phases below rewrite items inside an existing receipt rather than authoring one, so none of them opens it.
92
+ Write the full proposal to `.claude/review/memory/memory-review-<slug>.md` at the main worktree root. Do not print it inline. Read `${CLAUDE_SKILL_DIR}/references/receipt-format.md` for the file structure, the item template, and how each action type varies the body. The four phases below rewrite items inside an existing receipt rather than authoring one, so none of them opens it.
93
93
 
94
94
  A phase changing items reads the receipt, applies every change for that phase, and writes the whole file back in one command. Batching is what keeps a per-item rewrite from costing a full read each time, and it is the only route from a linked worktree, where the guard above rules out editing a line in place.
95
95
 
96
- Tell the user `✅ Wrote proposal to .claude/review/memory-review-<slug>.md`. Ask them to fill in `Decision:` per item, then re-ping with "discuss" for question rounds or "apply" to commit.
96
+ Tell the user `✅ Wrote proposal to .claude/review/memory/memory-review-<slug>.md`. Ask them to fill in `Decision:` per item, then re-ping with "discuss" for question rounds or "apply" to commit.
97
97
 
98
98
  Rewrite the review file in place whenever the proposal changes mid-review. The file stays the source of truth for the current decisions.
99
99
 
@@ -101,7 +101,7 @@ Rewrite the review file in place whenever the proposal changes mid-review. The f
101
101
 
102
102
  Trigger: user says "challenge the promotes", "challenge before apply", or asks for a high-bar pass. Run before Apply. No mutations to memory files or promotion targets. Review file only.
103
103
 
104
- 1. Read the latest `.claude/review/memory-review-*.md` at the main root.
104
+ 1. Read the latest `.claude/review/memory/memory-review-*.md` at the main root.
105
105
  2. For each promote item, apply three tests:
106
106
  - **Absorbed**: grep the target surface for the rule's keywords. If already stated or implied, flip to retire.
107
107
  - **Delta**: if the rule is a nice-to-have next to existing bullets, flip to retire.
@@ -112,7 +112,7 @@ Trigger: user says "challenge the promotes", "challenge before apply", or asks f
112
112
 
113
113
  Trigger: user says "discuss", "respond to questions", or any `Decision:` value contains `?` or an unrecognized verb. No mutations to memory files or targets. Review file only. Multi-round.
114
114
 
115
- 1. Read the latest `.claude/review/memory-review-*.md` at the main root.
115
+ 1. Read the latest `.claude/review/memory/memory-review-*.md` at the main root.
116
116
  2. For each item whose `Decision:` contains `?` or any unrecognized verb (anything other than `apply`, `skip`, `defer`):
117
117
  - Write a `Take:` line under `Decision:`, separated by exactly one blank line. If a `Take:` line already exists, overwrite it.
118
118
  - Format: pick + one-line reason. Max 2 sentences. Decision-help style. State the recommendation (`apply` / `skip` / `retire` / specific alternative) first, then the reason. Do not enumerate tradeoffs unless one changes the call.
@@ -188,9 +188,9 @@ Trigger: user says "cleanup" or "delete the receipt" after Apply has run.
188
188
 
189
189
  Cleanup folds one receipt's skips and removes that receipt, and does nothing else. It is the fallback route now that Apply and `claude-docs` Step 10 each collect a resolved receipt on their own, so it reaches a file those two left behind rather than being the only collector. Apply is still the only phase that moves a memory entry out of the pen, and it does so per approved item into `.claude/.tmp/memory-archive/`. A user asking to sweep stale memories wants Propose, which classifies entries and writes a decision slot per entry.
190
190
 
191
- If no `.claude/review/memory-review-*.md` exists at the main root, stop: `✅ No review receipt to clean up.` Every other refusal in this skill carries a message, and the phase reads a receipt before it does anything else.
191
+ If no `.claude/review/memory/memory-review-*.md` exists at the main root, stop: `✅ No review receipt to clean up.` Every other refusal in this skill carries a message, and the phase reads a receipt before it does anything else.
192
192
 
193
- 1. Read the latest `.claude/review/memory-review-*.md` at the main root and confirm Apply has run against it. If any item is still 📝 pending, stop and name the pending numbers.
193
+ 1. Read the latest `.claude/review/memory/memory-review-*.md` at the main root and confirm Apply has run against it. If any item is still 📝 pending, stop and name the pending numbers.
194
194
  2. Collect it per the collection rule in `${CLAUDE_SKILL_DIR}/../../standards/memory.md`, folding each ⏭ skipped item before the file goes. The fold happens wherever a receipt is collected, so this phase runs the same rule the Apply sweep does.
195
195
  3. Delete that one file. Leave every other receipt beside it in place, because the pending test above covers the file it read and nothing has tested the rest.
196
196
  4. Leave every memory entry in the pen. A skip records the decline on the entry and keeps the file, and applied promotions, governance handoffs, and user-type memories each stay as the review left them.
@@ -5,7 +5,7 @@ description: The proposal file structure, its item template, and how each action
5
5
 
6
6
  # Memory review receipt format
7
7
 
8
- The shape Step 4 of the Propose phase writes to `.claude/review/memory-review-<slug>.md`. Only Propose writes this file. Challenge, Discuss, and Apply rewrite items inside a receipt that already exists, and Cleanup deletes one, so none of the four needs this file.
8
+ The shape Step 4 of the Propose phase writes to `.claude/review/memory/memory-review-<slug>.md`. Only Propose writes this file. Challenge, Discuss, and Apply rewrite items inside a receipt that already exists, and Cleanup deletes one, so none of the four needs this file.
9
9
 
10
10
  ## Structure
11
11
 
@@ -104,7 +104,7 @@ Write no shape for a correction. A correction is a sentence, and a format for ad
104
104
  4. Hand off. The human opens a worker worktree with `claude-worktree` and runs `claude-autoship` against the plan. The orchestrator does not spawn workers.
105
105
  5. Review the PR. When a worker opens a PR, run `claude-pr-review` to post findings to it. This is the deep, independent pass. The worker's autoship self-review was only the green gate.
106
106
  - Learning that a PR moved is the mechanical half, so read `${CLAUDE_SKILL_DIR}/references/orchestrator-poll.md` and start the poll it carries on the first dispatch rather than checking the board by hand. That runbook holds the routing, and a summary of it here is a second source that drifts from it.
107
- 6. Dispatch the handback. A pass posting a finding at any severity tells the session holding that branch to run `claude-address-review`, rather than waiting for a person to relay it. Re-review when the answer lands, then the human merges. Tell the trailing worker to rebase when its branch shares a seam with the merged one.
107
+ 6. Dispatch the handback. A pass posting anything owed, a finding at any severity or a testing question, tells the session holding that branch to run `claude-address-review`, rather than waiting for a person to relay it. Re-review when the answer lands, then the human merges. Tell the trailing worker to rebase when its branch shares a seam with the merged one.
108
108
  - Read the threshold off `claude-pr-review`, which states it once and governs the heading with it, so an open heading and an owed dispatch answer the same question and either one is enough to send
109
109
  - Resolve the target at the moment of sending with `aitk sessions list --branch`, never from a mapping written down earlier, since names rotate as sessions end and one recorded earlier in a session has failed inside the hour. The runbook read at step 5 routes on the count and the confidence it answers with
110
110
  - Open the message with the worktree and branch the sender believes the reader holds, asking to be corrected, whenever that mapping is inferred rather than confirmed
@@ -186,7 +186,7 @@ Promoting, demoting, and archiving a row all write `.claude/tasks/priority.md`,
186
186
  - Re-resolve every Plan pointer after anything archives a plan
187
187
  - Read the file back after writing it, since the row that lands is the row a worker acts on
188
188
 
189
- A Plan pointer goes stale from a branch this board never sees. `claude-docs` moves a plan to `.claude/plans-archive/` and rewrites the citation in the task file alone, so a row for a task still on the board keeps pointing into `.claude/plans/` at a file that has moved. Workers running the ship chain on their own branches archive plans this board still cites, and the board reads as correct until a pointer is followed.
189
+ A Plan pointer goes stale from a branch this board never sees. `claude-docs` moves a plan to `.claude/plans/archive/` and rewrites the citation in the task file alone, so a row for a task still on the board keeps pointing into `.claude/plans/` at a file that has moved. Workers running the ship chain on their own branches archive plans this board still cites, and the board reads as correct until a pointer is followed.
190
190
 
191
191
  ## Parallelism
192
192
 
@@ -13,9 +13,9 @@ findings to the PR, so the vantage is independent and the output is durable.
13
13
  It posts at least twice over a pull request's life. A first pass opens the
14
14
  review against the whole change, and every later pass reads only the commits
15
15
  added since. The heading reports state rather than pass number: a pass carrying
16
- a finding at any severity takes `## Review`, and `## Review closed` covers a
17
- pass carrying none, so the most recent comment's heading reports whether any
18
- work is owed. Every pass is this skill, and which one it is gets detected from
16
+ anything owed takes `## Review`, and `## Review closed` covers a pass carrying
17
+ none, so the most recent comment's heading reports whether any work is owed.
18
+ Owed is a finding at any severity or a Testing question, defined once at Step 4. Every pass is this skill, and which one it is gets detected from
19
19
  the thread rather than named by the caller.
20
20
 
21
21
  ## Guards
@@ -83,9 +83,15 @@ Review the diff and files for the same axes as `claude-review` (bugs, edge cases
83
83
  - Contract: does a contract downstream features depend on land correctly, and should the plan itself be questioned?
84
84
  - Consumers: when the change touches a resource with more than one consumer, enumerate them and check the rule against each. A rule written for the consumer the change targets can be wrong for a sibling that writes.
85
85
 
86
+ Then read the description's `## Testing` section, which is the one part of a pull request body this session is positioned to falsify. The branch author cannot see what a sibling branch drove the same day, and the arm list is what settles the claim rather than the diff.
87
+
88
+ Test every unchecked box against the testing discipline in `${CLAUDE_SKILL_DIR}/../../standards/bundled/pr.md`, which reserves an unchecked box for a capability the agent lacks. Raise the box when it names no human at all, when the human it names is a live agent session, or when it names a person for a step the repository ships a harness for, `scripts/sandbox/run.sh` and `scripts/eval/run.sh` being the two. Cost alone is not an answer, since authorizing a spend is the operator's and performing the run is not. A refusal the author actually met is an answer, and it names which one.
89
+
90
+ Ask rather than grade. Whether a human is genuinely required is a reading the branch author may hold a reason this session cannot see, so the question carries no severity and enters no count. What it does carry is the heading and the dispatch, on the rule Step 4 states, because a question the author never receives corrects nothing and the author is the only party who can answer it. Answering it closes it, and the answer may be that the requirement holds.
91
+
86
92
  Apply the high-signal filter: flag only what will cause incorrect behavior, break a documented rule, or mislead a downstream feature. If uncertain, do not flag.
87
93
 
88
- A later pass applies the same axes to the delta, and adds one check the first pass cannot make: did each prior finding land, and did the fix regress anything it touched. Findings of its own are normal findings, stated at the same severity and counted the same way. That count is what Step 4 reads to pick the heading, so a pass raising a finding of its own is not a close-out at any severity.
94
+ A later pass applies the same axes to the delta, and adds one check the first pass cannot make: did each prior finding land, and did the fix regress anything it touched. Findings of its own are normal findings, stated at the same severity and counted the same way. That count is one of the two things Step 4 reads to pick the heading, so a pass raising a finding of its own is not a close-out at any severity.
89
95
 
90
96
  A prior finding can also be settled by argument rather than by a fix. A reply naming the plan question that already declined it, or a constraint this session could not see, withdraws the finding or moves its grade. State that outcome in the body under the finding it changes, naming the fact that produced it, whether the argument arrived on the thread or through the channel that carried the dispatch. Dropping the finding from this body instead leaves a reader unable to tell a withdrawal from an oversight, and the reasoning goes with the session that heard it. A withdrawal removes the finding from the count, so a pass that withdrew every finding it carried is a close-out. Write the withdrawal and its cause into that body rather than taking the short close-out line Step 4 supplies, which reports prior findings addressed and would credit a fix nobody made.
91
97
 
@@ -144,9 +150,19 @@ Re-reviewed `<short-sha>`, N commits since the prior pass. X critical, Y should-
144
150
  🤖 Reviewed by Claude Code
145
151
  ```
146
152
 
147
- The threshold is stated here and nowhere else, and every other surface acting on it cites this skill rather than restating the grades. One rule governs both the heading and the dispatch: a pass carrying a finding at any severity takes `## Review` and owes a dispatch to the session holding the branch, and a pass carrying nothing at all takes `## Review closed` and owes none. Sending that dispatch is `claude-orchestrate`'s step rather than this one, which posts and stops. Post the open heading whether it is the first pass or the fourth. A pull request thread then reads as `## Review`, the worker's answer under `## Review response` from `claude-address-review`, another `## Review` while any finding is open, and `## Review closed` when none is.
153
+ A Testing box the Step 3 check raised goes in a `**Testing**` block placed after the file blocks, one bullet per box, each quoting the box and naming what would drive it. It carries no severity and enters no count, and it is still something owed, so a pass carrying one takes `## Review` and the full body rather than either line. Say so on the summary line as `plus N testing question(s)`, since the three counts read as zero and would otherwise report the pass as silent.
154
+
155
+ ```markdown
156
+ **Testing**
157
+
158
+ - `- [ ] <the box as written>` names no capability the agent lacks. `scripts/sandbox/run.sh <arm>` drives it. Was there a reason to leave it?
159
+ ```
160
+
161
+ Keep it to the boxes the check raised. Restating a box whose stated requirement holds teaches the branch author to skip the block.
148
162
 
149
- Keying either half on the grade was measured wrong: across 8 findings on one archived pass, 3 were posted as minor and 2 of those were defects a worker fixed rather than recorded, so a floor at should-fix loses real fixes to a grade that runs low. Splitting the two halves so the dispatch fired lower than the heading was the other candidate, and it left a thread reading closed while work was owed on it.
163
+ The threshold is stated here and nowhere else, and every other surface acting on it cites this skill rather than restating the grades. One rule governs both the heading and the dispatch: a pass carrying anything owed takes `## Review` and owes a dispatch to the session holding the branch, and a pass carrying nothing at all takes `## Review closed` and owes none. Owed covers a finding at any severity and a Testing question alike, which is what keeps the two halves from separating. Sending that dispatch is `claude-orchestrate`'s step rather than this one, which posts and stops. Post the open heading whether it is the first pass or the fourth. A pull request thread then reads as `## Review`, the worker's answer under `## Review response` from `claude-address-review`, another `## Review` while anything stays open, and `## Review closed` when nothing does.
164
+
165
+ Keying either half on the grade was measured wrong: across 8 findings on one archived pass, 3 were posted as minor and 2 of those were defects a worker fixed rather than recorded, so a floor at should-fix loses real fixes to a grade that runs low. Splitting the two halves so the dispatch fired lower than the heading was the other candidate, and it left a thread reading closed while work was owed on it. The Testing question was first written to sit outside both, which is that same split reached from the other side, and it left the one party who could answer the question with no route to it.
150
166
 
151
167
  The cost is that the merge decision no longer reads off the heading alone, since an open heading covers a minor as well as a critical. Take it from the counts on the summary line, which is where they already sit. No summary line reports the merge as unblocked under either heading, since a thread reading open cannot also report that nothing blocks it.
152
168
 
@@ -174,7 +190,7 @@ gh pr review <number> --comment --body-file .claude/.tmp/pr-review/body-<number>
174
190
 
175
191
  A pass carrying nothing at all takes `## Review closed` and a short body, with the footer line included either way. On a first pass, post `✅ No findings. Reviewed against project docs and the board.` On a later pass, post `✅ Prior findings addressed. Re-reviewed <short-sha>, N commits since the prior pass.`
176
192
 
177
- A pass carrying only minors is an ordinary finding-carrying pass, so it takes the open heading and the full shape rather than either short line, since the minors have to be readable and neither line reports them. Keep whichever scope sentence the pass owes on the summary line:
193
+ A pass carrying only minors is an ordinary finding-carrying pass, so it takes the open heading and the full shape rather than either short line, since the minors have to be readable and neither line reports them. A pass carrying only Testing questions takes the same route for the same reason. Keep whichever scope sentence the pass owes on the summary line:
178
194
 
179
195
  ```markdown
180
196
  ## Review
@@ -198,4 +214,6 @@ Post a close-out even when there is nothing to report. A review left with no clo
198
214
  X critical, Y should-fix, Z minor. Posted to PR #<number>.
199
215
  ```
200
216
 
217
+ Add `N Testing question(s) raised.` to that line when the Step 3 check raised any. The counts cover findings alone, so a pass whose only output was a question otherwise reports as silent to the session that drove it. That session is not who the question is addressed to, which is what the dispatch covers.
218
+
201
219
  Report the merge decision as a plain recommendation in chat (merge, or address findings first). Do not merge.
@@ -120,7 +120,7 @@ If nothing is wrong, use: `✅ No findings.`
120
120
 
121
121
  Derive `<slug>` per `${CLAUDE_SKILL_DIR}/../../standards/slug.md`. Fall back to `latest` on an empty result.
122
122
 
123
- Write the full report directly to `.claude/review/review-<slug>.md` at the main worktree root, not the current worktree. See Worktrees in `CLAUDE.md`. Create the directory if it does not exist. Always overwrite.
123
+ Write the full report directly to `.claude/review/branch/review-<slug>.md` at the main worktree root, not the current worktree. See Worktrees in `CLAUDE.md`. Create the directory if it does not exist. Always overwrite.
124
124
 
125
125
  From a linked worktree the file-editing tools refuse that path, so the report goes out through `Bash`. Send the `mkdir -p` and the heredoc as two plain commands rather than joining them with `&&`, which is refused as compound.
126
126
 
@@ -128,13 +128,15 @@ If there are no findings, write `✅ No findings.` to the file with a timestamp.
128
128
 
129
129
  The `.claude/review/` directory is gitignored. Do not stage or commit the file.
130
130
 
131
+ The report is disposable. `claude-docs` deletes it at ship, and sweeps any branch report whose branch no longer exists, because the durable record of what a review found is the comment `claude-pr-review` posts on the pull request. A review run on a branch that never opens one leaves nothing behind once that branch is gone, so fold anything worth keeping into the pull request body or a task finding while the report is still on disk.
132
+
131
133
  ### Chat output
132
134
 
133
135
  Output only the summary line and the file path. Do not repeat the full report in chat.
134
136
 
135
137
  ```plaintext
136
138
  X critical, Y should-fix, Z minor across N files.
137
- 📝 Wrote .claude/review/review-<slug>.md
139
+ 📝 Wrote .claude/review/branch/review-<slug>.md
138
140
  ```
139
141
 
140
- If no findings: `✅ No findings. Wrote .claude/review/review-<slug>.md`
142
+ If no findings: `✅ No findings. Wrote .claude/review/branch/review-<slug>.md`
@@ -8,8 +8,8 @@ description: Drafts a screencast script with pre-seeded beats, defaults, and dec
8
8
  ## Guards
9
9
 
10
10
  - If no topic is provided, stop: `❌ No screencast topic. Describe what you are recording.`
11
- - Do not record, edit video, or generate captions. Output the script and stop.
12
- - Stack-agnostic. Never name recording software, editing software, fonts, or window managers in the draft.
11
+ - Draft, then hand off. Do not edit video or generate captions, and do not drive the application. A recording is another command's job rather than something forbidden: write the draft, name `aitk demo compile` as the next step, and stop.
12
+ - Stack-agnostic in the draft. Never name a recording tool, an editing tool, a font, or a window manager. Keep selectors, URLs, wait conditions, and timings out of the beats too, since those four are exactly what the compiler adds in a plan of its own. A beat carrying them stops being a document a person can read and edit down.
13
13
 
14
14
  ## Step 1: read the project context
15
15
 
@@ -156,7 +156,12 @@ Print the file path on its own line and a one-line summary. Do not paraphrase th
156
156
  ```markdown
157
157
  📝 Wrote .claude/.tmp/screencast/<slug>.md
158
158
 
159
- Draft has 5 beats and pre-seeded defaults. Edit beats and resolved decisions, then record.
159
+ Draft has 5 beats and pre-seeded defaults. Edit the beats and the resolved decisions.
160
+
161
+ To record it rather than shoot it by hand:
162
+ aitk demo compile .claude/.tmp/screencast/<slug>.md
160
163
  ```
161
164
 
162
- Do not proceed to recording. Do not generate captions. Stop.
165
+ Name the command and stop there. Do not compile the draft, do not run it, and do not generate captions. The operator edits the beats first, and the compiler reports which selectors and URLs they still owe it.
166
+
167
+ Say so plainly if `aitk demo compile` is not available, rather than driving the application some other way. The command ships with the CLI and the skills ship with the plugin, so a project carrying one and not the other is a real state.
@@ -57,7 +57,7 @@ Scan for work that has been decided and would otherwise be forgotten. Three orig
57
57
 
58
58
  List `.claude/groundwork/` and run `gh issue list --state open` when a remote is configured, then grep the board for each track name and issue number. Report any with no task, one line each.
59
59
 
60
- Read the dumps through `aitk intake list --json`, which reports items, open, unread, and malformed per folder and owns the parse of the answer contract `${CLAUDE_SKILL_DIR}/../../standards/intake.md` fixes. Then grep both `.claude/tasks/` and `.claude/task-archive/` for each folder slug. A dump with no live task is the ordinary shape of one already promoted and shipped, so a check reading the board by itself reports every finished folder as abandoned.
60
+ Read the dumps through `aitk intake list --json`, which reports items, open, unread, and malformed per folder and owns the parse of the answer contract `${CLAUDE_SKILL_DIR}/../../standards/intake.md` fixes. Then grep both `.claude/tasks/` and `.claude/tasks/archive/` for each folder slug. A dump with no live task is the ordinary shape of one already promoted and shipped, so a check reading the board by itself reports every finished folder as abandoned.
61
61
 
62
62
  A dump is the stronger case for this scan rather than the weaker one. A track holds one question and stays visible, while a dump holds dozens of items whose verdicts were reached and then left with nothing carrying them forward.
63
63
 
@@ -153,7 +153,7 @@ Drop either block when it carries no rows. When both are empty, which is the ord
153
153
  Archive, reporting the paths the command returned:
154
154
 
155
155
  ```plaintext
156
- 📦 Archived: .claude/task-archive/vXX.Y-<slug>.md
156
+ 📦 Archived: .claude/tasks/archive/vXX.Y-<slug>.md
157
157
 
158
158
  <ordering and index disposition in one line>
159
159
  ```
@@ -54,6 +54,9 @@ Does not govern:
54
54
  - Quote the count or output the run reported, never a figure carried from elsewhere.
55
55
  - Leave a box unchecked only when a human is required, and name which human and why on the same line.
56
56
  - Human-only covers visual or aesthetic judgment, anything needing credentials or a live third-party service, anything needing a second machine or a fresh OS, and judgment about whether a boundary or an abstraction reads correctly. The agent runs everything else.
57
+ - What makes a human required is a capability the agent lacks, never the cost of the run. Authorizing a spend is the operator's and performing the run is not, so an arm the repository ships a harness for gets driven once the operator has cleared the spend, and the box records what it returned.
58
+ - A tool refusal that actually fired is a capability gap, and the line says which refusal rather than naming the cost behind it. A refusal predicted and never met is not one.
59
+ - A live agent session is not a human. A box reading `needs a live session driving the skill` names the thing writing the description, so that run is owed rather than blocked.
57
60
  - Put a request for the reviewer under `## For the reviewer`. It is a request rather than unfinished testing, so it never appears as an unchecked Testing box.
58
61
 
59
62
  ## Formatting
@@ -38,7 +38,7 @@ Output up to four lines:
38
38
  ✅ Shipped
39
39
  <N facts routed to context entries>
40
40
  <N memories captured in .claude/memory/>
41
- <Memory proposal at .claude/review/memory-review-<slug>.md>
41
+ <Memory proposal at .claude/review/memory/memory-review-<slug>.md>
42
42
  ```
43
43
 
44
44
  Omit the second line if nothing routed. Omit the third and fourth if `claude-memory-capture` wrote no memory file this session, since an empty pen means no scoped review and no proposal.
@@ -54,6 +54,9 @@ Does not govern:
54
54
  - Quote the count or output the run reported, never a figure carried from elsewhere.
55
55
  - Leave a box unchecked only when a human is required, and name which human and why on the same line.
56
56
  - Human-only covers visual or aesthetic judgment, anything needing credentials or a live third-party service, anything needing a second machine or a fresh OS, and judgment about whether a boundary or an abstraction reads correctly. The agent runs everything else.
57
+ - What makes a human required is a capability the agent lacks, never the cost of the run. Authorizing a spend is the operator's and performing the run is not, so an arm the repository ships a harness for gets driven once the operator has cleared the spend, and the box records what it returned.
58
+ - A tool refusal that actually fired is a capability gap, and the line says which refusal rather than naming the cost behind it. A refusal predicted and never met is not one.
59
+ - A live agent session is not a human. A box reading `needs a live session driving the skill` names the thing writing the description, so that run is owed rather than blocked.
57
60
  - Put a request for the reviewer under `## For the reviewer`. It is a request rather than unfinished testing, so it never appears as an unchecked Testing box.
58
61
 
59
62
  ## Formatting
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: toolkit-feedback
3
- description: Format a paste-back report about something broken, missing, or off in aitk and write it directly to the toolkit's `.claude/review/` folder via `aitk feedback`. Use when asked to "send this to the toolkit", "report this to aitk", "file toolkit feedback", or "give the toolkit feedback about X". Do NOT use for general complaints about other tooling, IDE issues, or in-project bugs that do not implicate aitk surfaces.
3
+ description: Format a paste-back report about something broken, missing, or off in aitk and write it directly to the toolkit's `.claude/review/feedback/` folder via `aitk feedback`. Use when asked to "send this to the toolkit", "report this to aitk", "file toolkit feedback", or "give the toolkit feedback about X". Do NOT use for general complaints about other tooling, IDE issues, or in-project bugs that do not implicate aitk surfaces.
4
4
  ---
5
5
 
6
6
  # Toolkit feedback
@@ -48,7 +48,7 @@ Detect whether `aitk` is on PATH:
48
48
  command -v aitk >/dev/null 2>&1
49
49
  ```
50
50
 
51
- If present, pipe the block to `aitk feedback`. The CLI writes to its own repo's `.claude/review/feedback-<slug>-<ts>.md` and prints the absolute path on stdout:
51
+ If present, pipe the block to `aitk feedback`. The CLI writes to its own repo's `.claude/review/feedback/feedback-<slug>-<ts>.md` and prints the absolute path on stdout:
52
52
 
53
53
  ```bash
54
54
  cat <<'EOF' | aitk feedback
@@ -32,4 +32,6 @@ What is asserted is the font. The command reads the first family the captured el
32
32
 
33
33
  The browser binary installs separately from the package. A fresh clone runs `bunx playwright install chromium` once, and a run that cannot launch one reports the engine's own remediation inside the frame and exits 1 rather than escaping as a stack trace.
34
34
 
35
- The command is toolkit-only. Its render module holds every browser reference in the toolkit and `files` in `package.json` excludes it, so an installed `aitk` carries the command, reports it as absent on one line, and exits 1. Every other command is unaffected, which is the reason the browser import sits behind a dynamic import rather than at a command's top level.
35
+ The command is toolkit-only. Its render module holds every browser reference capture makes and `files` in `package.json` excludes it, so an installed `aitk` carries the command, reports it as absent on one line, and exits 1. Every other command is unaffected, which is the reason the browser import sits behind a dynamic import rather than at a command's top level.
36
+
37
+ `aitk demo` is the other browser command and it ships, because the reason capture stays here is that it regenerates images committed to this repository and a target has nothing to regenerate. See `demo.md`.
@@ -24,7 +24,7 @@ Full help: `aitk <command> --help`. Behavior notes for the install and sync verb
24
24
  | `aitk design render` | Render `.claude/DESIGN.md` tokens to HTML and CSS |
25
25
  | `aitk slides render` | Render a `.claude/SLIDES.md` source into a PowerPoint deck |
26
26
  | `aitk slides list` | List the available slide layouts (`--json` for the catalog) |
27
- | `aitk feedback` | Write toolkit feedback from stdin to `.claude/review/`, or open a GitHub issue with `--github` |
27
+ | `aitk feedback` | Write toolkit feedback from stdin to `.claude/review/feedback/`, or open a GitHub issue with `--github` |
28
28
  | `aitk transcripts <url>` | Fetch a YouTube transcript with metadata frontmatter (needs `yt-dlp`) |
29
29
  | `aitk tasks archive` | Move a shipped task off the board, clear its ordering row, and regenerate the index |
30
30
  | `aitk tasks pull-request` | Record a pull request number on the task a branch closes, by stem or `--plan` (`--json`) |
@@ -57,6 +57,8 @@ Full help: `aitk <command> --help`. Behavior notes for the install and sync verb
57
57
  | `aitk capture [source]` | Render HTML capture sources to PNG, toolkit-only and absent from an installed package |
58
58
  | `aitk upgrade` | Reinstall the CLI globally with the package manager the install path names (`--json`) |
59
59
 
60
+ `aitk demo` is the second browser command and the one that ships, since its purpose is running in a target rather than regenerating what this repository commits. It needs a browser binary the package does not carry, installed once with `bunx playwright install chromium`.
61
+
60
62
  ## Domain commands
61
63
 
62
64
  Each domain exposes a consistent shape where applicable: `list`, `install`, `sync`, `create`.
@@ -68,6 +70,7 @@ Each domain exposes a consistent shape where applicable: `list`, `install`, `syn
68
70
  | `standards` | `list`, `<name>` |
69
71
  | `gov` | `list`, `install`, `sync`, `build`, `regen`, `test-order`, `superseded` |
70
72
  | `claude` | `init`, `sync`, `seeds list`, `skills list`, `skills audit`, `skills drift`, `skills reach`, `setup [dest]` |
73
+ | `demo` | `compile`, `run` |
71
74
  | `wiki` | `init` |
72
75
  | `design` | `render` |
73
76
  | `slides` | `render`, `list` |
@@ -0,0 +1,82 @@
1
+ ---
2
+ title: Demo
3
+ description: Compiling a screencast draft into a runnable plan, driving a served application to a recording and a still, the pointer the recording paints, and what each refusal reports
4
+ ---
5
+
6
+ # Demo
7
+
8
+ `aitk demo` drives a project's running application and writes a recording of what it did, plus a still frame of the same run. It exists so a project card and a short demo stop depending on someone sitting down to record one by hand.
9
+
10
+ Two verbs, and they are separate because the artifact between them is edited.
11
+
12
+ ```bash
13
+ aitk demo compile .claude/.tmp/screencast/inline-edit.md
14
+ aitk demo run demos/inline-edit.json
15
+ aitk demo run demos/inline-edit.json --cursor ~/cursors/theme --out assets
16
+ ```
17
+
18
+ ## The draft and the plan are different files
19
+
20
+ `claude-screencast` drafts beats for a person. A beat carries what is on screen, one verb, what to watch for, an emphasis, and a caption, and none of that names a selector, a URL, a wait condition, or a timing. Those four are what an executor needs and what would ruin the draft, since the format is pre-seeded so the operator edits down rather than fills blanks.
21
+
22
+ So `aitk demo compile` writes a second artifact rather than adding fields to a beat. It maps each beat's verb to a step, seeds the timing, marks which beat the still comes from, and leaves the target and the URL empty for a person to fill. The report names every field it could not supply.
23
+
24
+ The plan is committed, not scratch. Its timing is a starting point tuned by watching a recording, and the draft cannot reproduce a tuned value, so a recompile over an existing plan refuses and names `--force`.
25
+
26
+ | Option | Behavior |
27
+ | --------------- | ----------------------------------------------------------------- |
28
+ | `--out <dir>` | Directory the plan and its output paths point at, default `demos` |
29
+ | `--slug <slug>` | Plan name, defaulting to the draft filename |
30
+ | `--force` | Overwrite an existing plan, losing any timing tuned by hand |
31
+ | `--json` | Add a record on stdout carrying the beats and what is unfilled |
32
+
33
+ ## What a run does
34
+
35
+ `aitk demo run` reads the plan, refuses if a field is still empty, and drives the application the plan's URL names. It records the whole run to `webm` and writes the still from the beat the draft calls the hero, falling back to the last beat, since a demo's final state is the payoff and a cold open is usually an empty screen.
36
+
37
+ | Option | Behavior |
38
+ | ---------------- | ----------------------------------------------------------- |
39
+ | `--out <dir>` | Directory to write into, overriding what the plan names |
40
+ | `--cursor <dir>` | Cursor theme folder to draw the pointer from |
41
+ | `--no-video` | Write only the still |
42
+ | `--no-still` | Write only the recording |
43
+ | `--json` | Add a record on stdout carrying both paths and the duration |
44
+
45
+ A step waits on its `waitFor` selector becoming visible and then holds for its own `holdMs`, which is what puts a finished state on screen long enough to read. `navigate` uses the plan's URL unless the step names its own.
46
+
47
+ ## The pointer is painted inside the page
48
+
49
+ The browser engine's own annotation draws a red dot at the moment of a click and an action label in a corner. It paints no cursor, so a run without more looks like the pointer teleports between targets.
50
+
51
+ The recorder injects a pointer element before navigation and moves it through the engine's pointer with interpolated steps rather than through the element-clicking helper, which resolves a target and jumps to it. The step count is the whole difference between a cursor that travels and one that appears. The pointer reads the element under it on every move and switches between an arrow, a hand, and a text beam, so it reflects the page the way a real cursor does.
52
+
53
+ `--cursor` points at a folder of Windows cursor resources and the browser decodes them directly, with no conversion step and no image tooling. Each resource carries a hotspot per size, and the largest entry's hotspot scaled to the drawn size is what puts the artwork's tip where the click lands. A theme contributes per state, so a folder holding an arrow and no hand still supplies its arrow and the bundled artwork covers the rest.
54
+
55
+ Three of the nineteen states a theme carries are read. A drag, a resize, or a wait shows the arrow where a real session would show something else, and the two animated states have no still frame to draw.
56
+
57
+ ## What the refusals report
58
+
59
+ Every refusal exits 1 and names its reason in the `--json` record, so a skill branches on `reason` rather than on the exit code.
60
+
61
+ | Reason | What happened |
62
+ | --------------------- | ----------------------------------------------------------------------------------- |
63
+ | `draft-missing` | No file at the path given to `compile` |
64
+ | `draft-unreadable` | The draft carries no beat sheet, or a sheet with no beats |
65
+ | `plan-exists` | A plan is already there and `--force` was not passed |
66
+ | `plan-unresolved` | A URL or a target is still empty, named field by field |
67
+ | `no-output-requested` | `--no-video` and `--no-still` together, which would drive the app and write nothing |
68
+ | `plan-unreadable` | The plan is not JSON, or a step names a kind nothing drives |
69
+ | `browser-missing` | The browser binary is not installed, with `install` carrying the command |
70
+ | `engine-missing` | The browser package itself did not resolve |
71
+
72
+ ## The browser reaches every target
73
+
74
+ Unlike `aitk capture`, this command ships. Capture is toolkit-only because it regenerates images committed to this repository, and that reason does not transfer to a command whose whole purpose is running in someone else's project.
75
+
76
+ The cost is stated rather than hidden: the browser binary installs separately, so a target runs `bunx playwright install chromium` once before a recording works at all. A run that cannot launch reports that command inside the frame and exits 1.
77
+
78
+ ## What it does not do
79
+
80
+ A generated recording is a raw take. Nothing trims it, scores it, or narrates it, and the beat's caption does not reach the video, since the engine's overlay carries the action it performed rather than text from the draft.
81
+
82
+ It also does not replace a narrated screencast. That has a hero moment, a cut list, and a voice, none of which survives being generated. This answers the case where the alternative is recording nothing.
@@ -14,6 +14,7 @@ CLI catalog and invocation rules for agents, split by command domain. Start with
14
14
  - [Comments](comments.md): Comment density by language and kind, the two structural exclusions, and how the degradation sweep finds its vocabulary
15
15
  - [Context audit checks](context-audit-checks.md): What each non-gating check reports, the unit each checkpoint is measured in, the architecture record's length gate and claim coverage, which folders each check reaches, and what moved to the attribute tier
16
16
  - [Context audit](context-audit.md): Running the audit, its flags and folder scope, the exit codes, the citation gate, and the widened gate the seed stage runs
17
+ - [Demo](demo.md): Compiling a screencast draft into a runnable plan, driving a served application to a recording and a still, the pointer the recording paints, and what each refusal reports
17
18
  - [Docs](docs.md): How aitk docs resolves the toolkit's own reference surface from an install root, and how a split domain is named
18
19
  - [Indexes](indexes.md): Flags, exit codes, and JSON shape for aitk indexes regen, plus when it auto-stages what it rewrote
19
20
  - [Install and sync](install-and-sync.md): What each install and sync verb writes, refuses, or leaves alone, and how drift is attributed in a target project
@@ -110,7 +110,7 @@ aitk records push --json
110
110
  aitk records pull
111
111
  ```
112
112
 
113
- The backed folders are `groundwork`, `intake`, `memory`, `plans`, `plans-archive`, `review`, `review-archive`, `task-archive`, `tasks`, and `teach`, all under `.claude/`. They are the Claude ignore group the claude manifest ships, minus three entries: `.claude/.tmp`, which is deletable without loss, `.claude/worktrees/`, whose contents belong to the project repository already, and `.claude/.records.git/`, which is the history the other ten are pushed into. The list is a constant rather than configuration, matching the four folder names `validate` hardcodes.
113
+ The backed folders are `groundwork`, `intake`, `memory`, `plans`, `review`, `tasks`, and `teach`, all under `.claude/`. They are the Claude ignore group the claude manifest ships, minus three entries: `.claude/.tmp`, which is deletable without loss, `.claude/worktrees/`, whose contents belong to the project repository already, and `.claude/.records.git/`, which is the history the other seven are pushed into. Each name is a top-level record folder and every archive sits inside the one it archives, so the list stays at one entry per surface however many archives appear. It is a constant rather than configuration, matching the six record kinds `validate` hardcodes.
114
114
 
115
115
  Records are gitignored by design, so the history lives in a second git directory at `.claude/.records.git` with `.claude/` as its work tree. Every path stays where it is, which is what a separate checkout could not do. The verbs stage the ten folders by explicit pathspec with `--force`, so nothing outside them can enter the index however the ignore rules read, and the project working tree and its index are never touched.
116
116
 
@@ -145,4 +145,4 @@ The two `pull` refusals exist because the directions are not symmetric. A push o
145
145
 
146
146
  ### When it runs
147
147
 
148
- `.husky/post-merge` runs `push` after the task-archive loop, on every merge rather than only on one that archived a task. A review report and a memory entry both land on runs that close nothing. The call sits inside an `if` and last in the file, so an unreachable remote neither aborts the hook nor delays the archiving above it, and a checkout that never ran the setup reports nothing. Anything the hook misses is covered by running the verb by hand.
148
+ `.husky/post-merge` runs `push` after the task archiving loop, on every merge rather than only on one that archived a task. A review report and a memory entry both land on runs that close nothing. The call sits inside an `if` and last in the file, so an unreachable remote neither aborts the hook nor delays the archiving above it, and a checkout that never ran the setup reports nothing. Anything the hook misses is covered by running the verb by hand.
@@ -7,7 +7,7 @@ description: Selecting a shipped task by stem or pull request, recording a numbe
7
7
 
8
8
  ## Archive
9
9
 
10
- `aitk tasks archive` moves a shipped task from `.claude/tasks/` into `.claude/task-archive/`, drops its row from `priority.md`, and regenerates the board index. The three run as one unit, so the attended and unattended callers cannot archive differently.
10
+ `aitk tasks archive` moves a shipped task from `.claude/tasks/` into `.claude/tasks/archive/`, drops its row from `priority.md`, and regenerates the board index. The three run as one unit, so the attended and unattended callers cannot archive differently.
11
11
 
12
12
  Name the task by its filename stem, or by the pull request it carries:
13
13