axstack 0.19.1 → 0.20.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/README.md +10 -6
- package/docs/installation.md +2 -2
- package/docs/workflows.md +35 -30
- package/package.json +1 -1
- package/profiles/presets/claude-only.json +1 -10
- package/profiles/presets/codex-only.json +1 -10
- package/profiles/presets/mixed.json +1 -10
- package/skills/axstack/references/automations.md +201 -481
- package/skills/axstack/references/candidate-publication.md +3 -3
- package/skills/axstack/references/lifecycle.md +7 -7
- package/skills/axstack/references/orca-runtime.md +1 -1
- package/skills/axstack/references/review-manager-prompt.md +10 -0
- package/skills/axstack/references/routing.md +3 -3
- package/skills/axstack/references/watch-manager-prompt.md +11 -0
- package/skills/axstack-relay/SKILL.md +3 -22
- package/skills/axstack-review/SKILL.md +27 -23
- package/skills/axstack-watch/SKILL.md +35 -25
- package/skills/axstack-watch/references/repair-publication.md +10 -12
- package/skills/axstack-watch/references/watch-runtime.md +36 -50
|
@@ -1,481 +1,201 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
Read this
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
- **
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
and
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
##
|
|
88
|
-
|
|
89
|
-
The
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
record (retry once).
|
|
203
|
-
|
|
204
|
-
A debounced peer PR is eligible when self has not reviewed its head. Read
|
|
205
|
-
`gh pr view --json reviews` before dispatch. Whenever any self review with
|
|
206
|
-
state `CHANGES_REQUESTED` exists on the PR, from whichever search it came,
|
|
207
|
-
dispatch only if the latest effective, non-dismissed self review body contains
|
|
208
|
-
the line prefix `<!-- axstack-automation verdict` or its id is listed in
|
|
209
|
-
`cursor.json.legacy_automation_reviews[]`; otherwise record and skip, so a
|
|
210
|
-
human-placed block is never overwritten. A dismissed block and a self-approved
|
|
211
|
-
PR are skipped. Dispatch one `axstack-review` agent in peer mode and link the
|
|
212
|
-
prior review in its brief.
|
|
213
|
-
|
|
214
|
-
The only concurrency limit is the host-wide cap: at most eight live dispatch
|
|
215
|
-
markers across all repositories and both reservations, oldest eligible
|
|
216
|
-
first; plus one repair per head. Put every eligible PR not dispatched
|
|
217
|
-
because the cap is reached in `deferred[]` with repo, PR, and head. Reaching
|
|
218
|
-
the cap records the count and is not a hold.
|
|
219
|
-
|
|
220
|
-
## Agents and verdicts
|
|
221
|
-
|
|
222
|
-
Every agent works in its own project-local worktree checked out detached at
|
|
223
|
-
the exact head and reports only through the Orca worker protocol.
|
|
224
|
-
|
|
225
|
-
Peer review runs the two isolated configured reviewers on the identical brief,
|
|
226
|
-
then the Luna gate. `APPROVE` requires complete exact-head/base reviews, gate
|
|
227
|
-
`proceed`, and zero validated blockers. `REQUEST_CHANGES` requires the same
|
|
228
|
-
completeness and `proceed`, plus at least one evidenced blocking finding.
|
|
229
|
-
`INCOMPLETE`, unresolved disagreement, unavailable review or gate, or unknown
|
|
230
|
-
GitHub state publishes nothing. Immediately before `gh pr review`, the agent
|
|
231
|
-
re-reads self's reviews at the head and skips with the existing id when one is
|
|
232
|
-
already present, then re-checks head, base, draft, authorship, open state and
|
|
233
|
-
the review request or recorded explicit comment. Closed or merged PRs are
|
|
234
|
-
skipped. A prior marked automation block can be followed up at a new head.
|
|
235
|
-
The verdict body ends with this exact marker line:
|
|
236
|
-
|
|
237
|
-
```text
|
|
238
|
-
<!-- axstack-automation verdict head=<sha> -->
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
The verdict body is written for the person reading the PR and reads as one
|
|
242
|
-
reviewer's findings. It never names the reviewer count, the brief, the
|
|
243
|
-
angles, the gate, receipts, or which reviewer found what: "two independent
|
|
244
|
-
reviews", "from secondary", and "the reviewers ran" are pipeline facts, not
|
|
245
|
-
review content. It is self-contained: every validated finding, blocking or
|
|
246
|
-
not, appears in full in the body — evidence and consequence, file and line
|
|
247
|
-
where they exist — so a reader is never told that notes exist without seeing
|
|
248
|
-
them, and a finding is never dropped to keep the body short. It never points
|
|
249
|
-
at the local review file or at anything the reader cannot open. Evidence
|
|
250
|
-
appears as what was checked and observed, not as who ran it: the reviewed
|
|
251
|
-
head and base SHAs, CI status, test counts, and diff size are reader-useful
|
|
252
|
-
facts and belong; "shape verified" and "pinned CI" are pipeline phrasing and
|
|
253
|
-
do not. The marker line is the only pipeline artefact the body carries.
|
|
254
|
-
|
|
255
|
-
Write the local review file to the workspace review directory
|
|
256
|
-
`~/defi/misc/reviews/` under the existing convention:
|
|
257
|
-
`review-PR-<num>.html` with no prefix means `defi-com/monorepo`;
|
|
258
|
-
`review-mobile-PR-<num>.html`,
|
|
259
|
-
`review-azure-next-hybrid-PR-<num>.html` and `review-ci-workflows-PR-<num>.html`
|
|
260
|
-
name those repositories. For any other repository use
|
|
261
|
-
`review-<owner>-<repo>-PR-<num>.html` so owners do not collide. A write
|
|
262
|
-
failure is recorded but does not withhold the verdict.
|
|
263
|
-
|
|
264
|
-
Authored repair commits a local candidate, obtains one Sol review at that
|
|
265
|
-
local SHA and the Luna gate, resolves every validated blocker, records test
|
|
266
|
-
evidence, re-reads remote head/base/draft/deploy set/allowlist, then pushes
|
|
267
|
-
fast-forward. The monorepo unit gate uses `~/.bun-1.2.2/bin/bun`; a suite that
|
|
268
|
-
cannot run locally is an explicit unverified boundary.
|
|
269
|
-
|
|
270
|
-
Every reviewer brief ends exactly:
|
|
271
|
-
|
|
272
|
-
```text
|
|
273
|
-
Escalate to user: yes | no — <criterion> — <reason>
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
PR work has exactly three criteria: a security concern, a permanent on-chain
|
|
277
|
-
state change, or an architectural change in approach. There is no
|
|
278
|
-
automation-health criterion for reviewers. The Luna gate returns exactly one
|
|
279
|
-
token, `escalate` or `proceed`; there is no gate for health findings.
|
|
280
|
-
`escalate` opens a decision token, sends its message, and exits without waiting
|
|
281
|
-
for a reply. `proceed` does not override a validated blocker. `worker_done`
|
|
282
|
-
names the PR, head, action, GitHub receipt or opened token. The driver alone
|
|
283
|
-
writes the run record.
|
|
284
|
-
|
|
285
|
-
## Decision tokens
|
|
286
|
-
|
|
287
|
-
Store `decisions/<token>.json`, where `<token>` contains at least 96 random
|
|
288
|
-
bits as lowercase hex, produced for example by `openssl rand -hex 16`.
|
|
289
|
-
Immutable bound fields are written once: `repo`, `pr`, `head`, `base`,
|
|
290
|
-
`action` (`approve-verdict`, `request-changes-verdict`, or `push`), plus exact
|
|
291
|
-
`body` and `commit` for verdicts or `candidate_sha`, `head_branch`, and
|
|
292
|
-
`expected_remote_head` for a push. Mutable fields are `state`, `created_at`,
|
|
293
|
-
`decided_at`, `decided_message_id`, `consumed_at`, `receipt`, `send`, and
|
|
294
|
-
`reason`. Never delete a token file.
|
|
295
|
-
|
|
296
|
-
Lifecycle has one named writer per transition, each by temp file + rename:
|
|
297
|
-
|
|
298
|
-
| transition | writer |
|
|
299
|
-
| --- | --- |
|
|
300
|
-
| create `open` | the agent that escalated |
|
|
301
|
-
| `open → approved` / `open → rejected` | the Hermes script only |
|
|
302
|
-
| `approved → spent` / `approved → stale` | the driver only |
|
|
303
|
-
| `rejected → closed` | the driver only |
|
|
304
|
-
| `spent` + `receipt` | the driver only |
|
|
305
|
-
|
|
306
|
-
### Opening
|
|
307
|
-
|
|
308
|
-
Before opening a `push` token, the repair agent pins its candidate with local
|
|
309
|
-
ref `refs/axstack/decisions/<token>` in the project clone, so the candidate
|
|
310
|
-
survives worktree removal. It then sends one
|
|
311
|
-
`hermes send --to telegram` message naming the PR, criterion, every reviewer's
|
|
312
|
-
reason, and the exact replies `/axstack-decide approve <token>` and
|
|
313
|
-
`/axstack-decide reject <token>` (the slash form loads the Hermes skill
|
|
314
|
-
deterministically; bare `approve <token>` is best effort). Store the
|
|
315
|
-
send receipt. The driver retries a `failed` send once next tick and reconciles
|
|
316
|
-
an `uncertain` send against Hermes output before any retry.
|
|
317
|
-
|
|
318
|
-
The Hermes gateway's fixed `axstack-decide` script accepts only those two exact
|
|
319
|
-
commands. It validates the private user/channel configuration on every call,
|
|
320
|
-
restricts tokens to `^[0-9a-f]{24,}$`, locks and re-reads an `open` token,
|
|
321
|
-
writes only its decision fields by temp file and rename, and prints one line.
|
|
322
|
-
Hermes never runs `gh`, `git`, or `orca`.
|
|
323
|
-
|
|
324
|
-
### Consuming
|
|
325
|
-
|
|
326
|
-
The driver is the only consumer. Immediately before acting it re-reads that
|
|
327
|
-
`state == approved`, then revalidates open/unmerged state, bound head/base,
|
|
328
|
-
absence of a self review for a verdict, or expected remote head plus reachable
|
|
329
|
-
candidate for a push. It writes `spent` before the GitHub call, executes
|
|
330
|
-
exactly the bound action with no second gate, then stores the receipt. A spent
|
|
331
|
-
token without a receipt is
|
|
332
|
-
reconciliation: match the exact review commit/body or destination
|
|
333
|
-
ref/candidate on GitHub; record a match, or the driver retries once under the
|
|
334
|
-
same approval after proving non-execution, or hold ambiguity. A revalidation
|
|
335
|
-
failure writes `stale`
|
|
336
|
-
with the reason and drops the PR's head from `cursor.json`; the driver never
|
|
337
|
-
mints a token. Close rejected files and skip that head. After `spent` or
|
|
338
|
-
`stale`, delete the candidate ref. Tokens do not expire; the watchdog reports
|
|
339
|
-
one open longer than 24 h.
|
|
340
|
-
|
|
341
|
-
## Watchdog
|
|
342
|
-
|
|
343
|
-
The hourly shell precheck only reads `cursor.json`, `precheck.log`,
|
|
344
|
-
`decisions/`, and `orca automations runs --id <driver>`. It performs exactly
|
|
345
|
-
these four checks and always exits non-zero, so no model session launches:
|
|
346
|
-
|
|
347
|
-
| check | trips when |
|
|
348
|
-
| --- | --- |
|
|
349
|
-
| driver stuck | a `changed` or `due` precheck is older than 1 h with no later `tick_done_at`, including a driver that never wrote `tick_started_at` (Orca run status alone is not evidence of completion) |
|
|
350
|
-
| precheck failing | the last three `precheck.log` entries are `error` |
|
|
351
|
-
| worker stuck | a dispatch marker is older than 3 h 30 min and remains uncleared |
|
|
352
|
-
| decision waiting | an `open` decision is older than 24 h |
|
|
353
|
-
|
|
354
|
-
Each trip is `(check, first_observed)`. Write one JSON line per tick to
|
|
355
|
-
`watchdog.log` with `{ts, checks, trips, sent}` and send each occurrence once
|
|
356
|
-
through `hermes send --to telegram`. Persist `sent`, `failed`, or `uncertain`;
|
|
357
|
-
retry `failed` next tick and reconcile `uncertain` before retry. Re-send only
|
|
358
|
-
after the check was observed clear and later recurs. Unreadable evidence is an
|
|
359
|
-
`unknown` occurrence. A healthy tick writes its line and sends nothing. There
|
|
360
|
-
is no gate for health findings.
|
|
361
|
-
|
|
362
|
-
## Run directory
|
|
363
|
-
|
|
364
|
-
The driver and watchdog run from the host's `root` folder workspace, not a
|
|
365
|
-
project worktree: no project owns the automation, and every dispatch
|
|
366
|
-
worktree belongs to the project it serves. That workspace is not a git repository, so
|
|
367
|
-
the run directory is private host state, one
|
|
368
|
-
`~/.local/share/axstack/runs/<run id>/` directory. Settlement leaves nothing
|
|
369
|
-
behind, but never destroys work. Before any destructive step the driver
|
|
370
|
-
proves the worktree is disposable: the worker is settled — on the release path
|
|
371
|
-
a settled release receipt, on the abandon path an accepted abandon receipt,
|
|
372
|
-
either with proven process exit; pending or unknown stops here — the
|
|
373
|
-
worktree's HEAD is either the pinned head or a candidate that is durably
|
|
374
|
-
reachable — pushed to the head branch, tested only after a successful
|
|
375
|
-
targeted fetch of that exact remote branch into a per-dispatch ref, never
|
|
376
|
-
`FETCH_HEAD`, so neither a stale tracking ref nor a concurrent fetch in the
|
|
377
|
-
shared clone can fake durability, a failed fetch retaining the worktree — or held by a
|
|
378
|
-
`refs/axstack/decisions/<token>` ref in the project clone; and, on the
|
|
379
|
-
abandon path, the worktree has no uncommitted changes.
|
|
380
|
-
Only then it closes any terminal tab still listed and removes the worktree
|
|
381
|
-
with `orca worktree rm --worktree <selector> --force` (the proof is the
|
|
382
|
-
gate; a finished worker's untracked artefacts are not), so the dispatch
|
|
383
|
-
leaves nothing behind. On the settled path the worker has finished, so untracked
|
|
384
|
-
files are artefacts by definition; a candidate there is already pushed or
|
|
385
|
-
token-held. A worktree whose release is settled but whose HEAD cannot be
|
|
386
|
-
proven disposable, and an abandoned worktree that is dirty or holds an
|
|
387
|
-
unproven candidate, are both **retained** — retained in place: named in one `health[]`
|
|
388
|
-
line with path and SHA, and blocking only that PR with the user as owner.
|
|
389
|
-
Retention is mechanical on both paths: the driver appends `retained_slots[]`
|
|
390
|
-
`{slot, pr, head, reason}` (`slot` is the worktree path); a retained worktree
|
|
391
|
-
is never removed by the driver, and the entry is cleared only by the user
|
|
392
|
-
after reconciling the candidate, who also removes the worktree. A leftover
|
|
393
|
-
worktree or terminal that outlives its dispatch without such a retention
|
|
394
|
-
record is a health finding. The run directory contains:
|
|
395
|
-
|
|
396
|
-
- `cursor.json` — driver only, with these exact keys: `fingerprint`,
|
|
397
|
-
`tick_started_at`, `tick_done_at`, `tick_outcome`, `prs{url: {head, base,
|
|
398
|
-
draft, checks, reviews, last_self_review}}`, `dispatch_markers[]` (`pr`,
|
|
399
|
-
`task_id`, `dispatch_id`, `worktree`, `head`, `started_at`, `reservation`,
|
|
400
|
-
`trigger`), `deferred[]`, `pending_settlement[]`,
|
|
401
|
-
`retained_slots[]` (`slot`, `pr`, `head`, `reason`),
|
|
402
|
-
`repaired_heads[]` (`pr`, `head`, `dispatched_at`),
|
|
403
|
-
`repair_caps{url: {expires_at}}` (legacy: the first rev-6 tick clears it to
|
|
404
|
-
`{}` with one health line; never written again),
|
|
405
|
-
`abandon_count{head: n}`,
|
|
406
|
-
`processed_reviews[]` (`review_id`, `pr`, `head`, `digest`),
|
|
407
|
-
`deploy_on_push{repo: [branches]}`,
|
|
408
|
-
`legacy_automation_reviews[]`, `health[]`,
|
|
409
|
-
`runtime_refusal{code, first_seen, last_seen}` (absent when no runtime
|
|
410
|
-
hold is open);
|
|
411
|
-
- `pending.json`, `precheck.log` — driver precheck only;
|
|
412
|
-
- `decisions/<token>.json` — writers assigned by the lifecycle table;
|
|
413
|
-
- `watchdog.log` and `watchdog-state.json` (occurrence `first_observed` values
|
|
414
|
-
and send receipts) — watchdog only;
|
|
415
|
-
- `progress.md` — driver only, one line per tick plus holds and mention
|
|
416
|
-
readings, with no per-PR prose.
|
|
417
|
-
|
|
418
|
-
Timestamps are UTC `YYYY-MM-DDTHH:MM:SSZ`; an unparsable timestamp is an
|
|
419
|
-
`error` for the precheck and `unknown` for the watchdog, never silently
|
|
420
|
-
ignored.
|
|
421
|
-
|
|
422
|
-
Orca run history is the authoritative log. The launch workspace is the host's
|
|
423
|
-
`root` folder workspace, not a project worktree: nobody develops there, it is
|
|
424
|
-
not a git repository, and no project owns the automation. The briefs and the
|
|
425
|
-
escalation template are read from the axstack checkout at an absolute path
|
|
426
|
-
given in the prompt, never relative to the launch workspace. Keep this notification-policy edge in the
|
|
427
|
-
run record: `Notification policy` authorizes the token and watchdog sends;
|
|
428
|
-
delivery uses [axstack-relay](../../axstack-relay/SKILL.md).
|
|
429
|
-
|
|
430
|
-
## Safety holds
|
|
431
|
-
|
|
432
|
-
- A GitHub API error makes PR state unknown; never publish or push for it.
|
|
433
|
-
- Enumerate deploy-on-push branches from both repair repositories before
|
|
434
|
-
enabling and store them in `cursor.json`; re-check on allowlist changes.
|
|
435
|
-
- A later tick observing resolution or an explicit user decision clears a
|
|
436
|
-
hold. Silence never clears one. For a hold caused by an Orca runtime
|
|
437
|
-
refusal — a sub-worker dispatch rejected for depth, a launch capability the
|
|
438
|
-
runtime declines — observing resolution means re-attempting the refused
|
|
439
|
-
operation, once per tick, on the next eligible PR: success clears the hold.
|
|
440
|
-
The hold is keyed on Orca's structured error code (for the depth case,
|
|
441
|
-
`nested_worker_depth_exceeded`), stored in `cursor.json` as
|
|
442
|
-
`runtime_refusal {code, first_seen, last_seen}`; the same code keeps the
|
|
443
|
-
hold and updates `last_seen` without a new health line, a different code is
|
|
444
|
-
a new finding. Prose is never the key. When `worker-start` itself is
|
|
445
|
-
refused after the worktree was created, there is no worker, so the
|
|
446
|
-
settlement proof does not apply; the driver reads the receipt's `failedStage`
|
|
447
|
-
and `residualResources` first. With no Dispatch and no residual resources
|
|
448
|
-
the no-worker branch applies: the worktree's HEAD must equal the pinned
|
|
449
|
-
head and `git status --porcelain` must be empty, and then the worktree is
|
|
450
|
-
simply removed in the same tick.
|
|
451
|
-
With a Dispatch or any residual resource the failed start owns runtime
|
|
452
|
-
state, and retaining alone is not recovery: the driver follows the
|
|
453
|
-
runtime's recovery guide. With a Dispatch: `worker-list` for that run, and
|
|
454
|
-
the row's `nextAction` is an object `{kind, argv}` — a non-empty `argv` is
|
|
455
|
-
run verbatim through the same Orca executable and nothing else, while
|
|
456
|
-
`kind: none` authorizes no action beyond inspection and retention. With
|
|
457
|
-
residual resources but no Dispatch there is no row: the mutation itself is
|
|
458
|
-
recovered through `request-show` on the receipt's request id. The no-worker
|
|
459
|
-
branch applies only after the resources are proven gone. It never retries
|
|
460
|
-
in the same tick. Anything unproven retains the worktree with a health line
|
|
461
|
-
naming the stage and the resources. Persisted configuration such
|
|
462
|
-
as `orca-data.json` is never evidence either way; it is a snapshot that
|
|
463
|
-
lags the live setting, and the driver never reads it.
|
|
464
|
-
|
|
465
|
-
## Cutover
|
|
466
|
-
|
|
467
|
-
Perform this order: the new pair exists disabled; the amended skills and
|
|
468
|
-
references are installed; C and D are disabled; every old driver and worker
|
|
469
|
-
attempt is reconciled to confirmed settlement and each unfinished candidate
|
|
470
|
-
is preserved; the old worktree is removed; the old run directory is made
|
|
471
|
-
read-only; the new pair is enabled at distinct minutes; the first real driver
|
|
472
|
-
tick is recorded. A failure leaves the new pair disabled, and both pairs never
|
|
473
|
-
run together. Historical artefacts are untouched.
|
|
474
|
-
|
|
475
|
-
## Exclusions
|
|
476
|
-
|
|
477
|
-
No obligations table, supersede counter, or review-budget hold. No `COMMENT`
|
|
478
|
-
reviews. No watch deadline or `expired` state. No terminal hygiene or global
|
|
479
|
-
busy guard. No terminal nudge from Hermes. No Hermes access to `gh`, `git`, or
|
|
480
|
-
`orca`. No re-review of human-placed blocks. No per-project state. No changes
|
|
481
|
-
to retired artefacts. No gate for health findings.
|
|
1
|
+
# Native PR managers
|
|
2
|
+
|
|
3
|
+
Read this only for the two native Orca PR-manager automations. The historical
|
|
4
|
+
automation specs and plans describe retired designs and are not instructions.
|
|
5
|
+
|
|
6
|
+
## Topology and schedules
|
|
7
|
+
|
|
8
|
+
There are exactly two logical manager lanes:
|
|
9
|
+
|
|
10
|
+
- **Review manager:** runs at minutes `0,15,30,45` and invokes
|
|
11
|
+
[axstack-review](../../axstack-review/SKILL.md) for eligible peer reviews.
|
|
12
|
+
- **Watch manager:** runs at minutes `7,22,37,52` and invokes
|
|
13
|
+
[axstack-watch](../../axstack-watch/SKILL.md) for eligible own-PR watch or
|
|
14
|
+
repair events.
|
|
15
|
+
|
|
16
|
+
Each scheduled pass starts a fresh finite manager session in its persistent
|
|
17
|
+
dedicated workspace; the workspace and saved continuity persist, but the
|
|
18
|
+
manager chat does not. A manager never checks out a PR branch in that
|
|
19
|
+
workspace. Missed slots do not replay a backlog; the next ordinary pass
|
|
20
|
+
discovers current state. The two short packaged prompts sit beside this file
|
|
21
|
+
and discover these rules by relative link instead of copying them.
|
|
22
|
+
|
|
23
|
+
This is prompt policy, not proof that Orca starts a fresh session or prevents
|
|
24
|
+
overlapping passes. Before activation a native canary must prove fresh-session
|
|
25
|
+
launch, overlapping-pass behavior, recovery after session loss, nested
|
|
26
|
+
dispatch depth for coordinator-launched leaves, and total process and memory
|
|
27
|
+
effects. A firing timestamp proves neither delivery nor useful completion.
|
|
28
|
+
|
|
29
|
+
## Session admission
|
|
30
|
+
|
|
31
|
+
Reconcile saved state, current GitHub state, and native Orca Tasks, Dispatches,
|
|
32
|
+
sessions, and liveness in the dedicated workspace before discovery or
|
|
33
|
+
admission. A confirmed live manager for the same lane remains authoritative.
|
|
34
|
+
The new duplicate does no PR work, makes no shared-record write, touches
|
|
35
|
+
nothing owned by the live manager, and closes only itself as its final action.
|
|
36
|
+
Unknown liveness blocks admission and shared-record writes; it does not
|
|
37
|
+
authorize takeover, cleanup, or a duplicate manager. Preserve `user_takeover`
|
|
38
|
+
and other user-owned sessions.
|
|
39
|
+
|
|
40
|
+
## Discovery and coverage
|
|
41
|
+
|
|
42
|
+
Resolve self on every tick with `gh api user --jq .login`; never hardcode the
|
|
43
|
+
account. Read every discovery page. If pagination or an API call fails, report
|
|
44
|
+
coverage incomplete and make no completeness claim; never silently cap the
|
|
45
|
+
monitored set.
|
|
46
|
+
|
|
47
|
+
The review manager covers open non-draft PRs across accessible repositories
|
|
48
|
+
that are authored by someone else and either officially request review from
|
|
49
|
+
self or have a non-self comment that explicitly mentions self and requests a
|
|
50
|
+
review or response. Incidental mentions grant no authority. Preserve a prior
|
|
51
|
+
human `CHANGES_REQUESTED` block across head changes. It has workflow provenance
|
|
52
|
+
only when its body ends with
|
|
53
|
+
`<!-- axstack-automation verdict head=<sha> -->` bound to its reviewed commit,
|
|
54
|
+
or a retained legacy receipt proves that provenance; otherwise never replace
|
|
55
|
+
it automatically.
|
|
56
|
+
|
|
57
|
+
The watch manager covers every open non-draft PR authored by self. It may
|
|
58
|
+
repair only `defi-com/monorepo` and `defi-com/mobile`; PRs elsewhere remain
|
|
59
|
+
observed but read-only. Preserve deploy-on-push exclusions, lowest-first stack
|
|
60
|
+
dependencies, and existing ownership boundaries. Peer code is always
|
|
61
|
+
read-only.
|
|
62
|
+
|
|
63
|
+
Coverage is not execution. Waiting for CI, a reviewer, a user decision, or a
|
|
64
|
+
merge occupies no execution slot after owned work and descendants settle.
|
|
65
|
+
Watch membership never reserves a slot and no job stays active merely until a
|
|
66
|
+
PR merges or closes. Thirty open PRs, including ten settled waiting PRs, are
|
|
67
|
+
all scanned; those ten occupy zero slots.
|
|
68
|
+
|
|
69
|
+
## Admission and fairness
|
|
70
|
+
|
|
71
|
+
Each manager admits at most five concurrently executing PR tasks across ticks.
|
|
72
|
+
The review manager admits at most five, and the watch manager admits at most
|
|
73
|
+
five. Their caps are separate; never borrow unused capacity from the other
|
|
74
|
+
lane. Admit fewer when the whole worker tree would put the host under resource
|
|
75
|
+
pressure.
|
|
76
|
+
|
|
77
|
+
A slot covers one bounded PR event and remains occupied while its author,
|
|
78
|
+
reviewers, or other owned descendants are active or unsettled. Leaf workers do
|
|
79
|
+
not create recursive teams. Settlement of the PR job and every descendant
|
|
80
|
+
frees the slot even while the PR stays open.
|
|
81
|
+
|
|
82
|
+
Inspect all eligible PRs before admission. Preserve unserved work in the
|
|
83
|
+
compact run record and select the oldest actionable unserved event first, with
|
|
84
|
+
ascending repository and PR-number tie breaks. A sixth event is admitted after
|
|
85
|
+
a slot settles; repeatedly changing PRs cannot starve older unserved work.
|
|
86
|
+
|
|
87
|
+
## Per-PR jobs
|
|
88
|
+
|
|
89
|
+
The logical manager lane owns ongoing discovery and continuity across finite
|
|
90
|
+
sessions; the bounded PR coordinator owns only its admitted event. Do not create a second live owner or
|
|
91
|
+
writer for the same PR. Reuse an existing valid per-PR worktree, owner, and
|
|
92
|
+
unchanged receipts before creating anything. Otherwise create one separate
|
|
93
|
+
Orca worktree per PR job, parented to that repository's primary worktree, and
|
|
94
|
+
pin the observed head and base. The bounded PR coordinator loads the
|
|
95
|
+
appropriate skill, launches only the reviewers or author that skill owns,
|
|
96
|
+
handles the current actionable event, returns exact receipts, then settles.
|
|
97
|
+
Settlement returns continuity to the manager rather than retaining an idle PR
|
|
98
|
+
coordinator. Reviewers retain the isolation required by `axstack-review`.
|
|
99
|
+
|
|
100
|
+
An unchanged exact head and unchanged event identity creates no job; an
|
|
101
|
+
unchanged exact head with a new event identity remains actionable. Event
|
|
102
|
+
identity includes the applicable review ID and body digest, check identity and
|
|
103
|
+
result, or other current GitHub event receipt. Dedupe from current GitHub state,
|
|
104
|
+
native Orca Task and Dispatch state, and the existing compact run record; do
|
|
105
|
+
not create machine cursor files or a queue engine. Record enough to resume: PR,
|
|
106
|
+
head, base, event identity, mode, owner and worker receipts, candidate,
|
|
107
|
+
publication receipt, hold, and next action. GitHub remains authoritative for
|
|
108
|
+
open state, revisions, reviews, checks, and merge state.
|
|
109
|
+
|
|
110
|
+
When the current event is handled, settle and release owned native resources.
|
|
111
|
+
Preserve dirty worktrees, unpushed candidates, review evidence, pending
|
|
112
|
+
external results, and user-owned work until durability and ownership are
|
|
113
|
+
proven. Unknown liveness, `user_takeover`, and ambiguous publication likewise
|
|
114
|
+
forbid cleanup. Here a pending external result means an unconfirmed publication
|
|
115
|
+
or send outcome, not pending CI. Waiting state belongs in GitHub and the compact
|
|
116
|
+
record, never in an idle model, per-PR timer, or polling loop.
|
|
117
|
+
|
|
118
|
+
## Review and repair authority
|
|
119
|
+
|
|
120
|
+
Peer review follows `axstack-review` peer mode: two isolated configured
|
|
121
|
+
reviewers inspect the exact head and base. Complete review may publish the
|
|
122
|
+
ordinary binding `APPROVE` or `REQUEST_CHANGES` verdict after a final head,
|
|
123
|
+
base, request, open-state, and existing-review readback. Incomplete review,
|
|
124
|
+
unknown GitHub state, unavailable required models, or unresolved disagreement
|
|
125
|
+
publishes nothing.
|
|
126
|
+
|
|
127
|
+
The public verdict is bound to the GitHub review commit parameter, ends with
|
|
128
|
+
the workflow marker above, and is read back by review ID at that head. It is
|
|
129
|
+
self-contained for the PR reader: include every validated finding and its
|
|
130
|
+
evidence and consequence; never narrate reviewer counts, gates, receipts, or
|
|
131
|
+
private or local artifacts. Write the local HTML copy under the established
|
|
132
|
+
`~/defi/misc/reviews/review-<repo>-PR-<num>.html` convention, with
|
|
133
|
+
`review-PR-<num>.html` reserved for `defi-com/monorepo`. Never publish a
|
|
134
|
+
`COMMENT` review. An ambiguous submission is looked up before retry.
|
|
135
|
+
|
|
136
|
+
An own PR becomes actionable for repair only when a failing check has a base
|
|
137
|
+
check-run with the same name and producing app identity observed passing (or a
|
|
138
|
+
legacy status has the same context), or when a new current-head
|
|
139
|
+
`CHANGES_REQUESTED` review has both an unhandled review ID and an unhandled body
|
|
140
|
+
digest. Missing, pending, or same-name/different-app base evidence holds repair.
|
|
141
|
+
A new head or generic event grants no repair authority by itself.
|
|
142
|
+
|
|
143
|
+
Authorized own-PR repair follows `axstack-watch`: produce the smallest repair
|
|
144
|
+
in the per-PR worktree, obtain the actual-author-provenance reviewer pairing,
|
|
145
|
+
and publish only a reviewed fast-forward repair push after exact-current
|
|
146
|
+
candidate, head, base, event, allowlist, deploy, and remote readback receipts.
|
|
147
|
+
Reconcile an ambiguous review or push result before any retry.
|
|
148
|
+
|
|
149
|
+
No manager, coordinator, or worker may merge, close, force-push, rebase,
|
|
150
|
+
restack, broaden scope, or use `gh stack` mutation. Human merge remains the
|
|
151
|
+
boundary.
|
|
152
|
+
|
|
153
|
+
## Exceptional decisions and notifications
|
|
154
|
+
|
|
155
|
+
A credible security concern, permanent on-chain state change, or architecture
|
|
156
|
+
decision is held in GitHub or a durable user-owned conversation that survives
|
|
157
|
+
the finite manager session. Store the PR, head, base, action, candidate,
|
|
158
|
+
decision context, durable decision location, and preserved candidate bytes or
|
|
159
|
+
refs in the compact record. The decision must never depend on a closed manager
|
|
160
|
+
chat. Send one deduplicated Telegram notification only when the recorded
|
|
161
|
+
`Notification policy` authorizes it, using
|
|
162
|
+
[axstack-relay](../../axstack-relay/SKILL.md) and telling the user where the
|
|
163
|
+
durable decision is actionable.
|
|
164
|
+
|
|
165
|
+
Telegram delivery, a Telegram reply, or silence never authorizes an action.
|
|
166
|
+
After a decision, revalidate the exact candidate, head, base, event, authority,
|
|
167
|
+
and remote state before acting. A changed input makes the old decision stale
|
|
168
|
+
and holds that action. There are no token files, Telegram decision interpreter,
|
|
169
|
+
or separate model gate.
|
|
170
|
+
|
|
171
|
+
## Finite-session teardown
|
|
172
|
+
|
|
173
|
+
After admission closes, settle every owned PR job and all descendants before the
|
|
174
|
+
manager session ends; active or unknown descendants keep their PR slot occupied
|
|
175
|
+
and must be reconciled rather than trusted from saved status. Then save durable
|
|
176
|
+
continuity, evidence locations, pending receipts, and user decisions before
|
|
177
|
+
self-close. Waiting PRs still occupy zero slots once their owned trees settle.
|
|
178
|
+
|
|
179
|
+
Cleanup is scoped to positively identified owned unused setup shells: use the
|
|
180
|
+
version-matched native exact-terminal close operation for each such terminal only.
|
|
181
|
+
Never blanket-close a workspace. Preserve dirty worktrees, unpushed candidates,
|
|
182
|
+
review evidence, user-owned terminals, unknown liveness, `user_takeover`, and
|
|
183
|
+
ambiguous publication state. Close the finite manager's own exact terminal
|
|
184
|
+
through the native guide. Self-close is the final action; perform no record
|
|
185
|
+
write, cleanup, or other work afterward.
|
|
186
|
+
|
|
187
|
+
## Recovery and limits
|
|
188
|
+
|
|
189
|
+
On a lost manager session, native recovery first reconciles actual Orca
|
|
190
|
+
workers and Dispatches, GitHub state, and the compact run record. Reuse valid
|
|
191
|
+
unchanged receipts. Unknown ownership blocks only the affected PR, as does
|
|
192
|
+
unknown liveness, approval, or publication outcome; recovery never copies old
|
|
193
|
+
capability, replaces a live writer, or takes over live user work. Other
|
|
194
|
+
unambiguous work may proceed.
|
|
195
|
+
|
|
196
|
+
Use only native schedules and Orca orchestration. Add no daemon, shell precheck,
|
|
197
|
+
watchdog script, custom scheduler, cursor or pending sidecar, runtime database,
|
|
198
|
+
workflow state machine, decision interpreter, or programmatic escalation gate.
|
|
199
|
+
The live VPS activation, native fresh-session and overlapping-pass behavior, recovery path,
|
|
200
|
+
nested dispatch depth for coordinator-launched leaves, and resource ceiling
|
|
201
|
+
remain unverified until the canary succeeds.
|