@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.
- package/dist/skills/SKILL.src.md +33 -14
- package/dist/skills/reference/brief-align.md +2 -2
- package/dist/skills/reference/brief-clarify.md +2 -2
- package/dist/skills/reference/brief-harden.md +2 -2
- package/dist/skills/reference/brief-polish.md +4 -4
- package/dist/skills/reference/brief-shape.md +2 -2
- package/dist/skills/reference/canon-gate.md +4 -4
- package/dist/skills/reference/canon-policy.md +7 -4
- package/dist/skills/reference/canon-report-dashboard.md +7 -4
- package/dist/skills/reference/canon-subject.md +5 -5
- package/dist/skills/reference/role-implementer.md +10 -8
- package/dist/skills/reference/role-orchestrator.md +35 -20
- package/dist/skills/reference/role-planner.md +67 -28
- package/dist/skills/reference/role-reviewer.md +22 -14
- package/man/canon-adapter-authorize.1 +2 -2
- package/man/canon-adapter-validate.1 +2 -2
- package/man/canon-adapter.1 +2 -2
- package/man/canon-artifacts-move.1 +2 -2
- package/man/canon-artifacts-store.1 +2 -2
- package/man/canon-artifacts-verify.1 +2 -2
- package/man/canon-artifacts.1 +2 -2
- package/man/canon-brief-approve.1 +12 -3
- package/man/canon-brief-check.1 +2 -2
- package/man/canon-brief-show.1 +6 -3
- package/man/canon-brief.1 +2 -2
- package/man/canon-change-new.1 +2 -2
- package/man/canon-change.1 +2 -2
- package/man/canon-completion.1 +2 -2
- package/man/canon-context-pack-add.1 +2 -2
- package/man/canon-context-pack-show.1 +2 -2
- package/man/canon-context-pack-verify.1 +2 -2
- package/man/canon-context-pack.1 +2 -2
- package/man/canon-context.1 +2 -2
- package/man/canon-dashboard.1 +2 -2
- package/man/canon-demo-init.1 +2 -2
- package/man/canon-demo-review.1 +2 -2
- package/man/canon-demo.1 +2 -2
- package/man/canon-dispatch-begin.1 +2 -2
- package/man/canon-dispatch-diff.1 +2 -2
- package/man/canon-dispatch-end.1 +2 -2
- package/man/canon-dispatch.1 +2 -2
- package/man/canon-divergence-accept.1 +12 -3
- package/man/canon-divergence-add.1 +2 -2
- package/man/canon-divergence-defer.1 +2 -2
- package/man/canon-divergence-list.1 +2 -2
- package/man/canon-divergence-resolve.1 +2 -2
- package/man/canon-divergence.1 +2 -2
- package/man/canon-evidence-add.1 +2 -2
- package/man/canon-evidence-approval-payload.1 +2 -2
- package/man/canon-evidence-audit.1 +2 -2
- package/man/canon-evidence.1 +2 -2
- package/man/canon-export.1 +2 -2
- package/man/canon-feature-new.1 +2 -2
- package/man/canon-feature.1 +2 -2
- package/man/canon-finding-add.1 +2 -2
- package/man/canon-finding-close.1 +2 -2
- package/man/canon-finding-list.1 +2 -2
- package/man/canon-finding.1 +2 -2
- package/man/canon-format.1 +2 -2
- package/man/canon-gate-check.1 +2 -2
- package/man/canon-gate-install-hooks.1 +2 -2
- package/man/canon-gate-promote.1 +2 -2
- package/man/canon-gate.1 +2 -2
- package/man/canon-ingest-plans.1 +2 -2
- package/man/canon-ingest-records.1 +2 -2
- package/man/canon-ingest-sessions.1 +2 -2
- package/man/canon-ingest.1 +2 -2
- package/man/canon-init.1 +2 -2
- package/man/canon-inventory-sync.1 +2 -2
- package/man/canon-inventory.1 +2 -2
- package/man/canon-ledger-compact.1 +2 -2
- package/man/canon-ledger.1 +2 -2
- package/man/canon-migrate.1 +15 -3
- package/man/canon-plugin-sync.1 +2 -2
- package/man/canon-plugin.1 +2 -2
- package/man/canon-policy-approve.1 +9 -3
- package/man/canon-policy-show.1 +2 -2
- package/man/canon-policy.1 +2 -2
- package/man/canon-prompt-add.1 +2 -2
- package/man/canon-prompt-show.1 +2 -2
- package/man/canon-prompt.1 +2 -2
- package/man/canon-purge.1 +2 -2
- package/man/canon-query.1 +2 -2
- package/man/canon-regime-show.1 +2 -2
- package/man/canon-regime.1 +2 -2
- package/man/canon-report-build.1 +2 -2
- package/man/canon-report-check.1 +2 -2
- package/man/canon-report-snapshot.1 +2 -2
- package/man/canon-report.1 +2 -2
- package/man/canon-retrieve.1 +2 -2
- package/man/canon-review-change.1 +2 -2
- package/man/canon-review-scenario.1 +2 -2
- package/man/canon-review.1 +2 -2
- package/man/canon-scenario-new.1 +2 -2
- package/man/canon-scenario.1 +2 -2
- package/man/canon-schema.1 +2 -2
- package/man/canon-search.1 +2 -2
- package/man/canon-selftest.1 +2 -2
- package/man/canon-skills-check.1 +2 -2
- package/man/canon-skills-doctor.1 +2 -2
- package/man/canon-skills-install.1 +2 -2
- package/man/canon-skills-show.1 +2 -2
- package/man/canon-skills.1 +2 -2
- package/man/canon-status.1 +2 -2
- package/man/canon-strategy-approval-payload.1 +2 -2
- package/man/canon-strategy-promote.1 +2 -2
- package/man/canon-strategy-rollback.1 +2 -2
- package/man/canon-strategy.1 +2 -2
- package/man/canon-subject-adopt.1 +2 -2
- package/man/canon-subject-move.1 +2 -2
- package/man/canon-subject-new.1 +2 -2
- package/man/canon-subject-show.1 +2 -2
- package/man/canon-subject-unadopt.1 +2 -2
- package/man/canon-subject.1 +2 -2
- package/man/canon-task-done.1 +2 -2
- package/man/canon-task.1 +2 -2
- package/man/canon-tier-age.1 +2 -2
- package/man/canon-tier.1 +2 -2
- package/man/canon-trace.1 +2 -2
- package/man/canon.1 +2 -2
- package/package.json +4 -4
package/dist/skills/SKILL.src.md
CHANGED
|
@@ -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
|
|
30
|
-
|
|
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
|
|
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
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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`,
|
|
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
|
|
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
|
|
228
|
-
`divergence accept`
|
|
229
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
303
|
-
|
|
304
|
-
`canon evidence add` is the backstop for that
|
|
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
|
|
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
|
|
79
|
-
it is refused with `HUMAN_ONLY` (exit 2, not retryable)
|
|
80
|
-
|
|
81
|
-
|
|
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
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
`canon brief approve` only from the
|
|
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
|
|
211
|
-
|
|
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
|
|
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:
|
|
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": "
|
|
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,
|
|
8
|
-
|
|
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`)
|
|
14
|
-
|
|
15
|
-
|
|
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.
|
|
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." |
|
|
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`)
|
|
8
|
-
|
|
9
|
-
|
|
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`;
|
|
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
|
|
501
|
-
and
|
|
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
|
|
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
|
|
514
|
-
its language
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
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
|
|
528
|
-
|
|
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." |
|
|
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
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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. **
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
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
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
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
|
|
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`:
|
|
277
|
-
|
|
278
|
-
approved`; read it in `data.state` of `canon brief show
|
|
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
|
|
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.
|
|
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
|
|