@erclx/aitk 3.54.0 → 3.56.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": "aitk",
3
3
  "description": "Automated governance, versioning, and discovery tools for Claude Code.",
4
- "version": "3.54.0",
4
+ "version": "3.56.0",
5
5
  "author": {
6
6
  "name": "Eric Le",
7
7
  "url": "https://github.com/erclx"
@@ -114,7 +114,7 @@ Write no shape for a correction. A correction is a sentence, and a format for ad
114
114
  4. Hand off. Read `${CLAUDE_SKILL_DIR}/references/orchestrator-dispatch.md` and follow it: check the branch is unclaimed, check the row's file set against every track in flight, then dispatch a background worker with `claude --bg`. Fall back to the human-launch line it replaces when the check refuses, the sets overlap, or a stated reason serializes the row behind something already out.
115
115
  5. Review the PR. When a worker opens a PR, run `claude-pr-review` to post findings to it. This is the deep, independent pass. The worker's autoship self-review was only the green gate.
116
116
  - Learning that a PR moved is the mechanical half, so read `${CLAUDE_SKILL_DIR}/references/orchestrator-poll.md` and start the poll it carries on the first dispatch rather than checking the board by hand. That runbook holds the routing, and a summary of it here is a second source that drifts from it.
117
- 6. Dispatch the handback. A pass posting anything owed, a finding at any severity or a testing question, tells the session holding that branch to run `claude-address-review`, rather than waiting for a person to relay it. Re-review when the answer lands, then the human merges. Tell the trailing worker to rebase when its branch shares a seam with the merged one.
117
+ 6. Dispatch the handback. A pass posting anything owed, a finding at any severity or a testing question, tells the session holding that branch to run `claude-address-review`, rather than waiting for a person to relay it. Re-review when the worker's own message says the address pass finished, per the channel `claude-worker` states, rather than polling for an answer nothing else marks as landed. Then the human merges. Tell the trailing worker to rebase when its branch shares a seam with the merged one.
118
118
  - Read the threshold off `claude-pr-review`, which states it once and governs the heading with it, so an open heading and an owed dispatch answer the same question and either one is enough to send
119
119
  - Resolve the target at the moment of sending with `aitk sessions list --branch`, never from a mapping written down earlier, since names rotate as sessions end and one recorded earlier in a session has failed inside the hour. The runbook read at step 5 routes on the count and the confidence it answers with
120
120
  - Open the message with the worktree and branch the sender believes the reader holds, asking to be corrected, whenever that mapping is inferred rather than confirmed
@@ -81,6 +81,48 @@ The last bullet is the one under pressure, since the dispatch that first proved
81
81
 
82
82
  Report the dispatch as loudly as the human-launch line it replaces: name the branch, the model, the task, and the session name, so a person reading the transcript can follow what fired without watching it happen.
83
83
 
84
+ ## Dispatch to address a review
85
+
86
+ `claude-address-review` is a single pass, not a chain, so a launch naming it
87
+ alone reaches no `claude-worker` and takes no role, which owes no message
88
+ either. `#1251`'s replacement session was launched that way, onto the branch a
89
+ review had already posted findings against, and it answered by posting a
90
+ thread reply and telling its controller nothing. Reach the role directly on
91
+ this launch instead of wrapping a second chain around one skill that has none
92
+ of its own.
93
+
94
+ The branch already exists here, opened by whatever built it, so this shape
95
+ skips the plan-derived name the build shape resolves above. Take `<branch>`
96
+ off the pull request's own head ref. Enter the worktree the original build
97
+ left on disk, `.claude/worktrees/<slug>/`, with `EnterWorktree`'s `path` form
98
+ when it is still there, or `git worktree add .claude/worktrees/<slug>/
99
+ <branch>` when it was cleaned up, so `<slug>` is that directory name either
100
+ way.
101
+
102
+ `EnterWorktree` refuses that path in the ordinary case, because the original
103
+ build session stays registered against its own worktree after going idle and
104
+ holds a harness-level lock the roster does not report. Work in the folder
105
+ directly with `Bash`, `Read`, and `Edit` instead of retrying the tool, which
106
+ is the route two workers already took today on two different branches.
107
+
108
+ ```bash
109
+ claude --bg --model <model> -n "worker-<slug>" "Enter the worktree for <branch> at .claude/worktrees/<slug>/, creating it from that branch if the folder is gone. Run /aitk:claude-worker, then /aitk:claude-address-review. Your controller is the session whose sessionId is <dispatcher-id>. Resolve its current name from that id at the moment you send, and never resolve an addressee by name prefix. Message it when the address pass finishes, carrying what was addressed and the PR's CI state, and message it again if you stop on a question."
110
+ ```
111
+
112
+ `<dispatcher-id>` and `<model>` resolve the same way the build shape resolves
113
+ them above.
114
+
115
+ Take this shape wherever a review needs answering and no live session already
116
+ holds the branch. Where one does, message it to run `claude-address-review`
117
+ instead, per the loop's own step 6, since a session already there needs no
118
+ second one dispatched onto the same branch.
119
+
120
+ That check is blind to a session working through the direct-path fallback
121
+ above, since a session that never runs `EnterWorktree` never moves its
122
+ registered branch off `main`, so `aitk sessions list --branch` reports nothing
123
+ holding it. A dispatch landing on a branch worked that way collides with
124
+ nothing the check can see.
125
+
84
126
  ## Fall back to the human
85
127
 
86
128
  Hand the row to the human-launch line in step 4 instead of dispatching when any of these hold, and name which one: the collision check refused, the row's file set overlaps a track already out, or a stated reason holds the row behind one.
@@ -75,3 +75,13 @@ Coverage is what it buys over the poll. A worker that finishes goes idle and a w
75
75
  It classifies nothing and routes nothing. A line it prints says a pull request opened or a worker moved, and the routing block above is still what decides whether a review follows, so the two compose rather than replace each other.
76
76
 
77
77
  Every session in the repository holding a branch other than the base one counts as a worker, whoever launched it. The prototype matched the `orchestrator-` prefix instead, which reads a dispatched worker and misses every hand-launched one. A failed read of either source reports itself on a `watch:` line and leaves the baseline untouched, since reading an empty result as current state would report every worker gone on the pass after.
78
+
79
+ ## The stall alarm
80
+
81
+ `watch.sh` prints `WORKER-STOPPED <name> <branch> <dwell>s` once a `waiting` row crosses `STALL_THRESHOLD_S`, and `WORKER-UNMEASURABLE <name> <branch>` for one whose record carries neither timestamp the dwell falls back to. Both are prints, not alerts, so the operator learns of one only when a session already reading the loop's output relays it further. The toolkit ships no notification verb, since the surface a stall reaches the operator through is a session tool rather than a command a shell loop can call.
82
+
83
+ The two lines carry different confidence and the push has to say so rather than treat them as one signal. `WORKER-STOPPED` fires only once the dwell has already crossed the threshold, so it reports a wait already confirmed long. `WORKER-UNMEASURABLE` has no dwell to threshold on, so it fires on the first pass that meets a `waiting` row carrying neither stamp, whether that row has sat five seconds or fifty minutes.
84
+
85
+ On meeting either line, push a notification to the operator through whatever notification surface the client offers, `PushNotification` in this repository's client and one example among the surfaces a different client exposes. Name the worker, the branch, which of the two lines fired, and the dwell where `WORKER-STOPPED` carries one, and send it once per stall the same way `watch.sh` prints it once, rather than repeating it on every interval the row stays stopped.
86
+
87
+ The bound stays open. The alarm reaches the operator only through the controller's own read, so a controller mid-turn does not see the line for as long as the turn runs, and a controller that is itself stopped never does. Neither case closes here, since the watch loop and the notification surface both live inside the same session that has to be free to act on either.
@@ -34,10 +34,11 @@ running and re-invoking it would restart the build.
34
34
 
35
35
  ## The channel
36
36
 
37
- The controlling session cannot watch this one build, so two messages are owed and
38
- nothing else.
37
+ The controlling session cannot watch this one build, so three messages are owed
38
+ and nothing else.
39
39
 
40
40
  - Announce the pull request as the ship chain's pull request step returns, carrying the number, the branch, and the task it closes. That transition is the one moment only this session knows, and the controller's review poll no longer starts on a dispatch because of it.
41
+ - Announce when an address-review pass finishes, as `claude-address-review` Step 8 returns, carrying what was addressed and the PR's new CI state. That transition is the other moment only this session knows, and it is what tells the controller to re-review rather than leaving it to poll for an answer nothing marks as landed.
41
42
  - Send a block out as a message before it becomes an interactive prompt. A session already waiting on input never reaches the tool round that drains an inbound message, so a relayed answer arrives under the open question and changes nothing.
42
43
  - Send nothing on progress. A worker reporting progress rebuilds, on this side of the channel, the poll the announcement retired on the other.
43
44
 
@@ -94,13 +94,19 @@ reply that changes an outcome, such as a worker naming the plan question that
94
94
  already declined a finding, still belongs back on the PR, since the session
95
95
  holding it ends and the thread is what a later reader opens.
96
96
 
97
- Two messages travel the other way and the worker owes both. It announces its own
98
- pull request as the ship chain opens one, naming the number, the branch, and the
99
- task it closes. That is the one transition only that session can observe, since
100
- a worker that finishes goes idle rather than exiting, and one sat unnoticed for
101
- eighteen minutes before the announcement existed.
102
-
103
- The second reports a block before that block becomes an interactive prompt. A
97
+ Three messages travel the other way and the worker owes all three. It announces
98
+ its own pull request as the ship chain opens one, naming the number, the
99
+ branch, and the task it closes. That is the one transition only that session
100
+ can observe, since a worker that finishes goes idle rather than exiting, and
101
+ one sat unnoticed for eighteen minutes before the announcement existed.
102
+
103
+ It announces again when an address-review pass finishes, naming what it
104
+ addressed and the pull request's new CI state. That transition is the other
105
+ one only the worker can observe, and it replaces the same idle-poll gap on the
106
+ review's return leg, after a worker once addressed a posted review by
107
+ answering on the thread alone and telling its controller nothing.
108
+
109
+ The third reports a block before that block becomes an interactive prompt. A
104
110
  queued message drains at the next tool round and a session already waiting on
105
111
  input never reaches one, so an answer relayed to an open prompt renders beneath
106
112
  the question and changes nothing. Nothing is sent on progress, which would
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@erclx/aitk",
3
3
  "type": "module",
4
- "version": "3.54.0",
4
+ "version": "3.56.0",
5
5
  "description": "Infrastructure and quality tooling for developer workflows",
6
6
  "license": "MIT",
7
7
  "bin": {