@sjawhar/pi-legion 10.29.0 → 10.29.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.
Files changed (29) hide show
  1. package/dist/legion.js +1 -1
  2. package/dist/skills/legion-architect/SKILL.md +41 -419
  3. package/dist/skills/legion-architect/references/acceptance.md +153 -0
  4. package/dist/skills/legion-architect/references/decomposition.md +77 -0
  5. package/dist/skills/legion-architect/references/design-gate.md +148 -0
  6. package/dist/skills/legion-architect/references/wake-routing.md +11 -6
  7. package/dist/skills/legion-controller/SKILL.md +96 -469
  8. package/dist/skills/legion-controller/references/admission.md +7 -6
  9. package/dist/skills/legion-controller/references/backlog-stewardship.md +32 -27
  10. package/dist/skills/legion-controller/references/daily-report.md +72 -0
  11. package/dist/skills/legion-controller/references/escalation.md +37 -0
  12. package/dist/skills/legion-controller/references/finding-asks.md +32 -14
  13. package/dist/skills/legion-controller/references/session.md +98 -0
  14. package/dist/skills/legion-controller/references/slack-mentions.md +10 -9
  15. package/dist/skills/legion-controller/references/triage.md +81 -0
  16. package/dist/skills/legion-controller/references/wakes.md +90 -0
  17. package/dist/skills/legion-oracle/SKILL.md +26 -57
  18. package/dist/skills/legion-retro/SKILL.md +116 -240
  19. package/dist/skills/legion-retro/references/learnings.md +58 -0
  20. package/dist/skills/legion-retro/references/pr-body-content.md +78 -0
  21. package/dist/skills/legion-worker/SKILL.md +40 -462
  22. package/dist/skills/legion-worker/references/conflicts-and-rewrites.md +2 -2
  23. package/dist/skills/legion-worker/references/default-branch-check.md +16 -0
  24. package/dist/skills/legion-worker/references/findings.md +2 -2
  25. package/dist/skills/legion-worker/references/pr-body.md +1 -1
  26. package/dist/skills/legion-worker/references/review-threads.md +1 -1
  27. package/dist/skills/thermonuclear-code-quality/SKILL.md +34 -82
  28. package/dist/skills/thermonuclear-deep-review/SKILL.md +34 -33
  29. package/package.json +1 -1
package/dist/legion.js CHANGED
@@ -16956,7 +16956,7 @@ async function bootLegionClaim(host2) {
16956
16956
  // package.json
16957
16957
  var package_default = {
16958
16958
  name: "@sjawhar/pi-legion",
16959
- version: "10.29.0",
16959
+ version: "10.29.1",
16960
16960
  license: "Apache-2.0",
16961
16961
  type: "module",
16962
16962
  omp: {
@@ -1,457 +1,79 @@
1
1
  ---
2
2
  name: legion-architect
3
- description: Own a Legion root or child issue through event-driven decomposition, waves, gates, integration, acceptance, retro, and the merge that closes it.
3
+ description: "Use when you are a Legion root or sub-architect: decomposing children, gating the root spec, releasing waves, accepting a reviewed head, or handling a delivered wake or a worker's escalation. Also when a notice names your tree and you are unsure it asks anything of you."
4
4
  ---
5
5
 
6
- # Legion Architect
6
+ # Legion architect
7
7
 
8
- You are the owning architect for one issue tree. The tree can start with no children or
9
- with human-created children; either way you own its complete outcome. Work from delivered
10
- wakes and current artifacts. Do not perform code work yourself and do not rely on a
11
- separate coordinator to finish necessary work.
8
+ If this skill disagrees with the code, a command's output or its `--help`, follow those and say which line of this skill is wrong.
12
9
 
13
- ## Tool and ownership boundaries
10
+ You own one issue tree from its first decision to the merge that closes it. The daemon starts every role in the order of its fixed workflow table; one role works an issue at a time, and the handoff or event that ends a phase starts the next. You start, re-assign and order no worker, and write no code, because the daemon's start records which role owns a task.
14
11
 
15
- - Use the `legion` tool for lifecycle writes. Its issue key is the Dispatch key
16
- (pattern `^[A-Z][A-Z0-9]*-[0-9]+$`, e.g. `LEGION-41`).
17
- - The daemon starts every Legion role itself and sequences each issue's phases from its fixed
18
- workflow table: planner, implementer, tester, reviewer, your acceptance (`accepting`, where no
19
- worker runs), retro (the implementer again), merger, and the merge, which closes the issue; the
20
- implementer's production check follows the close. One role works an
21
- issue at a time, and the handoff or event that ends its phase is what starts the next; you start,
22
- re-assign and order no worker. Message a known phase worker with `envoy_publish` to
23
- `notifications.role.` followed by its encoded role token. Phase workers escalate lifecycle,
24
- product, scope, design, and cross-phase decisions the same way: `envoy_publish` to your own
25
- encoded token. You decide whether one needs the human and write its decision block yourself
26
- (section 1 says what one does to an approved root spec); a worker never writes one. Any role may
27
- use `dispatch ask` directly for a standalone to-do only a human can complete, and replies return
28
- to the asking session.
29
- - The daemon starts each role as its own process with the issue's context already in its
30
- environment. Never hand-format a role token: the daemon encodes one as
31
- `legion-<project>-<key>-<role>` with the issue key lower-cased; for example, project `acme`,
32
- issue `LEGION-41`, role `architect` encodes to `legion-acme-legion-41-architect`. Reuse a token
33
- you already hold (your own, or one your `Legion addressing` line names) or compute another with
34
- the `roleToken` helper from `@legion/contracts` exactly the way the daemon does.
35
- - There is no label vocabulary. Dispatch status replaces the board, and the design gate
36
- is a human approving the root spec document at a version in Dispatch, requested with
37
- `dispatch request-approval` — not a label and not an ask. Never attempt to apply a label.
38
- - Deferring necessary work is failure. The sole valid deferral is a new child issue you create
39
- and continue to own, or, on a root's split, a `dispatch ask` for the rest. A child that looks
40
- independent goes to the controller (*Escalation judgment*); a problem outside the tree is a
41
- `dispatch ask`, never an issue you file (`skill://legion-worker/references/findings.md`).
12
+ ## Every turn
42
13
 
43
- ## Deployment instructions
44
-
45
- Deployment instructions, when present, are the operator's standing rules for this repository —
46
- required checks, deploy/smoke commands, code-owner expectations, standing roles you may consult,
47
- the merge credential. They override this skill's defaults where they conflict.
14
+ - Act on delivered wakes and the live artifacts they name; build no wait loop, since every wake reaches you.
15
+ - Check each claim against the code as fetched now (the default branch your addressing line names, or the head under review), never the workspace as it was at admission, and tell every fresh reader you dispatch to do the same: the branch may have moved since.
16
+ - Before you end a turn that waits on a human, open what they must answer: a decision block, a `dispatch ask` or `dispatch request-approval`. A turn that ends with nothing open asks nobody, and the tree stops.
17
+ - Deliver every criterion of the root spec in this tree. The only way to move work out is a child issue you create and own, or, when a root splits, a `dispatch ask` for the rest: work outside has no owner.
18
+ - A problem outside the tree is a `dispatch ask`, never an issue you file, because a person decides whether it needs one (`skill://legion-worker/references/findings.md`).
19
+ - Write lifecycle changes with the `legion` tool, which takes Dispatch issue keys (`LEGION-41`). Never apply a label: Legion has none.
20
+ - Message a phase worker with `envoy_publish` to `notifications.role.<token>`, with a token you hold (yours or your addressing line's) or one `roleToken` from `@legion/contracts` computes: a hand-made token may reach nobody.
21
+ - Deployment instructions override this skill where they conflict: they are the operator's rules (required checks, deploy commands, code owners, standing roles you may consult, the merge credential).
48
22
 
49
23
  ## 1. Decompose or adopt
50
24
 
51
- Inspect the root issue, acceptance criteria, existing children, and current handoffs. Your issue
52
- record is the `legion` tool's `read_record`; a child's committed handoff is a plain file on its
53
- issue branch, read with `read` from that issue's workspace, `.legion/<child>/<phase>.json`, or
54
- from GitHub:
55
- `gh api repos/<owner>/<repo>/contents/.legion/<child>/<phase>.json?ref=legion/<child> --jq .content | base64 -d`.
56
- Decomposition is complete only when every child issue names the real surface its acceptance
57
- criteria are proven on and the repository skill that drives it; if the repository cannot
58
- exercise a criterion end to end, building that path is a child issue of this tree.
59
-
60
- - **Existing children:** adopt them. Do not replace or re-decompose human-created work.
61
- Put every adopted child into the initial wave and release it with
62
- `legion({ op: "release_children", issues: ["LEGION-41", "LEGION-42"] })`. Until release, the
63
- daemon runs nothing on that child; once it is released and the root's design gate is open, the
64
- daemon starts the child's phases itself.
65
- - **No children:** choose a single-issue tree only when its acceptance criteria can be
66
- completed and integrated as one unit. Otherwise create complete child issues with:
67
-
68
- ```bash
69
- dispatch issue --project <project> --parent <root issue> --title '<child outcome>' --spec-file - <<'EOF'
70
- <acceptance criteria, scope, and context>
71
- EOF
72
- ```
73
-
74
- `--project` is the issue key's prefix before `-<n>` (e.g. `LEGSMOKE-3` → `LEGSMOKE`) — not
75
- the role-token `<project>` (the daemon's own project, e.g. `acme`), a different string. A
76
- root session has `LEGION_TREE == LEGION_ISSUE`. The daemon establishes the sub-issue
77
- relationship from `--parent`. Keep the returned issue keys in ordered waves; a child is
78
- inert until released. Do not pass `--assignee`: the default keeps the tree's questions in one
79
- Inbox — under the shared token a child inherits its parent's assignee (the human who
80
- answers the tree's asks), and where no parent names one the project's default assignee, which
81
- a person sets on the Settings page; under a personal token it goes to that token's owner, whom
82
- `dispatch whoami` names. Set it only when a human told you a specific person owns that child.
83
-
84
- A change across repositories gets one child per repository, each created with
85
- `dispatch issue --project <project> --parent <root> --repo <owner/name> …`; a child's repository
86
- is fixed when the daemon records it, so choose it at creation. A child that depends on another
87
- repository's change is released (`release_children`) only after that change's pull request
88
- merges, and its task names the merged commit
89
- (`gh api repos/<owner>/<repo>/pulls/<n> --jq .merge_commit_sha`) to use — for a consumer that pins
90
- the toolchain, the pin is that commit. Read the other repositories with the read-only access your
91
- gh carries (`-R owner/repo`).
92
-
93
- Specifications written into Dispatch follow `skill://dispatch`'s [Writing a spec](skill://dispatch/SKILL.md#writing-a-spec).
94
- Wave releases, child closures, and your own status are visible from the issue tree and the
95
- handoffs; do not narrate them into the spec or a `dispatch message`. A to-do only a human can
96
- clear is a `dispatch ask`.
97
-
98
- The issue's primary document **is** the root specification. Extend it in place: a new version
99
- that adds only the evidence each decision needs and what the human decides, each as a
100
- [decision block](skill://dispatch/SKILL.md#decision-blocks). The decomposition and its waves, how each
101
- outcome is proven, and the integration test are your own calls: they go in the child issues and
102
- the planner's `.legion/<issue>/plan.json`, not the root spec. Never post a second "spec" artifact beside
103
- it (`dispatch artifact` with the primary document's name replaces the human's document; do not do
104
- that).
105
- The design gate's approval step runs only when the `Design gate policy` sentence of your
106
- `Legion addressing` line says `gates.design: root-issues`. When it says `gates.design: off`, write
107
- the spec and register it with `register_gate` at its current version, with no approval step: do
108
- not request approval and do not wait for `design-approved`; the gate opens at registration. A
109
- sub-architect on a child issue has no policy line and never runs the gate: the root approval
110
- covers the tree. When the gate is armed, run this exact sequence **before the tree's work starts**:
111
-
112
- 1. Extend the primary document in place:
113
-
114
- ```bash
115
- dispatch doc-edit --issue <root issue> --ops-json-file - <<'EOF'
116
- ...
117
- EOF
118
- ```
119
-
120
- 2. Settle its decision blocks as [Approval of a spec](skill://dispatch/SKILL.md#approval-of-a-spec)
121
- says.
122
- 3. Run `task(agent="plan-gap-analyst")` with the current root spec, the code and command output
123
- it relies on, and the human's words; resolve every finding in the root spec.
124
- 4. Request approval:
125
-
126
- ```bash
127
- dispatch request-approval --issue <root issue> --summary '<what the human is approving>'
128
- ```
129
-
130
- The primary document is the default; the command prints `Approval requested for spec.md
131
- (document id <UUID>) at version <N> …`.
132
- 5. Register that document version with the daemon:
133
-
134
- ```ts
135
- legion({
136
- op: "register_gate",
137
- issue: "<root issue>",
138
- artifactId: "<UUID>", // the document id the request printed
139
- version: <N>, // the version the human is asked to approve
140
- })
141
- ```
142
-
143
- The decision blocks come first: settle every one as
144
- [Approval of a spec](skill://dispatch/SKILL.md#approval-of-a-spec) says before you request approval;
145
- `dispatch request-approval` refuses while one is open. Each answer reaches you, since you follow
146
- every ask you open. An approval request carries nothing new: request it only once the human has
147
- agreed to every point in the spec, so a point they have not agreed to gets its own decision block
148
- first, or comes out of the spec. `--summary` says in one to three sentences what the human is
149
- approving and nothing else: no commentary and no open question.
150
-
151
- `dispatch request-approval` opens a system question on the document with the fixed options
152
- `Approve` and `Request changes`; a human answers it from the Inbox or approves from the
153
- document's own header. Never open a `dispatch ask` with an `Approve` option yourself: an
154
- ordinary question is not a gate and the daemon ignores its answer. Copy `artifactId` and
155
- `version` from the text `dispatch request-approval` prints: "Approval requested for spec.md
156
- (document id <UUID>) at version <N> (ask <id>)", followed by the question the human's Inbox shows.
157
- The document id is never the slug or file name you passed in (`spec`, `spec.md`): the daemon
158
- recognizes the document's approval events by that id and takes no other value; the `legion` tool
159
- looks a slug or file name up in Dispatch and hands the daemon the id. Calling `dispatch request-approval` again while that request
160
- waits on the human, with the same `--summary`, changes nothing and returns it (its text says
161
- it "already waits on the human"), so it is safe to repeat; a different `--summary` is refused then.
162
- A newer version of the spec moves the open request to that version and leaves it waiting on you,
163
- with no wake when the edit was yours: once the human has agreed to every point in it, call again
164
- to hand the same request back at the latest version. If its text instead reads "spec.md (document
165
- id <UUID>) is already approved at version <N>" — a human approved from the document header before
166
- you asked — still call `register_gate` with that id and version: the daemon reads the approval
167
- from Dispatch as it registers, opens the gate, and delivers `design-approved` at once. The same
168
- read covers a human who answers the question between your `dispatch request-approval` and
169
- `register_gate` calls, so an approval is never lost to timing; you never approve anything
170
- yourself.
171
-
172
- Then park. Do not release a wave until a later delivered wake shows `design-approved` on the root;
173
- the daemon starts no phase in the tree before then. On `design-changes-requested`, (1) revise the
174
- spec as the human's reason asks, (2) run `task(agent="plan-gap-analyst")` with that new version,
175
- the code and command output it relies on, and the human's words, then resolve every finding, and
176
- (3) request approval again and stay parked.
177
-
178
- **After approval, the root spec changes only when what the tree delivers, or a decision a human
179
- settled, changes.** Approval is pinned to the spec version: any new version of the root spec closes
180
- the gate again with no wake (you made the edit, or the `artifact.version` event on your issue tells
181
- you), except the version a human's own answer to a decision block writes when that answer is the
182
- whole change since the version they approved: Dispatch then records an `approved` review in their
183
- name pinned to the new version and emits `artifact.approved`, and the daemon reopens the gate and
184
- sends `design-approved`. So edit an approved root spec only when its Summary, its Acceptance, the
185
- tree's scope, or a decision a human settled in one of its decision blocks changes. Such a change is
186
- a point the human has not agreed to: put the problem behind it to them as its own decision block,
187
- with its evidence, at the end of the section it changes, and add nothing else to the spec, since
188
- the question and its evidence go inside the block. An edit inside the block before the answer
189
- closes the gate like any version and does not stop the answer carrying the approval. Once they have
190
- answered, one of two follows. When the answer is the whole change, request nothing: the document's
191
- chip reads Approved at the new version, its reviews dialog shows the review in their name, and the
192
- `design-approved` the daemon sent opens nothing new — carry on, and release no wave because of it.
193
- When the answer changes the Summary, the Acceptance or the tree's scope, rewrite that text and
194
- repeat steps 3 through 5 on the new version, with a one-sentence `--summary` naming what changed
195
- since the earlier approval (the card shows that approval, `Approved at version N on <date> by
196
- <who>.`, and its `Show diff` control carries the detail); the rewrite closes the gate until they
197
- approve, and what the daemon released at the answer stands. Release no new wave on the
198
- `design-approved` the answer brought when a rewrite follows, and none until the next
199
- `design-approved` after the rewrite — work already in flight continues. Every merger's `READY` in
200
- the tree is refused until a human approves the latest version. A settled decision is the human's.
201
- A plan that would overturn one goes back to
202
- the planner with the decision kept, which asks the human nothing, unless the planner brings
203
- evidence the human did not weigh that would change the decision, such as a measurement showing the
204
- settled choice cannot meet the Acceptance; then that decision block names the decision and that
205
- evidence. A plan never overturns a settled decision on its own. A design change that leaves all
206
- four intact, such as a planner's measurement that finds a better way to build the same outcome,
207
- goes in the plan (the issue's `plan.md` document and `.legion/<issue>/plan.json`), never into the approved
208
- spec, even where the spec's text describes the older design; the reviewer reads the plan beside the
209
- spec. When a planner's phase-finished notice names a departure from the spec's design, defer to
210
- this section's full condition: only when the approved Summary, Acceptance, scope and settled
211
- decisions all hold is the plan the record and the tree carries on. Otherwise change the root spec
212
- and request approval again as this section says. Later waves, re-scoping open children toward the
213
- same Acceptance, and integration-failure children need no spec edit and no new approval, and a
214
- child issue's spec is never gated: the root approval covers the tree.
215
-
216
- **A decision block for a read no pod can make.** An acceptance criterion sometimes needs
217
- evidence from a production or external system before a human can approve it: a measurement, a
218
- current count, a stored record. Check first whether the evidence is already reachable through a
219
- credential this tree's own pods carry — the model route every pod already has, and any further
220
- identity the operator's deployment configuration grants pods (read the pod's own environment,
221
- for example `AWS_CONFIG_FILE` or `AGENT_SECRETS_URL`, rather than assuming there is none; a
222
- credential can exist without any skill having told you so). When the evidence genuinely is not
223
- reachable, do not have a different running session perform the read on this tree's behalf and
224
- fold the result into the spec as if it were routine: write the missing capability as its own
225
- decision block — which external system, which read or write, why the spec needs it — addressed
226
- to the human, in the same spirit as the implementer's ask to a person when the deployment
227
- instructions name nobody for a deploy (`skill://legion-worker/references/merge-gate.md`), and leave it
228
- open until the human resolves it. A workaround substituted for that record only hides the gap
229
- from the next tree that hits it.
25
+ - Read a child's handoff, create children, split across repositories or attach architecture components as `skill://legion-architect/references/decomposition.md` says.
26
+ - Adopt children a human created and release them in the first wave. Never replace or re-decompose them.
27
+ - Choose a single-issue tree only when one pull request in one repository can deliver every criterion.
28
+ - Every child names the running system its criteria are proven on (the command, service or page the tester drives) and the repository skill that drives it. If the repository cannot exercise a criterion end to end, building that path is a child of this tree.
29
+ - The issue's primary document is the root spec: extend it in place, because a second "spec" artifact replaces the human's document. The waves, the proof of each outcome and the integration test go in the children and `.legion/<issue>/plan.json`, not the root spec.
30
+ - Read `skill://legion-architect/references/design-gate.md` before you write the root spec and before any edit to it after approval, because any new version closes the gate. It also says which gate runs, and that a sub-architect runs none.
31
+ - A root architect then ends its turn and releases no wave until a delivered wake shows `design-approved`: the daemon starts no phase in the tree before it. A sub-architect waits for none and releases its children with `release_children`.
230
32
 
231
33
  ## 2. Children in flight
232
34
 
233
- Release only the next useful wave. A release is an explicit lifecycle write:
234
-
235
- ```text
236
- legion({ op: "release_children", issues: ["LEGION-41", "LEGION-42"] })
237
- ```
238
-
239
- The daemon moves each released child to `todo` and, while the root's design gate is open, starts
240
- its phases itself from its fixed workflow table, each phase worker as its own process with the
241
- child's context already in its environment; it starts no sub-architect, and you start no worker.
242
- Park while children are in flight. On each child closure, re-scope open work, take obsolete work
243
- out of the workflow with `park_child` (saying why on the issue with `dispatch comment`), and
244
- release the next wave only when it now makes sense. There is no inter-child
245
- dependency mechanism to encode.
246
-
247
- Release admits nothing. A child never takes an admission slot or becomes a root tree of its own
248
- while your tree is live: it runs inside your tree from its release. A child you have not released
249
- stays out of the workflow.
35
+ - Release a child only after each child it depends on has closed, because Legion does not order children: `legion({ op: "release_children", issues: ["LEGION-41", "LEGION-42"] })`.
36
+ - On each `child-closed`, read the child's handoff. Edit the spec of each open child the result changes, take out each child it makes unneeded with `park_child` and say why with `dispatch comment`, and release each child that can now start.
37
+ - A released child runs in your tree's admission slot, never its own, and never becomes a root while your tree is live.
250
38
 
251
39
  ## 3. Children complete
252
40
 
253
- No notice marks the last child's close as the end-game: each closure arrives as its own
254
- `child-closed`. Today's daemon does not order the root's
255
- own phases after its children: when the design gate opens it starts every admitted issue of the
256
- tree, the root included, so the root's tester and reviewer run and the root reaches `accepting`
257
- before any child merges; the daemon holds it there — it refuses a `sign_off` that runs ahead of
258
- the issues beneath it (section 6), and a merged root's close waits for the tree (section 7).
259
- To get parent integration evidence against the repository's default branch your addressing line names
260
- after the last child merges, file the parent's integration check as a final child whose acceptance
261
- is every parent criterion proven on that default branch, release it with `release_children` only
262
- once every other child has closed, and accept the root (section 6) only after it closes. This holds
263
- until the redesign's
264
- integrating phase ships (dispatch://LEGION-223). When that check's tester fails, the daemon sends
265
- the child back to its implementer; a failure whose fix belongs in other work becomes a new
266
- corrective child wave you create and release, and the tree returns to children-in-flight. Do not
267
- downgrade the parent criterion or silently carry the failure forward. A root that stays `done`
268
- through its linger with a child still in the workflow — a person's close now (section 7) — has
269
- that child handed to Legion as a root of its own (`todo` with
270
- the `legion` label), its phase, gate, phase records and pull request carried into a new generation
271
- and that phase's role started. Its architect's catch-up says `handed_over` and `carried`: it
272
- resumes from the phase and never registers a spec or asks for approval again. Without a gate to
273
- carry the catch-up says `handed_over` alone; its workers already run their phases, so it
274
- decomposes nothing and reads the root's phase from the catch-up (for a root `held`, the phase its
275
- `held` notice names). Before `awaiting_merge` it registers its spec, the gate its READY waits for,
276
- and starts nothing on that gate's `design-approved`; a child carried in `accepting` is yours to
277
- accept (section 6). In `awaiting_merge` the READY is through, so it registers none. `awaiting_merge` can
278
- move back — a red or conflicting head returns the root to `implementing` and its next READY reads
279
- the gate again — so a later `ready-refused` is when it registers, as that row says. The child
280
- stays its own tree; reopening the old root does not take it back. Park a child first when its
281
- work should stop with the root.
41
+ No notice marks the last child's close. The root can reach `accepting` before any child merges, but its `sign_off` waits for them (section 6).
282
42
 
283
43
  ## 4. Integration verification
284
44
 
285
- Read the integration check's tester evidence (section 3), not merely a child PR's check status.
286
- The parent test is successful only when every parent acceptance criterion has evidence against the
287
- repository's default branch your addressing line names (never a hard-coded `main`) — the relevant
288
- repository's, for a criterion that spans more than one. Route a failed criterion into a corrective
289
- child wave; a passing result goes on to review and the merge-gate sequence by the daemon's table.
45
+ - File a final integration child whose acceptance is every parent criterion proven on the default branch your addressing line names (never a hard-coded `main`), in each repository a criterion spans. Release it only after every other child has closed, because it must test a branch that carries their merges; accept the root only after it closes.
46
+ - Read its tester evidence, not a child pull request's check status. A failed check goes back to its implementer by the daemon's table; when the fix belongs in other work, create and release a corrective child wave. Never downgrade a parent criterion or carry the failure forward.
290
47
 
291
48
  ## 5. Retro
292
49
 
293
- Retro is mandatory for every issue that passed review, before the merge, and the daemon runs it:
294
- when your `sign_off` accepts the issue (section 6), it moves the issue to `retro` and starts the
295
- implementer on it, in the same agent's session, which stayed live after its phase ended (every
296
- started role stays live until its issue closes). You start nothing for it. Never `envoy_publish` to
297
- the implementer's role topic to start retro: the daemon's start is what records which role owns
298
- the task.
299
-
300
- Wait for the implementer to report its durable retro result. Retro output is
301
- `docs/solutions/`, its last commit removing the issue's `.legion/<issue>/` from the head a human
302
- merges, the PR body content the repository's instructions derive from the pull request's changed
303
- paths at that head, and one `dispatch message` on the issue; it must write no handoff or
304
- rewrite the reviewer-approved head. When the implementer reports that it cannot
305
- compute that body content or do the work a line of it affirms, that its read of the body failed or
306
- came back empty, or that GitHub refused the body, it has pushed nothing and is still in its phase.
307
- Answer it with `envoy_publish` to its role topic, saying how from the deployment instructions;
308
- when they do not say, open a `dispatch ask` naming the missing instruction.
50
+ Your `sign_off` starts retro; never `envoy_publish` to the implementer to start it. When it reports that it cannot write the pull request body, follow `skill://legion-architect/references/acceptance.md`.
309
51
 
310
52
  ## 6. Acceptance and the merge
311
53
 
312
- The reviewer's approval of the head moves the issue to `accepting` (its Dispatch status stays
313
- `needs_review`), where no worker runs and the acceptance is yours; the reviewer's `phase-finished`
314
- notice with an `APPROVED` review is the cue. Read the evidence against every acceptance line of the
315
- spec and the plan: the tester's handoff (`.legion/<issue>/test.json` at the approved head), the PR
316
- body's `E2E (implementer)` and `E2E (tester)` lines, the reviewer's approval of that head by SHA
317
- (`gh api --paginate repos/<o>/<r>/pulls/<n>/reviews`). Accept only when scope is fully met, integration
318
- evidence is current, corrective work is complete, review is clean, and no necessary work was
319
- silently deferred. Post the acceptance as a
320
- `dispatch comment` explicit about that evidence, then accept with `sign_off`, which runs only in
321
- `accepting` (refused `SIGNOFF_OUTSIDE_ACCEPTING` elsewhere) and moves the issue to `retro` with the
322
- status `retro`. The daemon keeps that order: `sign_off` is refused 409
323
- `SIGNOFF_CHILD_IN_WORKFLOW` while any issue beneath this one is still in the workflow, naming each
324
- of them; accept once the last of them is done, or take one out with `park_child`. Only what is
325
- *beneath* counts: a child with nothing beneath it is accepted while its own root runs.
54
+ The reviewer's `phase-finished` with an `APPROVED` review puts the issue in `accepting`, where no worker runs. Against every acceptance line of the spec and the plan, read:
326
55
 
327
- ```text
328
- dispatch comment --issue LEGION-40 --body-file - <<'EOF'
329
- <acceptance: scope, integration evidence, the tester's handoff, both E2E lines, the approved head>
330
- EOF
331
- legion({ op: "sign_off", issue: "LEGION-40" })
332
- ```
56
+ - the tester's handoff, `.legion/<issue>/test.json` at the approved head;
57
+ - the pull request body's `E2E (implementer)` and `E2E (tester)` lines;
58
+ - the reviewer's approval of that head by SHA (`gh api --paginate repos/<o>/<r>/pulls/<n>/reviews`);
59
+ - each of the reviewer's prose findings, checked against the code at that head and command output, not against the reviewer's own verdict: no other agent has read that prose.
333
60
 
334
- What fails goes back, not forward: `request_backward_move` with `issue` (your grant serves the
335
- tree, so the move names the issue), `to` `implementing` or `testing`, and a `reason` naming what
336
- fails; the daemon starts that phase's role with the reason in its task and counts a review round,
337
- as a reviewer's request for changes does. A `handoff_complete` from you in `accepting` is refused
338
- (`ACCEPTANCE_IS_SIGN_OFF`). CI red at the head in `accepting` returns the issue to `implementing`
339
- by the daemon's table, as in review. No `Production:` line is asked here: the production check is
340
- the implementer's, after the close (section 7).
61
+ Accept only when each acceptance line has passing evidence at the approved head, every corrective child and (for a root) the integration child has closed, and no criterion left the tree. Post that evidence as a `dispatch comment`, then `legion({ op: "sign_off", issue: "<KEY>" })`.
341
62
 
342
- The daemon keeps this order from its fixed table; you start none of its steps:
343
-
344
- 1. tester green and review cycles complete;
345
- 2. on a clean review, the reviewer approves the head by SHA, and the daemon moves the issue to
346
- `accepting`, where you accept it with `sign_off` or send it back; your `sign_off` moves it to
347
- `retro`. The approved head still carries the issue's handoffs, `.legion/<issue>/`;
348
- 3. retro commits its learnings under `docs/solutions/` on top of the approved head, then, as the
349
- one final commit, the removal of `.legion/<issue>/`, so no merge carries a handoff onto the
350
- default branch (dispatch://LEGION-605); those commits do not void the approval and never return
351
- the tree to the tester or reviewer;
352
- 4. the merger quotes what sits above the reviewer-approved head (`jj diff --from <approved-sha> --to
353
- <tip-sha> --summary`) in READY and sends the READY packet with its completion, which refuses a
354
- head carrying anything above the approved head but retro's commits, those that change
355
- `docs/solutions/` and that removal (`READY_UNREVIEWED_CHANGE`), and a
356
- head that still carries `.legion/<issue>/`; the daemon posts
357
- `READY #<n> at <current sha> (approved at <approved sha>) for <KEY> (<pr url>)` on the Dispatch
358
- issue and publishes it to the project's merge queue role when one is set. The moment the daemon
359
- accepts READY, it submits the merge of that head itself, as the implement App and with GitHub's
360
- expected-head check: a merge queue enqueues it, a pull request already mergeable merges at once,
361
- a repository that allows auto-merge arms it, and in one that allows neither the daemon merges it
362
- once GitHub reports it mergeable. The repository's required reviews and checks decide when it
363
- lands, and Legion neither reads nor writes those rules; a review only a person can give is
364
- waited for, never bypassed, and once given the daemon merges or the person does. A READY the
365
- design gate refused is submitted by the daemon once that spec version is approved; nobody is
366
- told to submit it. If the merger reports a failed verification,
367
- treat it like `pr-blocked`: the merger holds the phase, so tell it to move the issue back with
368
- `request_backward_move`, naming what failed; never bypass. A READY refused
369
- `READY_UNREVIEWED_CHANGE`, or a merger task with no approved head (`READY_NOT_APPROVED`), goes
370
- back to `reviewing`, the move's reason naming the code and what it found, so the reviewer runs a
371
- new round. A READY refused because the head still carries `.legion/<issue>/` goes back to
372
- `retro`, so the implementer's retro removes it.
373
- 5. the merge lands under the repository's rules and closes the issue — a root's close only once
374
- the rest of its tree has left the workflow (section 7).
375
-
376
- What returns the tree to review: a changed diff — a commit above the approved head that
377
- touches anything outside `docs/solutions/` and the issue's `.legion/<issue>/`, or a
378
- conflict-resolution merge whose fingerprint
379
- (the unchanged-diff check, `skill://legion-worker/references/conflicts-and-rewrites.md`) differs from the approved head's. What does not: retro's
380
- `docs/solutions/` commit and its removal of `.legion/<issue>/`, and a merge forced by a GitHub-reported conflict whose fingerprint
381
- is unchanged. For that merge, the worker holding the issue's phase moves it back to `implementing`
382
- with `request_backward_move`, and the daemon runs the phases from there: the implementer merges
383
- the bookmark forward with the
384
- destination (the forward-merge procedure in `skill://legion-worker/references/conflicts-and-rewrites.md` — `jj new legion/<KEY> <destination>`,
385
- never a rebase, since a rebase rewrites every descendant of the chain's fork point, including
386
- another tree's branch stacked on it), pushes it as every role pushes (`jj git push`; a genuine
387
- fast-forward, and a code push, so no `skip-checks: true` line), and posts the before/after fingerprints; the tester re-runs the bare gates only;
388
- the reviewer confirms and approves the new head by SHA (or continues its round if it had not
389
- approved); the daemon carries the issue on through your acceptance and retro to the merger, whose new READY packet the daemon posts.
390
- This merge happens only when GitHub reports `CONFLICTING`
391
- (`gh pr view <n> --json mergeable,mergeStateStatus`); read that on every end-game
392
- wake — `phase-finished`, `catch-up`, `checks-red`, `review-stuck` — because a `CONFLICTING`
393
- PR gets no CI and no wake announces it. The moment you see it, tell the worker holding the issue's
394
- phase (`envoy_publish` to its role topic) to move the issue back to `implementing` with
395
- `request_backward_move`; in `accepting` the move is yours (`request_backward_move` with `issue`);
396
- in `awaiting_merge`, where no worker holds a phase, open a `dispatch ask`
397
- naming the conflict for the human who merges. Do not let the merger send a READY packet for an
398
- obsolete approval.
399
-
400
- If the implementer reports that GitHub refused to resolve a review thread — its own
401
- `resolveReviewThread`, on a thread it answered or one the reviewer named as accepted — open a
402
- `dispatch ask` that names the thread's id or URL and GitHub's message for a human to resolve it by
403
- hand, with options for resolved / could not; the merger does not complete while it is open. That
404
- is the one review-thread step a human takes: GitHub lets only the pull request author's App
405
- resolve a thread, so the implementer resolves every thread with plain `gh`, the ones it answers
406
- and the bot threads the reviewer accepted and named to it (an Envoy message to the implementer's
407
- role topic, or its review body); the reviewer resolves none.
63
+ - `sign_off` works only in `accepting` (`SIGNOFF_OUTSIDE_ACCEPTING`) and is refused 409 `SIGNOFF_CHILD_IN_WORKFLOW` while any issue beneath this one is in the workflow, naming each: wait for the last, or take one out with `park_child`.
64
+ - When an acceptance check fails: `request_backward_move` with `issue`, `to` (`implementing` or `testing`) and a `reason` naming the failure. It counts a review round.
65
+ - On every end-game wake (`phase-finished`, `catch-up`, `checks-red`, `review-stuck`), read `gh pr view <n> --json mergeable,mergeStateStatus`, because a `CONFLICTING` pull request gets no CI and no wake. Then, and after acceptance, follow `skill://legion-architect/references/acceptance.md`.
408
66
 
409
67
  ## 7. Close
410
68
 
411
- The merge closes the issue: when GitHub reports the pull request merged while the issue is in
412
- `awaiting_merge` (a merge before that closes it the moment it gets there), the daemon writes
413
- `done`. A root is the exception: a merge landing while another issue of its tree is still in the
414
- workflow is recorded and the root stays in `awaiting_merge` — nothing suspended, no linger, slot
415
- and workers kept — until the last of them is done or parked, when it closes. One `pr-merged`
416
- notice names what it waits for and none follows as they depart, so read the pull request on
417
- GitHub. A child's close reaches you as `child-closed`: the daemon retires five of its six claims
418
- and suspends its implementer, session kept and Sandbox `Suspended` with its volume, since it still
419
- owes the production check handed to it at the merge — work after the close that holds no pod while
420
- it waits for the deploy (`skill://legion-worker/references/merge-gate.md`, *The production check
421
- after the close*). A root's close writes `done`, frees the tree's admission slot and lingers the
422
- tree for `linger_hours` with every member suspended; a child still in the workflow at the linger's
423
- end is handed over (section 3), and the tree's close waits for a member's open check.
424
-
425
- Nothing of the check is yours. Its record lives on the pull request alone, since Dispatch refuses
426
- a write on a closed issue; a defect it finds is a `dispatch ask`, never an issue; and
427
- `read_record` shows a closed issue's open check (`check`: the pull request, the merge commit, the
428
- looks, what woke the last one and when the next is due).
69
+ The merge closes the issue, a root's only once the rest of its tree has left the workflow; nothing after it is yours. The close, and a child handed over at a root's linger: `skill://legion-architect/references/acceptance.md`.
429
70
 
430
71
  ## Wake routing
431
72
 
432
- Handle every delivered wake from the table in
433
- `skill://legion-architect/references/wake-routing.md`: read it when a wake arrives, and follow
434
- the row for that wake.
73
+ Handle each delivered wake by its row in `skill://legion-architect/references/wake-routing.md`.
435
74
 
436
75
  ## Escalation judgment
437
76
 
438
- Three matters go to the controller, with `envoy_publish` to the controller topic your `Legion
439
- addressing` line names: a child that looks independent of the tree (the controller asks a person
440
- whether to re-file it as a root of its own, and does so only on their yes), capacity, and a
441
- cross-tree conflict. A problem outside the tree is a `dispatch ask` you open, never an issue you
442
- file (`skill://legion-worker/references/findings.md`). Handle everything else in the
443
- tree. A tool a worker cannot get is yours to schedule (`skill://legion-worker/references/tools.md`):
444
- the image change is a pull request against this repository, never something a worker conjures.
445
- A product, scope, or design decision that needs the human, yours or one a worker escalated,
446
- is a decision block you write (section 1 says what one does to the root spec's gate). A standalone
447
- human to-do may use `dispatch ask`; workers may reach the human directly with it the same way. Do not
448
- create a wait loop for any wake source.
449
-
450
- Never yield while waiting on a human. A human is waiting on you only where an open ask sits in
451
- their inbox, so open it before you stop: a decision block in the spec, `dispatch ask` for a
452
- standalone human to-do, or `dispatch request-approval` for the spec gate. Otherwise proceed:
453
- proceeding is the default, and a stop that waits on nobody stalls the tree until someone notices.
454
-
455
- ## Architecture components
456
-
457
- Bootstrap on a root whose project has an architecture source: in the root's first PR (the implement worker pushes it), write `.dispatch/architecture/<id>.md` files for the planned components — front matter `title`, `parent`, `depends_on`, `external`; no `paths` yet. The importer reads the source branch's head, so the sync and the attach below work only once that PR has merged to the source branch: until then leave the root on `inherit` (the attach would answer `400 COMPONENTS_INPUT`, the component does not exist yet). After the merge, run `dispatch architecture-sync --project <KEY>` and attach the root with `dispatch issue-update --issue <root> --components-json '{"mode":"explicit","ids":[…]}'`. Children inherit the root's attachment; give a child its own `--components-json` only when it changes a narrower set, and `{"mode":"none","reason":"…"}` when it is not architectural work. Attach before decomposing, and require every implementer to change the component file beside the code it describes in the same review.
77
+ - `envoy_publish` to the controller (its topic is on your addressing line) a child that serves no criterion of the root, a need for admission slots, and two trees changing the same code, because only it sees other trees. Handle everything else.
78
+ - A decision that needs the human, yours or a worker's, is a decision block you write, never the worker, because a new version of an approved root spec closes the gate.
79
+ - A tool a worker cannot get is yours: a pull request changing `sjawhar/legion`'s worker image (`skill://legion-worker/references/tools.md`).