@journeykit/canon 0.31.0 → 0.32.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 (121) hide show
  1. package/dist/skills/SKILL.src.md +33 -14
  2. package/dist/skills/reference/brief-align.md +2 -2
  3. package/dist/skills/reference/brief-clarify.md +2 -2
  4. package/dist/skills/reference/brief-harden.md +2 -2
  5. package/dist/skills/reference/brief-polish.md +4 -4
  6. package/dist/skills/reference/brief-shape.md +2 -2
  7. package/dist/skills/reference/canon-gate.md +4 -4
  8. package/dist/skills/reference/canon-policy.md +7 -4
  9. package/dist/skills/reference/canon-report-dashboard.md +7 -4
  10. package/dist/skills/reference/canon-subject.md +5 -5
  11. package/dist/skills/reference/role-implementer.md +10 -8
  12. package/dist/skills/reference/role-orchestrator.md +35 -20
  13. package/dist/skills/reference/role-planner.md +67 -28
  14. package/dist/skills/reference/role-reviewer.md +22 -14
  15. package/man/canon-adapter-authorize.1 +2 -2
  16. package/man/canon-adapter-validate.1 +2 -2
  17. package/man/canon-adapter.1 +2 -2
  18. package/man/canon-artifacts-move.1 +2 -2
  19. package/man/canon-artifacts-store.1 +2 -2
  20. package/man/canon-artifacts-verify.1 +2 -2
  21. package/man/canon-artifacts.1 +2 -2
  22. package/man/canon-brief-approve.1 +12 -3
  23. package/man/canon-brief-check.1 +2 -2
  24. package/man/canon-brief-show.1 +6 -3
  25. package/man/canon-brief.1 +2 -2
  26. package/man/canon-change-new.1 +2 -2
  27. package/man/canon-change.1 +2 -2
  28. package/man/canon-completion.1 +2 -2
  29. package/man/canon-context-pack-add.1 +2 -2
  30. package/man/canon-context-pack-show.1 +2 -2
  31. package/man/canon-context-pack-verify.1 +2 -2
  32. package/man/canon-context-pack.1 +2 -2
  33. package/man/canon-context.1 +2 -2
  34. package/man/canon-dashboard.1 +2 -2
  35. package/man/canon-demo-init.1 +2 -2
  36. package/man/canon-demo-review.1 +2 -2
  37. package/man/canon-demo.1 +2 -2
  38. package/man/canon-dispatch-begin.1 +2 -2
  39. package/man/canon-dispatch-diff.1 +2 -2
  40. package/man/canon-dispatch-end.1 +2 -2
  41. package/man/canon-dispatch.1 +2 -2
  42. package/man/canon-divergence-accept.1 +12 -3
  43. package/man/canon-divergence-add.1 +2 -2
  44. package/man/canon-divergence-defer.1 +2 -2
  45. package/man/canon-divergence-list.1 +2 -2
  46. package/man/canon-divergence-resolve.1 +2 -2
  47. package/man/canon-divergence.1 +2 -2
  48. package/man/canon-evidence-add.1 +2 -2
  49. package/man/canon-evidence-approval-payload.1 +2 -2
  50. package/man/canon-evidence-audit.1 +2 -2
  51. package/man/canon-evidence.1 +2 -2
  52. package/man/canon-export.1 +2 -2
  53. package/man/canon-feature-new.1 +2 -2
  54. package/man/canon-feature.1 +2 -2
  55. package/man/canon-finding-add.1 +2 -2
  56. package/man/canon-finding-close.1 +2 -2
  57. package/man/canon-finding-list.1 +2 -2
  58. package/man/canon-finding.1 +2 -2
  59. package/man/canon-format.1 +2 -2
  60. package/man/canon-gate-check.1 +2 -2
  61. package/man/canon-gate-install-hooks.1 +2 -2
  62. package/man/canon-gate-promote.1 +2 -2
  63. package/man/canon-gate.1 +2 -2
  64. package/man/canon-ingest-plans.1 +2 -2
  65. package/man/canon-ingest-records.1 +2 -2
  66. package/man/canon-ingest-sessions.1 +2 -2
  67. package/man/canon-ingest.1 +2 -2
  68. package/man/canon-init.1 +2 -2
  69. package/man/canon-inventory-sync.1 +2 -2
  70. package/man/canon-inventory.1 +2 -2
  71. package/man/canon-ledger-compact.1 +2 -2
  72. package/man/canon-ledger.1 +2 -2
  73. package/man/canon-migrate.1 +15 -3
  74. package/man/canon-plugin-sync.1 +2 -2
  75. package/man/canon-plugin.1 +2 -2
  76. package/man/canon-policy-approve.1 +9 -3
  77. package/man/canon-policy-show.1 +2 -2
  78. package/man/canon-policy.1 +2 -2
  79. package/man/canon-prompt-add.1 +2 -2
  80. package/man/canon-prompt-show.1 +2 -2
  81. package/man/canon-prompt.1 +2 -2
  82. package/man/canon-purge.1 +2 -2
  83. package/man/canon-query.1 +2 -2
  84. package/man/canon-regime-show.1 +2 -2
  85. package/man/canon-regime.1 +2 -2
  86. package/man/canon-report-build.1 +2 -2
  87. package/man/canon-report-check.1 +2 -2
  88. package/man/canon-report-snapshot.1 +2 -2
  89. package/man/canon-report.1 +2 -2
  90. package/man/canon-retrieve.1 +2 -2
  91. package/man/canon-review-change.1 +2 -2
  92. package/man/canon-review-scenario.1 +2 -2
  93. package/man/canon-review.1 +2 -2
  94. package/man/canon-scenario-new.1 +2 -2
  95. package/man/canon-scenario.1 +2 -2
  96. package/man/canon-schema.1 +2 -2
  97. package/man/canon-search.1 +2 -2
  98. package/man/canon-selftest.1 +2 -2
  99. package/man/canon-skills-check.1 +2 -2
  100. package/man/canon-skills-doctor.1 +2 -2
  101. package/man/canon-skills-install.1 +2 -2
  102. package/man/canon-skills-show.1 +2 -2
  103. package/man/canon-skills.1 +2 -2
  104. package/man/canon-status.1 +2 -2
  105. package/man/canon-strategy-approval-payload.1 +2 -2
  106. package/man/canon-strategy-promote.1 +2 -2
  107. package/man/canon-strategy-rollback.1 +2 -2
  108. package/man/canon-strategy.1 +2 -2
  109. package/man/canon-subject-adopt.1 +2 -2
  110. package/man/canon-subject-move.1 +2 -2
  111. package/man/canon-subject-new.1 +2 -2
  112. package/man/canon-subject-show.1 +2 -2
  113. package/man/canon-subject-unadopt.1 +2 -2
  114. package/man/canon-subject.1 +2 -2
  115. package/man/canon-task-done.1 +2 -2
  116. package/man/canon-task.1 +2 -2
  117. package/man/canon-tier-age.1 +2 -2
  118. package/man/canon-tier.1 +2 -2
  119. package/man/canon-trace.1 +2 -2
  120. package/man/canon.1 +2 -2
  121. package/package.json +4 -4
@@ -26,18 +26,34 @@ a feature, a one-line request included. A human is needed once per scope:
26
26
 
27
27
  - **The approval** (step 1). For a new subject or a scope change, the
28
28
  human must approve the brief. Write the brief,
29
- run `canon brief check` until it reports no blockers, then stop and
30
- report the brief to the human: build nothing for that scope (no
29
+ run `canon brief check` until it reports no blockers, then show it, ask and
30
+ record the answer: build nothing for that scope (no
31
31
  scenarios, code or evidence) before the human answers. The approval is
32
32
  the one thing you never assume, even when the human said they cannot
33
- answer until you report: the brief is that report. The one answer
33
+ answer until you show it. The one answer
34
34
  approves the brief and the policy, `.canon/policy.yaml`, which is what
35
35
  the gate grades the work against. The human may also approve it on the `canon dashboard` briefs page; you never use that form.
36
- The human records the answer, never you:
37
- `canon brief approve <slug> <slug> --approver <their name> --note "<their words>"`
38
- (one or more slugs, one answer for all, nothing written if any is refused)
39
- refuses every agent role (`HUMAN_ONLY`). Report that exact call, every slug filled in, and
40
- wait; never remove or unset your role (`env -u CANON_ROLE`, dropping `--as`) to run it yourself.
36
+ 1. **Show** with `canon brief show <slug> --body`: the brief file's bytes and,
37
+ last, `digest: sha256:<hex>`. Send it to the human's own view without
38
+ retyping it (omp: redirect it to `out://`, which is off for subagents and
39
+ non-TUI sessions and caps at 64 KiB; there, and in a harness with no such
40
+ channel, leave the tool output visible). A subagent has no question tool:
41
+ the orchestrator shows, asks and records.
42
+ 2. **Ask** with the harness question tool (`ask` in omp, `AskUserQuestion` in
43
+ Claude Code, otherwise in the chat): approve or request changes, several
44
+ briefs in one question.
45
+ 3. **Count only an explicit approval.** A question or a condition is a
46
+ revision request (change the brief, check, show and ask again); no answer
47
+ records nothing.
48
+ 4. **Record it** with the relay option:
49
+ `canon brief approve <slug> <slug> --approver <their name> --note "<their words>" --relayed-via <ask|AskUserQuestion|chat> --actor <your actor id> --digest <slug>=<digest shown>`
50
+ (one or more slugs, each with its own `--digest`, one answer for all, nothing written if any is refused).
51
+ The `Approved:` line then carries `(relayed by <role> <actor> via <tool>)`.
52
+ A digest that no longer matches the brief is `RELAY_DIGEST_MISMATCH`: show
53
+ it again. Without `--relayed-via` an agent role gets `HUMAN_ONLY`, and so
54
+ does a repo whose `canon.yaml` says `approval: { relay: deny }`: then the
55
+ human runs the call themselves. Never remove or unset your role
56
+ (`env -u CANON_ROLE`, dropping `--as`) to run it yourself.
41
57
  Never edit the policy to make the gate pass: a policy that differs from
42
58
  the approved one fails closed (`POLICY_CHANGED_SINCE_APPROVAL`, not
43
59
  waivable); stop and ask the human. A brief edited after its
@@ -74,7 +90,7 @@ a feature, a one-line request included. A human is needed once per scope:
74
90
  so in your report. That covers the brief's questions and work inside an
75
91
  approved scope, never the approval itself.
76
92
 
77
- 1. **Brief.** The planner writes the PRD brief (`.canon/changes/<slug>/brief.md`), checks it with `canon brief check`, and stops for the human. `canon skills show role-planner`
93
+ 1. **Brief.** The planner writes the PRD brief (`.canon/changes/<slug>/brief.md`), checks it with `canon brief check`, shows it to the human, asks, and records their explicit approval. `canon skills show role-planner`
78
94
  2. **Subject.** `canon subject new`, then `canon change new` (`--change-kind chore` for work that alters no behavior); the change writes the brief skeleton. `canon skills show role-planner`
79
95
  3. **Scenarios.** `canon scenario new --flow <F-id> --case <case>` per behavior of a flow step, failure paths (`--case failure`) included; many at once with `--input` (below). `canon skills show role-implementer`
80
96
  4. **Units.** Split the work; one unit is one flow step's slice with a named verify command, and each unit has its own actor id and session id, passed on everything it records. A unit never attests another unit's work.
@@ -217,16 +233,19 @@ A role is guidance, not enforcement: `--role` on `evidence add` and
217
233
  (`canon subject move <id> --to verifying`, `canon change new <slug>`), and
218
234
  `--kind` values carry no `_record` suffix (`--kind evidence`).
219
235
  - `canon status` sends the planner to write the brief while `brief check`
220
- has blockers; the human stop appears only when the brief is clean and
236
+ has blockers; the approval step appears only when the brief is clean and
221
237
  unapproved.
222
238
  - Page long lists with `--limit <n>` and `--cursor <nextCursor>` (`--all`
223
239
  for everything), and project fields with `--fields a,b` (`status`, `export`,
224
240
  `query`, `finding list`, `divergence list`, `context`).
225
241
  - `--override-reason <text>` is the only way to proceed past a waivable
226
242
  refusal; it is recorded, echoed in `data.overrides[]` and listed by `status`
227
- for the human. There is no `--force`. `brief approve`, `policy approve` and
228
- `divergence accept` are human-only and refuse every agent role: report the
229
- exact call, ids filled in, and wait; never unset your role to run one.
243
+ for the human. There is no `--force`. `brief approve`, `policy approve`,
244
+ `divergence accept` and the `migrate --commit` that re-binds `Approved:`
245
+ lines record a human's decision and refuse every agent role (`HUMAN_ONLY`)
246
+ unless they record the explicit answer the human gave you, with
247
+ `--relayed-via <tool>` (show, ask, record, as for the brief; `canon skills
248
+ show role-planner`); never unset your role to run one.
230
249
 
231
250
  ### Many records at once: `--input`
232
251
 
@@ -343,7 +362,7 @@ current step needs.
343
362
  | Name | What it is for |
344
363
  | --- | --- |
345
364
  | `canon` | This core guide: the loop, driving the CLI, routing. |
346
- | `role-planner` | Planner steps 1–2: subject, change, PRD brief, the human stop. |
365
+ | `role-planner` | Planner steps 1–2: subject, change, PRD brief, the approval. |
347
366
  | `role-implementer` | Implementer steps 3–6: scenarios, units, code, evidence. |
348
367
  | `role-reviewer` | Reviewer step 7: findings and signed reviews in a separate session. |
349
368
  | `role-orchestrator` | Orchestrator step 8: dispatch, transitions, resuming, upgrading. |
@@ -33,7 +33,7 @@ A chore adds no scenarios and has no flow: this pass does not apply to it.
33
33
 
34
34
  ## Next
35
35
 
36
- Implement, evidence and review (loop steps 5 to 7). If the brief had to change, the human answers again with `canon brief approve` (theirs; agent roles are refused).
36
+ Implement, evidence and review (loop steps 5 to 7). If the brief had to change, the human answers again: show the brief, ask, and record an explicit approval with `--relayed-via` (`canon skills show role-planner`).
37
37
 
38
38
  ## Invariants (every brief pass)
39
39
 
@@ -41,4 +41,4 @@ Implement, evidence and review (loop steps 5 to 7). If the brief had to change,
41
41
  - Explaining writes nothing. Asked what a finding means or what a pass would do, answer in chat and leave the brief untouched.
42
42
  - No pass requires another as a prerequisite. Run the one the findings or the human point at, in any order.
43
43
  - A pass closes only the findings it rechecked: rerun `canon brief check` after the edit and report a finding as closed only when it is gone from that run. Never claim a rule you did not rerun.
44
- - Write in the brief's language (detected from the text; `language:` in `canon.yaml` overrides it). Edits touch `.canon/changes/<slug>/brief.md` only. A brief edited after approval is not approved: it needs a new human answer and the human's `canon brief approve` again (agent roles are refused).
44
+ - Write in the brief's language (detected from the text; `language:` in `canon.yaml` overrides it). Edits touch `.canon/changes/<slug>/brief.md` only. A brief edited after approval is not approved: it needs a new human answer, shown and asked again, and a new `canon brief approve` (recorded with `--relayed-via` from that answer).
@@ -33,7 +33,7 @@ Every open line is a question with a proposed default or a stated assumption. `c
33
33
 
34
34
  ## Next
35
35
 
36
- `harden` if the flow changed; otherwise report to the human, who answers the questions and approves (`canon brief approve` is theirs; agent roles are refused).
36
+ `harden` if the flow changed; otherwise put the questions and the brief to the human and ask; record an explicit approval with `brief approve` with `--relayed-via <tool>` (`canon skills show role-planner`).
37
37
 
38
38
  ## Invariants (every brief pass)
39
39
 
@@ -41,4 +41,4 @@ Every open line is a question with a proposed default or a stated assumption. `c
41
41
  - Explaining writes nothing. Asked what a finding means or what a pass would do, answer in chat and leave the brief untouched.
42
42
  - No pass requires another as a prerequisite. Run the one the findings or the human point at, in any order.
43
43
  - A pass closes only the findings it rechecked: rerun `canon brief check` after the edit and report a finding as closed only when it is gone from that run. Never claim a rule you did not rerun.
44
- - Write in the brief's language (detected from the text; `language:` in `canon.yaml` overrides it). Edits touch `.canon/changes/<slug>/brief.md` only. A brief edited after approval is not approved: it needs a new human answer and the human's `canon brief approve` again (agent roles are refused).
44
+ - Write in the brief's language (detected from the text; `language:` in `canon.yaml` overrides it). Edits touch `.canon/changes/<slug>/brief.md` only. A brief edited after approval is not approved: it needs a new human answer, shown and asked again, and a new `canon brief approve` (recorded with `--relayed-via` from that answer).
@@ -34,7 +34,7 @@ brief has none of them: harden its Invariants and Checks instead.
34
34
 
35
35
  ## Next
36
36
 
37
- `align` (`canon skills show brief-align`) once scenarios exist; `polish` (`canon skills show brief-polish`) for prose; otherwise report to the human.
37
+ `align` (`canon skills show brief-align`) once scenarios exist; `polish` (`canon skills show brief-polish`) for prose; otherwise show the brief to the human and ask (`canon skills show role-planner`).
38
38
 
39
39
  ## Invariants (every brief pass)
40
40
 
@@ -42,4 +42,4 @@ brief has none of them: harden its Invariants and Checks instead.
42
42
  - Explaining writes nothing. Asked what a finding means or what a pass would do, answer in chat and leave the brief untouched.
43
43
  - No pass requires another as a prerequisite. Run the one the findings or the human point at, in any order.
44
44
  - A pass closes only the findings it rechecked: rerun `canon brief check` after the edit and report a finding as closed only when it is gone from that run. Never claim a rule you did not rerun.
45
- - Write in the brief's language (detected from the text; `language:` in `canon.yaml` overrides it). Edits touch `.canon/changes/<slug>/brief.md` only. A brief edited after approval is not approved: it needs a new human answer and the human's `canon brief approve` again (agent roles are refused).
45
+ - Write in the brief's language (detected from the text; `language:` in `canon.yaml` overrides it). Edits touch `.canon/changes/<slug>/brief.md` only. A brief edited after approval is not approved: it needs a new human answer, shown and asked again, and a new `canon brief approve` (recorded with `--relayed-via` from that answer).
@@ -2,7 +2,7 @@
2
2
 
3
3
  Make the brief something a human reads once and understands. Run it whenever
4
4
  `canon brief check` reports `prose.*` advisories; `canon status` and
5
- `meta.next` name it before the human stop. It never blocks approval, and it
5
+ `meta.next` name it before the approval step. It never blocks approval, and it
6
6
  is not finished by silencing rules: it is finished when the brief reads
7
7
  plainly and each advisory is gone or waived with a reason.
8
8
 
@@ -218,7 +218,7 @@ uses the section key `brief`.
218
218
  1. Fix the mode problems above, then the findings, section by section.
219
219
  2. Run `canon brief check <slug> --json`: the findings are in `data.findings[]`.
220
220
  3. Repeat until no advisory remains, or each remaining one is waived with a reason.
221
- 4. Stop and report to the human, in the brief's language. Do not loop further: a clean run says nothing about whether the brief is good, only that these counts are within budget.
221
+ 4. Stop polishing and show the brief to the human (`canon brief show <slug> --body`), in the brief's language, and ask. Do not loop further: a clean run says nothing about whether the brief is good, only that these counts are within budget.
222
222
 
223
223
  ## NEVER
224
224
 
@@ -236,7 +236,7 @@ uses the section key `brief`.
236
236
 
237
237
  ## Next
238
238
 
239
- Report to the human, who approves with `canon brief approve` (theirs; agent roles are refused).
239
+ Show the brief to the human and ask (`canon brief show <slug> --body`, then the harness question tool); record an explicit approval with `brief approve` with `--relayed-via <tool>` (`canon skills show role-planner`).
240
240
 
241
241
  ## Invariants (every brief pass)
242
242
 
@@ -244,4 +244,4 @@ Report to the human, who approves with `canon brief approve` (theirs; agent role
244
244
  - Explaining writes nothing. Asked what a finding means or what a pass would do, answer in chat and leave the brief untouched.
245
245
  - No pass requires another as a prerequisite. Run the one the findings or the human point at, in any order.
246
246
  - A pass closes only the findings it rechecked: rerun `canon brief check` after the edit and report a finding as closed only when it is gone from that run. Never claim a rule you did not rerun.
247
- - Write in the brief's language (detected from the text, or `language:` in `canon.yaml` when set). Edits touch `.canon/changes/<slug>/brief.md` only. A brief edited after approval is not approved: it needs a new human answer and the human's `canon brief approve` again (agent roles are refused).
247
+ - Write in the brief's language (detected from the text, or `language:` in `canon.yaml` when set). Edits touch `.canon/changes/<slug>/brief.md` only. A brief edited after approval is not approved: it needs a new human answer, shown and asked again, and a new `canon brief approve` (recorded with `--relayed-via` from that answer).
@@ -69,7 +69,7 @@ prints the guidance of each empty one (in `language:`). A wrong heading
69
69
 
70
70
  ## Next
71
71
 
72
- `clarify` if the Questions section still has open lines; `harden` if flow and detail disagree; otherwise report to the human, who approves with `canon brief approve` (theirs; agent roles are refused).
72
+ `clarify` if the Questions section still has open lines; `harden` if flow and detail disagree; otherwise show the brief to the human and ask; record an explicit approval with `brief approve` with `--relayed-via <tool>` (`canon skills show role-planner`).
73
73
 
74
74
  ## Invariants (every brief pass)
75
75
 
@@ -77,4 +77,4 @@ prints the guidance of each empty one (in `language:`). A wrong heading
77
77
  - Explaining writes nothing. Asked what a finding means or what a pass would do, answer in chat and leave the brief untouched.
78
78
  - No pass requires another as a prerequisite. Run the one the findings or the human point at, in any order.
79
79
  - A pass closes only the findings it rechecked: rerun `canon brief check` after the edit and report a finding as closed only when it is gone from that run. Never claim a rule you did not rerun.
80
- - Write in the brief's language (detected from the text; `language:` in `canon.yaml` overrides it). Edits touch `.canon/changes/<slug>/brief.md` only. A brief edited after approval is not approved: it needs a new human answer and the human's `canon brief approve` again (agent roles are refused).
80
+ - Write in the brief's language (detected from the text; `language:` in `canon.yaml` overrides it). Edits touch `.canon/changes/<slug>/brief.md` only. A brief edited after approval is not approved: it needs a new human answer, shown and asked again, and a new `canon brief approve` (recorded with `--relayed-via` from that answer).
@@ -299,9 +299,9 @@ never rides along into a confirming audit. `--drop-attachment` and
299
299
 
300
300
  ### Nothing is attested before the brief is approved (`--override-reason`)
301
301
 
302
- The approval is never assumed: the agent writes the brief, stops and
303
- reports it, and builds nothing for that scope until the human answers.
304
- `canon evidence add` is the backstop for that stop (0.16 M7). It
302
+ The approval is never assumed: the agent writes the brief, shows it to the
303
+ human and asks, and builds nothing for that scope until the human answers.
304
+ `canon evidence add` is the backstop for that rule (0.16 M7). It
305
305
  refuses (exit `1`, nothing staged or stored) while a subject the record
306
306
  attests for has an enforced, unapproved brief: a change the record
307
307
  answers to (below) has a canon `.canon/changes/<change>/brief.md` with no `Approved:`
@@ -315,7 +315,7 @@ check `canon status` and the ship guard use; see
315
315
 
316
316
  ```stderr
317
317
  canon evidence add: unreviewed-promotion demo-subject — evidence for world.demo.01: brief not approved — .canon/changes/c-demo/brief.md has no `Approved:` line, so the human has not answered it; once they do, record their words with `canon brief approve c-demo --approver <the human> --note "<their words>"`
318
- canon evidence add: refused — stop, report the brief to the human and wait for their answer: nothing is built or attested for a subject before its brief is approved. Record their answer with `canon brief approve --approver <the human> --note "<their words>"` only from that answer; to attest anyway, pass --override-reason <text>, which is recorded on the evidence record
318
+ canon evidence add: refused — stop and get the human's answer to the brief: nothing is built or attested for a subject before its brief is approved. Show it (`canon brief show --body`), ask with the harness question tool, and on their explicit approval record it with `canon brief approve --approver <their name> --note "<their words>" --relayed-via <the question tool> --actor <your actor id> --digest <change>=<the digest shown>` (or they approve on `canon dashboard`); never unset your role to run it; to attest anyway, pass --override-reason <text>, which is recorded on the evidence record
319
319
  ```
320
320
 
321
321
  For a change from an external plan with no canon brief yet, the first
@@ -75,10 +75,13 @@ canon policy approve --approver <who> [--note <text>] [--repo <dir>]
75
75
  A human approves the policy after reviewing `.canon/policy.yaml`, in the
76
76
  same answer that approves a subject's brief (0.16; see the skill's working
77
77
  loop). `canon brief approve` records both in one call. `canon policy
78
- approve` is a human-only leaf: with a role declared (`--as` or `CANON_ROLE`)
79
- it is refused with `HUMAN_ONLY` (exit 2, not retryable), and no flag grants
80
- it to an agent. The human runs it themselves, for a policy-only change or
81
- after the brief answer, supplying `--approver` and `--note`. It
78
+ approve` is a human's decision: with a role declared (`--as` or `CANON_ROLE`)
79
+ it is refused with `HUMAN_ONLY` (exit 2, not retryable) unless it records the
80
+ answer the human gave in the conversation: show them `.canon/policy.yaml`, ask,
81
+ and on an explicit approval run it (the steps are in `canon skills show role-planner`) with `--relayed-via <tool>`, `--actor`,
82
+ `--approver` and `--note` (their name and words); the file then carries `relay`
83
+ (role, actor, tool). The human may run it themselves, for a policy-only change
84
+ or after the brief answer, supplying `--approver` and `--note`. It
82
85
  writes `.canon/policy.approval.json` directly (nothing to promote):
83
86
 
84
87
  ```json
@@ -163,10 +163,13 @@ refused brief): nothing is written and the page says to read it again. A request
163
163
  naming one brief the old way (`changeId`, `sha256`) is still accepted. The server is localhost only and
164
164
  refuses requests from other origins (`DASHBOARD_ORIGIN_REFUSED`).
165
165
 
166
- For an agent the human stop is unchanged: when clean briefs are waiting,
167
- tell the human they can approve them in `canon dashboard` (briefs page) or
168
- answer in chat. An agent never clicks Approve or fills the form, and runs
169
- `canon brief approve` only from the human's own words.
166
+ For an agent: when clean briefs are waiting, show them (`canon brief show
167
+ <slug> --body`), ask with the harness question tool, and tell the human they
168
+ can approve them in `canon dashboard` (briefs page) instead. An agent never
169
+ clicks Approve or fills the form; it runs `canon brief approve` only from the
170
+ human's explicit answer, with `--relayed-via`. The page lists the approvals an
171
+ agent recorded for the human under "Approved through an agent" (`relayed` in
172
+ `GET /api/briefs`), with the role, actor and tool of each.
170
173
 
171
174
  The dashboard renders SEVEN panels — trust matrix, session costs, role
172
175
  memory, flywheel funnel, review burn-down, review rounds, review totals.
@@ -207,8 +207,8 @@ the transition, not the check.
207
207
 
208
208
  This refusal is a backstop, and so is the evidence one: shipping is not
209
209
  the first thing an unapproved brief stops. The agent writes the brief,
210
- runs `canon brief check` until it has no blockers, then stops and reports
211
- it, and nothing is built or attested for the subject until the human
210
+ runs `canon brief check` until it has no blockers, then shows it to the
211
+ human and asks, and nothing is built or attested for the subject until the human
212
212
  answers. `canon evidence add` refuses (exit 1, nothing staged) a
213
213
  scenario whose `@subject` owner, or a task whose change
214
214
  an adopting subject, has an enforced, unapproved brief, through the same
@@ -547,7 +547,7 @@ warn, and a command that writes and judges it is refused
547
547
  human answers again and `approve` runs again. Run it only from the
548
548
  human's answer, with their words as `--note`.
549
549
 
550
- The optional refinement passes that fix findings before the human stop are
550
+ The optional refinement passes that fix findings before the approval step are
551
551
  listed in `role-planner.md` in this directory.
552
552
 
553
553
  A **chore** (`canon change new --change-kind chore`) changes how the subject is
@@ -688,7 +688,7 @@ uses, so status and the gate cannot disagree about a gap:
688
688
  newest change's canon
689
689
  `brief.md` has no `Approved:` line, or it has no canon `brief.md` yet
690
690
  and comes from an external openspec `proposal.md`) and clean gets
691
- `human: stop and report the brief in <brief>; build and attest nothing for <id> until the human answers (one answer approves brief and policy)`,
691
+ `human: show the brief in <brief> to the human and ask; build and attest nothing for <id> until the human answers (one answer approves brief and policy)`,
692
692
  where `<brief>` is the canon `brief.md`, or the external `proposal.md`
693
693
  when no canon brief exists yet. Its reason reads ``<id>: <why
694
694
  unanswered> (an older change's approval does not cover a new scope),
@@ -752,7 +752,7 @@ first, with `meta.nextOmitted` counting what was cut and `meta.waitingOn`
752
752
 
753
753
  ```json
754
754
  "next": [
755
- { "command": "stop and report the brief in openspec/changes/c-promo/proposal.md; build and attest nothing for promo until the human answers; then record their words with `canon brief approve c-promo --approver <the human> --note \"<their words>\"`", "argv": [], "why": "promo: the brief is not approved", "actor": "human", "role": null },
755
+ { "command": "show the brief in openspec/changes/c-promo/proposal.md; build and attest nothing for promo until the human answers; then record their words with `canon brief approve c-promo --approver <the human> --note \"<their words>\"`", "argv": [], "why": "promo: the brief is not approved", "actor": "human", "role": null },
756
756
  { "command": "canon finding close c-cart --round 1 --seq 1 --disposition fixed --actor <unit> --session <session>", "argv": [], "why": "cart: 1 open blocker finding(s); fix it, commit, then close it", "actor": "agent", "role": "implementer" },
757
757
  { "command": "canon status", "argv": ["canon", "status"], "why": "1 scenario(s) carry no @subject tag (first: cart.promo.01); add `@subject:<id>` above each in its .feature file, then check again", "actor": "agent", "role": "planner" }
758
758
  ]
@@ -4,15 +4,17 @@ You build inside an approved scope: scenarios, code, tests and evidence.
4
4
  Declare the role with `CANON_ROLE=implementer` (or `--as implementer`); `--role`
5
5
  on what you record then defaults to `implementer`.
6
6
  Build nothing before the brief is approved: `canon evidence add` refuses an
7
- unapproved brief's scenarios. If it is not approved, say so and wait; the
8
- planner and the human own that. The only waiver is `--override-reason
7
+ unapproved brief's scenarios. If it is not approved, tell the orchestrator or planner, who show it to the human and ask;
8
+ build nothing meanwhile. The only waiver is `--override-reason
9
9
  "<why>"`, for the case where you were told to attest while the brief waits for
10
10
  the human's answer: canon records it on the evidence, echoes it in
11
11
  `data.overrides[]` and lists it in `status` for the human. Never use it to
12
12
  skip the wait yourself. `brief approve`, `policy approve` and `divergence
13
- accept` are the human's; they refuse you (`HUMAN_ONLY`). You never run them, and never remove or unset your role (`env -u CANON_ROLE`,
14
- dropping `--as`) to get past the refusal: report the exact call, slug filled in, and
15
- wait; the human runs it (or uses `canon dashboard`).
13
+ accept` are the human's; they refuse you (`HUMAN_ONLY`) unless they record an
14
+ answer the human gave in the conversation (`--relayed-via`, the planner's
15
+ procedure: `canon skills show role-planner`). You never run them without that
16
+ answer, and never remove or unset your role (`env -u CANON_ROLE`, dropping
17
+ `--as`) to get past the refusal.
16
18
 
17
19
  ## Commands
18
20
 
@@ -318,7 +320,7 @@ canon evidence add --input '[{"scenario":"auth.login.01","class":"test-run","ref
318
320
  match the scenario because of something outside this change, record the
319
321
  evidence `divergent` and say why in `--ref`; never record `faithful` to
320
322
  pass. The human accepts the tracked gap (`canon divergence accept`
321
- refuses agent roles); fixing the behavior and recording again is the
323
+ refuses agent roles unless it records their explicit answer); fixing the behavior and recording again is the
322
324
  other way out.
323
325
  5. **Promote.** Under `write: { promote: auto }` (what `canon init` writes)
324
326
  the record is final when `evidence add` returns. Only with
@@ -361,10 +363,10 @@ not another evidence step.
361
363
  |---|---|
362
364
  | "The suite is slow; record `faithful` to pass." | `faithful` over a failed case is refused; a limit outside this change is recorded `divergent` with the reason in `--ref`. |
363
365
  | "I fixed it, the test would pass." | Run the test red first and bind it, then green. Evidence is a claim; the history is what the reviewer reads. |
364
- | "The brief is as good as approved." | `evidence add` refuses an unapproved brief's scenarios. Say so and wait. |
366
+ | "The brief is as good as approved." | `evidence add` refuses an unapproved brief's scenarios. Tell the orchestrator or planner, who show it to the human and ask; build nothing meanwhile. |
365
367
  | "I will attest the other unit's work under my id." | Each unit records under its own actor id and session id. |
366
368
  | "I was told this twice already." | A correction repeated across runs belongs in a scenario, the policy or a gate; tell the orchestrator. |
367
- | "I will accept the divergence myself." | `divergence accept` refuses agent roles (`HUMAN_ONLY`); report the scenario, the reason and the tracking reference to the human. |
369
+ | "I will accept the divergence myself." | The human accepts a gap: report the scenario, the reason and the tracking reference so they are asked, and never record an answer they did not give. |
368
370
 
369
371
  ## Retry safety
370
372
 
@@ -4,9 +4,10 @@ You run the loop across agents and move the subject. You write no brief,
4
4
  code or review yourself. Declare the role with `CANON_ROLE=orchestrator` (or
5
5
  `--as orchestrator`); your `canon status` also lists the human's steps. The
6
6
  human's acts (`brief approve`, `policy approve`, `divergence accept`) refuse
7
- every agent role, you included (`HUMAN_ONLY`). You never run them, and never remove or unset your role (`env -u CANON_ROLE`,
8
- dropping `--as`) to get past the refusal: report the exact call, slug filled in, and
9
- wait; the human runs it (or uses `canon dashboard`).
7
+ every agent role, you included (`HUMAN_ONLY`), unless you record the answer the
8
+ human gave you in the conversation with `--relayed-via <tool>` (below). You never
9
+ run them without that answer, and never remove or unset your role (`env -u CANON_ROLE`,
10
+ dropping `--as`) to get past the refusal.
10
11
 
11
12
  ## Commands
12
13
 
@@ -227,7 +228,7 @@ canon ledger compact
227
228
  ```
228
229
  ```text
229
230
  # Bring a repo from an earlier canon up to date
230
- canon migrate [--commit --plan-digest <DIGEST>] [--revert] [--backup <DIR> (with --revert)] [--input]
231
+ canon migrate [--commit --plan-digest <DIGEST>] [--revert | --relayed-via <NAME>] [--backup <DIR> (with --revert)] [--actor <ACTOR_ID> (with --relayed-via)] [--approver <NAME> (with --relayed-via)] [--note <TEXT> (with --relayed-via)] [--input]
231
232
  # a bare run previews and prints planDigest; `--commit --plan-digest <DIGEST>` with that digest acts
232
233
  ```
233
234
  ```bash
@@ -491,14 +492,14 @@ text.
491
492
  | Harness | In-harness subagents | Isolation | Ask the human | Hooks | Skipped |
492
493
  |---|---|---|---|---|---|
493
494
  | claude (`.claude`) | yes, a subagent tool; a child shares your environment, so pass the role in the task | a subagent can run in its own git worktree | yes, a question tool | yes, in the harness settings; `scripts/canon-retrieve-pre-dispatch.sh` is a sidecar, not installed | none |
494
- | codex (`.agents`) | `verify`: none when #39 was filed; start the reviewer as a new `codex exec` run | none from canon: use a separate worktree you create | no in `codex exec`; stop and report | `verify` | in-harness spawn, unless a newer version provides it |
495
+ | codex (`.agents`) | `verify`: none when #39 was filed; start the reviewer as a new `codex exec` run | none from canon: use a separate worktree you create | no in `codex exec`; ask in the chat | `verify` | in-harness spawn, unless a newer version provides it |
495
496
  | omp (`.omp`) | yes, the task tool | `verify` | yes, an ask tool | yes | none |
496
497
  | pi (`.pi`) | `verify`: assume none; start a new `pi` process | none from canon | `verify` | `verify` | in-harness spawn, isolation |
497
498
 
498
499
  Where a harness has no subagent tool, the reviewer is still a separate
499
500
  process with its own session id: start it from the shell with its own
500
- `CANON_ROLE=reviewer`. A harness that cannot ask the human means you stop
501
- and report in your final message; you never assume the answer.
501
+ `CANON_ROLE=reviewer`. A harness that cannot ask the human means you ask
502
+ in the chat and record only the reply; you never assume the answer.
502
503
 
503
504
  The reviewer is a separate process with its own session id, never your
504
505
  session or the implementer's under another label. Start it as a new process
@@ -507,25 +508,39 @@ implementer's context, and have it record its real session id as
507
508
  `--session` (#39). A reviewer that cannot run the tests says so and does
508
509
  not sign off.
509
510
 
510
- ## Relay the human stop
511
+ ## Relay the human's answer
511
512
 
512
513
  When `status` or `meta.next` shows a step with `actor: human` (the brief's
513
- approval), stop everything for that scope, report the brief to the human in
514
- its language, and wait. Tell the human they can approve the clean briefs in
515
- `canon dashboard` (the briefs page) or run, in their own shell, the exact call
516
- with every slug filled in: `canon brief approve <slug> <slug> --approver <their name>
517
- --note "<their own words>"` (several slugs take one answer; nothing is written if
518
- one is refused). You never click Approve, fill the form or run
519
- `brief approve` yourself: it refuses you (`HUMAN_ONLY`), and removing or
520
- unsetting your declared role (`env -u CANON_ROLE`, dropping `--as`) to get past
521
- that is the same act under another label. Report the call and wait. Do not start the
514
+ approval), stop everything for that scope and put the brief in front of the
515
+ human in its language: `canon brief show <slug> --body` prints the brief and,
516
+ last, its digest. Send the output to the human's own view, never retyped (omp:
517
+ redirect it to `out://`, off for subagents and non-TUI sessions and capped at
518
+ 64 KiB; there, and where there is no such channel, leave the tool output
519
+ visible). You are the session that talks to the human: a subagent has no
520
+ question tool, so you show, ask and record for it. Ask with the harness question tool (`ask` in omp, `AskUserQuestion`
521
+ in Claude Code, otherwise in the chat), approve or request changes, all the
522
+ clean briefs in one question. Only an explicit approval counts; a question or a
523
+ condition is a revision request for the planner, and no answer means you wait.
524
+ They may also approve in `canon dashboard` (the briefs page); you never click
525
+ Approve or fill the form. On their approval record it: `canon brief approve
526
+ <slug> <slug> --approver <their name> --note "<their own words>" --relayed-via
527
+ <ask|AskUserQuestion|chat> --actor <your actor id> --digest <slug>=<the digest
528
+ shown>` (several slugs take one answer, each with its own `--digest`; nothing is written
529
+ if one is refused). The record says you recorded it, with your role, actor and
530
+ tool. `RELAY_DIGEST_MISMATCH` means the brief changed after they saw it: show it
531
+ again. When `canon.yaml` has `approval: { relay: deny }` the call is refused
532
+ (`HUMAN_ONLY`, naming the key): report the human's own call and wait for them to
533
+ run it. Removing or unsetting your declared role (`env -u CANON_ROLE`,
534
+ dropping `--as`) to get past a refusal is the same act under another label.
535
+ `canon skills show role-planner` has the full procedure. Do not start the
522
536
  implementer before `canon brief show <slug>` reports `state: approved`.
523
537
  Never approve it yourself and never edit the policy to pass the gate. A
524
538
  policy that no longer matches the approval fails closed
525
539
  (`POLICY_CHANGED_SINCE_APPROVAL`, or `POLICY_APPROVAL_UNREADABLE`): the ship
526
540
  guard and the reopen refuse, and `--override-reason` does not waive it. Run
527
- `canon policy show`, then stop and ask the human to re-approve
528
- (the call `canon policy approve --approver <their name>` is theirs to run, never yours) or restore the
541
+ `canon policy show`, then show the policy to the human, ask them to re-approve
542
+ and record their explicit answer (`canon policy approve --approver <their name>
543
+ --note "<their words>" --relayed-via <tool> --actor <your actor id>`), or restore the
529
544
  approved policy from git; never edit the policy yourself. Inside an
530
545
  approved scope never stop for a human: fixes, follow-ups and re-reviews go
531
546
  straight to the implementer and reviewer in the same change. A known gap the
@@ -563,7 +578,7 @@ its preview, never from an old digest.
563
578
  |---|---|
564
579
  | "Edit the policy so the gate passes." | A changed policy fails closed (`POLICY_CHANGED_SINCE_APPROVAL`); ask the human to re-approve or restore it from git. |
565
580
  | "The reviewer can be me under another label." | The reviewer is a separate process with its own real session id (#39). |
566
- | "Approve the brief; the human said they are busy." | `brief approve` refuses agent roles. Report the brief and wait. |
581
+ | "Approve the brief; the human said they are busy." | An answer they did not give is not recorded. Show the brief, ask, and record only an explicit approval with `--relayed-via`. |
567
582
  | "Override the refusal to ship." | Fix the gap the refusal names; `--override-reason` waives only the `require_review` gaps and the brief gap, is recorded on the subject, and is for the human's call, not a shortcut. |
568
583
  | "Run the commit now, the preview looked fine earlier." | A bare run previews; `--commit --plan-digest` acts only on the plan you just previewed (`PLAN_CHANGED` otherwise). Preview again, then act. |
569
584
  | "I have corrected this agent before." | A correction repeated across runs belongs in a scenario, the policy or a gate, not more prose. Tell the human. |
@@ -4,10 +4,12 @@ You turn a request into an approved scope: a subject, a change and a PRD
4
4
  brief the human answers once. You build nothing. Declare the role with
5
5
  `CANON_ROLE=planner` (or `--as planner`); `canon status` and `meta.next`
6
6
  then show your steps and count the rest under `waitingOn`. The approvals are
7
- the human's: `brief approve`, `policy approve` and `divergence accept` refuse
8
- every agent role (`HUMAN_ONLY`, `retryable: false`), and no flag grants them. You never run them, and never remove or unset your role (`env -u CANON_ROLE`,
9
- dropping `--as`) to get past the refusal: report the exact call, slug filled in, and
10
- wait; the human runs it (or uses `canon dashboard`).
7
+ the human's: `brief approve`, `policy approve`, `divergence accept` and the
8
+ `migrate --commit` that re-binds `Approved:` lines refuse every agent role
9
+ (`HUMAN_ONLY`, `retryable: false`) unless you record the answer the human gave
10
+ you in the conversation, with `--relayed-via <tool>` (step 4). Without a human's
11
+ explicit answer you never run them, and you never remove or unset your role
12
+ (`env -u CANON_ROLE`, dropping `--as`) to get past the refusal.
11
13
 
12
14
  ## Commands
13
15
 
@@ -30,7 +32,7 @@ canon brief check
30
32
  ```
31
33
  ```text
32
34
  # Show where the change stands and the next one to three steps; never edits
33
- canon brief show [<CHANGE_ID>]
35
+ canon brief show [<CHANGE_ID>] [--body]
34
36
  ```
35
37
  ```bash
36
38
  canon brief show
@@ -243,26 +245,63 @@ ids); the human step comes after it. A policy that no longer matches its approva
243
245
  the advisories are gone or each remaining one is waived with a reason.
244
246
  It never blocks approval, but you do not hand the human a brief with
245
247
  unexamined advisories.
246
- 4. **Stop for the human.** Report the brief to the human, in the brief's
247
- language, asking once, and say they can approve it in `canon dashboard`
248
- (the briefs page, `/briefs.html`) or answer in chat. You never click
249
- Approve or fill that form yourself. Build nothing for that scope (no scenarios, code
250
- or evidence) until the human answers. The approval is never assumed, even
251
- when the human said they cannot answer until you report: the brief is
252
- that report. The one answer approves the brief and the policy
248
+ 4. **Show, ask, count only an explicit approval.** Build nothing for that
249
+ scope (no scenarios, code or evidence) until the human has answered. The
250
+ approval is never assumed, even when the human said they cannot answer
251
+ until you show the brief. The one answer approves the brief and the policy
253
252
  (`.canon/policy.yaml`, written by `canon init`), which is what the gate
254
253
  grades the work against.
255
- 5. **The human records the answer.** `brief approve` is the human's leaf: run
256
- by an agent role it is refused (`HUMAN_ONLY`) with a hint addressed to the
257
- human. Report the exact call, slug filled in, and wait: `canon brief approve
258
- add-login --approver <their name> --note "<their own words>"`; the human
259
- runs it in their own shell (`--approver` and `--note` are theirs to supply)
260
- or approves in the dashboard. Never approve in their name, never remove or
261
- unset your role (`env -u CANON_ROLE`, dropping `--as`) to run it, and never
262
- edit the policy to make the gate pass.
254
+ - **Show.** `canon brief show <slug> --body` prints the brief file's bytes
255
+ as they are and, as its last line, `digest: sha256:<hex>`, the value
256
+ `brief approve` records. Send that output to the human's own view; never
257
+ retype or paraphrase the brief into the conversation. In omp, redirect it
258
+ to `out://` (`canon brief show add-login --body > out://add-login`).
259
+ `out://` is off for subagents and non-TUI sessions (the redirect then
260
+ errors) and caps a reply at 64 KiB: there, and in a harness with no such
261
+ channel, leave the tool output visible, which is the same. Read the digest alone with `canon brief show add-login --body |
262
+ tail -n 1`. Show every brief of one request, each with its digest.
263
+ - **Ask.** Use the harness's question tool: `ask` in omp, `AskUserQuestion`
264
+ in Claude Code; a harness without one, ask in the chat and wait for the
265
+ reply. Two choices: approve, or request changes. Several briefs are one
266
+ question. Say in the brief's language what is approved: the brief and
267
+ the policy.
268
+ - **Count only an explicit approval.** The approve choice, or the human
269
+ saying in the chat that they approve. A question, a condition ("yes, if
270
+ …") or an approval of part of it is a revision request: change the brief,
271
+ `brief check` until clean, show it again and ask again. No answer means
272
+ nothing is recorded: wait.
273
+ A subagent has no question tool and no human in front of it: the
274
+ orchestrator (the session talking to the human) shows, asks and records.
275
+ They may also approve on `canon dashboard` (the briefs page,
276
+ `/briefs.html`); you never click Approve or fill that form yourself.
277
+ 5. **Record the answer you were given.** Run `brief approve` with the relay
278
+ option: `canon brief approve add-login --approver <their name> --note "<their
279
+ answer, as they gave it>" --relayed-via <ask|AskUserQuestion|chat> --actor
280
+ <your actor id> --digest add-login=<the digest you showed>` (several slugs:
281
+ one `--digest <slug>=<digest>` each, one answer for all, nothing written if
282
+ any is refused). `--actor` may be `CANON_ACTOR` instead. The record keeps
283
+ their name and words and says that you, with your role and actor, recorded
284
+ them through that tool: the `Approved:` line gains `(relayed by <role>
285
+ <actor> via <tool>)`, which is outside the digest, and `status`, `brief
286
+ show` and the dashboard name it. Never approve in their name without their
287
+ answer, never write the answer for them, and never edit the policy to make
288
+ the gate pass. A digest that differs from the brief now
289
+ (`RELAY_DIGEST_MISMATCH`) means the brief changed after they saw it: show
290
+ it again and ask again; nothing was written. Without `--relayed-via` the call is
291
+ `HUMAN_ONLY`; with it and no role declared, `USAGE`. When `canon.yaml`
292
+ turns relaying off (`approval: { relay: deny }`), the refusal names that key:
293
+ report the human's call (`canon brief approve add-login --approver <their
294
+ name> --note "<their own words>"`) and wait for them to run it. Never
295
+ remove or unset your role (`env -u CANON_ROLE`, dropping `--as`) to run it.
296
+ `canon policy approve`, `canon divergence accept` and `canon migrate
297
+ --commit --plan-digest <d>` follow the same procedure, each taking
298
+ `--approver <their name> --note "<their answer>" --relayed-via <tool>` (and
299
+ `--actor <your actor id>`, which `divergence accept` already requires): show what is approved (the policy file, the divergent
300
+ evidence with its reason and tracking reference, the migrate plan), ask,
301
+ count only an explicit approval, then record with the relay option.
263
302
  `canon brief show <slug>` then reports `state: approved`. A brief edited
264
303
  after its approval is not approved (`BRIEF_CHANGED_SINCE_APPROVAL`): it
265
- needs a new answer and a new `brief approve` by the human. A follow-up that
304
+ needs a new answer, shown and asked again, and a new `brief approve`. A follow-up that
266
305
  adds or changes a step of the brief is a scope change and needs a new
267
306
  answer.
268
307
 
@@ -273,17 +312,17 @@ approval.
273
312
 
274
313
  **Done when:** `canon brief check add-login` exits 0 (no blockers, and the
275
314
  prose advisories are gone or waived with a reason) and `canon brief show
276
- add-login` reports `state: ready`: the brief is handed to the human and you
277
- stop. The scope is approved when the same command reports `state:
278
- approved`; read it in `data.state` of `canon brief show add-login --json`.
279
- Nothing else starts before that.
315
+ add-login` reports `state: ready`: show it to the human and ask (step 4). The scope is approved
316
+ when you have recorded their explicit approval (step 5) and the same command
317
+ reports `state: approved`; read it in `data.state` of `canon brief show
318
+ add-login --json`. Nothing else starts before that.
280
319
 
281
320
  ## Non-behavior work is a chore
282
321
 
283
322
  A refactor, dependency, build, CI or infra change that alters nothing a user
284
323
  can observe: `change new --change-kind chore`. Its brief is short (intent,
285
324
  category, invariants, checks, out of scope) and approved like any brief, one
286
- human stop. A chore adds no scenarios: the
325
+ human answer. A chore adds no scenarios: the
287
326
  implementer runs the subject's suite again where the code changed and binds
288
327
  it with `canon evidence add --all-scenarios` (a docs-only chore changes no
289
328
  code and needs no new evidence), then the reviewer records one
@@ -310,9 +349,9 @@ old column, delete the old format) in its own later change.
310
349
 
311
350
  | The thought | The reality |
312
351
  |---|---|
313
- | "The human is unavailable; I will assume the approval." | Never. The brief is the report; stop, and put open questions into Questions and assumptions. |
352
+ | "The human is unavailable; I will assume the approval." | Never. Show the brief and ask; without an explicit answer nothing is recorded and nothing is built. Put open questions into Questions and assumptions. |
314
353
  | "This could change policy, but I will decide it." | Anything that could change policy goes to the questions. |
315
- | "A small follow-up needs no new answer." | A follow-up that adds or changes a flow step is a scope change and needs a new `brief approve`. |
354
+ | "A small follow-up needs no new answer." | A follow-up that adds or changes a flow step is a scope change and needs a new answer and a new `brief approve`. |
316
355
  | "This migration is just a chore." | Data, interface or output changes are feature changes. |
317
356
  | "Put the file and line in the brief so nobody has to look." | Paths rot; describe behavior. |
318
357