@journeykit/canon 0.27.0 → 0.29.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 (133) hide show
  1. package/dist/skills/SKILL.src.md +245 -89
  2. package/dist/skills/reference/brief-align.md +4 -2
  3. package/dist/skills/reference/brief-clarify.md +7 -5
  4. package/dist/skills/reference/brief-harden.md +4 -2
  5. package/dist/skills/reference/brief-polish.md +7 -5
  6. package/dist/skills/reference/brief-shape.md +4 -2
  7. package/dist/skills/reference/canon-artifact-ingest.md +11 -7
  8. package/dist/skills/reference/canon-authoring.md +16 -2
  9. package/dist/skills/reference/canon-context.md +21 -11
  10. package/dist/skills/reference/canon-fmt.md +10 -2
  11. package/dist/skills/reference/canon-gate.md +107 -69
  12. package/dist/skills/reference/canon-inventory.md +23 -15
  13. package/dist/skills/reference/canon-learn.md +23 -19
  14. package/dist/skills/reference/canon-plan-import.md +10 -7
  15. package/dist/skills/reference/canon-plugins.md +15 -8
  16. package/dist/skills/reference/canon-policy.md +20 -16
  17. package/dist/skills/reference/canon-report-dashboard.md +30 -19
  18. package/dist/skills/reference/canon-retrieve.md +13 -10
  19. package/dist/skills/reference/canon-review.md +96 -68
  20. package/dist/skills/reference/canon-session-ingest.md +7 -3
  21. package/dist/skills/reference/canon-storage.md +65 -39
  22. package/dist/skills/reference/canon-subject.md +116 -79
  23. package/dist/skills/reference/canon-vocab.md +1 -1
  24. package/dist/skills/reference/role-implementer.md +295 -64
  25. package/dist/skills/reference/role-orchestrator.md +547 -55
  26. package/dist/skills/reference/role-planner.md +189 -32
  27. package/dist/skills/reference/role-reviewer.md +257 -58
  28. package/dist/skills/scripts/canon-retrieve-pre-dispatch.sh +10 -5
  29. package/man/canon-adapter-authorize.1 +44 -0
  30. package/man/canon-adapter-validate.1 +44 -0
  31. package/man/canon-adapter.1 +46 -0
  32. package/man/canon-artifacts-move.1 +63 -0
  33. package/man/canon-artifacts-store.1 +54 -0
  34. package/man/canon-artifacts-verify.1 +48 -0
  35. package/man/canon-artifacts.1 +45 -0
  36. package/man/canon-brief-approve.1 +62 -0
  37. package/man/canon-brief-check.1 +44 -0
  38. package/man/canon-brief-show.1 +50 -0
  39. package/man/canon-brief.1 +63 -0
  40. package/man/canon-change-new.1 +66 -0
  41. package/man/canon-change.1 +42 -0
  42. package/man/canon-completion.1 +60 -0
  43. package/man/canon-context-pack-add.1 +47 -0
  44. package/man/canon-context-pack-show.1 +44 -0
  45. package/man/canon-context-pack-verify.1 +44 -0
  46. package/man/canon-context-pack.1 +50 -0
  47. package/man/canon-context.1 +44 -0
  48. package/man/canon-dashboard.1 +50 -0
  49. package/man/canon-demo-init.1 +44 -0
  50. package/man/canon-demo-review.1 +44 -0
  51. package/man/canon-demo.1 +47 -0
  52. package/man/canon-dispatch-begin.1 +80 -0
  53. package/man/canon-dispatch-diff.1 +41 -0
  54. package/man/canon-dispatch-end.1 +60 -0
  55. package/man/canon-dispatch.1 +45 -0
  56. package/man/canon-divergence-accept.1 +68 -0
  57. package/man/canon-divergence-add.1 +97 -0
  58. package/man/canon-divergence-defer.1 +71 -0
  59. package/man/canon-divergence-list.1 +56 -0
  60. package/man/canon-divergence-resolve.1 +68 -0
  61. package/man/canon-divergence.1 +51 -0
  62. package/man/canon-evidence-add.1 +168 -0
  63. package/man/canon-evidence-approval-payload.1 +65 -0
  64. package/man/canon-evidence-audit.1 +121 -0
  65. package/man/canon-evidence.1 +57 -0
  66. package/man/canon-export.1 +108 -0
  67. package/man/canon-feature-new.1 +62 -0
  68. package/man/canon-feature.1 +39 -0
  69. package/man/canon-finding-add.1 +196 -0
  70. package/man/canon-finding-close.1 +117 -0
  71. package/man/canon-finding-list.1 +59 -0
  72. package/man/canon-finding.1 +67 -0
  73. package/man/canon-format.1 +49 -0
  74. package/man/canon-gate-check.1 +44 -0
  75. package/man/canon-gate-install-hooks.1 +59 -0
  76. package/man/canon-gate-promote.1 +62 -0
  77. package/man/canon-gate.1 +50 -0
  78. package/man/canon-ingest-plans.1 +53 -0
  79. package/man/canon-ingest-records.1 +56 -0
  80. package/man/canon-ingest-sessions.1 +62 -0
  81. package/man/canon-ingest.1 +50 -0
  82. package/man/canon-init.1 +98 -0
  83. package/man/canon-inventory-sync.1 +50 -0
  84. package/man/canon-inventory.1 +39 -0
  85. package/man/canon-ledger-compact.1 +50 -0
  86. package/man/canon-ledger.1 +54 -0
  87. package/man/canon-migrate.1 +89 -0
  88. package/man/canon-plugin-sync.1 +53 -0
  89. package/man/canon-plugin.1 +39 -0
  90. package/man/canon-policy-approve.1 +50 -0
  91. package/man/canon-policy-show.1 +41 -0
  92. package/man/canon-policy.1 +52 -0
  93. package/man/canon-prompt-add.1 +47 -0
  94. package/man/canon-prompt-show.1 +41 -0
  95. package/man/canon-prompt.1 +43 -0
  96. package/man/canon-purge.1 +70 -0
  97. package/man/canon-query.1 +111 -0
  98. package/man/canon-regime-show.1 +50 -0
  99. package/man/canon-regime.1 +39 -0
  100. package/man/canon-report-build.1 +44 -0
  101. package/man/canon-report-check.1 +41 -0
  102. package/man/canon-report-snapshot.1 +47 -0
  103. package/man/canon-report.1 +45 -0
  104. package/man/canon-retrieve.1 +56 -0
  105. package/man/canon-review-change.1 +98 -0
  106. package/man/canon-review-scenario.1 +98 -0
  107. package/man/canon-review.1 +42 -0
  108. package/man/canon-scenario-new.1 +80 -0
  109. package/man/canon-scenario.1 +39 -0
  110. package/man/canon-schema.1 +63 -0
  111. package/man/canon-selftest.1 +69 -0
  112. package/man/canon-skills-check.1 +47 -0
  113. package/man/canon-skills-doctor.1 +47 -0
  114. package/man/canon-skills-install.1 +53 -0
  115. package/man/canon-skills-show.1 +104 -0
  116. package/man/canon-skills.1 +48 -0
  117. package/man/canon-status.1 +51 -0
  118. package/man/canon-strategy-approval-payload.1 +53 -0
  119. package/man/canon-strategy-promote.1 +59 -0
  120. package/man/canon-strategy-rollback.1 +62 -0
  121. package/man/canon-strategy.1 +45 -0
  122. package/man/canon-subject-adopt.1 +53 -0
  123. package/man/canon-subject-move.1 +80 -0
  124. package/man/canon-subject-new.1 +65 -0
  125. package/man/canon-subject-show.1 +44 -0
  126. package/man/canon-subject-unadopt.1 +63 -0
  127. package/man/canon-subject.1 +51 -0
  128. package/man/canon-task-done.1 +47 -0
  129. package/man/canon-task.1 +42 -0
  130. package/man/canon-tier-age.1 +50 -0
  131. package/man/canon-tier.1 +39 -0
  132. package/man/canon.1 +169 -0
  133. package/package.json +9 -5
@@ -1,50 +1,254 @@
1
1
  # Role: implementer
2
2
 
3
3
  You build inside an approved scope: scenarios, code, tests and evidence.
4
- Declare the role with `CANON_ROLE=implementer` (or `--as implementer`).
4
+ Declare the role with `CANON_ROLE=implementer` (or `--as implementer`); `--role`
5
+ on what you record then defaults to `implementer`.
5
6
  Build nothing before the brief is approved: `canon evidence add` refuses an
6
7
  unapproved brief's scenarios. If it is not approved, say so and wait; the
7
- planner and the human own that.
8
+ planner and the human own that. The only waiver is `--override-reason
9
+ "<why>"`, for the case where you were told to attest while the brief waits for
10
+ the human's answer: canon records it on the evidence, echoes it in
11
+ `data.overrides[]` and lists it in `status` for the human. Never use it to
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`).
8
16
 
9
17
  ## Commands
10
18
 
11
- Every line is complete; fill the `<placeholders>`. `<root-id>` is the `id` of
12
- a `specs.roots[]` entry in `canon.yaml` (`root` by default).
19
+ Every leaf of this role is below with its full syntax line (every option the leaf
20
+ has) and an example generated from the CLI's own spec, which runs as written against
21
+ the example story (subject `demo`, change `add-login`, scenario `auth.login.01`): swap
22
+ in your ids. Use only the options on a line; never guess one. Ask `canon schema
23
+ <command> --json` only for a leaf this block does not list, or after a `USAGE` refusal.
13
24
 
25
+ <!-- canon:generated commands-implementer begin -->
26
+ Every leaf takes `--as <ROLE>` and `--json`; `--repo <DIR>` too, except `completion`, `schema`, `skills show`. `--input <JSON|FILE|->` runs a leaf from one JSON document (an array is a batch) and is only on the lines ending `[--input]`. Its document keys are the option names in camelCase, singular even when the option repeats (the value is then an array), and `operands` holds the operands. `--fields <FIELDS>` is a comma list; camelCase and snake_case both match.
27
+ In a syntax line `<X>` is a value, `[x]` optional, `a | b` a choice, `(a | b)` exactly one is required, `[--x <V>]*` may repeat, `<X>+` is one or more, `[--a --b <V>]` go together. An option that is not on the line does not exist: it is refused (`USAGE`).
28
+
29
+ ```text
30
+ # Write the shell completion script for canon (bash, zsh or fish)
31
+ canon completion <SHELL>
32
+ ```
33
+ ```bash
34
+ canon completion zsh
35
+ ```
36
+ ```text
37
+ # Show what you can author here: record kinds, fields, enums, policies
38
+ canon context [--fields <FIELDS>]
39
+ ```
40
+ ```bash
41
+ canon context
42
+ ```
43
+ ```text
44
+ # Create an immutable context pack from a repository-local JSON manifest
45
+ canon context-pack add --manifest <FILE> [--input]
46
+ ```
47
+ ```bash
48
+ canon context-pack add --manifest .canon/context-manifest.json
49
+ ```
50
+ ```text
51
+ # Show a context pack after verifying its manifest and content objects
52
+ canon context-pack show <PACK_ID>
53
+ ```
54
+ ```bash
55
+ canon context-pack show sha256:0000000000000000000000000000000000000000000000000000000000000000
56
+ ```
57
+ ```text
58
+ # Verify a context pack's manifest and immutable content objects
59
+ canon context-pack verify <PACK_ID>
60
+ ```
61
+ ```bash
62
+ canon context-pack verify sha256:0000000000000000000000000000000000000000000000000000000000000000
63
+ ```
64
+ ```text
65
+ # Add a divergence candidate, staged with no run_seq yet
66
+ canon divergence add <SCENARIO_ID> --actor-id <ACTOR_ID> [--project-id <PROJECT_ID>] [--rev <REV>] [--state <open|still-divergent|resolved|deferred>] [--reason <TEXT>] [--expiry <TIMESTAMP>] [--round <N>] [--session-id <SESSION_ID>] [--detail <TEXT>] [--role <ROLE>] [--promote | --no-promote] [--input]
67
+ ```
68
+ ```bash
69
+ canon divergence add auth.login.01 --actor-id alice --role reviewer
70
+ ```
71
+ ```text
72
+ # Directly record a deferred divergence (requires --reason/--expiry)
73
+ canon divergence defer <SCENARIO_ID> --actor-id <ACTOR_ID> --reason <TEXT> --expiry <TIMESTAMP> [--project-id <PROJECT_ID>] [--rev <REV>] [--round <N>] [--session-id <SESSION_ID>] [--role <ROLE>] [--input]
74
+ ```
75
+ ```bash
76
+ canon divergence defer auth.login.01 --actor-id alice --reason "waiting on the vendor" --expiry 2030-01-01T00:00:00Z --role reviewer
77
+ ```
78
+ ```text
79
+ # List the current divergence burn-down state
80
+ canon divergence list [--as-of <TIMESTAMP>] [--limit <N> | --all] [--cursor <CURSOR>] [--fields <FIELDS>]
81
+ ```
82
+ ```bash
83
+ canon divergence list --as-of 2030-01-01
84
+ ```
85
+ ```text
86
+ # Directly record a resolved divergence
87
+ canon divergence resolve <SCENARIO_ID> --actor-id <ACTOR_ID> [--project-id <PROJECT_ID>] [--rev <REV>] [--round <N>] [--session-id <SESSION_ID>] [--detail <TEXT>] [--role <ROLE>] [--input]
88
+ ```
89
+ ```bash
90
+ canon divergence resolve auth.login.01 --actor-id alice --role reviewer
91
+ ```
92
+ ```text
93
+ # Record one attributed EvidenceRecord for a task or scenario
94
+ canon evidence add [--task-id <TASK_ID>] [--project-id <PROJECT_ID>] [--class <CLASS>] [--ref <TEXT>] [--verdict <faithful|not-applicable|divergent>] [--summary <TEXT>] [--command-result <TEXT>] [--scenario-id <SCENARIO_ID>] [--run-id <RUN_ID>] [--surface-ref <PATH_OR_EFFECT>]* [--actor-id <ACTOR_ID>] [--role <ROLE>] [--session-id <SESSION_ID>] [--approver <NAME>] [--approval-role <human>] [--signature-file <FILE>] [--approval-at <TIMESTAMP>] [--rev <REV>] [--artifact <PATH>]* [--report <FORMAT:PATH>]* [--report-case <NAME>]* [--all-scenarios] [--max-artifact-mib <N>] [--override-reason <TEXT>] [--promote | --no-promote] [--input]
95
+ ```
96
+ ```bash
97
+ canon evidence add --scenario-id auth.login.01 --class test-run --ref "npm test" --role implementer
98
+ ```
99
+ ```text
100
+ # Emit exact bytes for external `ssh-keygen -Y sign -n canon-approval-v1`
101
+ canon evidence approval-payload --approver <NAME> --approval-at <TIMESTAMP> [--task-id <TASK_ID>] [--project-id <PROJECT_ID>] [--scenario-id <SCENARIO_ID>] [--run-id <RUN_ID>] [--rev <REV>] [--surface-ref <PATH_OR_EFFECT>]*
102
+ ```
103
+ ```bash
104
+ canon evidence approval-payload --scenario-id auth.login.01 --project-id root --approver alice --approval-at 2030-01-01T00:00:00Z
105
+ ```
106
+ ```text
107
+ # Record an external evaluator's re-audit of one scenario (class `audit`; the verdict follows --audit-result; canon never runs the evaluator)
108
+ canon evidence audit <SCENARIO_ID> --ref <TEXT> --evaluator-id <ID> --evaluator-version <TEXT> --evaluator-digest <DIGEST> --audit-result <confirmed|refuted|indeterminate> [--project-id <PROJECT_ID>] [--summary <TEXT>] [--command-result <TEXT>] [--run-id <RUN_ID>] [--actor-id <ACTOR_ID>] [--role <ROLE>] [--session-id <SESSION_ID>] [--rev <REV>] [--artifact <PATH>]* [--report <FORMAT:PATH>]* [--report-case <NAME>]* [--max-artifact-mib <N>] [--override-reason <TEXT>] [--promote | --no-promote] [--input]
109
+ ```
110
+ ```bash
111
+ canon evidence audit auth.login.01 --ref audit-report.json --evaluator-id eval-1 --evaluator-version 2.1 --evaluator-digest 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef --audit-result confirmed --role implementer
112
+ ```
113
+ ```text
114
+ # Create a fresh .feature file for a new area.surface
115
+ canon feature new <SURFACE> --title <TEXT> [--actor-id <ACTOR_ID>] [--session-id <SESSION_ID>] [--project-id <PROJECT_ID>] [--input]
116
+ ```
117
+ ```bash
118
+ canon feature new billing.invoice --title Invoices
119
+ ```
120
+ ```text
121
+ # List a change's committed findings at their latest version
122
+ canon finding list --change-id <CHANGE_ID> [--open] [--limit <N> | --all] [--cursor <CURSOR>] [--fields <FIELDS>]
123
+ ```
14
124
  ```bash
15
- canon status --as implementer --json # once, at the start
16
- canon feature new <area>.<surface> --title "<title>" --as implementer --json
17
- canon scenario new <area>.<surface>.<nn> --subject-id <subject-id> --flow <F-id> --case <happy|edge|failure> --title "<title>" --as implementer --json
18
- canon scenario new --from - --as implementer --json # many at once: NDJSON on stdin, one {"id","title","subject-id","flow","case",…} per line
19
- canon evidence add --project-id <root-id> --all-scenarios --report <junit|cucumber|swift-testing>:<path> --kind test-run --role implementer --ref "<test command>" --actor-id <unit> --session-id <session> --as implementer --json
20
- canon evidence add --project-id <root-id> --scenario-id <id> --artifact <path> --kind test-run --role implementer --ref "<what it shows>" --actor-id <unit> --session-id <session> --as implementer --json
21
- canon evidence add --project-id <root-id> --scenario-id <id> --verdict divergent --artifact <path> --kind test-run --role implementer --ref "<the external limit, and where it is tracked>" --actor-id <unit> --session-id <session> --as implementer --json # honest divergent evidence
22
- canon artifacts verify --full --as implementer --json # bound files are in the artifact store (omit --full to trust the store's size and digest metadata); refuses when an object store is unreachable
23
- canon finding add --change-id <slug> --round <n> --seq <n> --severity <blocker|should-fix|note> --reviewer <unit> --actor-id <unit> --session-id <session> --summary "<defect>" --as implementer --json
24
- canon inventory sync --as implementer --json # only after a write printed NOT refreshed
25
- canon query --kind <kind> --history --as implementer --json # earlier versions too; without --history only the current record of each key
26
- canon ledger compact --as implementer --json # only for a pre-0.23 ledger or an interrupted move (add --dry-run to preview)
27
- canon gate promote --as implementer --json # only with write.promote: manual
125
+ canon finding list --change-id add-login
28
126
  ```
127
+ ```text
128
+ # Validate a spec/artifact corpus against canon's format
129
+ canon format [<DIR>]
130
+ ```
131
+ ```bash
132
+ canon format .canon/specs
133
+ ```
134
+ ```text
135
+ # Run the coverage/ledger/staleness/trust checks (0 clean, 1 red, 2 usage)
136
+ canon gate check [--release]
137
+ ```
138
+ ```bash
139
+ canon gate check
140
+ ```
141
+ ```text
142
+ # Promote staged records (evidence, findings, divergences) to the committed ledger
143
+ canon gate promote [--kind <evidence|finding|divergence>] [--dry-run] [--input]
144
+ ```
145
+ ```bash
146
+ canon gate promote --kind evidence
147
+ ```
148
+ ```text
149
+ # Validate each spec root, then materialize scenario index records
150
+ canon inventory sync [--spec-root <DIR>] [--dry-run] [--input]
151
+ ```
152
+ ```bash
153
+ canon inventory sync
154
+ ```
155
+ ```text
156
+ # Read stored records across every storage tier
157
+ canon query --kind <change|task|scenario|session|run|event|handoff|review|divergence|trajectory|strategy_item|evidence|subject|finding> [--since <TIMESTAMP>] [--plugin-id <PLUGIN_ID> | --history] [--change-id <CHANGE_ID>] [--status <STATUS>] [--domain <NAME>] [--include-sensitive] [--limit <N> | --all] [--cursor <CURSOR>] [--fields <FIELDS>]
158
+ ```
159
+ ```bash
160
+ canon query --kind evidence
161
+ ```
162
+ ```text
163
+ # Fetch role-scoped strategy guidance
164
+ canon retrieve --for-role <ROLE> [--regime <KEY>] [--domain <NAME>] [--subject-id <SUBJECT_ID>] [--limit <N>]
165
+ ```
166
+ ```bash
167
+ canon retrieve --for-role reviewer --domain dev --limit 20
168
+ ```
169
+ ```text
170
+ # Append a tagged scenario stub to its .feature file (created if missing); many at once with `--input`
171
+ canon scenario new <SCENARIO_ID> --title <TEXT> [--subject-id <SUBJECT_ID>] [--lane <NAME>] [--case <NAME>] [--flow <FLOW_ID>] [--change-id <CHANGE_ID> (with --flow)] [--actor-id <ACTOR_ID>] [--session-id <SESSION_ID>] [--feature <FILE>] [--project-id <PROJECT_ID>] [--input]
172
+ ```
173
+ ```bash
174
+ canon scenario new auth.login.02 --title "Sign out" --feature .canon/specs/kind=feature/area=auth/login.feature
175
+ ```
176
+ ```text
177
+ # Describe canon's own commands
178
+ canon schema [<PATH>]* [--errors | --error <CODE>]
179
+ ```
180
+ ```bash
181
+ canon schema evidence add
182
+ ```
183
+ ```text
184
+ # Print a guide built into this binary (markdown on stdout); the installed SKILL.md is a stub that points here
185
+ canon skills show <NAME> [--full]
186
+ ```
187
+ ```bash
188
+ canon skills show canon --full
189
+ ```
190
+ ```text
191
+ # Show where this repo stands: subjects by status, their gaps, and the next commands
192
+ canon status [--fields <FIELDS>]
193
+ ```
194
+ ```bash
195
+ canon status
196
+ ```
197
+ ```text
198
+ # Flip one task checkbox, gated on real evidence (fails closed)
199
+ canon task done <TASK_ID> [--input]
200
+ ```
201
+ ```bash
202
+ canon task done add-login#1
203
+ ```
204
+ <!-- canon:generated commands-implementer end -->
29
205
 
30
206
  After the first `status`, follow `meta.next` of each write; do not call
31
- `canon status` again to learn the next step.
207
+ `canon status` again to learn the next step. Every record you write takes
208
+ the commit it is about from `--rev` (default `HEAD`, any git revision). You
209
+ need not commit first: code that is not committed yet is recorded with its
210
+ `codeTree` and `worktreeDirty: true`, never refused. Outside git, or in a
211
+ repo with no commits, a write that needs a commit refuses `NO_COMMIT`.
212
+
213
+ The forms you reach for most (the story's ids; swap in yours):
214
+
215
+ ```bash
216
+ canon evidence add --all-scenarios --report junit:a.xml --report junit:b.xml --role implementer
217
+ canon evidence add --scenario-id auth.login.01 --report junit:red.xml
218
+ canon evidence add --scenario-id auth.login.01 --verdict divergent --class test-run --ref "upstream limit, tracked in issue 118" --artifact limit.log
219
+ canon finding add --change-id add-login --round 1 --seq 1 --severity should-fix --actor-id unit-1 --summary "Token is logged"
220
+ ```
221
+
222
+ Batches are one `--input` document (the keys are option names in camelCase,
223
+ `operands` holds the positional arguments):
224
+
225
+ ```text
226
+ canon scenario new --input '[{"operands":["auth.login.01"],"title":"Logs in","case":"happy","flow":"F1"},{"operands":["auth.login.02"],"title":"Rejects a wrong password","case":"failure","flow":"F1"}]'
227
+ canon evidence add --input '[{"scenarioId":"auth.login.01","class":"test-run","ref":"npm test","role":"implementer"},{"scenarioId":"auth.login.02","class":"test-run","ref":"npm test","role":"implementer"}]'
228
+ ```
32
229
 
33
230
  ## Steps
34
231
 
35
232
  1. **Scenarios.** One `feature new` per feature surface, then one
36
- `scenario new` per behavior (several at once with `scenario new --from -`:
37
- one JSON object per line, validated all-or-nothing), each pointing at the brief's flow step it
233
+ `scenario new` per behavior, each pointing at the brief's flow step it
38
234
  proves, with failure paths (`--case failure`) as well as `happy` and
39
- `edge`. When the gate asks for a missing case (`require_cases`), add a new
40
- scenario; never retag an existing one. Every bug fix adds or extends a
41
- scenario. Canon indexes added, edited or deleted `.feature` files itself;
42
- run `inventory sync` only when a command prints `NOT refreshed` (a format
43
- violation or a duplicate id: it names each problem). Specs live at
44
- `<root>/kind=feature/area=<area>/<surface>.feature` under a `specs.roots[]`
45
- root (default `.canon/specs`); `reference/canon-authoring.md` has the
46
- scaffold. When you fill in a scenario, keep its `# canon: {...}` provenance
47
- lines: dropping one aborts `inventory sync` on `missing-provenance`.
235
+ `edge`. Several scenarios at once are one `scenario new --input` with a
236
+ JSON array: inline, a file or `-` for stdin, one object per scenario whose
237
+ keys are the option names in camelCase plus `operands` (the scenario id);
238
+ every element is validated before the first write, so a bad element
239
+ writes nothing and `error.field` names it (`/items/1/case`).
240
+ `canon schema scenario new --json` shows the input schema and an example.
241
+ (`scenario new --from` is gone.) When the gate asks for a missing case
242
+ (`require_cases`), add a new scenario; never retag an existing one. Every
243
+ bug fix adds or extends a scenario. Canon indexes added, edited or deleted
244
+ `.feature` files itself; run `inventory sync` only when a command prints
245
+ `NOT refreshed` (a format violation or a duplicate id: it names each
246
+ problem). Specs live at `<root>/kind=feature/area=<area>/<surface>.feature`
247
+ under a `specs.roots[]` root (default `.canon/specs`); `canon skills show
248
+ canon-authoring` has the scaffold. When you fill in a scenario, keep its
249
+ `# canon: {...}` provenance lines: dropping one aborts `inventory sync`
250
+ on `missing-provenance`. `--project-id` is needed only when the repo
251
+ configures more than one spec root.
48
252
  2. **Units.** One unit is one flow step's complete path (sees, does,
49
253
  becomes) that can be verified on its own, sized to one session. Name the
50
254
  command that proves it (a test filter, a script) before you start it, and
@@ -58,18 +262,25 @@ After the first `status`, follow `meta.next` of each write; do not call
58
262
  with `finding add` the moment you find it, before review.
59
263
  **A fix fails first.** For a bug fix, write or extend the scenario's test
60
264
  and run it red on the unfixed code, then bind that failing run before you
61
- change the code (`evidence add --scenario-id <id> --report <fmt>:<path> …`
62
- with `--verdict divergent`; a failed case never records `faithful`, and
63
- `--all-scenarios` derives `divergent` from it).
64
- Fix the code, run again and bind the passing run: the green record
65
- supersedes the red one, and `canon query --kind evidence --history
66
- --scenario-id <id>` shows the red-then-green pair to the reviewer. A red
67
- run is never an accepted gap. When no executable reproduction is
68
- possible, say in `--ref` what the closest check is and why.
69
- 4. **Evidence.** One test run that proves several scenarios is bound once with
70
- `--all-scenarios`: one record per indexed scenario owning a case, each with
71
- the verdict its own cases show; any refusal writes none. For one scenario
72
- use `--scenario-id <id>` (repeatable) with `--report` or `--artifact`.
265
+ change the code (`evidence add --scenario-id <id> --report <fmt>:<path>`).
266
+ A bound report decides the verdict: a failed case records `divergent`, a
267
+ skipped case and none failed records `not-applicable`, otherwise
268
+ `faithful`; an explicit `--verdict faithful` over a failed or skipped case
269
+ is refused. Fix the code, run again and bind the passing run: the green
270
+ record supersedes the red one, and the reviewer reads the red-then-green
271
+ pair in `canon query --kind evidence --history --json`. A red run is never
272
+ an accepted gap. When no executable reproduction is possible, say in
273
+ `--ref` what the closest check is and why.
274
+ 4. **Evidence.** With at least one `--report`, `--class` defaults to
275
+ `test-run` and `--ref` to the report paths; without a report, pass both.
276
+ One test run that proves several scenarios is bound once with
277
+ `--all-scenarios`: one record per indexed scenario owning a case, each
278
+ with the verdict its own cases show; any refusal writes none. It needs
279
+ `--project-id` only when the repo has several spec roots. For one scenario
280
+ use `--scenario-id <id>` with `--report` or `--artifact`; for many
281
+ records with different values, one `evidence add --input` with an array
282
+ (validated before any write; a write that fails stops the batch, the
283
+ earlier elements stay written and a rerun reports them `unchanged`).
73
284
  A record binds exactly what its own write names (`--report`,
74
285
  `--artifact`): nothing is carried forward from an earlier record, so name
75
286
  every file the record should prove again. canon stores the bytes by digest
@@ -79,7 +290,7 @@ After the first `status`, follow `meta.next` of each write; do not call
79
290
  re-checks them, so the working-tree report may be gitignored. Run
80
291
  `canon artifacts verify` to ask the store yourself; it refuses, never
81
292
  passes, when an object store cannot be reached. Moving an existing store
82
- (`canon artifacts migrate`) is the repo owner's call: do not run it.
293
+ (`canon artifacts move --tier`) is the repo owner's call: do not run it.
83
294
  For a scenario about what users see, let the test report carry its
84
295
  screenshots: Playwright's JUnit reporter attaches, per test case, what a
85
296
  test attaches (`testInfo.attach(name, {path})`, or `screenshot: 'on'`), and
@@ -87,13 +298,14 @@ After the first `status`, follow `meta.next` of each write; do not call
87
298
  record only its own tests' files. A file the report does not name goes
88
299
  with `--artifact <scenario-id>=<path>`; a bare `--artifact` in a batch is
89
300
  refused. An external evaluator's audit is
90
- `--kind audit`; canon never generates one. Evidence for a task of an
91
- imported plan (`--task <id>`) must bind the artifact or report that proves
301
+ `canon evidence audit`; canon never generates one. Evidence for a task of an
302
+ imported plan (`--task-id <id>`) must bind the artifact or report that proves
92
303
  the task; a canon command is never that proof. When the behavior cannot
93
304
  match the scenario because of something outside this change, record the
94
305
  evidence `divergent` and say why in `--ref`; never record `faithful` to
95
- pass. A reviewer may accept the tracked gap (`canon divergence accept`);
96
- fixing the behavior and recording again is the other way out.
306
+ pass. The human accepts the tracked gap (`canon divergence accept`
307
+ refuses agent roles); fixing the behavior and recording again is the
308
+ other way out.
97
309
  5. **Promote.** Under `write: { promote: auto }` (what `canon init` writes)
98
310
  the record is final when `evidence add` returns. Only with
99
311
  `write.promote: manual` (or no `write:` key) follow it with
@@ -103,16 +315,31 @@ After the first `status`, follow `meta.next` of each write; do not call
103
315
  digests) of the evidence it saw, not which record it was. Recording the
104
316
  same verdict from the same checks keeps every review current; a different
105
317
  verdict, different checks or an edited scenario stales it. The add prints
106
- the reviewer and the `canon review add … --pin <sha>` that re-pins it; that
107
- is the reviewer's call. Do not run it yourself.
108
- 7. **After a fix or a chore, record the whole suite again.** A blocker the
109
- reviewer closed `fixed`, and an approved chore, are not done until every
110
- evidenced scenario has evidence newer than the close or the approval:
111
- run the suite and bind it with `canon evidence add --all-scenarios …`
112
- (the shipping refusal names the scenarios and this command). Reviews stay
113
- current while the verdicts and checks are unchanged; a scenario whose gap
114
- was accepted is accepted again by the reviewer once new evidence says
115
- something different.
318
+ the reviewer and the `canon review scenario` call that signs it again; that
319
+ is the reviewer's call. Do not run it yourself. A review of an uncommitted
320
+ working tree survives the commit you make from it: the review is judged by
321
+ the scenario and the evidence it pins, never by the commit.
322
+ 7. **After a fix or a chore, record again only where the code changed.**
323
+ A blocker the reviewer closed `fixed` is not done until the scenarios it
324
+ names (the whole suite when it names none) have evidence newer than the
325
+ close. An approved chore asks for new evidence only on the scenarios whose
326
+ latest evidence was recorded on a different `codeTree` than the current
327
+ code (`code.exclude` in `canon.yaml` decides what is not code; the default
328
+ is `docs/**` and `*.md`). A docs-only chore needs its change-level review
329
+ alone. When code did change, the shipping refusal, `status` and
330
+ `meta.next` lead with one command over every report, with the real paths
331
+ (`--project-id <id>` is added only with several spec roots):
332
+ `canon evidence add --all-scenarios --report junit:a.xml --report junit:b.xml --role implementer`.
333
+ Run the suite and bind it with that one command, not one scenario at a
334
+ time. Reviews stay current while the verdicts and checks are unchanged; a
335
+ scenario whose gap was accepted needs the human to accept again once new
336
+ evidence says something different.
337
+
338
+ **Done when:** `canon gate check` lists no `uncovered-cell` or
339
+ `stale-evidence` violation for the change's scenarios (read `data.violations[]`
340
+ in `canon gate check --json`; a remaining `unreviewed-promotion` is the
341
+ reviewer's step), and the `meta.next` of your last write names the review,
342
+ not another evidence step.
116
343
 
117
344
  ## Excuses that fail
118
345
 
@@ -123,19 +350,23 @@ After the first `status`, follow `meta.next` of each write; do not call
123
350
  | "The brief is as good as approved." | `evidence add` refuses an unapproved brief's scenarios. Say so and wait. |
124
351
  | "I will attest the other unit's work under my id." | Each unit records under its own actor id and session id. |
125
352
  | "I was told this twice already." | A correction repeated across runs belongs in a scenario, the policy or a gate; tell the orchestrator. |
353
+ | "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. |
126
354
 
127
355
  ## Retry safety
128
356
 
129
- Repeating `evidence add` with identical input returns the existing record
130
- with `meta.unchanged: true` instead of a duplicate. After a timeout or a lost
131
- response, run it again.
357
+ `evidence add` is content-keyed: repeating it with identical input returns
358
+ the existing record with `meta.unchanged: true` instead of a duplicate (a
359
+ batch reports that element `unchanged`). After a timeout or a lost
360
+ response, run the same command again. `scenario new` is not: an existing
361
+ scenario id is refused (`SCENARIO_TAG_EXISTS`) and nothing changes, so check
362
+ before you repeat it.
132
363
 
133
364
  ## Next
134
365
 
135
366
  When every scenario has evidence, the review is the reviewer's session, in a
136
367
  separate process: do not review your own change. A chore adds no scenarios:
137
- once it is approved, run the suite and bind it with `--all-scenarios`;
138
- shipping needs that evidence newer than the chore's approval, plus the
139
- reviewer's one change-level review of the chore (`review add --change-id`).
140
- Scenario reviews stay current when the verdicts and checks are unchanged.
141
- Reference: `reference/canon-gate.md`.
368
+ once it is approved, record evidence where the code changed (the batch
369
+ above names it) and the reviewer records one change-level review of the
370
+ chore (`review change`); shipping needs both. Scenario reviews stay current
371
+ when the verdicts and checks are unchanged. Reference: `canon skills show
372
+ canon-gate`.