@erclx/canon 4.2.0 → 4.3.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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "canon",
3
3
  "description": "Automated governance, versioning, and discovery tools for Claude Code.",
4
- "version": "4.2.0",
4
+ "version": "4.3.0",
5
5
  "author": {
6
6
  "name": "Eric Le",
7
7
  "url": "https://github.com/erclx"
@@ -241,3 +241,42 @@ workers running a server take a port apiece without being told to, since a
241
241
  stack derives it from the worktree it runs in through `scripts/worktree-port.sh`.
242
242
  Read that value rather than assigning one, and set `WORKTREE_PORT_OFFSET` by
243
243
  hand only when two worktrees derive the same offset.
244
+
245
+ ### The review fallback
246
+
247
+ Two conditions move the review itself out of this session rather than binding the
248
+ track count. One is a diff too large for this session to hold. The other is three
249
+ or more open pull requests awaiting a first pass. Either one makes review the
250
+ bottleneck every track is waiting on, and both answer the same way: dispatch the
251
+ narrow re-review and keep the first pass here.
252
+
253
+ Three is the operator's number, set by hand on 2026-08-31 and marked as such so a
254
+ measurement replaces it rather than argues with it. It is calibrated against a
255
+ session that ran five workers across two waves and reviewed five pull requests in
256
+ one stretch, several of them twice, where a sixth track was declined on judgment
257
+ and on nothing else. What counts toward it is a pull request awaiting a first
258
+ pass rather than every open one, since a branch already closed out and waiting on
259
+ a merge costs this session nothing and counting it would fire the switch on a
260
+ queue that is clear.
261
+
262
+ Only the narrow re-review dispatches. A first pass reads across branches, and the
263
+ findings that pay for its cost are the ones no single pull request shows: two
264
+ branches regenerating one binary asset for the same count, three writing one
265
+ context entry, a merge order making one branch's figure true only after another
266
+ lands. A re-review asks whether the prior findings landed and whether the fix
267
+ regressed anything, which is bounded to a delta and carries none of that reading,
268
+ so it is the half that leaves cleanly.
269
+
270
+ What it dispatches has no role skill yet. `claude-worker` and `claude-planner`
271
+ each state what their session may not do and no third body states a reviewer's,
272
+ so a dispatched re-review would hold its obligations in whatever launch string
273
+ this session types. That is the defect those two skills were written to close, so
274
+ write the third after the first trial rather than before it, since nothing has
275
+ ever dispatched a reviewer and a body written now encodes a shape nobody has
276
+ driven. Until it exists, say in the launch itself that the pass is bounded to the
277
+ delta and that the cross-branch reading stays here.
278
+
279
+ Nothing counts the pull requests. This is prose this session applies to itself,
280
+ on the same standing as the poll's own start condition, so a wave past three
281
+ reviewed one at a time is a rule that went unread rather than a check that
282
+ failed.
@@ -66,6 +66,12 @@ The five review headings the script matches are written by `claude-pr-review` an
66
66
 
67
67
  The state reaches every stalled dispatch, since one threshold governs the heading and the dispatch alike and a pass carrying anything posts the open heading. A minors-only pass therefore reports here on the same terms as a blocking one, which widens the state from what it caught while the two were split. It stays a heading test rather than a count test, so nothing here pins the summary line, which is a second string this script does not own.
68
68
 
69
+ ### The count behind the review fallback
70
+
71
+ The report is also where the count in `## Parallelism` is legible. That threshold trips on open pull requests awaiting a first pass, which is what `OPENED` and a pull request with no prior pass name here and what `SEEN` excludes, so read the count off these lines rather than off `gh pr list`, which counts a branch closed out and waiting on a merge the same as one nobody has read. It is a separate condition from the poll-start fallback above, which decides when this loop runs rather than where a review runs.
72
+
73
+ The count reads low, and it errs in the direction that breaks the trigger. A review's `commit.oid` is stamped with the head at submission rather than with the commit the reviewer read, so an author pushing between the diff read and the post leaves the pass recorded against a commit it never saw, and `SEEN` then fires on a head still awaiting its first look at that delta. Measured on `#1299` on 2026-08-31, where a pass written against `5653721` landed stamped `a5ceb40` and the delta it skipped was a real fix. So a `SEEN` on a head you do not recognize is worth one `gh pr view --json reviews` before it is believed, and a wave past three is likelier to trip the fallback late than early.
74
+
69
75
  ## The watch beside it
70
76
 
71
77
  `${CLAUDE_SKILL_DIR}/scripts/watch.sh` is a long-running loop rather than a scheduled prompt. It reads the open pull request list and the session roster together every sixty seconds and prints one line per new pull request, per worker whose status changed, and per worker that dropped out of the roster. Start it in the background and read what it emits. It writes nothing.
@@ -157,7 +157,11 @@ Respond with one line, using the `url` the final command printed:
157
157
 
158
158
  `✅ PR: <url>`
159
159
 
160
- Add a second line only when the labelling command printed its warning, quoting the label `gh` refused:
160
+ Add a line for each `uncovered` path the labels step reported, naming the path and the map it belongs in:
161
+
162
+ `⚠️ No label covers <path>. Add a row to .claude/canon/pr-labels.toml or a [declined] entry.`
163
+
164
+ Add a further line only when the labelling command printed its warning, quoting the label `gh` refused:
161
165
 
162
166
  `⚠️ Labels not applied: <what gh reported>`
163
167
 
@@ -220,6 +220,14 @@ above it, and stop adding once you can no longer review every output properly.
220
220
  Serialize a track sharing a wiring seam with another, and serialize one whose
221
221
  sets are disjoint when a stated reason still puts it behind another.
222
222
 
223
+ Past that, review moves rather than the track count, on either of two conditions:
224
+ a diff too large for the controlling session to hold, or three or more open pull
225
+ requests awaiting a first pass. Three is set by hand rather
226
+ than measured, so a later measurement replaces it. Only the narrow re-review
227
+ leaves: a first pass reads across branches and a re-review bounded to a delta
228
+ carries none of that reading. Nothing counts the pull requests, so the switch
229
+ holds only while the session applies it to itself.
230
+
223
231
  Inbound turns cost the controlling session as well, so weigh the spend before
224
232
  widening. A message from one of your other sessions arrives as a new turn
225
233
  carrying the whole accumulated context, and a recurring poll bills that window
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@erclx/canon",
3
3
  "type": "module",
4
- "version": "4.2.0",
4
+ "version": "4.3.0",
5
5
  "description": "Infrastructure and quality tooling for developer workflows",
6
6
  "license": "MIT",
7
7
  "bin": {