@sjawhar/pi-legion 10.28.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.
- package/dist/legion.js +1 -1
- package/dist/skills/legion-architect/SKILL.md +41 -419
- package/dist/skills/legion-architect/references/acceptance.md +153 -0
- package/dist/skills/legion-architect/references/decomposition.md +77 -0
- package/dist/skills/legion-architect/references/design-gate.md +148 -0
- package/dist/skills/legion-architect/references/wake-routing.md +11 -6
- package/dist/skills/legion-controller/SKILL.md +96 -469
- package/dist/skills/legion-controller/references/admission.md +7 -6
- package/dist/skills/legion-controller/references/backlog-stewardship.md +32 -27
- package/dist/skills/legion-controller/references/daily-report.md +72 -0
- package/dist/skills/legion-controller/references/escalation.md +37 -0
- package/dist/skills/legion-controller/references/finding-asks.md +32 -14
- package/dist/skills/legion-controller/references/session.md +98 -0
- package/dist/skills/legion-controller/references/slack-mentions.md +10 -9
- package/dist/skills/legion-controller/references/triage.md +81 -0
- package/dist/skills/legion-controller/references/wakes.md +90 -0
- package/dist/skills/legion-oracle/SKILL.md +26 -57
- package/dist/skills/legion-retro/SKILL.md +116 -240
- package/dist/skills/legion-retro/references/learnings.md +58 -0
- package/dist/skills/legion-retro/references/pr-body-content.md +78 -0
- package/dist/skills/legion-worker/SKILL.md +40 -462
- package/dist/skills/legion-worker/references/conflicts-and-rewrites.md +2 -2
- package/dist/skills/legion-worker/references/default-branch-check.md +16 -0
- package/dist/skills/legion-worker/references/findings.md +2 -2
- package/dist/skills/legion-worker/references/pr-body.md +1 -1
- package/dist/skills/legion-worker/references/review-threads.md +1 -1
- package/dist/skills/legion-worker/references/tools.md +7 -11
- package/dist/skills/thermonuclear-code-quality/SKILL.md +34 -82
- package/dist/skills/thermonuclear-deep-review/SKILL.md +34 -33
- 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.
|
|
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:
|
|
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
|
|
6
|
+
# Legion architect
|
|
7
7
|
|
|
8
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
the
|
|
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
|
-
|
|
52
|
-
|
|
53
|
-
issue
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
|
234
|
-
|
|
235
|
-
|
|
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
|
|
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
|
-
|
|
286
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
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
|
-
|
|
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
|
-
|
|
343
|
-
|
|
344
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
439
|
-
|
|
440
|
-
|
|
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`).
|