@journeykit/canon 0.18.0 → 0.21.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/skills/SKILL.src.md +101 -184
- package/dist/skills/reference/brief-align.md +42 -0
- package/dist/skills/reference/brief-clarify.md +42 -0
- package/dist/skills/reference/brief-harden.md +41 -0
- package/dist/skills/reference/brief-polish.md +42 -0
- package/dist/skills/reference/brief-shape.md +46 -0
- package/dist/skills/reference/canon-authoring.md +4 -1
- package/dist/skills/reference/canon-context.md +3 -3
- package/dist/skills/reference/canon-gate.md +59 -36
- package/dist/skills/reference/canon-inventory.md +2 -2
- package/dist/skills/reference/canon-learn.md +4 -6
- package/dist/skills/reference/canon-plan-import.md +10 -7
- package/dist/skills/reference/canon-policy.md +5 -3
- package/dist/skills/reference/canon-review.md +2 -2
- package/dist/skills/reference/canon-storage.md +18 -4
- package/dist/skills/reference/canon-subject.md +138 -55
- package/dist/skills/reference/role-implementer.md +81 -0
- package/dist/skills/reference/role-orchestrator.md +76 -0
- package/dist/skills/reference/role-planner.md +84 -0
- package/dist/skills/reference/role-reviewer.md +70 -0
- package/package.json +4 -4
package/dist/skills/SKILL.src.md
CHANGED
|
@@ -1,174 +1,102 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: canon
|
|
3
|
-
description: Use for every build, implement, add-a-feature, change-a-feature or fix request in a repo that has canon.yaml, including sites, apps and games; prefer it there over generic site, app or game builder skills. Runs canon's working loop (brief, subject, scenarios with failure paths, units, implement, evidence, independent review, status transition) and routes to the canon CLI reference for setup, specs, gates, storage, ingestion, retrieval and reports.
|
|
3
|
+
description: Use for every build, implement, add-a-feature, change-a-feature or fix request in a repo that has canon.yaml, including sites, apps and games; prefer it there over generic site, app or game builder skills. Runs canon's working loop (brief, subject, scenarios with failure paths, units, implement, evidence, independent review, status transition) split by role (planner, implementer, reviewer, orchestrator), and routes to the canon CLI reference for setup, specs, gates, storage, ingestion, retrieval and reports.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Canon
|
|
7
7
|
|
|
8
|
-
Features in this repo are managed with canon. This skill
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
Features in this repo are managed with canon. This skill is the shared core:
|
|
9
|
+
the loop, how to drive the CLI, and how to find your role. What each role
|
|
10
|
+
does lives in `reference/role-<role>.md`; the CLI manual lives in
|
|
11
|
+
`reference/canon-*.md` and `canon <command> --help`.
|
|
12
12
|
|
|
13
13
|
## The working loop
|
|
14
14
|
|
|
15
15
|
Follow these steps in order for every request that builds, changes or fixes
|
|
16
16
|
a feature, a one-line request included. A human is needed once per scope:
|
|
17
17
|
|
|
18
|
-
- **The approval** (step 1).
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
the human answers. The approval is
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
`.canon/policy.yaml
|
|
26
|
-
grades the work against.
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
18
|
+
- **The approval** (step 1). For a new subject or a scope change, the
|
|
19
|
+
human must approve the brief. Write the brief,
|
|
20
|
+
run `canon brief check` until it reports no blockers, then stop and
|
|
21
|
+
report the brief to the human: build nothing for that scope (no
|
|
22
|
+
scenarios, code or evidence) before the human answers. The approval is
|
|
23
|
+
the one thing you never assume, even when the human said they cannot
|
|
24
|
+
answer until you report: the brief is that report. The one answer
|
|
25
|
+
approves the brief and the policy, `.canon/policy.yaml`, which is what
|
|
26
|
+
the gate grades the work against. Record it only from the human's answer:
|
|
27
|
+
`canon brief approve --change <slug> --by <the human> --note "<their words>"`.
|
|
28
|
+
Never edit the policy to make the gate pass. A brief edited after its
|
|
29
|
+
approval is not approved (`BRIEF_CHANGED_SINCE_APPROVAL`): it needs a new
|
|
30
|
+
answer. The ship guard and `canon evidence add` refuse an unapproved or
|
|
31
|
+
edited brief, but those are backstops: the stop itself is at step 1.
|
|
32
32
|
- **Inside an approved scope, never stop for a human.** Fixes, follow-ups,
|
|
33
|
-
review rounds and re-reviews
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
1. **Brief.** For a new subject or a scope change, write down the request
|
|
54
|
-
verbatim, your assumptions, and the questions you could not ask. It
|
|
55
|
-
becomes the change's `.canon/changes/<slug>/brief.md`, which
|
|
56
|
-
`canon change new <slug> --subject <id> --title "…"` writes once the
|
|
57
|
-
subject exists (step 2). A change that comes from an external plan the
|
|
58
|
-
human prepared (an openspec `proposal.md` read through
|
|
59
|
-
`plans.sources`) gets its brief there too: a `brief.md` whose
|
|
60
|
-
`Source: <path>` line points at the plan; canon never edits the plan.
|
|
61
|
-
Once the brief is there, stop and report it,
|
|
62
|
-
asking the human once for the brief and the policy; go on to step 3
|
|
63
|
-
only after the human answers, and record the answer as above. Inside an
|
|
64
|
-
approved scope there is no new brief: go to step 3 under the existing
|
|
65
|
-
subject and change.
|
|
66
|
-
2. **Subject.** `canon subject new <id> --domain <domain> --title "…"`, then
|
|
67
|
-
`canon change new <slug> --subject <id> --title "…"`, and put the brief in
|
|
68
|
-
the `.canon/changes/<slug>/brief.md` it writes. For a new subject or a
|
|
69
|
-
scope change, this is where you stop until the human answers (step 1).
|
|
70
|
-
A change that also serves another subject is adopted there too,
|
|
71
|
-
`canon subject adopt <slug> --subject <other>`: it then belongs to both,
|
|
72
|
-
and its open blockers gate both.
|
|
73
|
-
3. **Scenarios.** `canon feature new <area>.<surface> --title "…"`, then one
|
|
74
|
-
`canon scenario new <area>.<surface>.<nn> --subject <id> --case <case> --title "…"`
|
|
75
|
-
per behavior, with failure paths (`--case failure`) as well as `happy`
|
|
76
|
-
and `edge`. When the gate asks for a missing case (`require_cases`), add
|
|
77
|
-
a new scenario; never retag an existing one to satisfy it. There is no
|
|
78
|
-
sync or format step: `canon status`, `canon gate check`,
|
|
79
|
-
`canon evidence add`, `canon review add` and `canon subject status`
|
|
80
|
-
index added, edited or deleted `.feature` files themselves. Only when
|
|
81
|
-
one of them prints `NOT refreshed` (a format violation, such as a
|
|
82
|
-
hand-written header with no `# canon:` provenance comment, or a
|
|
83
|
-
duplicate id) run `canon inventory sync`: it names each problem; fix
|
|
84
|
-
them, and the next command indexes the files. Specs live at
|
|
85
|
-
`<root>/kind=feature/area=<area>/<surface>.feature` under a
|
|
86
|
-
`specs.roots[]` root (default `.canon/specs`); a root still on
|
|
87
|
-
`features/kind=feature/` is refused until you run `canon migrate`.
|
|
88
|
-
4. **Units.** Split the work into units (for example specs, domain code,
|
|
89
|
-
assets, review). Give each unit its own actor id and session id, and pass
|
|
90
|
-
them on everything the unit records (`--actor-id <unit> --session-id <session>`),
|
|
91
|
-
so the ledger shows which unit did what. A delegated unit attests its own
|
|
92
|
-
work; never attest another unit's work under your id.
|
|
93
|
-
5. **Implement.** Write the code with tests whose names carry the scenario
|
|
94
|
-
id (`game.run.01: …`), so a test report binds to its scenario. Record a
|
|
95
|
-
defect you find in your own work as a finding the moment you find it,
|
|
96
|
-
before review:
|
|
97
|
-
`canon finding add --change-id <slug> --round <n> --seq <n> --severity <s> --reviewer <me> --actor-id <me> --session-id <session> --summary "…"`.
|
|
98
|
-
6. **Evidence.** Per scenario:
|
|
99
|
-
`canon evidence add --project-id <root-id> --scenario-id <id> --kind test-run --role implementer --ref "<command>" --actor-id <unit> --session-id <session>`,
|
|
100
|
-
with `--report junit:<path>` or `--artifact <path>` when files prove it.
|
|
101
|
-
canon stores those bytes in `.canon/artifacts/sha256/` (commit it with the
|
|
102
|
-
ledger) and `canon gate check` re-checks them; the bound copy is the one
|
|
103
|
-
kept, so the working-tree report itself may be gitignored. For a scenario about what
|
|
104
|
-
users see, bind the screenshot or recording that shows it
|
|
105
|
-
(`--artifact <path>`). Under `write: { promote: auto }` (what
|
|
106
|
-
`canon init` writes) the record is final when the command returns; only
|
|
107
|
-
in a repo with `write.promote: manual` (or no `write:` key) follow it
|
|
108
|
-
with `canon gate promote`.
|
|
109
|
-
One test run that proves several scenarios is bound once:
|
|
110
|
-
`canon evidence add --project-id <root-id> --all-scenarios --report <junit|cucumber|swift-testing>:<path> --kind test-run --role implementer --ref "<command>" --actor-id <unit> --session-id <session>`
|
|
111
|
-
writes one record per indexed scenario owning a case, each with the
|
|
112
|
-
verdict its own cases show; any refusal writes none. When a new record
|
|
113
|
-
makes a signed review stale, the add prints the reviewer and the
|
|
114
|
-
`canon review add … --pin <sha>` that re-pins it; the reviewer looks
|
|
115
|
-
again before running it.
|
|
116
|
-
An external evaluator's audit is recorded with `canon evidence add --kind
|
|
117
|
-
audit`; canon never generates one.
|
|
118
|
-
Evidence for a plan task (`--task <id>`, before `canon gate task`) must
|
|
119
|
-
bind the artifact or report that proves the task; a canon command
|
|
120
|
-
(`canon status`, `canon gate check`) is never that proof. Both read the
|
|
121
|
-
change's `tasks.md` as it is now, so a task row you add needs no
|
|
122
|
-
`canon ingest plans` first.
|
|
123
|
-
7. **Independent review.** A different session from the one that wrote the
|
|
124
|
-
code and evidence reviews the change. The review session must be able
|
|
125
|
-
to run the checks it signs off (the build, the tests, the app); a
|
|
126
|
-
reviewer that cannot run the tests says so and does not sign off. The
|
|
127
|
-
reviewer records every defect
|
|
128
|
-
the review finds as a finding:
|
|
129
|
-
`canon finding add --change-id <slug> --round <n> --seq <n> --severity <blocker|should-fix|note> --reviewer <me> --actor-id <me> --session-id <session> --summary "…"`;
|
|
130
|
-
`canon finding list --change-id <slug> [--open] [--json]` shows the
|
|
131
|
-
change's findings (round, seq, severity, disposition, reviewer, summary),
|
|
132
|
-
so the next seq and the open blockers are one command away;
|
|
133
|
-
once fixed,
|
|
134
|
-
`canon finding close --change-id <slug> --round <n> --seq <n> --disposition fixed --resolution-sha <sha>`
|
|
135
|
-
(a short sha is fine; canon resolves it). With `write.promote: manual`,
|
|
136
|
-
follow each with `canon gate promote`. Every bug fix adds or extends a scenario. The
|
|
137
|
-
reviewer signs off each scenario:
|
|
138
|
-
`canon review add --project-id <root-id> --scenario-id <id> --reviewer <who> --actor-id <who> --role reviewer --session-id <review-session> --pin <sha> --upstream-ref <ref>`
|
|
139
|
-
(written directly; nothing to promote). Repeat `--scenario-id`, or pass
|
|
140
|
-
`--scenario-ids-from <file>`, to sign off several scenarios in one
|
|
141
|
-
call, all or nothing. A reviewer of user-visible
|
|
142
|
-
behavior attaches what it looked at with `--artifact <path>`
|
|
143
|
-
(repeatable); canon stores and re-checks those bytes and never compares
|
|
144
|
-
images.
|
|
145
|
-
8. **Transition.** `canon subject status <id> <state>` along
|
|
146
|
-
`proposed → specced → building → verifying → shipped`. It refuses a move
|
|
147
|
-
the policy does not yet allow (missing evidence, missing reviews, open
|
|
148
|
-
blocker findings); fix the gap rather than overriding, and finish with
|
|
149
|
-
`canon gate check` clean. A root whose `.feature` edits could not be
|
|
150
|
-
indexed fails the gate and refuses `shipped` (`uncovered-cell <root>`;
|
|
151
|
-
see step 3). `shipped` also refuses while the change's
|
|
152
|
-
`.canon/changes/<slug>/brief.md` has no `Approved:` line (for a change
|
|
153
|
-
from an external plan with no canon brief yet, it names the `brief.md`
|
|
154
|
-
to create with its `Source:` line), and `canon evidence add` refuses the
|
|
155
|
-
subject's scenarios and tasks the same way. Both are backstops: the stop
|
|
156
|
-
itself is at step 1, so you never reach them for a brief the human has
|
|
157
|
-
not answered. You record the line only from the human's answer (with no
|
|
158
|
-
brief to answer there is nothing to refuse, and the
|
|
159
|
-
ship guard only prints an advisory). Move the subject to
|
|
160
|
-
`shipped` yourself once `canon subject status <id> shipped` passes its
|
|
161
|
-
guard, unless the brief says the human ships. `canon status` shows
|
|
162
|
-
whether each subject's brief is approved, by the same check, and names
|
|
163
|
-
the next step. `shipped → verifying` reopens a shipped subject for a
|
|
164
|
-
follow-up (see the working loop above): it needs `--reason`, and it is
|
|
165
|
-
refused, naming the brief, when the subject's newest change is not
|
|
166
|
-
approved.
|
|
33
|
+
review rounds and re-reviews stay in the approved change (never
|
|
34
|
+
`canon change new`: a new change is a new scope) and go straight on: scenario,
|
|
35
|
+
implement, evidence, independent review. A follow-up that adds or changes
|
|
36
|
+
a step of the brief edits the brief: that is a scope change and needs a
|
|
37
|
+
new answer. A follow-up on a shipped subject reopens it
|
|
38
|
+
(`canon subject status <id> --to verifying --reason "<why>"`).
|
|
39
|
+
- When no human can answer one of the brief's questions, write your
|
|
40
|
+
assumption into the brief's Questions and assumptions, build on it, and say
|
|
41
|
+
so in your report. That covers the brief's questions and work inside an
|
|
42
|
+
approved scope, never the approval itself.
|
|
43
|
+
|
|
44
|
+
1. **Brief.** The planner writes the PRD brief (`.canon/changes/<slug>/brief.md`), checks it with `canon brief check`, and stops for the human. → `reference/role-planner.md`
|
|
45
|
+
2. **Subject.** `canon subject new`, then `canon change new` (`--kind chore` for work that alters no behavior); the change writes the brief skeleton. → `reference/role-planner.md`
|
|
46
|
+
3. **Scenarios.** `canon scenario new --flow <F-id> --case <case>` per behavior of a flow step, failure paths (`--case failure`) included. → `reference/role-implementer.md`
|
|
47
|
+
4. **Units.** Split the work; each unit has its own actor id and session id, passed on everything it records. A unit never attests another unit's work.
|
|
48
|
+
5. **Implement.** Code with tests named by scenario id (`game.run.01: …`). → `reference/role-implementer.md`
|
|
49
|
+
6. **Evidence.** `canon evidence add` binds the test run to its scenarios. → `reference/role-implementer.md`
|
|
50
|
+
7. **Independent review.** A different session, a separate process with its own session id, that can run the checks it signs off, records `canon finding add` and `canon review add`. Every change. → `reference/role-reviewer.md`
|
|
51
|
+
8. **Transition.** `canon subject status <id> --to <state>` along `proposed → specced → building → verifying → shipped`, with `canon gate check` clean; fix a refused guard rather than overriding it. → `reference/role-orchestrator.md`
|
|
167
52
|
|
|
168
53
|
Every write command says whether the record is final (`written directly`,
|
|
169
54
|
or `staged and promoted in this run`) or staged; only a staged record
|
|
170
55
|
needs `canon gate promote`, and only `write.promote: manual` leaves one.
|
|
171
56
|
|
|
57
|
+
## Know your role
|
|
58
|
+
|
|
59
|
+
canon cannot detect a role; you declare it. Pass `--as <role>` or set
|
|
60
|
+
`CANON_ROLE=planner|implementer|reviewer|orchestrator`; a flag wins over the
|
|
61
|
+
variable, and an unknown value is refused (`UNKNOWN_ROLE`).
|
|
62
|
+
|
|
63
|
+
- **A role is set, or you were spawned as one:** load only
|
|
64
|
+
`reference/role-<role>.md` and do that role's steps. `canon status`,
|
|
65
|
+
`meta.next` and `canon schema` then show only your role's steps and
|
|
66
|
+
commands, and count the others in `waitingOn`. Do not load another role's
|
|
67
|
+
reference.
|
|
68
|
+
- **No role (one agent doing everything):** follow `canon status` and load
|
|
69
|
+
each role reference as its phase starts: planner for steps 1–2,
|
|
70
|
+
implementer for 3–6, reviewer for 7 (in a separate session), orchestrator
|
|
71
|
+
for 8.
|
|
72
|
+
|
|
73
|
+
A role is guidance, not enforcement: `--role` on `evidence add` and
|
|
74
|
+
`review add` defaults to it.
|
|
75
|
+
|
|
76
|
+
## Driving the CLI
|
|
77
|
+
|
|
78
|
+
- Start a session with `canon status`: where each subject stands and the next
|
|
79
|
+
commands. After that, do not call it only to learn the next step: every
|
|
80
|
+
write returns `meta.next` (`[{command, why, actor, role}]`), the same steps
|
|
81
|
+
`status` would give, narrowed to what the write touched. `actor: human`
|
|
82
|
+
marks a step only the human takes.
|
|
83
|
+
- Your role reference's **Commands** block (`reference/role-<role>.md`) is
|
|
84
|
+
your complete command set. Run `canon schema <command> --json` only for a
|
|
85
|
+
command it does not list, or after a `USAGE` refusal (read `error.field`
|
|
86
|
+
and `expected` first). `canon schema` alone lists every command.
|
|
87
|
+
- Pass `--json` and read stdout as one document. On failure it is
|
|
88
|
+
`{"error":{"code","message","hint","retryable","field","expected"}}`: branch
|
|
89
|
+
on `error.code`, fix the option `field` names using the `expected` values,
|
|
90
|
+
and follow `error.hint`. The codes are stable; `canon schema --errors --json`
|
|
91
|
+
lists them.
|
|
92
|
+
- A renamed command still runs for one release, warns on stderr and sets
|
|
93
|
+
`meta.deprecated`; use the new name it prints.
|
|
94
|
+
- Page long lists with `--limit <n>` and `--cursor <nextCursor>` (`--all`
|
|
95
|
+
for everything), and project fields with `--fields a,b` (`status`, `export`,
|
|
96
|
+
`query`, `finding list`, `divergence status`, `context`).
|
|
97
|
+
- `canon purge` deletes only in two steps: `--plan` prints the removal set
|
|
98
|
+
and a `planDigest`; then `--confirm <planDigest>`.
|
|
99
|
+
|
|
172
100
|
## Command reference
|
|
173
101
|
|
|
174
102
|
Load only the reference the current step needs.
|
|
@@ -187,40 +115,29 @@ canon skills doctor # diagnostics, incl. a stray canon
|
|
|
187
115
|
`install` and `doctor` end with `owned-paths:`, the globs of every path
|
|
188
116
|
canon writes. Add them to the repo's formatter and linter ignore lists; a
|
|
189
117
|
formatter that rewrites a projection or a ledger record makes canon read
|
|
190
|
-
drift
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
`.
|
|
197
|
-
`
|
|
198
|
-
|
|
199
|
-
The canonical bundle is read-only. Claude receives
|
|
200
|
-
`.claude/skills/canon/SKILL.md`; Codex receives
|
|
201
|
-
`.agents/skills/canon/SKILL.md`; OMP receives `.omp/skills/canon/SKILL.md`; and
|
|
202
|
-
Pi receives `.pi/skills/canon/SKILL.md`. Every selected provider receives
|
|
203
|
-
matching `reference/**` and `scripts/**` sidecars under its `canon` bundle. A
|
|
204
|
-
legacy `.codex/skills/canon*` projection from canon 0.13.0 or earlier is
|
|
205
|
-
migrated by `canon skills install` and reported by `check`/`doctor`. OMP and Pi
|
|
206
|
-
projections are project-local passive skill bundles: the
|
|
207
|
-
`scripts/canon-retrieve-pre-dispatch.sh` file is available as a sidecar, not
|
|
208
|
-
installed as a native hook. `canon/skills-dev` is a separate developer-only
|
|
209
|
-
legacy source and is installed explicitly with `--source canon/skills-dev`.
|
|
118
|
+
drift (`doctor` reports it as `formatter-rewritten` and names the entry to
|
|
119
|
+
add). Specs, `policy.yaml` and the changes are written by hand and are not
|
|
120
|
+
on the list. The harness list lives in `canon.yaml` as
|
|
121
|
+
`skills: { providers: [...] }`; change it with `canon skills install --providers=<list>`,
|
|
122
|
+
never by assuming a default. The projection is a read-only copy: Claude
|
|
123
|
+
`.claude/skills/canon/`, Codex `.agents/skills/canon/`, OMP
|
|
124
|
+
`.omp/skills/canon/`, Pi `.pi/skills/canon/`, each with `reference/**` and
|
|
125
|
+
`scripts/**` sidecars (the retrieve script is a sidecar, not an installed hook).
|
|
210
126
|
|
|
211
127
|
### Route by task
|
|
212
128
|
|
|
213
|
-
- **
|
|
214
|
-
- **
|
|
215
|
-
- **
|
|
216
|
-
- **
|
|
217
|
-
- **
|
|
218
|
-
- **
|
|
219
|
-
- **
|
|
220
|
-
- **
|
|
221
|
-
- **
|
|
222
|
-
- **
|
|
223
|
-
- **
|
|
129
|
+
- **Your role's steps:** `reference/role-planner.md`, `role-implementer.md`, `role-reviewer.md`, `role-orchestrator.md`.
|
|
130
|
+
- **Where the repo stands, subjects and changes:** `reference/canon-subject.md` (`canon status`, `canon subject new|adopt|status`, `canon change new`).
|
|
131
|
+
- **Write or reorganize `.feature` specs:** `reference/canon-authoring.md` before editing; use the scaffold.
|
|
132
|
+
- **Fields, enums, policy bindings:** `reference/canon-context.md` and `reference/canon-vocab.md`.
|
|
133
|
+
- **Replayable run inputs / versioned prompts:** `reference/canon-context.md`, then `canon context-pack new|show|verify` and `canon prompt add|show` with repository-relative JSON manifests.
|
|
134
|
+
- **Validate or index specs:** `reference/canon-fmt.md` and `reference/canon-inventory.md`.
|
|
135
|
+
- **Evidence, gates, imported-plan task checkboxes, hooks:** `reference/canon-gate.md`.
|
|
136
|
+
- **Findings and reviews:** `reference/canon-review.md`.
|
|
137
|
+
- **Ingest artifacts, sessions or plans:** `reference/canon-artifact-ingest.md`, `canon-session-ingest.md`, or `canon-plan-import.md`.
|
|
138
|
+
- **Storage, policy, plugins, strategy learning:** `reference/canon-storage.md`, `canon-policy.md`, `canon-plugins.md`, or `canon-learn.md`.
|
|
139
|
+
- **Dispatch guidance:** `reference/canon-retrieve.md`; load `scripts/canon-retrieve-pre-dispatch.sh` when wiring hooks.
|
|
140
|
+
- **Reports and dashboards:** `reference/canon-report-dashboard.md`.
|
|
224
141
|
|
|
225
142
|
### Safety contract
|
|
226
143
|
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Brief pass: align
|
|
2
|
+
|
|
3
|
+
Check that scenarios cover the brief's flow, and that the brief still says
|
|
4
|
+
what the scenarios prove. Run it after scenarios exist, or when the check
|
|
5
|
+
reports `brief.flow-uncovered` or `brief.flow-no-failure`, which gate
|
|
6
|
+
shipping, not approval.
|
|
7
|
+
|
|
8
|
+
## Scope
|
|
9
|
+
|
|
10
|
+
The flow steps of the current change against the `.feature` scenarios that
|
|
11
|
+
carry `@flow:<change>.<F-id>` (written by `canon scenario new --flow <F-id>`).
|
|
12
|
+
A chore adds no scenarios and has no flow: this pass does not apply to it.
|
|
13
|
+
|
|
14
|
+
## Inspect
|
|
15
|
+
|
|
16
|
+
- `canon status`: each flow step with its scenarios and their evidence and review state; steps with no scenario or no failure scenario are flagged.
|
|
17
|
+
- `canon brief check --json`: the coverage findings per step.
|
|
18
|
+
- Each step has a `--case failure` scenario for the failure path the Acceptance names, plus `happy` and `edge` where the step has them.
|
|
19
|
+
- A scenario's title and steps say what the Acceptance line says. A scenario that proves more than the brief claims means the brief is thin; a brief claim with no scenario is a gap.
|
|
20
|
+
|
|
21
|
+
## NEVER
|
|
22
|
+
|
|
23
|
+
- Never retag an existing scenario's case or flow to satisfy coverage: add a new scenario with `canon scenario new --flow`.
|
|
24
|
+
- Never edit the brief to match a scenario that drifted; scenario-led brief edits are a scope change and need a new human answer.
|
|
25
|
+
- Never write scenario ids into the brief.
|
|
26
|
+
- Never report a step covered because a scenario exists: covered means indexed, and evidence and review are checked separately by the gate.
|
|
27
|
+
|
|
28
|
+
## Verify
|
|
29
|
+
|
|
30
|
+
`canon brief check` no longer lists the coverage rules; `canon status` shows every step with a failure scenario.
|
|
31
|
+
|
|
32
|
+
## Next
|
|
33
|
+
|
|
34
|
+
Implement, evidence and review (loop steps 5 to 7). If the brief had to change, the human answers again.
|
|
35
|
+
|
|
36
|
+
## Invariants (every brief pass)
|
|
37
|
+
|
|
38
|
+
- Never invent policy. An edit that could change what the gate demands, who approves, or what ships goes to the brief's Questions and assumptions, not into the text as a decision.
|
|
39
|
+
- Explaining writes nothing. Asked what a finding means or what a pass would do, answer in chat and leave the brief untouched.
|
|
40
|
+
- No pass requires another as a prerequisite. Run the one the findings or the human point at, in any order.
|
|
41
|
+
- A pass closes only the findings it rechecked: rerun `canon brief check` after the edit and report a finding as closed only when it is gone from that run. Never claim a rule you did not rerun.
|
|
42
|
+
- Write in the brief's language (`language:` in `canon.yaml`). Edits touch `.canon/changes/<slug>/brief.md` only. A brief edited after approval is not approved: it needs a new human answer and `canon brief approve` again.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Brief pass: clarify
|
|
2
|
+
|
|
3
|
+
Turn what is unresolved into questions a human can answer in one reply, and
|
|
4
|
+
make every assumption explicit. Run it when `canon brief` says lines under
|
|
5
|
+
the questions section are still open, or the request left a decision the
|
|
6
|
+
brief quietly made.
|
|
7
|
+
|
|
8
|
+
## Scope
|
|
9
|
+
|
|
10
|
+
The Questions and assumptions section, plus any sentence elsewhere in the
|
|
11
|
+
brief that decides something the request did not say.
|
|
12
|
+
|
|
13
|
+
## Inspect
|
|
14
|
+
|
|
15
|
+
- Each open line: is it a question or an assumption you will build on? Label it so.
|
|
16
|
+
- Decisions hidden in Intent, Outcome, Step detail or Acceptance that the request never stated: move each to Questions with your assumption.
|
|
17
|
+
- Anything that could change policy (what the gate demands, who approves, what ships, retention, access): it is a question, never a decision.
|
|
18
|
+
- Whether the language is settled: with `language:` unset, "which language?" belongs in the questions.
|
|
19
|
+
- Questions answerable from the repo or a tool: answer them from there instead of asking.
|
|
20
|
+
|
|
21
|
+
## NEVER
|
|
22
|
+
|
|
23
|
+
- Never answer a question yourself by editing the brief as if the human had; an assumption is stated as an assumption.
|
|
24
|
+
- Never drop a question you could not answer to make the section read as done. `None.` is for a section that is truly empty.
|
|
25
|
+
- Never ask what a command, the code or the request already answers.
|
|
26
|
+
- Never ask more than the human can answer in one reply: order by what changes the scope most, keep the rest as assumptions.
|
|
27
|
+
|
|
28
|
+
## Verify
|
|
29
|
+
|
|
30
|
+
Every open line is a question with a proposed default or a stated assumption. `canon brief check` still has no blockers (the pass changes no structure). `canon brief` still counts the lines left open, and those go in the report to the human, not away.
|
|
31
|
+
|
|
32
|
+
## Next
|
|
33
|
+
|
|
34
|
+
`harden` if the flow changed; otherwise report to the human, who answers the questions with the approval.
|
|
35
|
+
|
|
36
|
+
## Invariants (every brief pass)
|
|
37
|
+
|
|
38
|
+
- Never invent policy. An edit that could change what the gate demands, who approves, or what ships goes to the brief's Questions and assumptions, not into the text as a decision.
|
|
39
|
+
- Explaining writes nothing. Asked what a finding means or what a pass would do, answer in chat and leave the brief untouched.
|
|
40
|
+
- No pass requires another as a prerequisite. Run the one the findings or the human point at, in any order.
|
|
41
|
+
- A pass closes only the findings it rechecked: rerun `canon brief check` after the edit and report a finding as closed only when it is gone from that run. Never claim a rule you did not rerun.
|
|
42
|
+
- Write in the brief's language (`language:` in `canon.yaml`). Edits touch `.canon/changes/<slug>/brief.md` only. A brief edited after approval is not approved: it needs a new human answer and `canon brief approve` again.
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Brief pass: harden
|
|
2
|
+
|
|
3
|
+
Make the flow and its step detail agree, and give each step an observable
|
|
4
|
+
result and a failure path. Run it when the check reports
|
|
5
|
+
`brief.flow-duplicate-id` or `brief.detail-mismatch`, or a step reads vague.
|
|
6
|
+
|
|
7
|
+
## Scope
|
|
8
|
+
|
|
9
|
+
User flow, Step detail and Acceptance sections of a feature brief. A chore
|
|
10
|
+
brief has none of them: harden its Invariants and Checks instead.
|
|
11
|
+
|
|
12
|
+
## Inspect
|
|
13
|
+
|
|
14
|
+
- Flow ids `F1`, `F2`, … are unique and in order; Step detail has one `### F<n> …` subheading per step, same ids, same order.
|
|
15
|
+
- Each step reads sees → does → becomes, and names who and what state it starts from.
|
|
16
|
+
- Acceptance states, per step, what must be observable and which failure path is covered (invalid input, empty state, interrupted, repeated, denied).
|
|
17
|
+
- Step detail holds rules, states and edge cases of that step only; a rule that spans steps is stated once, where it first applies.
|
|
18
|
+
- Acceptance writes no scenario ids: scenarios do not exist yet and point at steps.
|
|
19
|
+
|
|
20
|
+
## NEVER
|
|
21
|
+
|
|
22
|
+
- Never renumber ids after scenarios carry `@flow:<change>.<F-id>` tags without moving the tags (`canon status` lists coverage per id).
|
|
23
|
+
- Never add a step the request did not imply; an extra step is scope the human has not approved: put it in Questions.
|
|
24
|
+
- Never write a failure path as "handles errors": name the condition and what the user sees.
|
|
25
|
+
- Never invent a rule, limit or copy the request and repo do not give: ask in Questions.
|
|
26
|
+
|
|
27
|
+
## Verify
|
|
28
|
+
|
|
29
|
+
`canon brief check` no longer lists `brief.flow-duplicate-id` or `brief.detail-mismatch`; every flow id has a detail subheading and an acceptance line with a failure path.
|
|
30
|
+
|
|
31
|
+
## Next
|
|
32
|
+
|
|
33
|
+
`align` once scenarios exist; `polish` for prose; otherwise report to the human.
|
|
34
|
+
|
|
35
|
+
## Invariants (every brief pass)
|
|
36
|
+
|
|
37
|
+
- Never invent policy. An edit that could change what the gate demands, who approves, or what ships goes to the brief's Questions and assumptions, not into the text as a decision.
|
|
38
|
+
- Explaining writes nothing. Asked what a finding means or what a pass would do, answer in chat and leave the brief untouched.
|
|
39
|
+
- No pass requires another as a prerequisite. Run the one the findings or the human point at, in any order.
|
|
40
|
+
- A pass closes only the findings it rechecked: rerun `canon brief check` after the edit and report a finding as closed only when it is gone from that run. Never claim a rule you did not rerun.
|
|
41
|
+
- Write in the brief's language (`language:` in `canon.yaml`). Edits touch `.canon/changes/<slug>/brief.md` only. A brief edited after approval is not approved: it needs a new human answer and `canon brief approve` again.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Brief pass: polish
|
|
2
|
+
|
|
3
|
+
Tighten the prose of the normative sections so a reader can act on it. Run it
|
|
4
|
+
last or whenever `canon brief` reports prose advisories; it never blocks
|
|
5
|
+
approval.
|
|
6
|
+
|
|
7
|
+
## Scope
|
|
8
|
+
|
|
9
|
+
Sections with `role=normative`: Desired outcome, User flow, Step detail,
|
|
10
|
+
Acceptance (feature) or Invariants and Checks (chore). Context and question
|
|
11
|
+
sections are not judged. Prose rules ship for `language: en` and `ko`; any
|
|
12
|
+
other language gets the structure rules only.
|
|
13
|
+
|
|
14
|
+
## Inspect
|
|
15
|
+
|
|
16
|
+
- `canon brief check --json`, the `prose.*` findings: `evaluative`, `connective`, `contrast`, `colloquial` (ko), `degree`, `sentence-length`, `paragraph-length`, `key-sentence`. Each carries the matched phrase or the threshold and the measured value.
|
|
17
|
+
- Replace an evaluative or degree word with the observable fact it stood for. Split a long sentence or paragraph. Cut connectives that only decorate.
|
|
18
|
+
- Each normative section carries exactly one key sentence marked `==**…**==`: the one line a reader must not miss.
|
|
19
|
+
- A finding is a prompt to reread, not a verdict: if the phrase is the precise term (a state name, a quoted label), keep it and waive that rule in that section with `<!-- canon:waive <rule-id> <section-key> "<reason>" -->`.
|
|
20
|
+
|
|
21
|
+
## NEVER
|
|
22
|
+
|
|
23
|
+
- Never change meaning: no flow step, rule, limit or failure path added, removed or softened while rewording.
|
|
24
|
+
- Never rewrite to dodge a rule (swap a listed phrase for a near synonym); say the concrete thing.
|
|
25
|
+
- Never polish sections that are not normative, or touch flow ids and subheadings.
|
|
26
|
+
- Never treat a clean prose run as a claim about who wrote the brief or whether it is good.
|
|
27
|
+
|
|
28
|
+
## Verify
|
|
29
|
+
|
|
30
|
+
`canon brief check` no longer lists the `prose.*` findings you rewrote (or lists them as waived with a reason); no blockers appeared.
|
|
31
|
+
|
|
32
|
+
## Next
|
|
33
|
+
|
|
34
|
+
Report to the human and `canon brief approve` from their answer.
|
|
35
|
+
|
|
36
|
+
## Invariants (every brief pass)
|
|
37
|
+
|
|
38
|
+
- Never invent policy. An edit that could change what the gate demands, who approves, or what ships goes to the brief's Questions and assumptions, not into the text as a decision.
|
|
39
|
+
- Explaining writes nothing. Asked what a finding means or what a pass would do, answer in chat and leave the brief untouched.
|
|
40
|
+
- No pass requires another as a prerequisite. Run the one the findings or the human point at, in any order.
|
|
41
|
+
- A pass closes only the findings it rechecked: rerun `canon brief check` after the edit and report a finding as closed only when it is gone from that run. Never claim a rule you did not rerun.
|
|
42
|
+
- Write in the brief's language (`language:` in `canon.yaml`). Edits touch `.canon/changes/<slug>/brief.md` only. A brief edited after approval is not approved: it needs a new human answer and `canon brief approve` again.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Brief pass: shape
|
|
2
|
+
|
|
3
|
+
Make the brief's structure what `canon brief check` expects. Run it when the
|
|
4
|
+
check reports `brief.section-missing`, `brief.section-duplicate`,
|
|
5
|
+
`brief.section-order`, `brief.placeholder`, `brief.flow-no-steps`,
|
|
6
|
+
`brief.waiver-invalid`, or (chore) `brief.chore-section`,
|
|
7
|
+
`brief.chore-category`, `brief.chore-empty`.
|
|
8
|
+
|
|
9
|
+
## Scope
|
|
10
|
+
|
|
11
|
+
`.canon/changes/<slug>/brief.md`: section markers, order, and leftover
|
|
12
|
+
template text. A feature brief runs intent → outcome → flow → detail →
|
|
13
|
+
acceptance → questions → out-of-scope; a chore brief runs intent → category →
|
|
14
|
+
invariants → checks → out-of-scope (`<!-- canon:kind chore -->` under the
|
|
15
|
+
title). Sections are found by their `<!-- canon:section <key> role=… -->`
|
|
16
|
+
marker, never by heading text.
|
|
17
|
+
|
|
18
|
+
## Inspect
|
|
19
|
+
|
|
20
|
+
- `canon brief check --json`: each finding names the rule, section key, line and hint.
|
|
21
|
+
- Every section present once, in order, with its marker; no `<!-- canon:hint … -->` comment left; no `TODO`/`TBD`; no empty section (write `None.` where nothing applies).
|
|
22
|
+
- The flow is a numbered list with ids `F1`, `F2`, … each reading sees → does → becomes.
|
|
23
|
+
- A chore's category is exactly one of `refactor`, `dependency`, `build`, `ci`, `infra`; its invariants and checks say something.
|
|
24
|
+
- A `canon:waive <rule-id> <section-key> "<reason>"` comment is well formed with a real reason.
|
|
25
|
+
|
|
26
|
+
## NEVER
|
|
27
|
+
|
|
28
|
+
- Never fill a section with text you made up to silence a placeholder: write what the request and the repo support, and put the rest in Questions.
|
|
29
|
+
- Never delete a section, retag a marker's role, or add a global waiver to pass. A waiver is one rule in one section with a reason the human can read.
|
|
30
|
+
- Never turn a chore's missing invariants into "none" to pass: behavior-changing work is a feature change.
|
|
31
|
+
|
|
32
|
+
## Verify
|
|
33
|
+
|
|
34
|
+
`canon brief check` reports none of the rules above. Report only the ones it no longer lists.
|
|
35
|
+
|
|
36
|
+
## Next
|
|
37
|
+
|
|
38
|
+
`clarify` if the Questions section still has open lines; `harden` if flow and detail disagree; otherwise report to the human and `canon brief approve` from their answer.
|
|
39
|
+
|
|
40
|
+
## Invariants (every brief pass)
|
|
41
|
+
|
|
42
|
+
- Never invent policy. An edit that could change what the gate demands, who approves, or what ships goes to the brief's Questions and assumptions, not into the text as a decision.
|
|
43
|
+
- Explaining writes nothing. Asked what a finding means or what a pass would do, answer in chat and leave the brief untouched.
|
|
44
|
+
- No pass requires another as a prerequisite. Run the one the findings or the human point at, in any order.
|
|
45
|
+
- A pass closes only the findings it rechecked: rerun `canon brief check` after the edit and report a finding as closed only when it is gone from that run. Never claim a rule you did not rerun.
|
|
46
|
+
- Write in the brief's language (`language:` in `canon.yaml`). Edits touch `.canon/changes/<slug>/brief.md` only. A brief edited after approval is not approved: it needs a new human answer and `canon brief approve` again.
|
|
@@ -75,7 +75,7 @@ spec_coverage:
|
|
|
75
75
|
Every feature surface (`<area>.<surface>`) with in-scope scenarios must
|
|
76
76
|
then carry at least one scenario of each listed case, or `canon gate
|
|
77
77
|
check` reports it as `uncovered-cell`, and `canon subject status <id>
|
|
78
|
-
shipped` refuses for a subject that owns such a surface. An untagged
|
|
78
|
+
--to shipped` refuses for a subject that owns such a surface. An untagged
|
|
79
79
|
scenario counts toward its surface but satisfies no case, so an
|
|
80
80
|
untagged corpus reports every surface instead of passing silently. The
|
|
81
81
|
base set comes from `canon.core`; a repo replaces it with its own `case`
|
|
@@ -110,6 +110,9 @@ Fix it and the next command indexes the files (see `canon-inventory`).
|
|
|
110
110
|
|
|
111
111
|
- `--actor <id>` (or `CANON_ACTOR` in the environment) puts YOUR id on the
|
|
112
112
|
provenance line. Default is `canon-scaffold`.
|
|
113
|
+
- **Keep the `# canon:` lines when you fill in the scenario.** Dropping one
|
|
114
|
+
makes `canon inventory sync` abort on `missing-provenance`; restore it
|
|
115
|
+
from git history or a sibling scenario (the error shows its shape).
|
|
113
116
|
- **Never hand-type, move, or edit a `# canon:` line.** The scaffold
|
|
114
117
|
writes it directly above the scenario's tags:
|
|
115
118
|
|
|
@@ -43,8 +43,8 @@ an immutable content-addressed registry and records only metadata and digests
|
|
|
43
43
|
in the pack manifest.
|
|
44
44
|
|
|
45
45
|
```bash
|
|
46
|
-
canon context-pack
|
|
47
|
-
canon context-pack
|
|
46
|
+
canon context-pack new --manifest .canon/context-manifest.json
|
|
47
|
+
canon context-pack new --manifest .canon/context-manifest.json --repo ../my-repo --json
|
|
48
48
|
canon context-pack show sha256:<pack-digest> --repo . --json
|
|
49
49
|
canon context-pack verify sha256:<pack-digest>
|
|
50
50
|
```
|
|
@@ -87,7 +87,7 @@ Version prompt inputs separately when several runs should share the same
|
|
|
87
87
|
prompt files:
|
|
88
88
|
|
|
89
89
|
```bash
|
|
90
|
-
canon prompt
|
|
90
|
+
canon prompt add --name reviewer --version v1 \
|
|
91
91
|
--manifest .canon/reviewer-prompt.json
|
|
92
92
|
canon prompt show --name reviewer --version v1 --json
|
|
93
93
|
```
|