@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
@@ -13,18 +13,18 @@ trajectories into retrievable, promotable insights. Two tiers:
13
13
  ## Rebuilding strategy memory
14
14
 
15
15
  Strategy memory is re-derived from the current trajectory set as part of
16
- `canon ingest artifacts` (see `canon-artifact-ingest`): after it
16
+ `canon ingest records` (see `canon-artifact-ingest`): after it
17
17
  persists a repo's verdict trajectories, it re-derives the distilled
18
18
  strategies. This is NON-DESTRUCTIVE — a rebuild never drops a
19
19
  hand-promoted strategy the trajectory rows don't touch. There is no
20
- standalone `canon learn` rebuild command; the only subcommand is
21
- `promote`.
20
+ standalone rebuild command under `canon strategy`; its subcommands are
21
+ `promote`, `approval-payload` and `rollback`.
22
22
 
23
- # `canon learn promote <strategy_id> [--repo <dir>] [--evaluation <path> --approval <path>] [--signature <path>] [--dry-run]`
23
+ # `canon strategy promote <strategy_id> [--repo <dir>] [--evaluation <path> --approval <path>] [--signature-file <path>] [--dry-run]`
24
24
 
25
25
  The production activation path is a signed, paired-evaluation workflow:
26
26
 
27
- 1. Run `canon ingest artifacts`. Ingest resolves covering verdicts and rebuilds
27
+ 1. Run `canon ingest records`. Ingest resolves covering verdicts and rebuilds
28
28
  newly distilled strategies as `lifecycle: quarantined`.
29
29
  2. Check eligibility with the configured `occurrence` or `crn` gate. This is
30
30
  only a prerequisite; occurrence alone MUST NOT activate a strategy.
@@ -44,14 +44,14 @@ The production activation path is a signed, paired-evaluation workflow:
44
44
  5. Produce the unsigned approval payload:
45
45
 
46
46
  ```bash
47
- canon learn approve <strategy_id> --evaluation evaluation.json \
48
- --principal alice --repo .
47
+ canon strategy approval-payload 01J8ZQ4W7K2M5N6P8R0S3T9VXY --evaluation evaluation.json \
48
+ --approver alice --approval-at 2026-10-02T12:00:00Z --repo .
49
49
  ```
50
50
 
51
51
  With `--json` the payload is `.data` of the `{ "data", "meta" }` envelope, and
52
52
  `meta.next` names the human signing step. The `data` contains the evaluation digest, RFC3339 `approved_at`,
53
53
  subject `strategy:<strategy_id>`, namespace
54
- `canon-learning-approval-v1`, and `payload_hex`. `approve` never
54
+ `canon-learning-approval-v1`, and `payload_hex`. `approval-payload` never
55
55
  reads a private key and never sets `verified`.
56
56
  6. Decode `payload_hex` to the exact canonical JSON bytes. The signed object
57
57
  is:
@@ -97,12 +97,12 @@ The production activation path is a signed, paired-evaluation workflow:
97
97
  8. Activate only with both evidence files:
98
98
 
99
99
  ```bash
100
- canon learn promote <strategy_id> --repo . \
100
+ canon strategy promote 01J8ZQ4W7K2M5N6P8R0S3T9VXY --repo . \
101
101
  --evaluation evaluation.json --approval approval.json
102
102
  # Or attach an armored signature file and recompute the approval digest:
103
- canon learn promote <strategy_id> --repo . \
103
+ canon strategy promote 01J8ZQ4W7K2M5N6P8R0S3T9VXY --repo . \
104
104
  --evaluation evaluation.json --approval approval.json \
105
- --signature approval.sig
105
+ --signature-file approval.sig
106
106
  ```
107
107
 
108
108
  `--evaluation` and `--approval` MUST be supplied together. A quarantined
@@ -123,6 +123,10 @@ An unknown `strategy_id` fails nonzero. A candidate's lifecycle defaults to
123
123
  The old public writer is retained only for already-`active` items; it is not a
124
124
  way to activate new or legacy candidates.
125
125
 
126
+ **Done when:** `canon strategy promote <strategy_id>` exits `0` and
127
+ `canon retrieve` returns the strategy for its regime (a quarantined
128
+ candidate stays out of retrieval).
129
+
126
130
  ### The eligibility gates: `crn` vs `occurrence`
127
131
 
128
132
  A role's eligibility gate is a `canon.yaml` `learn:`-section choice:
@@ -160,11 +164,11 @@ A role with no explicit `promotion.<role>` entry defaults to
160
164
 
161
165
  Both gates read resolved `verdict_record.outcome`, not raw verdict rows.
162
166
  `Pending` trajectories neither corroborate nor contradict. `canon ingest
163
- artifacts` is therefore always first:
167
+ records` is therefore always first:
164
168
 
165
169
  ```bash
166
- canon ingest artifacts
167
- canon learn promote <id> --evaluation evaluation.json --approval approval.json
170
+ canon ingest records
171
+ canon strategy promote 01J8ZQ4W7K2M5N6P8R0S3T9VXY --evaluation evaluation.json --approval approval.json
168
172
  ```
169
173
 
170
174
  ### Demotion versus authenticated rollback
@@ -178,15 +182,15 @@ record.
178
182
 
179
183
  An operator-requested rollback is a distinct authenticated action:
180
184
 
181
- ```bash
182
- canon learn rollback <strategy_id> --reason "<reason>" --actor-id alice \
183
- --signature-file rollback.sig --approved-at 2026-10-02T12:00:00Z \
185
+ ```text
186
+ canon strategy rollback <strategy_id> --reason "<reason>" --actor-id alice \
187
+ --signature-file rollback.sig --approval-at 2026-10-02T12:00:00Z \
184
188
  [--contradicting-trajectory-id <trajectory_id>] --repo .
185
189
  ```
186
190
 
187
191
  `--signature-file` is an armored SSH detached signature over the
188
192
  `canon-learning-approval-v1` payload bound to
189
- `strategy:<id>:rollback:<sha256(reason)>`, actor, and `--approved-at`.
193
+ `strategy:<id>:rollback:<sha256(reason)>`, actor, and `--approval-at`.
190
194
  `actor` MUST be listed in policy-pinned `approval.allowed_signers`; verification
191
195
  uses that file and `ssh-keygen -Y verify`. Successful rollback writes durable
192
196
  provenance, sets lifecycle `rolled_back`, and records the optional contradicting
@@ -203,7 +207,7 @@ not upgrade legacy rows or establish measured uplift.
203
207
 
204
208
  ## How verdicts feed scoring
205
209
 
206
- Verdicts arrive from `canon ingest artifacts` (see
210
+ Verdicts arrive from `canon ingest records` (see
207
211
  `canon-artifact-ingest`), persisted regime-keyed
208
212
  (`<role>/<repo>/<area>/<hash>`). Each verdict scores its covering
209
213
  trajectory into `Success` / `Failure` / `RolledBack` / `Pending`; the
@@ -13,8 +13,8 @@ one, and neither can `canon gate`.
13
13
  one `<slug>/` directory per change holding `brief.md` (and a `tasks.md`
14
14
  only when someone adds one: an optional work note), written by
15
15
  `canon change new` (see `canon-subject`). Every plan reader —
16
- `canon ingest plans`, `canon gate task`, `canon evidence add --task`,
17
- `canon dispatch --task`, `canon status` and the brief check — reads it
16
+ `canon ingest plans`, `canon task done`, `canon evidence add --task-id`,
17
+ `canon dispatch begin --task-id`, `canon status` and the brief check — reads it
18
18
  first whenever the directory exists, with no `plans:` entry. Being first,
19
19
  it owns a change id an external source also carries (the external copy
20
20
  is the later duplicate, skipped and counted under `duplicate_change_id`).
@@ -27,7 +27,7 @@ document and holds the human's `Approved:` line, written by
27
27
  skips that directory and the external source keeps the change id.
28
28
 
29
29
  `plans.sources` lists only EXTERNAL plans — documents you prepare outside
30
- canon, which canon only reads. The one exception: `canon gate task`
30
+ canon, which canon only reads. The one exception: `canon task done`
31
31
  flips the task's checkbox in an external plan's `tasks.md` (see
32
32
  `canon-gate`). Their briefs and approvals live in
33
33
  `.canon/changes/<change>/brief.md`, never in the external document.
@@ -58,7 +58,7 @@ single ad hoc import, reading only the source it names; either flag alone
58
58
  fails loud):
59
59
 
60
60
  ```bash
61
- canon ingest plans --dialect openspec --source ../other-repo
61
+ canon ingest plans --dialect openspec --plan-source ../other-repo
62
62
  ```
63
63
 
64
64
  ## 2. Run the import
@@ -78,11 +78,14 @@ the adapter's `unmapped` drop counts, and `malformed` (structurally
78
78
  broken constructs). A source whose content is byte-identical to its last
79
79
  successful run is `skipped_unchanged` — re-importing writes zero records.
80
80
 
81
+ **Done when:** `canon ingest plans` exits `0` with `malformed` and
82
+ `changes_unwritten` at `0` for every source; step 3 lists the imported rows.
83
+
81
84
  ## 3. Read the imported rows
82
85
 
83
86
  ```bash
84
- canon query --kind change [--json]
85
- canon query --kind task [--json]
87
+ canon query --kind change --json
88
+ canon query --kind task --json
86
89
  ```
87
90
 
88
91
  No dialect/plugin filter exists or is needed — an imported `change`/
@@ -181,7 +184,7 @@ downstream reader's job.
181
184
  `.canon/changes/<slug>/brief.md` (no `tasks.md`) and adopts the change
182
185
  into a subject (see `canon-subject`); it never scaffolds an openspec
183
186
  change dir. This skill covers IMPORTING plans.
184
- - **`canon gate check`/`canon gate task`** (the hand-authored one-task-at-
187
+ - **`canon gate check`/`canon task done`** (the hand-authored one-task-at-
185
188
  a-time path this complements at bulk) — see `canon-gate`.
186
189
  - **Wiring an imported `Task`/`Change` into a `canon gate` decision** —
187
190
  out of scope; needs its own reviewed change.
@@ -61,17 +61,21 @@ matching; no field outside envelope ∪ join-key ∪ declared), then writes.
61
61
  The on-disk path is derived from the join-key field values in declared
62
62
  order plus a body digest — a byte-identical resubmission dedupes to the
63
63
  same path; a different body for the same join key appends at a new path,
64
- never overwriting.
64
+ never overwriting. `--dry-run` validates and reports what would be written
65
+ without writing; an identical rerun writes nothing and reports `unchanged`.
66
+
67
+ **Done when:** `canon plugin sync <plugin-id>` exits `0` with no validation
68
+ error; the next step (3) reads the overlay back.
65
69
 
66
70
  ## 3. Project a read
67
71
 
68
72
  ```bash
69
- canon query --kind scenario --plugin porting # human table, projected fields appended
70
- canon query --kind scenario --plugin porting --json # merged record bodies
71
- canon query --kind scenario # no --plugin: byte-identical to the core view
73
+ canon query --kind scenario --plugin-id porting # human table, projected fields appended
74
+ canon query --kind scenario --plugin-id porting --json # merged record bodies
75
+ canon query --kind scenario # no --plugin-id: byte-identical to the core view
72
76
  ```
73
77
 
74
- `--plugin <id>` folds the plugin's overlay records (latest-by-
78
+ `--plugin-id <id>` folds the plugin's overlay records (latest-by-
75
79
  `(join_key, at)`) onto each queried core record. Fail-soft everywhere:
76
80
 
77
81
  - No overlay record for a core key → that record projects UNMODIFIED (no
@@ -81,9 +85,12 @@ canon query --kind scenario # no --plugin: byte-identi
81
85
  SKIPPED + diagnosed; siblings still project.
82
86
  - An absent plugin/manifest → the unmodified core view + a diagnostic,
83
87
  never a process error.
84
- - Omitting `--plugin` is byte-identical to `canon query`'s output without
88
+ - Omitting `--plugin-id` is byte-identical to `canon query`'s output without
85
89
  plugins — it's a purely additive layer.
86
90
 
91
+ **Done when:** the projected table or JSON shows the plugin's fields on the
92
+ scenarios you synced.
93
+
87
94
  ## The `porting` worked example
88
95
 
89
96
  `porting` moves the `covered`/`surface_ref` fields off the core
@@ -91,7 +98,7 @@ canon query --kind scenario # no --plugin: byte-identi
91
98
 
92
99
  1. `.canon/plugins/porting/plugin.yaml` — the manifest above.
93
100
  2. Its overlay source reads a spec root's `inventory/**/*.yaml` (the same
94
- inventory files `canon format --check` covers) and, for every
101
+ inventory files `canon format` covers) and, for every
95
102
  `(project_id, scenario_id)` `canon inventory sync` would index, emits
96
103
  one candidate: `covered = true` iff that `scenario_id` appears in ANY
97
104
  inventory entry's `covered_by` list; `surface_ref` = every inventory-
@@ -101,7 +108,7 @@ canon query --kind scenario # no --plugin: byte-identi
101
108
  (zero new files) and a genuine coverage edit supersedes the prior
102
109
  overlay via latest-`at`-wins.
103
110
  3. `canon plugin sync porting` writes/dedupes those candidates.
104
- 4. `canon query --kind scenario --plugin porting [--json]` projects
111
+ 4. `canon query --kind scenario --plugin-id porting [--json]` projects
105
112
  `covered`/`surface_ref` back onto each scenario.
106
113
 
107
114
  `canon gate check`'s verdicts are byte-identical with and without a
@@ -69,15 +69,16 @@ statuses (see `canon-gate`).
69
69
  ## Approving the policy
70
70
 
71
71
  ```bash
72
- canon policy approve --by <who> [--note <text>] [--repo <dir>]
72
+ canon policy approve --approver <who> [--note <text>] [--repo <dir>]
73
73
  ```
74
74
 
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
- loop). `canon brief approve` records both in one call, so the agent does
78
- not run this command next to it. Run `canon policy approve` alone for a
79
- policy-only change, as the human, or as the agent right after that answer
80
- (`canon policy approve --by <the human> --note "<their words>"`). It
77
+ loop). `canon brief approve` records both in one call. `canon policy
78
+ approve` is a human-only leaf: with a role declared (`--as` or `CANON_ROLE`)
79
+ it is refused with `HUMAN_ONLY` (exit 2, not retryable), and no flag grants
80
+ it to an agent. The human runs it themselves, for a policy-only change or
81
+ after the brief answer, supplying `--approver` and `--note`. It
81
82
  writes `.canon/policy.approval.json` directly (nothing to promote):
82
83
 
83
84
  ```json
@@ -91,34 +92,37 @@ writes `.canon/policy.approval.json` directly (nothing to promote):
91
92
 
92
93
  Commit it with the policy: the file is tracked, and neither canon's
93
94
  `.gitignore` nor the one `canon init` writes ignores it. Running the
94
- command again replaces the record. With no `.canon/policy.yaml` it is
95
- refused (exit `2`), and so is an empty `--by`.
95
+ command again replaces the one approval file (replay-safe). With no
96
+ `.canon/policy.yaml` it is
97
+ refused (exit `2`), and so is an empty `--approver`.
98
+
99
+ **Done when:** `canon policy show` reports `approval: approved` and
100
+ `canon gate check` no longer prints `policy not approved`.
96
101
 
97
102
  While a policy exists with no approval, `canon gate check` prints after
98
103
  its result:
99
104
 
100
105
  ```
101
- advisory: policy not approved: .canon/policy.yaml has no approval record (.canon/policy.approval.json); a human reviews it and runs `canon policy approve --by <who>`
106
+ advisory: policy not approved: .canon/policy.yaml has no approval record (.canon/policy.approval.json); a human reviews it and runs `canon policy approve --approver <who>`
102
107
  ```
103
108
 
104
109
  Once the policy's bytes no longer match the approved digest, or the
105
110
  approval file cannot be read, the gate fails closed instead:
106
111
 
107
112
  ```
108
- unreviewed-promotion policy — policy changed since approval: .canon/policy.yaml is sha256:<now>, but `<who>` approved sha256:<then> at <time>; … (--override-reason does not waive it); the human re-approves the policy in force with `canon policy approve --by <human> --note "<words>"`, or restore the approved .canon/policy.yaml (and .canon/policy.approval.json) from git
113
+ unreviewed-promotion policy — policy changed since approval: .canon/policy.yaml is sha256:<now>, but `<who>` approved sha256:<then> at <time>; … (--override-reason does not waive it); the human re-approves the policy in force with `canon policy approve --approver <human> --note "<words>"`, or restore the approved .canon/policy.yaml (and .canon/policy.approval.json) from git
109
114
  ```
110
115
 
111
- `canon gate check` exits `1`; `canon subject status` (the ship guard and
116
+ `canon gate check` exits `1`; `canon subject move` (the ship guard and
112
117
  the reopen) refuses with `POLICY_CHANGED_SINCE_APPROVAL`, or
113
118
  `POLICY_APPROVAL_UNREADABLE` for an unreadable approval, and
114
119
  `--override-reason` does not waive either. A policy never approved stays
115
120
  an advisory. `canon status` prints the same text as a `warning:` line (and
116
- in `--json` `warnings`). canon cannot tell whether a human or an agent
117
- ran `policy approve`, so the record names who approved which bytes and
118
- the gate fails when that no longer holds. An agent never edits the policy
121
+ in `--json` `warnings`). The record names who approved which bytes and
122
+ the gate fails when that no longer holds, whoever ran `policy approve`.
123
+ An agent never edits the policy
119
124
  to pass the gate: it stops and asks the human, who re-approves or restores
120
- it. An agent runs `canon policy approve` only to record a human's answer,
121
- never without one and never on its own behalf.
125
+ it.
122
126
 
123
127
  ## `canon policy show [--json]`
124
128
 
@@ -251,7 +255,7 @@ read as a big-endian u64, are less than `rate · 2^64` — computed exactly,
251
255
  as a comparison against `ceil(rate · 2^64)`, so `rate: 0` samples nothing
252
256
  and `rate: 1` samples everything. A sampled in-scope scenario whose
253
257
  latest audit is missing or `indeterminate` is `uncovered-cell`; with
254
- `shipped` in `scope`, `canon subject status <id> --to shipped` also refuses
258
+ `shipped` in `scope`, `canon subject move <id> --to shipped` also refuses
255
259
  it. `canon context` and the `canon status` policy line show
256
260
  `require_audit=(rate=… seed=`…` scope=…)`.
257
261
 
@@ -1,7 +1,7 @@
1
1
  # canon-report-dashboard
2
2
 
3
- canon's single status surface: `canon report` renders TEN panels to
4
- markdown, `canon report --snapshot` exports the same ten marts to
3
+ canon's single status surface: `canon report build` renders TEN panels to
4
+ markdown, `canon report snapshot` exports the same ten marts to
5
5
  Parquet, and `canon dashboard` serves a small zero-network web app that
6
6
  renders SEVEN of them from such a snapshot. Neither surface computes an
7
7
  aggregate itself — both read canon's precomputed
@@ -24,24 +24,24 @@ file to those literals. Copy a claim; do not paraphrase it.
24
24
 
25
25
  `.canon/REPORT.md` carries a leading `<!-- GENERATED by \`canon report\` …
26
26
  DO NOT EDIT. -->` comment. If it looks stale or wrong, the fix is
27
- **always** re-running `canon report` (or fixing the underlying
27
+ **always** re-running `canon report build` (or fixing the underlying
28
28
  ledger/policy it renders) — never hand-editing the file. The report
29
29
  header embeds only input-derived digests (corpus hash, policy hash,
30
30
  ledger-head hash) and **no timestamp, no `source_git_sha`**, so a
31
31
  committed report is reproducible from named inputs and `canon report
32
- --check` can byte-diff it deterministically. `source_git_sha` belongs
33
- only in `--snapshot`'s `manifest.json` (below), which is never
32
+ check` can byte-diff it deterministically. `source_git_sha` belongs
33
+ only in `report snapshot`'s `manifest.json` (below), which is never
34
34
  drift-checked.
35
35
 
36
- ## `canon report [--repo <dir>]`
36
+ ## `canon report build [--repo <dir>]`
37
37
 
38
38
  Renders the current ten-panel report to `<repo>/.canon/REPORT.md`.
39
39
  `--repo` resolves through the nearest-`canon.yaml`-ancestor walk every
40
40
  subcommand uses — omit it (or pass `.`) to run from any subdirectory.
41
41
 
42
42
  ```bash
43
- canon report # writes .canon/REPORT.md
44
- canon report --repo /path/to/repo
43
+ canon report build # writes .canon/REPORT.md
44
+ canon report build --repo /path/to/repo
45
45
  ```
46
46
 
47
47
  Between the digest header and the first panel, the report may also
@@ -51,26 +51,35 @@ probe, and an empty set renders NO section at all — so a repo routing
51
51
  nothing to a not-directly-readable backend renders exactly as before
52
52
  the section existed.
53
53
 
54
- ## `canon report --check` — the CI drift gate
54
+ **Done when:** `canon report build` exits `0` and `canon report check`
55
+ then exits `0` (no `DRIFT`).
56
+
57
+ ## `canon report check` — the CI drift gate
55
58
 
56
59
  Regenerates the report in memory and byte-compares it against the
57
60
  committed `.canon/REPORT.md`:
58
61
 
59
- - `MISSING` (exit 1) — no report has ever been written; run `canon report` first.
62
+ - `MISSING` (exit 1) — no report has ever been written; run `canon report build` first.
60
63
  - no drift (exit 0) — the committed file is byte-identical to what the
61
64
  current inputs would render now.
62
65
  - `DRIFT` (exit 1) — the committed file disagrees with current inputs
63
66
  (hand-edited, or the corpus/policy/ledger moved and nobody re-ran
64
- `canon report`).
67
+ `canon report build`).
65
68
 
66
69
  ```bash
67
- canon report --check # wire into CI exactly like canon format --check / canon gate check
70
+ canon report check # wire into CI exactly like canon format / canon gate check
68
71
  ```
69
72
 
70
73
  Wire it as a CI step or pre-push hook the same way `canon gate
71
- install-hooks` wires `canon gate check`; run `canon report --check`
74
+ install-hooks` wires `canon gate check`; run `canon report check`
72
75
  directly wherever CI already runs those.
73
76
 
77
+ **Done when:** `canon report check` exits `0` in CI on the committed
78
+ `.canon/REPORT.md`; `DRIFT` or `MISSING` means run `canon report build`
79
+ and commit the result.
80
+
81
+ ## `canon report snapshot <dir>`
82
+
74
83
  Exports all ten views to `<dir>/<table>.parquet` plus a
75
84
  `<dir>/manifest.json`. One explicit `COPY` per view — the exported
76
85
  columns are each view's own `SELECT` list, wider than the curated column
@@ -107,9 +116,11 @@ corpus/policy/ledger digests the report header renders, so a snapshot's
107
116
  provenance is comparable to a report's without re-deriving anything.
108
117
 
109
118
  ```bash
110
- canon report --snapshot /tmp/canon-snap
119
+ canon report snapshot /tmp/canon-snap
111
120
  ```
112
121
 
122
+ **Done when:** `<dir>/manifest.json` exists and lists the exported tables.
123
+
113
124
  ## `canon dashboard [--repo <dir>] [--snapshot <dir>] [--port <n>]`
114
125
 
115
126
  Serves the dashboard web app locally, pointed at a real snapshot:
@@ -119,7 +130,7 @@ canon dashboard # regenerates a fresh snapshot every run,
119
130
  canon dashboard --snapshot /tmp/canon-snap --port 8080
120
131
  ```
121
132
 
122
- - `--snapshot` omitted: `canon dashboard` calls `canon report --snapshot`
133
+ - `--snapshot` omitted: `canon dashboard` calls `canon report snapshot`
123
134
  itself every run, into the conventional `.canon/dashboard-snapshot`
124
135
  scratch directory — always fresh.
125
136
  - `--snapshot <dir>` given: served AS-IS when `<dir>` already has a
@@ -141,11 +152,11 @@ canon dashboard --snapshot /tmp/canon-snap --port 8080
141
152
  `Approved:` line, or edited since) with its intent, outcome, flow steps,
142
153
  acceptance, questions and assumptions, and its `canon brief check`
143
154
  blockers and advisories. The human types their name and their answer and
144
- clicks Approve: that records exactly what `canon brief approve --change-id
145
- <id> --by <name> --note <text>` records, the `Approved:` line bound to the
155
+ clicks Approve: that records exactly what `canon brief approve
156
+ <id> --approver <name> --note <text>` records, the `Approved:` line bound to the
146
157
  brief digest and the policy approval. It is refused when the brief changed
147
158
  after the page loaded (`BRIEF_CHANGED_SINCE_PAGE_LOAD`: reload) or while it
148
- has blockers (`BRIEF_HAS_BLOCKERS`). The server is localhost only and
159
+ has blockers (`BRIEF_APPROVE_REFUSED`). The server is localhost only and
149
160
  refuses requests from other origins (`DASHBOARD_ORIGIN_REFUSED`).
150
161
 
151
162
  For an agent the human stop is unchanged: when clean briefs are waiting,
@@ -220,7 +231,7 @@ computes it; nothing here is derived a second time.
220
231
  window down by `EvidenceRecord.verdict`. `divergence_open_running_total` is
221
232
  a running `opened - resolved` event count, NOT the number open now —
222
233
  the two differ whenever one `resolved` record closes several findings on a
223
- scenario. For current state per scenario, run `canon divergence status`.
234
+ scenario. For current state per scenario, run `canon divergence list`.
224
235
 
225
236
  - **Scope status** (`mart_scope_status`) —
226
237
  Every specified scenario × evidence-verified × plan-carried × spec-covered (`mart_scope_status`). Driven by the spec corpus, so a scenario no plan task declares still appears — with a NULL `task_id`, which is the worklist entry.
@@ -4,30 +4,30 @@
4
4
  `canon-learn`) at task-dispatch time. It is a fail-soft, advisory-only
5
5
  read: it NEVER blocks a dispatch and NEVER gates reproducibility.
6
6
 
7
- ## `canon retrieve --role <r> --regime <k> [--k <n>] [--repo <dir>] [--json]`
7
+ ## `canon retrieve --for-role <r> --regime <k> [--limit <n>] [--repo <dir>] [--json]`
8
8
 
9
9
  Prints the top-`k` retrievable strategies stored for `regime_key = <k>`
10
10
  (active strategies plus backward-compatible legacy rows without a lifecycle;
11
11
  guardrails are just strategies distilled from a failure-polarity verdict),
12
- newest-distilled first, capped at `--k` (default 5). Demoted,
12
+ newest-distilled first, capped at `--limit` (default 5). Demoted,
13
13
  quarantined, rejected, and rolled-back rows are not retrievable.
14
14
 
15
15
  ```bash
16
- canon retrieve --role dev --regime dev/canon/join-spine/9c93d024b1a2
17
- canon retrieve --role dev --regime dev/canon/join-spine/9c93d024b1a2 --k 3 --json
16
+ canon retrieve --for-role dev --regime dev/canon/join-spine/9c93d024b1a2
17
+ canon retrieve --for-role dev --regime dev/canon/join-spine/9c93d024b1a2 --limit 3 --json
18
18
  ```
19
19
 
20
20
  - `--regime` is the FULL `regime_key` string
21
21
  (`<role>/<repo>/<area>/<hash>`) — the same serialization the write side
22
22
  produces.
23
- - Assembling `--regime` in a script or hook? Use `canon regime-key
24
- --role <r> --repo <r> --area <a> --hash <h>`: it runs canon's ONE
23
+ - Assembling `--regime` in a script or hook? Use `canon regime show
24
+ --role-segment <r> --repo-name <r> --area <a> --hash <h>`: it runs canon's ONE
25
25
  canonical `regime_key` serializer and prints the validated key, so a
26
26
  caller routes through the exact normalizer the write path uses instead
27
27
  of a drifting shell slug. Exits `2` with empty stdout on a malformed
28
28
  result (empty segment / bad `<hash>`) — a clean fail-soft branch for
29
29
  `|| exit 0` callers.
30
- - `--role` MUST equal `--regime`'s leading segment — a mismatch is a
30
+ - `--for-role` MUST equal `--regime`'s leading segment — a mismatch is a
31
31
  clean usage error, exit `2` (mirroring `canon gate check`'s
32
32
  0-clean/1-red/2-usage convention), never a panic or a silently-ignored
33
33
  mismatch.
@@ -36,7 +36,7 @@ canon retrieve --role dev --regime dev/canon/join-spine/9c93d024b1a2 --k 3 --jso
36
36
  `canon.yaml` `learn:` section names the store root (`.canon/learn` by
37
37
  default); a repo with no `canon.yaml` still works, defaulting cleanly.
38
38
 
39
- **FAIL-SOFT, always exit `0`** once `--role`/`--regime` agree: a store
39
+ **FAIL-SOFT, always exit `0`** once `--for-role`/`--regime` agree: a store
40
40
  outage, an empty/nonexistent store, or a malformed on-disk row all
41
41
  degrade to an empty guidance list — never a nonzero exit or an error a
42
42
  caller must handle.
@@ -46,8 +46,8 @@ caller must handle.
46
46
  A generic, fail-soft, advisory-only shell script that fires at a
47
47
  PreToolUse-equivalent point for a `task`-shaped dispatch (Claude Code's
48
48
  `Task` tool / Codex's equivalent). It reads the tool's `subagent_type`
49
- as `--role`, assembles `--regime` by routing its repo/area segments
50
- through `canon regime-key` (so it never re-derives the join key with a
49
+ as `--for-role`, assembles `--regime` by routing its repo/area segments
50
+ through `canon regime show` (so it never re-derives the join key with a
51
51
  drifting shell slug), calls `canon retrieve --json`, and emits the
52
52
  result as a `PreToolUse` `hookSpecificOutput.additionalContext` JSON
53
53
  envelope on stdout — Claude Code's convention for surfacing advisory
@@ -76,6 +76,9 @@ timeout}]}` entry into BOTH `<repo>/.claude/settings.json` and
76
76
  `<repo>/.codex/hooks.json`, additive and idempotent — see the
77
77
  `canon-gate` skill for `install-hooks`'s full contract.
78
78
 
79
+ **Done when:** the hook entry is in both `settings.json` and `hooks.json`;
80
+ running `canon gate install-hooks` again changes nothing.
81
+
79
82
  ## Replay vs. live retrieval
80
83
 
81
84
  A run manifest records `injected_guidance` — a full SNAPSHOT (each entry