@journeykit/canon 0.26.0 → 0.28.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 +119 -83
  12. package/dist/skills/reference/canon-inventory.md +34 -22
  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 +82 -51
  22. package/dist/skills/reference/canon-subject.md +123 -84
  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,46 +1,210 @@
1
1
  # Role: reviewer
2
2
 
3
3
  You are the independent second look. Declare the role with
4
- `CANON_ROLE=reviewer` (or `--as reviewer`); `--role` on `review add` then
5
- defaults to `reviewer`.
4
+ `CANON_ROLE=reviewer` (or `--as reviewer`); `--role` on `review scenario`,
5
+ `review change` and `finding add` then defaults to `reviewer`. The human's
6
+ acts refuse you (`HUMAN_ONLY`): `brief approve`, `policy approve` and
7
+ `divergence accept`. Name what the human has to decide in your report; never
8
+ look for a flag that grants it. 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`).
6
11
 
7
12
  ## Commands
8
13
 
9
- Every line is complete; fill the `<placeholders>`. `<root-id>` is the `id` of
10
- a `specs.roots[]` entry in `canon.yaml` (`root` by default).
14
+ Every leaf of this role is below with its full syntax line (every option the leaf
15
+ has) and an example generated from the CLI's own spec, which runs as written against
16
+ the example story (subject `demo`, change `add-login`, scenario `auth.login.01`): swap
17
+ in your ids. Use only the options on a line; never guess one. Ask `canon schema
18
+ <command> --json` only for a leaf this block does not list, or after a `USAGE` refusal.
11
19
 
20
+ <!-- canon:generated commands-reviewer begin -->
21
+ 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.
22
+ 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`).
23
+
24
+ ```text
25
+ # Read the brief against the rules
26
+ canon brief check [<CHANGE_ID>]
27
+ ```
28
+ ```bash
29
+ canon brief check
30
+ ```
31
+ ```text
32
+ # Show where the change stands and the next one to three steps; never edits
33
+ canon brief show [<CHANGE_ID>]
34
+ ```
35
+ ```bash
36
+ canon brief show
37
+ ```
38
+ ```text
39
+ # Write the shell completion script for canon (bash, zsh or fish)
40
+ canon completion <SHELL>
41
+ ```
42
+ ```bash
43
+ canon completion zsh
44
+ ```
45
+ ```text
46
+ # Show what you can author here: record kinds, fields, enums, policies
47
+ canon context [--fields <FIELDS>]
48
+ ```
49
+ ```bash
50
+ canon context
51
+ ```
52
+ ```text
53
+ # Add a divergence candidate, staged with no run_seq yet
54
+ 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]
55
+ ```
56
+ ```bash
57
+ canon divergence add auth.login.01 --actor-id alice --role reviewer
58
+ ```
59
+ ```text
60
+ # Directly record a deferred divergence (requires --reason/--expiry)
61
+ 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]
62
+ ```
63
+ ```bash
64
+ canon divergence defer auth.login.01 --actor-id alice --reason "waiting on the vendor" --expiry 2030-01-01T00:00:00Z --role reviewer
65
+ ```
66
+ ```text
67
+ # List the current divergence burn-down state
68
+ canon divergence list [--as-of <TIMESTAMP>] [--limit <N> | --all] [--cursor <CURSOR>] [--fields <FIELDS>]
69
+ ```
70
+ ```bash
71
+ canon divergence list --as-of 2030-01-01
72
+ ```
73
+ ```text
74
+ # Directly record a resolved divergence
75
+ 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]
76
+ ```
77
+ ```bash
78
+ canon divergence resolve auth.login.01 --actor-id alice --role reviewer
79
+ ```
80
+ ```text
81
+ # Record one code-review finding
82
+ canon finding add --change-id <CHANGE_ID> --round <N> --seq <N> --severity <blocker|should-fix|note> --actor-id <ACTOR_ID> --summary <TEXT> [--disposition <open|fixed|rejected|deferred>] [--rev <REV>] [--resolution-rev <REV>] [--introduced-rev <REV>] [--file-ref <TEXT>] [--scenario-id <SCENARIO_ID>]* [--role <ROLE>] [--session-id <SESSION_ID>] [--promote | --no-promote] [--input]
83
+ ```
84
+ ```bash
85
+ canon finding add --change-id add-login --round 1 --seq 2 --severity should-fix --actor-id alice --summary "Token is logged"
86
+ ```
87
+ ```text
88
+ # Move an already-committed finding's disposition
89
+ canon finding close <CHANGE_ID> --round <N> --seq <N> --disposition <open|fixed|rejected|deferred> [--resolution-rev <REV>] [--reason <TEXT>] [--actor-id <ACTOR_ID>] [--role <ROLE>] [--session-id <SESSION_ID>] [--promote | --no-promote] [--input]
90
+ ```
91
+ ```bash
92
+ canon finding close add-login --round 1 --seq 1 --disposition rejected --reason "works as designed"
93
+ ```
94
+ ```text
95
+ # List a change's committed findings at their latest version
96
+ canon finding list --change-id <CHANGE_ID> [--open] [--limit <N> | --all] [--cursor <CURSOR>] [--fields <FIELDS>]
97
+ ```
98
+ ```bash
99
+ canon finding list --change-id add-login
100
+ ```
101
+ ```text
102
+ # Validate a spec/artifact corpus against canon's format
103
+ canon format [<DIR>]
104
+ ```
12
105
  ```bash
13
- canon brief check --change-id <slug> --as reviewer --json
14
- canon gate check --as reviewer --json # once, before review add
15
- canon finding add --change-id <slug> --round <n> --seq <n> --severity <blocker|should-fix|note> --reviewer <me> --actor-id <me> --session-id <session> --summary "<defect>" --scenario-id <id> --scenario-id <id> --as reviewer --json # one --scenario-id per scenario the defect is about
16
- canon finding list --change-id <slug> --open --as reviewer --json
17
- canon finding close --change-id <slug> --round <n> --seq <n> --disposition fixed --resolution-sha <sha> --as reviewer --json
18
- canon finding close --change-id <slug> --round <n> --seq <n> --disposition rejected|deferred --reason "<why, one line>" --as reviewer --json # --reason is required here (FINDING_REASON_REQUIRED); optional for fixed
19
- canon review add --project-id <root-id> --scenario-id <id> --scenario-id <id> --reviewer <me> --actor-id <me> --role reviewer --session-id <session> --pin <sha> --upstream-ref <ref> --as reviewer --json
20
- canon review add --project-id <root-id> --scenario-ids-from - --reviewer <me> --actor-id <me> --role reviewer --session-id <session> --pin <sha> --upstream-ref <ref> --as reviewer --json # ids on stdin, one per line
21
- canon review add --project-id <root-id> --change-id <chore-slug> --reviewer <me> --actor-id <me> --role reviewer --session-id <session> --pin <sha> --upstream-ref <ref> --as reviewer --json # a chore: one change-level review of its invariants and checks against the diff
22
- canon divergence accept --project-id <root-id> --scenario-id <id> --reason "<why the gap stays>" --tracking <issue-url-or-ref> [--expiry YYYY-MM-DD] --reviewer <me> --actor-id <me> --session-id <session> --as reviewer --json
23
- canon artifacts verify --full --as reviewer --json # the files the evidence and reviews bind are in the artifact store; refuses when an object store is unreachable
24
- canon query --kind evidence --history --as reviewer --json # every version, not only the current record
25
- canon query --kind evidence --history --scenario-id <id> --as reviewer --json # one scenario's red-then-green pair
106
+ canon format .canon/specs
26
107
  ```
108
+ ```text
109
+ # Run the coverage/ledger/staleness/trust checks (0 clean, 1 red, 2 usage)
110
+ canon gate check [--release]
111
+ ```
112
+ ```bash
113
+ canon gate check
114
+ ```
115
+ ```text
116
+ # Read stored records across every storage tier
117
+ 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>]
118
+ ```
119
+ ```bash
120
+ canon query --kind evidence
121
+ ```
122
+ ```text
123
+ # Fetch role-scoped strategy guidance
124
+ canon retrieve --for-role <ROLE> [--regime <KEY>] [--domain <NAME>] [--subject-id <SUBJECT_ID>] [--limit <N>]
125
+ ```
126
+ ```bash
127
+ canon retrieve --for-role reviewer --domain dev --limit 20
128
+ ```
129
+ ```text
130
+ # Write one attributed Review record for a chore change directly to the ledger (exactly one provenance ref required)
131
+ canon review change <CHANGE_ID> --actor-id <ACTOR_ID> (--upstream-ref <TEXT> | --original-spec-ref <TEXT>) [--project-id <PROJECT_ID>] [--rev <REV>] [--role <ROLE>] [--session-id <SESSION_ID>] [--review-outcome <signed|indeterminate|unavailable>] [--reviewer-provider <NAME>] [--reviewer-model <NAME>] [--reviewer-harness <NAME>] [--artifact <PATH>]* [--max-artifact-mib <N>] [--input]
132
+ ```
133
+ ```bash
134
+ canon review change add-login --actor-id alice --role reviewer --original-spec-ref docs/prd.md
135
+ ```
136
+ ```text
137
+ # Write one attributed Review record per scenario directly to the ledger, nothing to promote (exactly one provenance ref required)
138
+ canon review scenario <SCENARIO_ID>+ --actor-id <ACTOR_ID> (--upstream-ref <TEXT> | --original-spec-ref <TEXT>) [--project-id <PROJECT_ID>] [--rev <REV>] [--role <ROLE>] [--session-id <SESSION_ID>] [--review-outcome <signed|indeterminate|unavailable>] [--reviewer-provider <NAME>] [--reviewer-model <NAME>] [--reviewer-harness <NAME>] [--artifact <PATH>]* [--max-artifact-mib <N>] [--input]
139
+ ```
140
+ ```bash
141
+ canon review scenario auth.login.01 --actor-id alice --role reviewer --original-spec-ref docs/prd.md
142
+ ```
143
+ ```text
144
+ # Describe canon's own commands
145
+ canon schema [<PATH>]* [--errors | --error <CODE>]
146
+ ```
147
+ ```bash
148
+ canon schema evidence add
149
+ ```
150
+ ```text
151
+ # Print a guide built into this binary (markdown on stdout); the installed SKILL.md is a stub that points here
152
+ canon skills show <NAME> [--full]
153
+ ```
154
+ ```bash
155
+ canon skills show canon --full
156
+ ```
157
+ ```text
158
+ # Show where this repo stands: subjects by status, their gaps, and the next commands
159
+ canon status [--fields <FIELDS>]
160
+ ```
161
+ ```bash
162
+ canon status
163
+ ```
164
+ <!-- canon:generated commands-reviewer end -->
27
165
 
28
- `review add` needs `--upstream-ref <ref>` or `--original-spec-ref <path>`;
29
- add `--artifact <path>` (repeatable) for user-visible behavior. A short
30
- `<sha>` is fine. With `write.promote: manual`, follow `finding add` and
31
- `finding close` with `canon gate promote --as reviewer --json`.
166
+ `review scenario` needs exactly one of `--upstream-ref <ref>` or
167
+ `--original-spec-ref <path>`; add `--artifact <path>` (repeatable) for
168
+ user-visible behavior. `--rev` is the commit you reviewed (default `HEAD`;
169
+ any git revision, a short sha included). With `write.promote: manual`,
170
+ follow `finding add` and `finding close` with `canon gate promote --as
171
+ reviewer --json`. `review scenario` has no `--summary` or note option: what you
172
+ found goes in `finding add --summary`.
32
173
 
33
- A scenario review pins what you saw: the scenario's digest plus the verdict
174
+ The forms you reach for most (the story's ids; swap in yours):
175
+
176
+ ```bash
177
+ canon review scenario auth.login.01 auth.login.02 --actor-id reviewer-1 --session-id session-7 --original-spec-ref docs/prd.md
178
+ canon review scenario auth.login.01 --actor-id reviewer-1 --session-id session-7 --review-outcome indeterminate --original-spec-ref docs/prd.md
179
+ canon review change add-login --actor-id reviewer-1 --session-id session-7 --original-spec-ref docs/prd.md
180
+ canon finding add --change-id add-login --round 1 --seq 2 --severity blocker --actor-id reviewer-1 --session-id session-7 --summary "No rate limit" --scenario-id auth.login.01 --scenario-id auth.login.02 --introduced-rev HEAD~3
181
+ canon finding close add-login --round 1 --seq 2 --disposition fixed --resolution-rev HEAD
182
+ canon finding close add-login --round 1 --seq 3 --disposition rejected --reason "works as designed"
183
+ canon finding list --change-id add-login --open
184
+ ```
185
+
186
+ Several findings at once are one `--input` array (the keys are option names
187
+ in camelCase):
188
+
189
+ ```text
190
+ canon finding add --input '[{"changeId":"add-login","round":1,"seq":3,"severity":"note","actorId":"reviewer-1","summary":"Token is logged"},{"changeId":"add-login","round":1,"seq":4,"severity":"should-fix","actorId":"reviewer-1","summary":"Error text leaks the user name"}]'
191
+ ```
192
+
193
+ A review pins what you saw: the scenario's digest plus the verdict
34
194
  and checks (report format and matched case names, or artifact digests) of its
35
195
  latest evidence per role, not which record held them. It stays current when
36
196
  the implementer records the same verdict from the same checks again, and
37
197
  goes stale when the verdict or the checks differ or the scenario changes.
38
- Reviews written before 0.23 do not count until `canon migrate` re-pins them
39
- (an advisory names it); that is the orchestrator's step, not yours.
198
+ A review of code that is not committed yet is allowed: the record carries
199
+ `codeTree` and `worktreeDirty: true`, and the commit made from that working
200
+ tree has the same `codeTree`, so the review survives the commit; only its
201
+ pins (above) make it stale, never the commit or the code tree. Reviews
202
+ written before 0.23 do not count until `canon migrate` re-pins them (an
203
+ advisory names it); that is the orchestrator's step, not yours.
40
204
 
41
- Run `gate check` once, before `review add`: its `unreviewed-promotion`
205
+ Run `gate check` once, before `review scenario`: its `unreviewed-promotion`
42
206
  violations are the subjects and scenarios that need your review. Do not loop
43
- it. After `review add`, read its `meta.next` instead of calling `gate check`
207
+ it. After `review scenario`, read its `meta.next` instead of calling `gate check`
44
208
  or `status` again.
45
209
 
46
210
  ## Separate session
@@ -53,7 +217,7 @@ everything you record. A harness with no subagent tool starts you (a new
53
217
 
54
218
  ## Read the PRD
55
219
 
56
- 1. `brief check`: the brief must have no blockers.
220
+ 1. `brief check`: the brief must have no blockers (exit 1 means it has some).
57
221
  2. Read the brief itself, `.canon/changes/<slug>/brief.md`: intent, the flow
58
222
  `F1`, `F2`, …, acceptance and failure path per step, out of scope. You do
59
223
  not refine the brief; a brief defect is a finding, not an edit.
@@ -65,10 +229,12 @@ everything you record. A harness with no subagent tool starts you (a new
65
229
  ## Run the checks yourself
66
230
 
67
231
  Run the build, the tests and the app the evidence claims to cover, on the
68
- commit you pin. Compare the results with the evidence records. Never sign
232
+ code you review: the commit `--rev` names, or the working tree when it is
233
+ not committed yet. Compare the results with the evidence records. Never sign
69
234
  what you could not run: a reviewer that cannot run the tests says so and
70
- does not sign off; record that instead (`--outcome indeterminate`, or
71
- `unavailable` when you could not run).
235
+ does not sign off; record that instead (`--review-outcome indeterminate`,
236
+ or `unavailable` when you could not run). Only `signed` counts; the others
237
+ stay on the record as a review gap.
72
238
 
73
239
  ## Check the checks
74
240
 
@@ -88,54 +254,86 @@ steps, in two separate passes, and say which pass a finding came from:
88
254
 
89
255
  When a check looks weak, you may name the one-line change to the code that
90
256
  should make it fail and run it if it is cheap; if the test stays green, record
91
- the finding. For a fix, read `canon query --kind evidence --history
92
- --scenario-id <id>`: expect an earlier non-faithful version, or a named
93
- closest reproduction in `--ref`; record a finding when neither exists. Put
94
- one blast-radius fact in the finding or review `--summary`: what else the
95
- change touches that the checks do not exercise. Do all of this before you
257
+ the finding. For a fix, read `canon query --kind evidence --history --json`
258
+ for that scenario's records: expect an earlier non-faithful version, or a
259
+ named closest reproduction in `--ref`; record a finding when neither exists.
260
+ Put one blast-radius fact in the finding or review `--summary`: what else the
261
+ change touches that the checks do not exercise. Read the waivers too:
262
+ `status` lists every `--override-reason` an implementer or the orchestrator
263
+ used (it is echoed in `data.overrides[]` of the write that took it). A
264
+ waiver whose reason does not hold is a finding. Do all of this before you
96
265
  sign.
97
266
 
98
- ## Accept a known gap
267
+ ## A known gap is the human's to accept
99
268
 
100
269
  `divergence accept` is for a scenario whose honest evidence is `divergent`
101
270
  and whose gap is limited by something outside this change (an upstream
102
- limit, a platform bug) and is tracked there: give the reason and the
103
- `--tracking` reference, and an `--expiry` when the limit should be gone by
104
- a date. Never use it to skip a fix you can make in this change. It is your
105
- step, from a session that did not attest the evidence
106
- (`DIVERGENCE_ACCEPT_REFUSED` otherwise). The acceptance pins that evidence:
107
- new evidence for the scenario, or its expiry, ends it, and you accept (or
108
- the implementer fixes) again. An accepted gap counts as covered for the
109
- ship guard and stays listed as `accepted-divergence` in `status` and
110
- `gate check`.
271
+ limit, a platform bug) and is tracked there. It records a human's decision,
272
+ so it refuses every agent role (`HUMAN_ONLY`), you included. What you do:
273
+ confirm the evidence really is divergent and the limit is outside this
274
+ change, then report to the human the scenario ids, the reason, the
275
+ tracking reference and an expiry when the limit should be gone by a date.
276
+ Give the exact call, ids filled in: the human runs `canon divergence accept
277
+ <ids> --actor-id <name> --reason "<why>" --tracking <ref>` themselves in their
278
+ own shell, from a session that did not attest the evidence
279
+ (`DIVERGENCE_ACCEPT_REFUSED` otherwise); you never run it or unset your role to. Never suggest it to skip
280
+ a fix the implementer can make in this change. The acceptance pins that
281
+ evidence: new evidence for the scenario, or its expiry, ends it, and the
282
+ human accepts (or the implementer fixes) again. An accepted gap counts as
283
+ covered for the ship guard and stays listed as `accepted-divergence` in
284
+ `status` and `gate check`.
111
285
 
112
286
  ## Record
113
287
 
114
288
  - Every defect is a finding; `finding list` shows round, seq, severity and
115
289
  disposition, so the next seq and the open blockers are one command away.
116
- Close a finding once it is dealt with. When you close it `rejected` or
117
- `deferred`, give the reason in one line with `--reason "<why>"`: the close
118
- is refused without it (`FINDING_REASON_REQUIRED`), and `finding list` shows
119
- it as `[reason: …]` so the next reader sees why it was not fixed.
120
- - Sign off in one batch with `review add`, all or nothing. It writes
290
+ `--rev` of a finding is the commit the round reviewed; `--introduced-rev`
291
+ is the commit that introduced the defect and has no default: source it
292
+ (`git log -S`, `git blame`) or leave it out, never guess it. Many findings
293
+ at once are one `finding add --input` with an array, validated before any
294
+ write.
295
+ - Close a finding once it is dealt with: `finding close <slug> --round <n>
296
+ --seq <n> --disposition fixed` records `--resolution-rev` (default
297
+ `HEAD`). When you close it `rejected` or `deferred`, give the reason in
298
+ one line with `--reason "<why>"`: the close is refused without it
299
+ (`FINDING_REASON_REQUIRED`), and `finding list` shows it as
300
+ `[reason: …]` so the next reader sees why it was not fixed. Closing a
301
+ finding that already has that disposition is `unchanged`.
302
+ - Sign off in one batch with `review scenario <ids>`, all or nothing. It writes
121
303
  directly; nothing to promote. canon stores and re-checks attached bytes
122
304
  and never compares images.
123
305
  - Pass `--scenario-id` for each scenario a finding is about. A blocker you
124
306
  close `fixed` then stays blocking until the implementer records evidence
125
- again for those scenarios alone (`evidence add --scenario-id <id> …`); the
307
+ again for those scenarios alone (`evidence add --scenario-id <id>`); the
126
308
  close inherits the list. A blocker naming no scenario asks for the whole
127
309
  suite again (`evidence add --all-scenarios`), which on a big suite is
128
310
  a long e2e run for a one-scenario fix, so name them. Your pinned review
129
311
  stays current when the new evidence says the same, otherwise look again.
130
312
  - Fixes you ask for return as a re-review of the same change. When new
131
313
  evidence changes a verdict or the checks and so stales your review, look
132
- again before you re-pin.
314
+ again before you sign it again.
133
315
  A chore has no scenarios: review it with one change-level review, `canon
134
- review add --project-id <root-id> --change-id <slug> --reviewer <me> --role
135
- reviewer --pin <sha> --upstream-ref <ref> …`. It signs the chore's
136
- invariants and checks against the diff and pins its brief, so editing the
137
- brief stales it. The chore also needs evidence recorded after its approval
138
- (the implementer's `--all-scenarios` run) before it ships.
316
+ review change <slug> --actor-id <me> --session-id <session>
317
+ --upstream-ref <ref>` (or `--original-spec-ref <path>`). It signs the
318
+ chore's invariants and checks against the diff and pins its brief, so
319
+ editing the brief stales it. The chore also needs new evidence on every
320
+ scenario whose code changed since its latest evidence (the implementer's
321
+ batch) before it ships; a docs-only chore needs your review alone.
322
+
323
+ **Done when:** `canon gate check` lists no `unreviewed-promotion` violation
324
+ and no open blocker for the change (read `data.violations[]` in `canon gate
325
+ check --json`; `canon finding list --change-id add-login --open` shows the
326
+ open findings), or each remaining one is a finding you recorded and the
327
+ implementer owns. Your last write's `meta.next` names the next step.
328
+
329
+ ## Retry safety
330
+
331
+ `review scenario`, `review change` and `finding add` are content-keyed: an
332
+ identical repeat is reported `unchanged` (`meta.unchanged: true`, or the
333
+ element's `status` in a batch), so after a timeout run the same command
334
+ again. A different finding under an occupied round and seq is refused
335
+ (`FINDING_SEQ_OCCUPIED`): take the next seq. `finding close` with the same
336
+ disposition is a no-op too.
139
337
 
140
338
  ## Excuses that fail
141
339
 
@@ -146,5 +344,6 @@ ship guard and stays listed as `accepted-divergence` in `status` and
146
344
  | "I cannot run the tests, but the evidence looks right." | Say so and record `indeterminate` or `unavailable`; never sign what you could not run. |
147
345
  | "This is a minor defect; I will skip the finding." | Every defect is a finding; severity says how much it matters. |
148
346
  | "I will edit the brief to fix it." | A brief defect is a finding, not an edit. |
347
+ | "I will accept the gap myself, the limit is real." | `divergence accept` refuses agent roles; report the gap to the human. |
149
348
 
150
- Reference: `reference/canon-review.md`.
349
+ Reference: `canon skills show canon-review`.
@@ -73,7 +73,7 @@ TOOL_NAME="$(printf '%s' "$INPUT" | jq -r '.tool_name // empty' 2>/dev/null || t
73
73
  # fixed point of `regime_key`'s own segment canonicalizer, so the
74
74
  # derived `--role` still equals the assembled regime_key's leading
75
75
  # segment. The repo/area segments are NOT slugified here — they are
76
- # canonicalized by `canon regime-key` below (the write-path serializer).
76
+ # canonicalized by `canon regime show` below (the write-path serializer).
77
77
  slugify() {
78
78
  printf '%s' "$1" | tr '[:upper:]' '[:lower:]' | tr -c 'a-z0-9' '-' | sed -E 's/-+/-/g; s/^-//; s/-$//'
79
79
  }
@@ -97,20 +97,25 @@ if [ -z "$REGIME" ]; then
97
97
  fi
98
98
  [ -n "$HASH" ] || exit 0
99
99
  # Assemble the regime_key through canon's OWN serializer (`canon
100
- # regime-key` -> `canon_model::ids::regime_key`), the identical
100
+ # regime show` -> `canon_model::ids::regime_key`), the identical
101
101
  # normalizer the S4/S6/S14 WRITE path uses — never a second shell
102
102
  # derivation. A prior local `slugify` of the repo segment mapped a
103
103
  # written `my_repo` to a queried `my-repo`, so `retrieve_guidance`
104
104
  # fail-softed to empty and silently missed the namespace. `--role`
105
105
  # is the already-kebab ROLE (a fixed point of that canonicalizer, so
106
106
  # it still equals the assembled key's leading segment). Malformed
107
- # segments make `canon regime-key` exit nonzero -> `|| true` -> empty
107
+ # segments make `canon regime show` exit nonzero -> `|| true` -> empty
108
108
  # REGIME -> the silent no-op just below.
109
- REGIME="$(canon regime-key --role "$ROLE" --repo "$REPO_RAW" --area "$AREA_RAW" --hash "$HASH" 2>/dev/null || true)"
109
+ REGIME="$(canon regime show --role-segment "$ROLE" --repo-name "$REPO_RAW" --area "$AREA_RAW" --hash "$HASH" 2>/dev/null || true)"
110
110
  [ -n "$REGIME" ] || exit 0
111
111
  fi
112
112
 
113
- GUIDANCE_JSON="$(canon retrieve --role "$ROLE" --regime "$REGIME" --json 2>/dev/null || true)"
113
+ GUIDANCE_JSON="$(canon retrieve --for-role "$ROLE" --regime "$REGIME" --json 2>/dev/null || true)"
114
+ [ -n "$GUIDANCE_JSON" ] || exit 0
115
+
116
+ # canon >= 0.28 envelopes the result ({ok, data: [...], meta}); 0.27 printed the bare array.
117
+ # `(.data? // .)` reads either, so this hook works before and after the upgrade.
118
+ GUIDANCE_JSON="$(printf '%s' "$GUIDANCE_JSON" | jq -c '(.data? // .)' 2>/dev/null || true)"
114
119
  [ -n "$GUIDANCE_JSON" ] || exit 0
115
120
 
116
121
  COUNT="$(printf '%s' "$GUIDANCE_JSON" | jq 'length' 2>/dev/null || echo 0)"
@@ -0,0 +1,44 @@
1
+ .ie \n(.g .ds Aq \(aq
2
+ .el .ds Aq '
3
+ .TH canon-adapter-authorize 1 "authorize 0.28.0"
4
+ .SH NAME
5
+ canon\-adapter\-authorize \- Authorize declared capabilities against repository policy (preflight only)
6
+ .SH SYNOPSIS
7
+ \fBcanon adapter authorize\fR [\fB\-\-as\fR] <\fB\-\-response\fR> [\fB\-\-repo\fR] [\fB\-\-json\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR]
8
+ .SH DESCRIPTION
9
+ Authorize declared capabilities against repository policy (preflight only)
10
+ .SH OPTIONS
11
+ .TP
12
+ \fB\-\-as\fR \fI<ROLE>\fR
13
+ The role you act as: planner, implementer, reviewer or orchestrator. Overrides `CANON_ROLE`. `schema` and `context` list only the role\*(Aqs commands, `status` keeps its steps, and `\-\-role` on `evidence add` / `evidence audit` / `review scenario` / `review change` defaults to it
14
+ .br
15
+
16
+ .br
17
+ \fIPossible values:\fR
18
+ .RS 14
19
+ .IP \(bu 2
20
+ planner
21
+ .IP \(bu 2
22
+ implementer
23
+ .IP \(bu 2
24
+ reviewer
25
+ .IP \(bu 2
26
+ orchestrator
27
+ .RE
28
+ .TP
29
+ \fB\-\-response\fR \fI<FILE>\fR
30
+ JSON response file to validate and authorize
31
+ .TP
32
+ \fB\-\-repo\fR \fI<DIR>\fR
33
+ The repo to act on (default: the nearest ancestor directory holding a canon.yaml)
34
+ .TP
35
+ \fB\-\-json\fR
36
+ Output authorization result as JSON
37
+ .TP
38
+ \fB\-h\fR, \fB\-\-help\fR
39
+ Print help
40
+ .TP
41
+ \fB\-V\fR, \fB\-\-version\fR
42
+ Print version
43
+ .SH VERSION
44
+ v0.28.0
@@ -0,0 +1,44 @@
1
+ .ie \n(.g .ds Aq \(aq
2
+ .el .ds Aq '
3
+ .TH canon-adapter-validate 1 "validate 0.28.0"
4
+ .SH NAME
5
+ canon\-adapter\-validate \- Read and validate one provider\-neutral response envelope
6
+ .SH SYNOPSIS
7
+ \fBcanon adapter validate\fR [\fB\-\-as\fR] <\fB\-\-response\fR> [\fB\-\-repo\fR] [\fB\-\-json\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR]
8
+ .SH DESCRIPTION
9
+ Read and validate one provider\-neutral response envelope
10
+ .SH OPTIONS
11
+ .TP
12
+ \fB\-\-as\fR \fI<ROLE>\fR
13
+ The role you act as: planner, implementer, reviewer or orchestrator. Overrides `CANON_ROLE`. `schema` and `context` list only the role\*(Aqs commands, `status` keeps its steps, and `\-\-role` on `evidence add` / `evidence audit` / `review scenario` / `review change` defaults to it
14
+ .br
15
+
16
+ .br
17
+ \fIPossible values:\fR
18
+ .RS 14
19
+ .IP \(bu 2
20
+ planner
21
+ .IP \(bu 2
22
+ implementer
23
+ .IP \(bu 2
24
+ reviewer
25
+ .IP \(bu 2
26
+ orchestrator
27
+ .RE
28
+ .TP
29
+ \fB\-\-response\fR \fI<FILE>\fR
30
+ JSON response file to validate
31
+ .TP
32
+ \fB\-\-repo\fR \fI<DIR>\fR
33
+ The repo to act on (default: the nearest ancestor directory holding a canon.yaml)
34
+ .TP
35
+ \fB\-\-json\fR
36
+ Output the normalized core summary as JSON
37
+ .TP
38
+ \fB\-h\fR, \fB\-\-help\fR
39
+ Print help
40
+ .TP
41
+ \fB\-V\fR, \fB\-\-version\fR
42
+ Print version
43
+ .SH VERSION
44
+ v0.28.0
@@ -0,0 +1,46 @@
1
+ .ie \n(.g .ds Aq \(aq
2
+ .el .ds Aq '
3
+ .TH canon-adapter 1 "adapter 0.28.0"
4
+ .SH NAME
5
+ canon\-adapter \- Validate a provider\-neutral adapter response without executing a provider
6
+ .SH SYNOPSIS
7
+ \fBcanon adapter\fR [\fB\-\-as\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR] <\fIsubcommands\fR>
8
+ .SH DESCRIPTION
9
+ Validate a provider\-neutral adapter response without executing a provider
10
+ .SH OPTIONS
11
+ .TP
12
+ \fB\-\-as\fR \fI<ROLE>\fR
13
+ The role you act as: planner, implementer, reviewer or orchestrator. Overrides `CANON_ROLE`. `schema` and `context` list only the role\*(Aqs commands, `status` keeps its steps, and `\-\-role` on `evidence add` / `evidence audit` / `review scenario` / `review change` defaults to it
14
+ .br
15
+
16
+ .br
17
+ \fIPossible values:\fR
18
+ .RS 14
19
+ .IP \(bu 2
20
+ planner
21
+ .IP \(bu 2
22
+ implementer
23
+ .IP \(bu 2
24
+ reviewer
25
+ .IP \(bu 2
26
+ orchestrator
27
+ .RE
28
+ .TP
29
+ \fB\-h\fR, \fB\-\-help\fR
30
+ Print help
31
+ .TP
32
+ \fB\-V\fR, \fB\-\-version\fR
33
+ Print version
34
+ .SH SUBCOMMANDS
35
+ .TP
36
+ canon\-adapter\-validate(1)
37
+ Read and validate one provider\-neutral response envelope
38
+ .TP
39
+ canon\-adapter\-authorize(1)
40
+ Authorize declared capabilities against repository policy (preflight only)
41
+ .SH EXTRA
42
+ Examples:
43
+ canon adapter validate \-\-response response.json
44
+ canon adapter validate \-\-response response.json \-\-repo . \-\-json
45
+ .SH VERSION
46
+ v0.28.0
@@ -0,0 +1,63 @@
1
+ .ie \n(.g .ds Aq \(aq
2
+ .el .ds Aq '
3
+ .TH canon-artifacts-move 1 "move 0.28.0"
4
+ .SH NAME
5
+ canon\-artifacts\-move \- Move the local artifact blobs to an object\-store tier, verify them, and remove the local copies
6
+ .SH SYNOPSIS
7
+ \fBcanon artifacts move\fR [\fB\-\-as\fR] <\fB\-\-tier\fR> [\fB\-\-commit\fR] [\fB\-\-plan\-digest\fR] [\fB\-\-repo\fR] [\fB\-\-json\fR] [\fB\-\-input\fR] [\fB\-h\fR|\fB\-\-help\fR] [\fB\-V\fR|\fB\-\-version\fR]
8
+ .SH DESCRIPTION
9
+ Move the local artifact blobs to an object\-store tier, verify them, and remove the local copies
10
+ .SH OPTIONS
11
+ .TP
12
+ \fB\-\-as\fR \fI<ROLE>\fR
13
+ The role you act as: planner, implementer, reviewer or orchestrator. Overrides `CANON_ROLE`. `schema` and `context` list only the role\*(Aqs commands, `status` keeps its steps, and `\-\-role` on `evidence add` / `evidence audit` / `review scenario` / `review change` defaults to it
14
+ .br
15
+
16
+ .br
17
+ \fIPossible values:\fR
18
+ .RS 14
19
+ .IP \(bu 2
20
+ planner
21
+ .IP \(bu 2
22
+ implementer
23
+ .IP \(bu 2
24
+ reviewer
25
+ .IP \(bu 2
26
+ orchestrator
27
+ .RE
28
+ .TP
29
+ \fB\-\-tier\fR \fI<TIER>\fR
30
+ The tier to move to: the name of an `s3` tier in canon.yaml (for example `cold`)
31
+ .TP
32
+ \fB\-\-commit\fR
33
+ Act on the previewed plan; needs \-\-plan\-digest
34
+ .TP
35
+ \fB\-\-plan\-digest\fR \fI<DIGEST>\fR
36
+ The `planDigest` the preview printed; the run acts only if the plan recomputed now has this digest
37
+ .TP
38
+ \fB\-\-repo\fR \fI<DIR>\fR
39
+ The repo to act on (default: the nearest ancestor directory holding a canon.yaml)
40
+ .TP
41
+ \fB\-\-json\fR
42
+ Output JSON instead of the human\-readable form
43
+ .TP
44
+ \fB\-\-input\fR \fI<JSON|FILE|\->\fR
45
+ The arguments as JSON: an object (one run) or an array / NDJSON file or `\-` (a batch); keys are the option names in camelCase, `operands` an array
46
+ .TP
47
+ \fB\-h\fR, \fB\-\-help\fR
48
+ Print help
49
+ .TP
50
+ \fB\-V\fR, \fB\-\-version\fR
51
+ Print version
52
+ .SH EXTRA
53
+ Examples:
54
+ canon artifacts move \-\-tier cold
55
+ canon artifacts move \-\-tier cold \-\-commit \-\-plan\-digest <DIGEST>
56
+
57
+ The bare run previews: it lists every upload and removal and prints a planDigest, and writes nothing. \-\-commit \-\-plan\-digest acts on exactly that plan (PLAN_CHANGED, exit 2, when it changed since).
58
+
59
+ \-\-tier names an `s3` tier of canon.yaml\*(Aqs `tiers:` (for example `cold`; its credentials are the tier\*(Aqs own). Every blob in .canon/artifacts/sha256 is hashed, uploaded under <prefix>sha256/<digest> (prefix artifacts/), and read back; only when all of them verified does canon.yaml gain `artifact_store: { backend: <tier>, prefix: artifacts/ }`, after which the local copies are removed and `.canon/artifacts/` is added to .gitignore. Commit the removal with the ledger.
60
+
61
+ Idempotent and resumable: a run stopped anywhere leaves a repo the gate still passes, and the next run finishes; a second run finds nothing to do. A blob whose bytes do not match its name is never moved. Moving back to local is refused; `\-\-tier local` on a local repo is a no\-op.
62
+ .SH VERSION
63
+ v0.28.0