axstack 0.14.2 → 0.15.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.
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
Read this when the current session is the native Orca PR **driver** or its
|
|
4
4
|
**watchdog**. The approved contract is
|
|
5
|
-
`docs/specs/pr-automations.md` revision
|
|
5
|
+
`docs/specs/pr-automations.md` revision 6; this reference restates the parts an
|
|
6
6
|
automation session must execute and does not widen them.
|
|
7
7
|
|
|
8
8
|
Pair A/B is retired for this contract; its artefacts remain untouched.
|
|
@@ -11,7 +11,7 @@ Pair A/B is retired for this contract; its artefacts remain untouched.
|
|
|
11
11
|
|
|
12
12
|
- **driver** — every 15 minutes, fresh Opus session in the host's `root`
|
|
13
13
|
folder workspace, which is not a git repository and belongs to no project. It discovers GitHub work, binds the persistent Orca
|
|
14
|
-
Run,
|
|
14
|
+
Run, creates one worktree per selected PR and checks its head out there, dispatches the
|
|
15
15
|
matching Axstack agent, reconciles completions and decisions, then exits. The
|
|
16
16
|
driver is the automation session itself, with no `axstack-monitor` or
|
|
17
17
|
`axstack-owner` role row. It never performs review or repair in its own
|
|
@@ -97,7 +97,7 @@ The driver performs this order and exits:
|
|
|
97
97
|
inbox. For a `worker_done` matching a live marker, verify the review id at
|
|
98
98
|
the bound head, push range, or opened token. Release the worker; once its
|
|
99
99
|
release receipt is settled and the process has exited, run the cleanup
|
|
100
|
-
under "Run directory" below, which proves the
|
|
100
|
+
under "Run directory" below, which proves the worktree disposable before
|
|
101
101
|
resetting it; then clear the marker. Unverifiable delivery stays in
|
|
102
102
|
`pending_settlement[]` and blocks only that PR.
|
|
103
103
|
3. Consume decisions as their sole consumer under "Decision tokens" below.
|
|
@@ -126,34 +126,38 @@ The driver performs this order and exits:
|
|
|
126
126
|
|
|
127
127
|
Claude Code trusts a folder per git toplevel and stops at its "Quick safety
|
|
128
128
|
check" dialog otherwise, and the driver never answers that dialog for a
|
|
129
|
-
worker.
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
129
|
+
worker. Trust inherits from the project's primary clone, which the user
|
|
130
|
+
trusted once (a fresh child worktree launched with no dialog — canary
|
|
131
|
+
2026-09-18). There is no fixed pool: fetch the head into the project clone first (a
|
|
132
|
+
failed fetch is a health line and no dispatch; no worktree exists yet), then
|
|
133
|
+
create one Orca worktree per dispatch, `orca worktree create --repo id:<clone
|
|
134
|
+
id> --name <repo short>-<num>-<head7> --base-branch <default branch>
|
|
135
|
+
--parent-worktree id:<clone id>::<clone path> --setup skip` (a name collision
|
|
136
|
+
with a retained worktree at the same head appends the tick's
|
|
137
|
+
`tick_started_at` stamp); close the creation terminal Orca opens in it with
|
|
138
|
+
`orca terminal close --worktree <selector> --all`; check the worktree out
|
|
139
|
+
detached at the pinned head and verify HEAD equals it; the marker's worktree
|
|
140
|
+
is that path. Never write
|
|
141
|
+
`~/.claude.json`. The worker is launched by Orca itself — `worker-start
|
|
142
|
+
--agent claude --model claude-opus-5 --effort medium` in that worktree — so
|
|
143
|
+
the runtime owns the process: `worker-release` ends it and `worker-show`
|
|
144
|
+
proves it exited, which is what allows the worktree to be removed. Never
|
|
145
|
+
pre-create the worker's terminal or hand a terminal handle to
|
|
143
146
|
`worker-start`: a reused handle is a resource Orca labels `external`, one it
|
|
144
|
-
can neither stop nor prove exited, so every such
|
|
145
|
-
`worker-start` run `worker-show` on the receipt's dispatch id and
|
|
146
|
-
`projection.resource.state == owned`; anything else is a launch Orca
|
|
147
|
-
own: apply the runtime-refusal recovery rules under "Safety holds"
|
|
148
|
-
`worker-list` row's `nextAction` argv verbatim; `none` means inspect
|
|
149
|
-
retain), append a `worker not owned` health line and a `retained_slots[]`
|
|
150
|
-
entry for the
|
|
151
|
-
`--dangerously-skip-permissions`; the brief loads
|
|
152
|
-
path. If `worker-start` reports a failed stage
|
|
153
|
-
safety check" trust dialog) the
|
|
154
|
-
line, defer the PR, dispatch nothing, never
|
|
155
|
-
|
|
156
|
-
|
|
147
|
+
can neither stop nor prove exited, so every such worktree ends retained.
|
|
148
|
+
After `worker-start` run `worker-show` on the receipt's dispatch id and
|
|
149
|
+
require `projection.resource.state == owned`; anything else is a launch Orca
|
|
150
|
+
does not own: apply the runtime-refusal recovery rules under "Safety holds"
|
|
151
|
+
(the `worker-list` row's `nextAction` argv verbatim; `none` means inspect
|
|
152
|
+
and retain), append a `worker not owned` health line and a `retained_slots[]`
|
|
153
|
+
entry for the worktree, defer the PR, and record no marker. Orca's per-agent
|
|
154
|
+
default arguments supply `--dangerously-skip-permissions`; the brief loads
|
|
155
|
+
the skill files it needs by path. If `worker-start` reports a failed stage
|
|
156
|
+
or a visible hold (the "Quick safety check" trust dialog) the worktree is not
|
|
157
|
+
trusted: name it in a health line, defer the PR, dispatch nothing, never
|
|
158
|
+
answer the dialog, and remove the worktree through the no-worker branch.
|
|
159
|
+
Project customizations load as they would for the user; the allowlist is
|
|
160
|
+
defi-com only and the user accepted that surface on 2026-09-18.
|
|
157
161
|
|
|
158
162
|
Every selected PR receives one dispatch marker with task id, dispatch id,
|
|
159
163
|
worktree, head, `started_at`, reservation (`verdict` or `repair`), and trigger:
|
|
@@ -175,16 +179,22 @@ An own PR needs repair when either trigger applies:
|
|
|
175
179
|
digest not recorded for that PR and head. Both keys are required: the same
|
|
176
180
|
finding under a new review id must not re-trigger repair. Record review id
|
|
177
181
|
and body digest when dispatching. A superseded head with a new review
|
|
178
|
-
triggers again
|
|
179
|
-
|
|
180
|
-
Repair also requires no deploy-on-push head branch,
|
|
181
|
-
selection of the lowest own PR in its stack that
|
|
182
|
-
|
|
183
|
-
worktree
|
|
184
|
-
|
|
182
|
+
triggers again at the new head.
|
|
183
|
+
|
|
184
|
+
Repair also requires no deploy-on-push head branch, a head not already in
|
|
185
|
+
`repaired_heads[]`, and selection of the lowest own PR in its stack that
|
|
186
|
+
needs repair. Create the
|
|
187
|
+
dispatch worktree (parented to that project's primary worktree, so the work
|
|
188
|
+
appears under the project it serves) at the exact head, and dispatch one
|
|
189
|
+
`axstack-watch` agent in authored repair mode. Its
|
|
185
190
|
brief contains only the triggering checks or review findings. Each open
|
|
186
191
|
descendant records one user-owned `pending restack` hold until it stops needing
|
|
187
|
-
repair.
|
|
192
|
+
repair. At dispatch record the head in `repaired_heads[]` (`pr`, `head`,
|
|
193
|
+
`dispatched_at`): one repair per head, no time cap. A repair pushes a new
|
|
194
|
+
head; a still-not-merge-ready new head shows a new failing check or review
|
|
195
|
+
and is repaired again; a repair that pushes nothing is not retried at that
|
|
196
|
+
head until a human or a new commit moves it. A confirmed abandon removes the
|
|
197
|
+
record (retry once).
|
|
188
198
|
|
|
189
199
|
A debounced peer PR is eligible when self has not reviewed its head. Read
|
|
190
200
|
`gh pr view --json reviews` before dispatch. Whenever any self review with
|
|
@@ -196,14 +206,15 @@ human-placed block is never overwritten. A dismissed block and a self-approved
|
|
|
196
206
|
PR are skipped. Dispatch one `axstack-review` agent in peer mode and link the
|
|
197
207
|
prior review in its brief.
|
|
198
208
|
|
|
199
|
-
|
|
200
|
-
markers
|
|
201
|
-
|
|
202
|
-
|
|
209
|
+
The only concurrency limit is the host-wide cap: at most eight live dispatch
|
|
210
|
+
markers across all repositories and both reservations, oldest eligible
|
|
211
|
+
first; plus one repair per head. Put every eligible PR not dispatched
|
|
212
|
+
because the cap is reached in `deferred[]` with repo, PR, and head. Reaching
|
|
213
|
+
the cap records the count and is not a hold.
|
|
203
214
|
|
|
204
215
|
## Agents and verdicts
|
|
205
216
|
|
|
206
|
-
Every agent works in
|
|
217
|
+
Every agent works in its own project-local worktree checked out detached at
|
|
207
218
|
the exact head and reports only through the Orca worker protocol.
|
|
208
219
|
|
|
209
220
|
Peer review runs the two isolated configured reviewers on the identical brief,
|
|
@@ -343,12 +354,12 @@ is no gate for health findings.
|
|
|
343
354
|
## Run directory
|
|
344
355
|
|
|
345
356
|
The driver and watchdog run from the host's `root` folder workspace, not a
|
|
346
|
-
project worktree: no project owns the automation, and every
|
|
347
|
-
belongs to the project it serves. That workspace is not a git repository, so
|
|
357
|
+
project worktree: no project owns the automation, and every dispatch
|
|
358
|
+
worktree belongs to the project it serves. That workspace is not a git repository, so
|
|
348
359
|
the run directory is private host state, one
|
|
349
360
|
`~/.local/share/axstack/runs/<run id>/` directory. Settlement leaves nothing
|
|
350
361
|
behind, but never destroys work. Before any destructive step the driver
|
|
351
|
-
proves the
|
|
362
|
+
proves the worktree is disposable: the worker is settled — on the release path
|
|
352
363
|
a settled release receipt, on the abandon path an accepted abandon receipt,
|
|
353
364
|
either with proven process exit; pending or unknown stops here — the
|
|
354
365
|
worktree's HEAD is either the pinned head or a candidate that is durably
|
|
@@ -358,20 +369,21 @@ targeted fetch of that exact remote branch into a per-dispatch ref, never
|
|
|
358
369
|
shared clone can fake durability, a failed fetch retaining the worktree — or held by a
|
|
359
370
|
`refs/axstack/decisions/<token>` ref in the project clone; and, on the
|
|
360
371
|
abandon path, the worktree has no uncommitted changes.
|
|
361
|
-
Only then it closes any terminal tab still listed
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
the worker has finished, so untracked
|
|
365
|
-
are
|
|
366
|
-
whose release is settled but whose HEAD cannot be
|
|
367
|
-
abandoned
|
|
368
|
-
**retained
|
|
369
|
-
only that PR with the user as owner.
|
|
370
|
-
the driver appends `retained_slots[]`
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
outlives its dispatch without such a retention
|
|
372
|
+
Only then it closes any terminal tab still listed and removes the worktree
|
|
373
|
+
with `orca worktree rm --worktree <selector> --force` (the proof is the
|
|
374
|
+
gate; a finished worker's untracked artefacts are not), so the dispatch
|
|
375
|
+
leaves nothing behind. On the settled path the worker has finished, so untracked
|
|
376
|
+
files are artefacts by definition; a candidate there is already pushed or
|
|
377
|
+
token-held. A worktree whose release is settled but whose HEAD cannot be
|
|
378
|
+
proven disposable, and an abandoned worktree that is dirty or holds an
|
|
379
|
+
unproven candidate, are both **retained** — retained in place: named in one `health[]`
|
|
380
|
+
line with path and SHA, and blocking only that PR with the user as owner.
|
|
381
|
+
Retention is mechanical on both paths: the driver appends `retained_slots[]`
|
|
382
|
+
`{slot, pr, head, reason}` (`slot` is the worktree path); a retained worktree
|
|
383
|
+
is never removed by the driver, and the entry is cleared only by the user
|
|
384
|
+
after reconciling the candidate, who also removes the worktree. A leftover
|
|
385
|
+
worktree or terminal that outlives its dispatch without such a retention
|
|
386
|
+
record is a health finding. The run directory contains:
|
|
375
387
|
|
|
376
388
|
- `cursor.json` — driver only, with these exact keys: `fingerprint`,
|
|
377
389
|
`tick_started_at`, `tick_done_at`, `tick_outcome`, `prs{url: {head, base,
|
|
@@ -379,7 +391,10 @@ outlives its dispatch without such a retention record is a health finding. The r
|
|
|
379
391
|
`task_id`, `dispatch_id`, `worktree`, `head`, `started_at`, `reservation`,
|
|
380
392
|
`trigger`), `deferred[]`, `pending_settlement[]`,
|
|
381
393
|
`retained_slots[]` (`slot`, `pr`, `head`, `reason`),
|
|
382
|
-
`
|
|
394
|
+
`repaired_heads[]` (`pr`, `head`, `dispatched_at`),
|
|
395
|
+
`repair_caps{url: {expires_at}}` (legacy: the first rev-6 tick clears it to
|
|
396
|
+
`{}` with one health line; never written again),
|
|
397
|
+
`abandon_count{head: n}`,
|
|
383
398
|
`processed_reviews[]` (`review_id`, `pr`, `head`, `digest`),
|
|
384
399
|
`deploy_on_push{repo: [branches]}`,
|
|
385
400
|
`legacy_automation_reviews[]`, `health[]`,
|
|
@@ -420,12 +435,12 @@ delivery uses [axstack-relay](../../axstack-relay/SKILL.md).
|
|
|
420
435
|
`runtime_refusal {code, first_seen, last_seen}`; the same code keeps the
|
|
421
436
|
hold and updates `last_seen` without a new health line, a different code is
|
|
422
437
|
a new finding. Prose is never the key. When `worker-start` itself is
|
|
423
|
-
refused after the
|
|
438
|
+
refused after the worktree was created, there is no worker, so the
|
|
424
439
|
settlement proof does not apply; the driver reads the receipt's `failedStage`
|
|
425
440
|
and `residualResources` first. With no Dispatch and no residual resources
|
|
426
441
|
the no-worker branch applies: the worktree's HEAD must equal the pinned
|
|
427
|
-
head and `git status --porcelain` must be empty, and then the
|
|
428
|
-
|
|
442
|
+
head and `git status --porcelain` must be empty, and then the worktree is
|
|
443
|
+
simply removed in the same tick.
|
|
429
444
|
With a Dispatch or any residual resource the failed start owns runtime
|
|
430
445
|
state, and retaining alone is not recovery: the driver follows the
|
|
431
446
|
runtime's recovery guide. With a Dispatch: `worker-list` for that run, and
|