@sjawhar/pi-legion-envoy 1.22.0 → 1.22.2
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.
|
@@ -18,7 +18,11 @@ separate coordinator to finish necessary work.
|
|
|
18
18
|
Message a known phase worker with `envoy_publish` to `notifications.role.` followed by
|
|
19
19
|
its encoded role token (the token `spawn_worker` returned for it); re-assign it by
|
|
20
20
|
calling `spawn_worker` again on the same existing role, which resumes the same process
|
|
21
|
-
instead of starting a fresh one.
|
|
21
|
+
instead of starting a fresh one. Phases on one issue are strictly sequential -- one role
|
|
22
|
+
is the issue's active phase at a time, and calling `spawn_worker` for a different role
|
|
23
|
+
while a phase is active supersedes that phase: the superseded worker's
|
|
24
|
+
`legion handoff complete` is then refused, so finish (or deliberately abandon) one role
|
|
25
|
+
before assigning the next. Phase workers escalate lifecycle, scope, and
|
|
22
26
|
cross-phase matters the same way: `envoy_publish` to your own encoded token. Any role
|
|
23
27
|
may use `dispatch_ask` directly for a standalone human question; replies return to the
|
|
24
28
|
asking session.
|
|
@@ -187,7 +191,7 @@ legion({
|
|
|
187
191
|
```
|
|
188
192
|
|
|
189
193
|
Wait for the implementer to report its durable retro result. Retro output is
|
|
190
|
-
`docs/solutions/` plus an issue comment; it must not create a `.legion` file or
|
|
194
|
+
`docs/solutions/` plus an issue comment; it must not create a `.legion` file or rewrite
|
|
191
195
|
the reviewer-approved head after cleanup.
|
|
192
196
|
|
|
193
197
|
## 6. Architect sign-off and merge
|
|
@@ -202,19 +206,31 @@ Preserve this order exactly:
|
|
|
202
206
|
2. on a clean review, `spawn_worker` the implementer once more to push only the `.legion/`
|
|
203
207
|
deletion (the review App holds no `contents` permission), then the reviewer approves that
|
|
204
208
|
head. The deletion must land before that approval, which is head-pinned. An implementer
|
|
205
|
-
completion
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
3. retro
|
|
210
|
-
|
|
211
|
-
|
|
209
|
+
completion advances the status only from `in_progress` to `testing`; this push, like retro
|
|
210
|
+
later, leaves the status where it is, so you set nothing by hand — on its `phase-complete`
|
|
211
|
+
wake, `spawn_worker` the reviewer to approve that head (a finished reviewer may already be
|
|
212
|
+
retired; `spawn_worker` resumes it);
|
|
213
|
+
3. retro commits its learnings under `docs/solutions/` on top of the approved head; that
|
|
214
|
+
commit does not void the approval and never returns the tree to the tester or reviewer;
|
|
215
|
+
4. the merger verifies the current head is the reviewer-approved head plus only commits that
|
|
216
|
+
change `docs/solutions/` (`jj diff --from <approved-sha> --to <tip-sha> --summary`, quoted in READY)
|
|
217
|
+
and publishes `READY #<n> at <sha>` to `notifications.role.pr-queue`; it never
|
|
212
218
|
merges. The merge queue merges under its own authority and the repository's own rules
|
|
213
219
|
(branch protection, CODEOWNERS); whether a human must approve first is that repository's
|
|
214
220
|
setting, not Legion's, and you never ask for or wait on such an approval.
|
|
215
221
|
|
|
216
|
-
|
|
217
|
-
|
|
222
|
+
What returns the tree to review: a changed diff — a commit above the approved head that
|
|
223
|
+
touches anything outside `docs/solutions/`, or a rebase whose fingerprint (the `legion-worker`
|
|
224
|
+
skill's unchanged-diff check) differs from the approved head's. What does not: retro's
|
|
225
|
+
`docs/solutions/` commit, and a rebase forced by a GitHub-reported conflict whose fingerprint
|
|
226
|
+
is unchanged. For that rebase the order is: the implementer rebases and posts the before/after
|
|
227
|
+
fingerprints; the tester re-runs the bare gates only; the reviewer confirms and approves the new
|
|
228
|
+
head by SHA (or continues its round if it had not approved); the merger republishes READY.
|
|
229
|
+
Retro does not re-run. A rebase happens only when GitHub reports `CONFLICTING`
|
|
230
|
+
(`legion gh -- pr view <n> --json mergeable,mergeStateStatus`); read that on every end-game
|
|
231
|
+
wake — `pr-ready`, `pr-review`, `phase-complete`, `catchup-overseer` — because a `CONFLICTING`
|
|
232
|
+
PR gets no CI and no wake announces it, and send the implementer to rebase the moment you see
|
|
233
|
+
it. Do not let the merger publish `READY` for an obsolete approval.
|
|
218
234
|
|
|
219
235
|
If a worker reports that `legion threads resolve` exited 1 naming a review thread GitHub refused
|
|
220
236
|
to resolve, open an action ask (`dispatch_ask` with `kind: "action"`) that names the thread's URL
|
|
@@ -245,11 +261,11 @@ corresponding lifecycle procedure.
|
|
|
245
261
|
| `child-closed` | Read the child completion and remaining open children. Re-scope or close obsolete open work; release an appropriate next wave, or await `children-complete`. |
|
|
246
262
|
| `children-complete` | Execute steps 3–4: parent integration verification; failures become a new child wave, success advances to review and retro. |
|
|
247
263
|
| `child-reopened` | Treat the completion edge as reset. Reassess the reopened child and return the tree to children-in-flight; do not continue an already-started end-game. |
|
|
248
|
-
| `phase-complete` | Payload `{type:"phase-complete", issue, role, summary}`. May arrive live or via `catchup-overseer`'s `phaseCompletions`. Read the committed handoff for that phase, then spawn the next phase's owner, or `spawn_worker` on the same role again to resume it with corrections if the handoff shows unresolved gaps. A `reviewer` completion whose GitHub review is `CHANGES_REQUESTED` (the daemon
|
|
264
|
+
| `phase-complete` | Payload `{type:"phase-complete", issue, role, summary}`. May arrive live or via `catchup-overseer`'s `phaseCompletions`. Read the committed handoff for that phase, then spawn the next phase's owner, or `spawn_worker` on the same role again to resume it with corrections if the handoff shows unresolved gaps. A `reviewer` completion whose GitHub review is `CHANGES_REQUESTED` (the daemon returns the issue's Dispatch status to `in_progress` for this, on the reviewer's completion and again when you spawn the corrective implementer unless the daemon already knows the issue is `in_progress`) means `spawn_worker` the **implementer** again with the review findings — thread URLs and blocking items — as its task, then route back through tester and reviewer in order; never `spawn_worker` the reviewer directly off this wake and never proceed to retro on this verdict. A reviewer completion with an `APPROVED` review proceeds to retro (step 5). A `reviewer` completion after a conflict-forced rebase whose review body names an unchanged fingerprint is a confirmation, not a round: if retro already completed, `spawn_worker` the merger; otherwise resume the step you were on. |
|
|
249
265
|
| `worker-queued` | Payload `{type:"worker-queued", issue, role}`. The deployment's worker cap is full; this role's spawn is queued. Do not respawn or retry — wait for `worker-started`. |
|
|
250
266
|
| `worker-started` | Payload `{type:"worker-started", issue, role}`. A previously queued role has been promoted and is now running. Treat it exactly as a normal spawn: resume tracking that role's live session. |
|
|
251
267
|
| `pr-ready` | Verify the live PR head, green status, and review state. Continue the review/retro/merger order only for that current head. |
|
|
252
|
-
| `pr-review` | Payload `{type:"pr-review", state, author, body}`. Delivered to whichever role is currently active for the issue, falling back to you when no worker phase is active. Follows the same verdict rule as a reviewer's `phase-complete`: `state: "changes_requested"` sends the implementer back in with the review findings, then tester, then reviewer — never the reviewer again and never retro; `state: "approved"` proceeds toward retro (step 5) once the step 6 integration/merge-gate conditions are met. |
|
|
268
|
+
| `pr-review` | Payload `{type:"pr-review", state, author, body}`. Delivered to whichever role is currently active for the issue, falling back to you when no worker phase is active. Follows the same verdict rule as a reviewer's `phase-complete`: `state: "changes_requested"` sends the implementer back in with the review findings, then tester, then reviewer — never the reviewer again and never retro; that `spawn_worker` returns the issue to `in_progress` on its own (the daemon writes it for a corrective implementer whenever the PR's latest recorded review is changes requested, a human's after approval included), so you set nothing by hand; `state: "approved"` proceeds toward retro (step 5) once the step 6 integration/merge-gate conditions are met. `state: "approved"` on a rebased head whose body names an unchanged fingerprint is that confirmation: proceed to retro if it has not run, otherwise to the merger — never to a second retro or test round. |
|
|
253
269
|
| `pr-blocked` | Payload `{type:"pr-blocked", pr, attempts}`. `attempts` counts heads pushed onto a red verdict that changed something outside `.legion/` — handoff-only pushes (`.legion/` paths only) never count; a push the daemon cannot classify (a listener without `changed_paths`, a list capped at 100, a push listing no commits) does. Published once per exhausted count, not on every later red verdict for that count. Read the failed CI evidence and recovery attempts. Assign a focused implementer or corrective child, then return it through testing and review; do not treat the blocked PR as final. |
|
|
254
270
|
| `pr-merged` | Payload `{type:"pr-merged", pr, mergeCommitSha}`. The merge queue landed the PR. This is your cue for step 7: post the sign-off comment naming that merge commit and set the issue `done`. Nothing else follows a merge. |
|
|
255
271
|
| `pr-closed-unmerged` | Decide from current scope whether to reopen the work, send a fresh implementer, or cancel it with a reason. Delegate the repository action to the responsible phase worker and keep ownership. |
|
|
@@ -19,13 +19,20 @@ retrospective's durable output.
|
|
|
19
19
|
approves that head.
|
|
20
20
|
3. Run this retro: commit durable learnings to `docs/solutions/` and post the issue comment.
|
|
21
21
|
Retro writes **no `.legion` file**, so it never re-dirties the cleaned handoff tree.
|
|
22
|
-
4. The merger verifies the
|
|
23
|
-
|
|
22
|
+
4. The merger verifies the tip is the approved head plus commits that change only
|
|
23
|
+
`docs/solutions/` — `jj diff --from <approved-sha> --to <tip-sha> --summary`, quoted in READY —
|
|
24
|
+
publishes `READY`, and pushes nothing; the merge queue merges under the repository's own
|
|
25
|
+
rules.
|
|
24
26
|
5. After the merge lands, the implementer — not the reviewer, the merger, or the queue — verifies
|
|
25
27
|
the change in production and records it on the PR and the issue (Sami, 2026-09-13, verbatim:
|
|
26
28
|
"the agent that developed it should be responsible for testing in production"). The
|
|
27
29
|
architect's sign-off waits for that record.
|
|
28
30
|
|
|
31
|
+
Retro's commit sits above the reviewer's approved head and the approval stands: a commit that
|
|
32
|
+
changes only `docs/solutions/` does not void it, and the tree goes from retro to the merger —
|
|
33
|
+
never back to the tester or reviewer. A conflict-forced rebase after retro moves these documents
|
|
34
|
+
with the branch; retro does not re-run.
|
|
35
|
+
|
|
29
36
|
Do not start retro before step 2, skip it because the change seems mechanical, or publish `READY`
|
|
30
37
|
before step 3. The design gate is not a substitute for review and retro.
|
|
31
38
|
|
|
@@ -83,13 +90,16 @@ legion gh -- issue comment <issue-number> \
|
|
|
83
90
|
```
|
|
84
91
|
|
|
85
92
|
The issue comment and `docs/solutions/` commit are the only retro outputs. Never write a
|
|
86
|
-
handoff, phase artifact, local feedback log, or completion label
|
|
93
|
+
handoff, phase artifact, local feedback log, or completion label; `.legion/` was deleted before
|
|
94
|
+
retro and nothing recreates it. Report completion with `legion handoff complete` alone (its
|
|
95
|
+
summary: two sentences for the architect) — no `legion handoff write`.
|
|
87
96
|
|
|
88
97
|
## Completion check
|
|
89
98
|
|
|
90
99
|
Before returning, verify all of the following:
|
|
91
100
|
|
|
92
|
-
- The reviewer cleanup commit remains below the retro documentation commit
|
|
101
|
+
- The reviewer cleanup commit remains below the retro documentation commit, and the reviewer's
|
|
102
|
+
approval of that cleanup head stands: the merger accepts the approved head plus this commit.
|
|
93
103
|
- The learning documents and issue comment both exist.
|
|
94
104
|
- No `.legion` file was created or modified by retro.
|
|
95
105
|
- The fresh-eyes analysis was considered alongside the implementer's context.
|
|
@@ -268,7 +268,13 @@ Negative control: <deliberately broken input> → <refusal or failure observed>.
|
|
|
268
268
|
The implementer rebases the issue branch only when GitHub reports it `CONFLICTING` or the
|
|
269
269
|
controller asks because of a conflict — never to pick up `main` or to refresh CI. A single
|
|
270
270
|
failed CI job is re-run on its own with `legion gh -- run rerun <run-id> --failed`, never by
|
|
271
|
-
pushing a new commit.
|
|
271
|
+
pushing a new commit. A conflict-forced rebase that leaves the branch's diff unchanged is a
|
|
272
|
+
confirmation, not a new round (see *The unchanged-diff check* below). Before rebasing, record
|
|
273
|
+
the fingerprint at the current tip; after pushing the rebased branch, record it at the new
|
|
274
|
+
tip; post one PR comment (Legion footer):
|
|
275
|
+
`rebase <old-tip-sha> → <new-tip-sha>; fingerprint <before> → <after>; unchanged|changed`.
|
|
276
|
+
Rebase the whole chain — `jj -R "$LEGION_WORKSPACE" rebase -s 'roots(main@origin..@)' -d main@origin` —
|
|
277
|
+
so the tester's and reviewer's commits move with yours.
|
|
272
278
|
- **No deferrals.** Sami, 2026-09-11, verbatim: "My rule is no deferrals." The `Fast-follow:`
|
|
273
279
|
field names naming, duplication, or wording cleanup only; anything that changes behaviour,
|
|
274
280
|
hides an error, or breaks a gate lands in this PR.
|
|
@@ -294,21 +300,33 @@ Negative control: <deliberately broken input> → <refusal or failure observed>.
|
|
|
294
300
|
whole staging gate never ran. Environment or
|
|
295
301
|
secret-scrub evidence (e.g. "`LEGION_*`/`DISPATCH_*`/`ENVOY_*` unset") is recorded once, in
|
|
296
302
|
`.legion/test.json`, and only when the issue's acceptance criteria call for it — never
|
|
297
|
-
re-pasted into the PR body each round.
|
|
303
|
+
re-pasted into the PR body each round. After a conflict-forced rebase, compute the
|
|
304
|
+
fingerprint at the head your `E2E` line names and at the new head. Equal: re-run only the
|
|
305
|
+
bare gates — the repository's CI green at the new head and its smoke check — and change the
|
|
306
|
+
`E2E` line's head to the new SHA with
|
|
307
|
+
`rebase re-check <old-sha> → <new-sha>: fingerprint unchanged, bare gates only`; the
|
|
308
|
+
real-surface verification is not repeated. Different: a full test round.
|
|
298
309
|
- The reviewer verifies the `CI`, `Threads`, and `E2E` facts against GitHub directly —
|
|
299
310
|
never from a handoff — then runs `task(agent="thermonuclear-deep-review")` and
|
|
300
311
|
`task(agent="thermonuclear-code-quality")` once at that head and records the verdict.
|
|
301
312
|
Skip the `Thermo` line entirely on a docs-only PR. Submit **one review per round** —
|
|
302
313
|
`REQUEST_CHANGES` when any correctness finding stands, otherwise `COMMENT` while the head
|
|
303
|
-
still carries `.legion/`; `APPROVE` only for
|
|
304
|
-
the `.legion/` deletion alone,
|
|
314
|
+
still carries `.legion/`; `APPROVE` only for a head that carries no `.legion/` — the head
|
|
315
|
+
that differs from the reviewed one by the `.legion/` deletion alone, or, after a
|
|
316
|
+
conflict-forced rebase, the new head whose fingerprint equals the approved head's — always
|
|
317
|
+
named by SHA — carrying every inline comment in that single
|
|
305
318
|
call: `legion gh -- api --method POST repos/{owner}/{repo}/pulls/{number}/reviews --input body.json`
|
|
306
319
|
with `commit_id`, `event` (`REQUEST_CHANGES`, `COMMENT`, or `APPROVE`), `body` (with the
|
|
307
320
|
Legion footer), and a `comments[]` array of `{path, line, side, body}`, one entry per
|
|
308
321
|
finding — never one `pr review` call per finding (each submission fires a `pr-review` wake).
|
|
309
322
|
Then return the issue to the architect; when clean, have the architect send the implementer
|
|
310
323
|
back to push the `.legion/` deletion (the review App cannot push), then review **that** head
|
|
311
|
-
and approve it by name.
|
|
324
|
+
and approve it by name. After a conflict-forced rebase, compute the fingerprint at the
|
|
325
|
+
`commit_id` of your last submitted review and at the new head. Equal and that review was
|
|
326
|
+
`APPROVE`: submit one more `APPROVE` naming the new head by SHA, its body naming both SHAs
|
|
327
|
+
and the fingerprint — a confirmation, not a round; no thermo pass, no thread pass. Equal and
|
|
328
|
+
that review was `COMMENT` or `REQUEST_CHANGES`: continue that round against the new head;
|
|
329
|
+
nothing restarts. Different: a new round — thermo again, one review.
|
|
312
330
|
When you re-review after a corrective push, answer every thread you opened in one of the
|
|
313
331
|
three forms above — `Accepted:` is the only reply the implementer's `legion threads resolve`
|
|
314
332
|
acts on — and approve only once every thread you opened carries your `Accepted:` reply and the
|
|
@@ -316,13 +334,24 @@ Negative control: <deliberately broken input> → <refusal or failure observed>.
|
|
|
316
334
|
the PR body).
|
|
317
335
|
- Once a base is frozen for others to stack on, never rewrite it — fixes land as new
|
|
318
336
|
commits on top, and the `Chain` line records what is frozen.
|
|
337
|
+
- **Retro's commit does not void the reviewer's approval.** After the reviewer approves the
|
|
338
|
+
cleaned head, retro commits its learnings under `docs/solutions/` on top of it; that commit
|
|
339
|
+
stays, the approval stands, and the tree goes to the merger — never back to the tester or
|
|
340
|
+
reviewer. Anything else above the approved head does void it, and the merger tells the
|
|
341
|
+
architect the head must return to review instead of publishing. A conflict-forced rebase
|
|
342
|
+
after retro moves those documents with the branch; retro never re-runs.
|
|
319
343
|
- The merger runs `legion threads resolve --pr <n> --repo <owner>/<repo>` (it acts as the same
|
|
320
344
|
code-writing App as the implementer; resolving a thread changes no commit, so this run never
|
|
321
345
|
invalidates the approval), does not publish while any `left open` line remains or the command
|
|
322
|
-
exits 1 (report the thread to the architect instead),
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
346
|
+
exits 1 (report the thread to the architect instead), then
|
|
347
|
+
proves that rule with two commands and publishes. First
|
|
348
|
+
`cd -- "$LEGION_WORKSPACE" && jj -R "$LEGION_WORKSPACE" git fetch && jj -R "$LEGION_WORKSPACE" diff --from <approved-sha> --to <tip-sha> --summary`,
|
|
349
|
+
whose output is quoted in READY (an empty output is quoted as
|
|
350
|
+
`no file changes above the approved head`); then the same with `'~docs/solutions'` appended,
|
|
351
|
+
which must print nothing. Then it publishes `READY #<n> at <tip-sha>` naming the approved
|
|
352
|
+
head, the tip, and that summary, plus the PR body's gate facts, to the merge queue's role
|
|
353
|
+
(`notifications.role.pr-queue`) with `envoy_publish`. The merger never merges; the queue
|
|
354
|
+
merges under its own authority.
|
|
326
355
|
- **After the queue merges, the implementer verifies in production.** Sami, 2026-09-13,
|
|
327
356
|
verbatim: "the agent that developed it should be responsible for testing in production."
|
|
328
357
|
The architect sends the implementer back once the merge lands; the implementer watches the
|
|
@@ -333,6 +362,44 @@ Negative control: <deliberately broken input> → <refusal or failure observed>.
|
|
|
333
362
|
failed at 00:12Z on a resource staging never runs. If the slot fails on the change, the
|
|
334
363
|
implementer owns the fix and the next slot.
|
|
335
364
|
|
|
365
|
+
## The unchanged-diff check
|
|
366
|
+
|
|
367
|
+
The fingerprint every role compares after a conflict-forced rebase (every flag and the fileset
|
|
368
|
+
verified on jj 0.45.1):
|
|
369
|
+
|
|
370
|
+
```bash
|
|
371
|
+
cd -- "$LEGION_WORKSPACE" && jj -R "$LEGION_WORKSPACE" git fetch && \
|
|
372
|
+
jj -R "$LEGION_WORKSPACE" diff --from "fork_point(main@origin | <head-sha>)" --to <head-sha> \
|
|
373
|
+
--git --context 0 '~(.legion | docs/solutions)' \
|
|
374
|
+
| sed -e '/^@@/d' -e '/^index /d' | sha256sum
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
- `<head-sha>` is a full commit SHA; a jj commit id is the git SHA GitHub shows.
|
|
378
|
+
- `fork_point(main@origin | <head-sha>)` is the base the branch was cut from *at that head*:
|
|
379
|
+
the old base for the pre-rebase head, the new base for the rebased one, so one command
|
|
380
|
+
serves both sides. On a stacked PR substitute its base branch for `main`
|
|
381
|
+
(`legion gh -- pr view <n> --json baseRefName`).
|
|
382
|
+
- A head the rebase hid is still addressable by its SHA in the shared workspace. A SHA the
|
|
383
|
+
workspace cannot resolve (`jj -R "$LEGION_WORKSPACE" log -r <sha>` errors) counts as a
|
|
384
|
+
changed diff — never as unchanged.
|
|
385
|
+
- `--context 0` drops context lines; the `sed` drops `@@` hunk headers (line positions move
|
|
386
|
+
on a rebase) and `index` lines (blob ids move when the base's copy of a file changed). What
|
|
387
|
+
is left is exactly the added and removed lines per file.
|
|
388
|
+
- The single fileset `'~(.legion | docs/solutions)'` leaves out the handoff ledger and retro's
|
|
389
|
+
learnings: process artifacts the rules above already exempt from re-review, which change
|
|
390
|
+
between one role's verified head and the next without changing the product. This is what lets
|
|
391
|
+
each role compare against *its own* last verified head instead of trusting another role's
|
|
392
|
+
numbers. It must be one expression: jj unions positional filesets, so two separate
|
|
393
|
+
`'~.legion' '~docs/solutions'` arguments select every file and exclude nothing. Once
|
|
394
|
+
`.legion/` is gone, jj warns `No matching entries for paths: .legion` on stderr; the hash is
|
|
395
|
+
unaffected.
|
|
396
|
+
|
|
397
|
+
Where each role gets its two heads: the implementer — the tip before and after its own rebase;
|
|
398
|
+
the tester — the head its `E2E` line names and the new head; the reviewer — the `commit_id` of
|
|
399
|
+
its last submitted review (`legion gh -- api repos/{owner}/{repo}/pulls/{n}/reviews --jq '.[] | {commit_id, state, user: .user.login}'`)
|
|
400
|
+
and the new head; the merger never computes a fingerprint — it uses the `--summary` check
|
|
401
|
+
above.
|
|
402
|
+
|
|
336
403
|
## Completion gate: handoff write, verification, and persistence
|
|
337
404
|
|
|
338
405
|
Write the phase-specific handoff:
|
|
@@ -368,7 +435,13 @@ cd -- "$LEGION_WORKSPACE" && \
|
|
|
368
435
|
Do not report phase completion until the write, existence check, and handoff commit
|
|
369
436
|
succeed; when an issue branch exists, its push is also required. This is the committed
|
|
370
437
|
copy the next phase reads after revival. It is removed once, at the end of a clean review: the
|
|
371
|
-
implementer pushes that deletion at the reviewer's direction. No other phase removes it
|
|
438
|
+
implementer pushes that deletion at the reviewer's direction. No other phase removes it — and
|
|
439
|
+
once it is gone (`jj -R "$LEGION_WORKSPACE" file list -r @- .legion` prints nothing on stdout;
|
|
440
|
+
jj warns on stderr), this
|
|
441
|
+
gate no longer applies: a later rebase, bare-gate re-check, confirmation, or retro writes no
|
|
442
|
+
`.legion/<phase>.json`, commits no handoff, and reports with `legion handoff complete` alone
|
|
443
|
+
(below). Recreating `.legion/` after its deletion changes the approved head and restarts the
|
|
444
|
+
review loop this rule exists to end.
|
|
372
445
|
|
|
373
446
|
## Completion: report to the architect, then stay
|
|
374
447
|
|