@sjawhar/opencode-legion-envoy 8.30.0 → 8.30.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/skills/envoy/SKILL.md +47 -286
- package/skills/envoy/references/check-settlement.md +62 -0
- package/skills/envoy/references/deliveries.md +62 -0
- package/skills/envoy/references/legion.md +12 -0
- package/skills/envoy/references/roles.md +10 -0
- package/skills/envoy/references/sources.md +41 -0
- package/skills/legion-architect/SKILL.md +41 -419
- package/skills/legion-architect/references/acceptance.md +153 -0
- package/skills/legion-architect/references/decomposition.md +77 -0
- package/skills/legion-architect/references/design-gate.md +148 -0
- package/skills/legion-architect/references/wake-routing.md +11 -6
- package/skills/legion-controller/SKILL.md +96 -469
- package/skills/legion-controller/references/admission.md +7 -6
- package/skills/legion-controller/references/backlog-stewardship.md +32 -27
- package/skills/legion-controller/references/daily-report.md +72 -0
- package/skills/legion-controller/references/escalation.md +37 -0
- package/skills/legion-controller/references/finding-asks.md +32 -14
- package/skills/legion-controller/references/session.md +98 -0
- package/skills/legion-controller/references/slack-mentions.md +10 -9
- package/skills/legion-controller/references/triage.md +81 -0
- package/skills/legion-controller/references/wakes.md +90 -0
- package/skills/legion-oracle/SKILL.md +26 -57
- package/skills/legion-retro/SKILL.md +116 -240
- package/skills/legion-retro/references/learnings.md +58 -0
- package/skills/legion-retro/references/pr-body-content.md +78 -0
- package/skills/legion-worker/SKILL.md +40 -462
- package/skills/legion-worker/references/conflicts-and-rewrites.md +2 -2
- package/skills/legion-worker/references/default-branch-check.md +16 -0
- package/skills/legion-worker/references/findings.md +2 -2
- package/skills/legion-worker/references/pr-body.md +1 -1
- package/skills/legion-worker/references/review-threads.md +1 -1
- package/skills/thermonuclear-code-quality/SKILL.md +34 -82
- package/skills/thermonuclear-deep-review/SKILL.md +34 -33
|
@@ -5,481 +5,59 @@ description: Use when dispatched as a per-process Legion phase worker — planne
|
|
|
5
5
|
|
|
6
6
|
# Legion Phase Worker
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
`task`-spawned subagent and not a pipeline coordinator. The architect owns the tree; each
|
|
10
|
-
phase gets its own long-lived process against the same jj workspace, run in turn. Complete
|
|
11
|
-
the phase assigned to you, report its completion to the architect, and leave the durable
|
|
12
|
-
copy the next phase can trust.
|
|
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.
|
|
13
9
|
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
You work one phase of one issue in a jj workspace every role of the issue shares; the architect owns the tree. Your role prompt gives the workspace binding, `gh`, the push, the handoff file, `handoff_complete` and how long your session stays; this skill adds the rest.
|
|
11
|
+
|
|
12
|
+
## Every phase, in this order
|
|
13
|
+
|
|
14
|
+
1. **Read first.** Read the issue, then each committed handoff before your phase, with `read` from `$LEGION_WORKSPACE/.legion/<issue>/`, in order: `plan.json`, `implement.json`, `test.json`, `review.json`. Where one disagrees with your memory or a transcript, the file wins: it is the copy that survived. At each later assignment read them again, your own included, since other phases may have committed since. After a `Your workspace was recreated…` message, read `.legion/<issue>/workspace-recovered.json` too, once.
|
|
15
|
+
2. **Commit only your phase's work**, with `jj -R "$LEGION_WORKSPACE" split -m "<message>" <paths…>`, each commit holding only your phase's paths, so the next phase sees what you changed.
|
|
16
|
+
3. **Put back what you copied in.** Before you write the handoff, run `jj -R "$LEGION_WORKSPACE" status` and remove or restore every file you copied or fetched in that is not your phase's work, such as another branch's test rig. With jj the working copy is the commit: the next role's first commit builds on what you left, and its push ships it.
|
|
17
|
+
4. **Write the handoff** your role prompt names. Each `proof` entry, the implementer's or the tester's, is an object of six non-empty strings: `criterion` (the acceptance line it proves), `surface` (where a user reaches the change), `command`, `observed`, `headSha` (the commit it ran at) and `negativeControl` (a deliberately broken input and the refusal seen); `skill://legion-worker/references/pr-body.md#what-a-proof-is` defines each. To add to a handoff already on disk, `read` it, edit it, and `write` it whole with `completed` set to now.
|
|
18
|
+
5. **Push, then complete**, as the push section below says. `handoff_complete` is your only way to end a phase: add no label, keep no status of your own and run no loop of your own, since the daemon owns the issue's state and the architect its decomposition and gates.
|
|
19
|
+
|
|
20
|
+
## Stop rules
|
|
21
|
+
|
|
22
|
+
- **A refused completion is information, not a retry loop.** Quote the answer verbatim to the architect, so "my work is lost" and "my work belongs to an ended run" read differently. `HANDOFF_STALE_GENERATION` (the issue is on a newer run, or your turn began before the daemon recorded your task, which it then sends again) or `HANDOFF_NO_RUN` (your claim holds no task): push nothing further and tell the architect; when a task then arrives whose work is already committed, call `handoff_complete` again, and never redo the work or write a second handoff. `HANDOFF_NOT_CURRENT_PHASE`: the issue left your phase; report, never complete again. `HANDOFF_ALREADY_RECORDED`: the first answer stands, an acceptance or one of the four refusals the daemon records (`HANDOFF_STALE_GENERATION`, `HANDOFF_NOT_CURRENT_PHASE`, `READY_REQUIRED`, `HANDOFF_NOT_NEW`); if you did not see it, tell the architect. A refusal given before any fact is applied (READY's checks of the head among them) records nothing, so the corrected call at the same commit is applied. A reminder is not a task: after an accepted completion, a second call is refused.
|
|
23
|
+
- **After your phase completes, the workspace is read-only for you**: no commit, no `jj new`, no edit to a tracked file, in any later turn until a new task names your phase. The active phase owns it, and you stay live only to answer questions.
|
|
24
|
+
- **Never start another Legion role**: the daemon starts every phase worker.
|
|
25
|
+
- **Never end your turn blocked on a decision someone else owns.** Send a product, scope, design, lifecycle or cross-phase decision to the owning architect as your role prompt says, with the issue, phase, verified observation, what you tried and the decision needed; a human-only to-do is a `dispatch ask`. Otherwise proceed: a phase that stops silently holds its issue until someone notices.
|
|
26
|
+
- **No surface reaches the changed path** is a report to the architect, never a reason to complete (`skill://legion-worker/references/pr-body.md#when-no-surface-reaches-the-changed-path`).
|
|
27
|
+
- **Asking another role**: if its topic answers 404, read its committed handoff instead.
|
|
16
28
|
|
|
17
29
|
## References
|
|
18
30
|
|
|
19
|
-
|
|
20
|
-
with the `read` tool: a read by filesystem path stops at 300 lines.
|
|
31
|
+
Read each by its `skill://` link: a read by path stops at 300 lines.
|
|
21
32
|
|
|
22
33
|
| When | Read |
|
|
23
34
|
| --- | --- |
|
|
24
|
-
| You write or edit the PR body, record
|
|
25
|
-
| Before a push, to check your commits' App identity
|
|
26
|
-
| You reply on or resolve
|
|
27
|
-
|
|
|
28
|
-
| You write the `skip-checks: true` trailer
|
|
29
|
-
| You review or approve, build
|
|
35
|
+
| You write or edit the PR body, record or verify a proof, or run the simplify pass | `skill://legion-worker/references/pr-body.md` |
|
|
36
|
+
| Before a push, to check your commits' App identity | `skill://legion-worker/references/default-branch-check.md` |
|
|
37
|
+
| You reply on, list or resolve review threads, or judge a bot's finding | `skill://legion-worker/references/review-threads.md` |
|
|
38
|
+
| A conflict, a retarget, comparing heads after a conflict merge, or rewriting a pushed commit | `skill://legion-worker/references/conflicts-and-rewrites.md` |
|
|
39
|
+
| You write the `skip-checks: true` trailer, or expect a body edit to re-run a check | `skill://legion-worker/references/skip-checks-trailer.md` |
|
|
40
|
+
| You review or approve, build READY, or run the production check | `skill://legion-worker/references/merge-gate.md` |
|
|
30
41
|
| The issue renames a repository, package, or URL across the codebase | `skill://legion-worker/references/systematic-rename.md` |
|
|
31
42
|
| The issue deletes code, a command, or documentation | `skill://legion-worker/references/cleanup-deletion.md` |
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
35
|
-
## Identity, scope, and role
|
|
36
|
-
|
|
37
|
-
The daemon spawns you as a separate `omp --mode rpc` process (behind `legion worker-shim`,
|
|
38
|
-
in a tmux pane or an Agent Sandbox pod) with `LEGION_TREE`, `LEGION_ISSUE`, `LEGION_ROLE`,
|
|
39
|
-
`LEGION_GENERATION`, `LEGION_PROJECT`, `LEGION_BOOT_TOKEN_FILE` (the file holding your boot
|
|
40
|
-
token; the extension reads it for you), `LEGION_DAEMON_URL`, `LEGION_STATE_DIR`, and
|
|
41
|
-
`LEGION_WORKSPACE` in your environment. The extension completes the boot handshake for you at
|
|
42
|
-
session start — it registers with the daemon, claims your role, and signals readiness. You never
|
|
43
|
-
call `envoy_role_set` yourself.
|
|
44
|
-
|
|
45
|
-
Your role token is not the issue key spelled out literally. The daemon encodes it as
|
|
46
|
-
`legion-<project>-<key>-<role>` with the issue key lower-cased. For example, project `acme`, issue
|
|
47
|
-
`LEGION-41`, role `architect` encodes to `legion-acme-legion-41-architect`. Never hand-format one for another role: your own role
|
|
48
|
-
topic and the topic of the architect that owns your issue are in the `Legion addressing` line of
|
|
49
|
-
your system prompt (the daemon appends it; it names the tree root's architect, also on a child
|
|
50
|
-
issue), a sibling role's topic is yours with the trailing `-<role>` replaced, and the `roleToken`
|
|
51
|
-
helper in `@legion/contracts` computes any other one exactly the way the daemon does — prefer a
|
|
52
|
-
topic you've already been given before recomputing one.
|
|
53
|
-
|
|
54
|
-
If the handshake fails (a rejected boot token, or a bootstrap failure after your role
|
|
55
|
-
registered), the extension logs it and exits the process outright — it does not retry, and
|
|
56
|
-
you do not troubleshoot it by hand. The daemon resumes this same session from its recorded
|
|
57
|
-
session file the next time this role is needed; that is not an instant automatic respawn.
|
|
58
|
-
|
|
59
|
-
Once ready, your assignment arrives as the first prompt in your session — you do not fetch
|
|
60
|
-
it. Read the current issue and its acceptance criteria before changing the workspace. Work
|
|
61
|
-
only on this phase's artifact.
|
|
62
|
-
|
|
63
|
-
You never start another Legion role: the daemon starts every phase worker itself, from its fixed
|
|
64
|
-
workflow table. You may still use ordinary `task` subagents for your own phase work; none of them
|
|
65
|
-
is a Legion role. A subagent runs in your pane as you, with every host tool but the `legion` tool
|
|
66
|
-
(it is never offered one), so completing your phase is yours alone: give a subagent no completion
|
|
67
|
-
step. Escalate a product, scope, design, cross-phase, or lifecycle decision to the owning architect
|
|
68
|
-
with `envoy_publish` to its role topic (`notifications.role.` followed by its encoded token, see
|
|
69
|
-
above), carrying the verified facts and the decision needed. A `write` to `agent://` only reaches
|
|
70
|
-
agents inside your own process, not the architect's separate one. Never write a decision block
|
|
71
|
-
into a spec yourself: the architect decides whether the human must answer it and writes the block,
|
|
72
|
-
since a new version of an approved root spec closes the tree's design gate. A standalone to-do
|
|
73
|
-
only a human can do is a `dispatch ask`, and its replies return to your own session. So is a
|
|
74
|
-
problem outside your tree, never an issue you file: `skill://legion-worker/references/findings.md`.
|
|
75
|
-
|
|
76
|
-
Because the same agent works its role until the issue closes, you may receive more than one
|
|
77
|
-
assignment across your lifetime: your session stays live after your phase ends, and when a later
|
|
78
|
-
event (a review round, a red check) starts your role again the new prompt arrives in this same
|
|
79
|
-
session. Treat it as a continuation — re-read the current issue and your own prior handoff, since
|
|
80
|
-
time has passed — never as a fresh identity.
|
|
81
|
-
|
|
82
|
-
## Deployment instructions
|
|
83
|
-
|
|
84
|
-
Deployment instructions, when present, are the operator's standing rules for this repository —
|
|
85
|
-
required checks, deploy/smoke commands, code-owner expectations, standing roles you may consult,
|
|
86
|
-
the merge credential. They override this skill's defaults where they conflict, except four rules
|
|
87
|
-
they never override: no deferrals (*PR body, review, and the merge gate*, below); bringing the base
|
|
88
|
-
into the branch only on a real conflict or a retarget
|
|
89
|
-
(`skill://legion-worker/references/conflicts-and-rewrites.md#reintegrating-the-base`); the
|
|
90
|
-
implementer's own proof on a production-like surface at the head that merges, an applied simplify
|
|
91
|
-
head included (`skill://legion-worker/references/pr-body.md#what-a-proof-is`,
|
|
92
|
-
`skill://legion-worker/references/pr-body.md#the-rules-every-phases-evidence-follows`); and the
|
|
93
|
-
implementer's production check after the merge closes the issue
|
|
94
|
-
(`skill://legion-worker/references/merge-gate.md#the-production-check-after-the-close`).
|
|
95
|
-
|
|
96
|
-
## Asking another role
|
|
97
|
-
|
|
98
|
-
Reach any live role on this issue the same way you reach the architect: `envoy_publish` to
|
|
99
|
-
`notifications.role.` followed by that role's encoded token. Use it when you need context an
|
|
100
|
-
earlier phase has that its handoff doesn't cover — ask the planner why a constraint was
|
|
101
|
-
scoped that way, ask the implementer what a commit actually did. A role that finished its phase
|
|
102
|
-
stays live and answers until its issue leaves the workflow. If a publish is rejected with 404,
|
|
103
|
-
read that role's committed handoff.
|
|
104
|
-
|
|
105
|
-
## Workspace and handoff precedence
|
|
106
|
-
|
|
107
|
-
`LEGION_WORKSPACE` is the authoritative issue workspace. Before reading repository files or
|
|
108
|
-
handoffs, you **MUST** bind to that exact path with:
|
|
109
|
-
|
|
110
|
-
```bash
|
|
111
|
-
cd -- "$LEGION_WORKSPACE" && jj -R "$LEGION_WORKSPACE" status
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
Never rely on the inherited cwd. Every later repository shell command **MUST** begin
|
|
115
|
-
`cd -- "$LEGION_WORKSPACE" &&`; every jj command **MUST** use `-R "$LEGION_WORKSPACE"`; and
|
|
116
|
-
native filesystem tool paths **MUST** be absolute under that workspace. Do not create an
|
|
117
|
-
isolated worktree, change the workspace topology, or mix another issue's work into it.
|
|
118
|
-
Concurrent issues have disjoint workspaces; only the currently active phase mutates this
|
|
119
|
-
one. After you complete and go idle, treat `$LEGION_WORKSPACE` as read-only in every later
|
|
120
|
-
turn, including one an Envoy question starts: you are kept alive to answer questions, not to keep
|
|
121
|
-
editing. Do not create new commits, run `jj -R "$LEGION_WORKSPACE" new`, or touch tracked files
|
|
122
|
-
once your own handoff is committed and pushed — a code change belongs to
|
|
123
|
-
whichever phase is active now. The same holds once the Go daemon has taken your phase back without
|
|
124
|
-
your completion: CI settling red while you tested, reviewed a round you had not completed, or
|
|
125
|
-
built READY, moves the issue to `implementing` and interrupts your turn, and the implementer starts
|
|
126
|
-
only once that turn has ended. Do not resume the interrupted work afterward. From retro the
|
|
127
|
-
issue moves the same way with nothing interrupted: you are the implementer, handed the implementing
|
|
128
|
-
task once your turn ends; a retro completion started after the move is refused, and one in flight
|
|
129
|
-
when the red lands can be taken as your implementing completion, caught by the tester's CI read.
|
|
130
|
-
|
|
131
|
-
On every start, and especially after revival or re-creation, read the issue and then the
|
|
132
|
-
committed predecessor handoffs in lifecycle order, with the `read` tool from
|
|
133
|
-
`$LEGION_WORKSPACE/.legion/<issue>/`:
|
|
134
|
-
|
|
135
|
-
1. `plan.json`
|
|
136
|
-
2. `implement.json`
|
|
137
|
-
3. `test.json`
|
|
138
|
-
4. `review.json`
|
|
139
|
-
|
|
140
|
-
Read only files that precede the assigned phase. Each was checked against its phase's rules when
|
|
141
|
-
its phase completed (the completion gate below): fields the phase does not declare passed untouched
|
|
142
|
-
and reach the next worker. Write the phase-specific fields the next phase and the architect need,
|
|
143
|
-
consistent with what predecessor phases already wrote. The durable copy lives in
|
|
144
|
-
`$LEGION_WORKSPACE/.legion/<issue>/<phase>.json`. If a committed handoff conflicts with memory or a
|
|
145
|
-
prior transcript, the committed file wins: it is the copy that survived.
|
|
146
|
-
|
|
147
|
-
If your task, prompt, or a message since your last turn begins `Your workspace was recreated…`, read
|
|
148
|
-
your phase's committed handoff and any `.legion/<issue>/workspace-recovered.json`, and reconcile
|
|
149
|
-
before new work: anything unpushed is gone. That message stays in history; reconciled, it is done.
|
|
150
|
-
|
|
151
|
-
## Phase work
|
|
152
|
-
|
|
153
|
-
Specifications written into Dispatch follow `skill://dispatch`'s [Writing a spec](skill://dispatch/SKILL.md#writing-a-spec), except that a phase worker writes no decision block: it sends an open product, scope or design decision to its architect, which writes the block.
|
|
154
|
-
|
|
155
|
-
Follow the repository's normal engineering workflow and the assigned issue's acceptance
|
|
156
|
-
criteria. Your phase's own charter and the predecessor handoffs you read define the phase
|
|
157
|
-
artifact and its completion evidence. Do not replace architect-owned decomposition, gate
|
|
158
|
-
discipline, scheduling, or human communication with labels or a local status model.
|
|
159
|
-
An issue that renames a repository, package, or URL across the codebase also follows
|
|
160
|
-
`skill://legion-worker/references/systematic-rename.md`; one that deletes code, a command, or
|
|
161
|
-
documentation follows `skill://legion-worker/references/cleanup-deletion.md`.
|
|
162
|
-
|
|
163
|
-
Create reviewable commits with `jj -R "$LEGION_WORKSPACE" split -m "<message>" <paths…>`, each holding only your phase's paths.
|
|
164
|
-
|
|
165
|
-
Commit attribution is automatic: the extension exports a `JJ_CONFIG` overlay when your
|
|
166
|
-
session starts, so every jj commit you make carries an `Omp-Session: <this-session-id>`
|
|
167
|
-
trailer with no action from you. Do not add attribution trailers by hand.
|
|
168
|
-
|
|
169
|
-
Your pane's environment already supplies your phase's author and committer identity (`JJ_USER`/`JJ_EMAIL` and the Git author/committer variables, set by the daemon when it opened the pane).
|
|
170
|
-
Before your turn's first commit, run `jj -R "$LEGION_WORKSPACE" log -r @ --no-graph -T 'empty'`.
|
|
171
|
-
If it prints `true`, run `jj -R "$LEGION_WORKSPACE" new @-`; if it prints `false`, `@` holds only
|
|
172
|
-
your own resumed edits, so run `jj -R "$LEGION_WORKSPACE" new`. Never `jj describe` or `jj split`
|
|
173
|
-
the working-copy commit you found at the start of your turn: it can carry the previous role's
|
|
174
|
-
author, and those commands keep it. Never set or override `user.name`/`user.email`
|
|
175
|
-
in any jj or Git scope — not `jj config set`, not `--config`, not `git config`: `--config` outranks
|
|
176
|
-
the pane environment and would put the wrong App back on your commits, and the repository-scoped jj
|
|
177
|
-
config is one file shared by every issue workspace of the clone. Legion has two GitHub Apps, not
|
|
178
|
-
one per role: your role's App is the **implement** App if you are the implementer or the merger,
|
|
179
|
-
and the **review** App if you are the planner, tester, reviewer, or an architect; your pane's
|
|
180
|
-
`JJ_USER` and `JJ_EMAIL` name your role's App's bot account. A planner's commits authored
|
|
181
|
-
by the review App are right. Before a push, check your commits against your issue's own default
|
|
182
|
-
branch, read and quoted safely (never a branch name pasted into shell source), per `skill://legion-worker/references/default-branch-check.md`, which shows your role's App in both columns **on every commit you made** — not on the whole list:
|
|
183
|
-
earlier phases' commits are legitimately authored by their own role's App. Their *committer* is
|
|
184
|
-
a different matter, and no longer noise to accept. Resolving a conflict rewrites nothing — it is a
|
|
185
|
-
forward merge (`skill://legion-worker/references/conflicts-and-rewrites.md`) — so it changes no
|
|
186
|
-
committer at all, and the one rewrite still open to you (*Rewriting pushed commits*, in the same
|
|
187
|
-
reference) resets the committer only of commits on your own chain that descend from the commit
|
|
188
|
-
you named, after its guard cleared. Another role's commit
|
|
189
|
-
carrying you as committer, which you did not rewrite that way, is evidence that something
|
|
190
|
-
rewrote commits it should not have. Stop and send the
|
|
191
|
-
architect that log; do not accept it as a side effect. A wrong identity on your own commit, the
|
|
192
|
-
other App or none, is a pane-environment problem to report to the architect, not something to
|
|
193
|
-
pin (`docs/solutions/legion/shared-main-repo-hazards-for-concurrent-issue-workspaces.md`,
|
|
194
|
-
Hazard 1).
|
|
195
|
-
Your pane's `gh` and `git` already carry your role's GitHub identity; invoke GitHub with plain
|
|
196
|
-
`gh`:
|
|
197
|
-
|
|
198
|
-
```bash
|
|
199
|
-
gh <gh args…>
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
How `gh` works in a worker pane. `LEGION_GH_OWNERS_DIR` holds one read-only gh directory per
|
|
203
|
-
GitHub owner of the project (`hosts.yml`, an App installation token, and `config.yml`), which the
|
|
204
|
-
daemon rewrites in place so no token expires under you: your issue's owner's, which `GH_CONFIG_DIR`
|
|
205
|
-
names, holds your role's App token; every other owner's the same App's, read-only. Your `gh` picks
|
|
206
|
-
the directory of the owner a command names (`-R owner/repo`, `repos/owner/repo` in `gh api`, a
|
|
207
|
-
GitHub URL), your issue's owner's otherwise, so name the repository whenever it is not your
|
|
208
|
-
issue's; `git` picks by the remote URL's owner (`!legion git-credential`). `GH_TOKEN`,
|
|
209
|
-
`GITHUB_TOKEN` and `GH_HOST` are empty so nothing outranks the files. Never run `gh auth login`,
|
|
210
|
-
`gh auth switch`, `gh auth setup-git`, `gh config set` or `gh alias set`: there is no login state
|
|
211
|
-
to create. One rule nothing enforces: **Legion's issues live on Dispatch, never on
|
|
212
|
-
GitHub issues** — no `gh issue` write and no non-GET `gh api` call to an `/issues` path
|
|
213
|
-
(pull-request conversation comments live on that path too; edit them with `gh pr comment`); use
|
|
214
|
-
`dispatch message` or `dispatch comment` on your `LEGION_ISSUE`. The `legion` tool's own daemon
|
|
215
|
-
calls carry a credential of their own, minted in-process; `gh` and `git` never see it, and you
|
|
216
|
-
never `cat`, `echo`, copy, or `export` a token; a `task` subagent or background job inherits them.
|
|
217
|
-
|
|
218
|
-
**Other credentials your pod may already carry.** Before reporting that a read is unreachable,
|
|
219
|
-
check for them rather than assuming none exist: `AGENT_SECRETS_URL` and `AGENT_SECRETS_KEY_DIR`
|
|
220
|
-
are set when the deployment enrolls pods with the agent-secrets broker (`docs/kubernetes.md`,
|
|
221
|
-
"Operator configuration"), in which case `agent-secrets <SECRET> -- <command>` runs `<command>`
|
|
222
|
-
with only the secrets this pod generation's grant allows — refuses closed, naming the secret, if
|
|
223
|
-
the rule does not allow it. `AWS_CONFIG_FILE` is set when the deployment's `pod.volumes` carries a
|
|
224
|
-
further projected token beyond the model route's own; read the file it names for what profiles it
|
|
225
|
-
configures before assuming the AWS CLI has nothing to reach. Neither variable existing is a
|
|
226
|
-
guarantee the read you need is covered — a refusal from either still means what it says — but
|
|
227
|
-
neither should be assumed absent without checking.
|
|
228
|
-
|
|
229
|
-
## GitHub PR comment attribution
|
|
230
|
-
|
|
231
|
-
Append this exact structured footer to **every** pull-request comment and review that this
|
|
232
|
-
phase posts on GitHub. It preserves session provenance on the artifact itself so work stays
|
|
233
|
-
attributable to the session that produced it. Dispatch comments carry session provenance
|
|
234
|
-
natively through their own `actor`/`origin` fields; this footer is for GitHub PR artifacts and
|
|
235
|
-
for the retro's Dispatch message (`skill://legion-retro`):
|
|
43
|
+
| You need a tool the image may not carry, before you install anything | `skill://legion-worker/references/tools.md` |
|
|
44
|
+
| A problem outside your issue, or a failed production check | `skill://legion-worker/references/findings.md` |
|
|
236
45
|
|
|
237
|
-
|
|
238
|
-
<!-- legion: {"session":"<session-id>","phase":"<phase>"} -->
|
|
239
|
-
```
|
|
46
|
+
## Every role pushes its own commits
|
|
240
47
|
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
gh pr comment <pr-number> \
|
|
245
|
-
--body $'Verification complete.\n\n<!-- legion: {"session":"<session-id>","phase":"<phase>"} -->' \
|
|
246
|
-
--repo <owner>/<repo>
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
## Planner artifact
|
|
250
|
-
|
|
251
|
-
The plan lives in `.legion/<issue>/plan.json` and the issue's `plan.md` document, never in the issue's
|
|
252
|
-
primary document, which is its spec. Legion sets no rule on whether a plan or spec goes in the
|
|
253
|
-
repository: the planner commits a plan, a spec or spec code when the issue, its spec or the
|
|
254
|
-
repository asks for it. Otherwise, a skill step that says "save the plan to a file" is satisfied by
|
|
255
|
-
the handoff write in the completion gate below.
|
|
256
|
-
|
|
257
|
-
A plan that departs from the spec's design records the departure in `plan.md` and in the required
|
|
258
|
-
`.legion/<issue>/plan.json` `specDepartures`: `[]` means no departure; otherwise each bounded record names
|
|
259
|
-
the spec, plan, evidence and outcome. The planner's role prompt defines that record. The planner
|
|
260
|
-
never edits the issue's spec document. Whether the spec changes is the architect's decision
|
|
261
|
-
(`skill://legion-architect`, section 1), and the reviewer reads the plan beside the spec.
|
|
262
|
-
|
|
263
|
-
## Implementer push and pull request
|
|
264
|
-
|
|
265
|
-
The implementer opens the pull request. After its implementation commit and verification, it
|
|
266
|
-
pushes the issue branch under this exact name with the one push procedure every role uses
|
|
267
|
-
(*Every role pushes its own commits*, below).
|
|
268
|
-
|
|
269
|
-
`jj git push` authenticates as your role's App through the clone's `!legion git-credential`, from
|
|
270
|
-
the file your `gh` reads for your issue's repository. Never handle a token.
|
|
271
|
-
|
|
272
|
-
Then open the pull request with `gh pr create`. The PR body **must** contain the
|
|
273
|
-
line `Dispatch: <KEY>` — the daemon's fallback link from a PR to its Dispatch issue when the
|
|
274
|
-
branch name alone is ambiguous. Your pane's `gh` and `git` provide the GitHub
|
|
275
|
-
identity; never export, fetch, or replace a token. Other phases advance the existing branch
|
|
276
|
-
rather than creating a replacement bookmark or PR.
|
|
48
|
+
- Before a push, read `jj -R "$LEGION_WORKSPACE" log -r 'ancestors(@, 5)'` (earlier phases' commits in it are expected) and run the identity check (`skill://legion-worker/references/default-branch-check.md`). Add no attribution trailer: the pane's jj adds `Omp-Session:`.
|
|
49
|
+
- A push whose commits touch only `.legion/` ends its head's message with `skip-checks: true`, unless it is retro's push (the implementer's retro phase, before the merger's). Retro's push never carries the line, whatever paths it touches, because it is the last push before the merge and a base that requires a check will not merge a head whose checks never ran. No other push carries it. The daemon classifies a push by its paths, never by the trailer, so a wrong trailer can stall the issue but never makes it pass.
|
|
50
|
+
- A planner whose issue moved back from implementing starts on the remote tip, `jj -R "$LEGION_WORKSPACE" new legion/<KEY>@origin`, so its handoff never sits on the implementer's unpushed commits.
|
|
277
51
|
|
|
278
52
|
## PR body, review, and the merge gate
|
|
279
53
|
|
|
280
|
-
The implementer
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
and
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
`skill://legion-worker/references/pr-body.md`**: the template, the full definition of a proof,
|
|
287
|
-
what the tester verifies, and the simplify pass.
|
|
288
|
-
|
|
289
|
-
- **The tester runs the application, not CI again.** It drives the changed surface for real and
|
|
290
|
-
tries to break it, judges whether the implementer's tests would catch what it broke, records what
|
|
291
|
-
it ran and saw, and must read CI on GitHub for everything static — lint, types and the unit
|
|
292
|
-
suites are CI's work, rerun by no tester: `skill://legion-worker/references/pr-body.md`.
|
|
293
|
-
- **Review threads** are answered and resolved one by one, never in bulk, and never one you have
|
|
294
|
-
not read: one disposition reply per thread, then that thread's own resolution by the
|
|
295
|
-
implementer, the pull request's author — its `gh api graphql` mutation after every push that
|
|
296
|
-
answers a review, before its completion, for the threads it answered and for the bot threads the
|
|
297
|
-
reviewer names to it as accepted (the review App cannot resolve one):
|
|
298
|
-
`skill://legion-worker/references/review-threads.md`.
|
|
299
|
-
- **No deferrals.** A finding that changes
|
|
300
|
-
behaviour, hides an error, or breaks a gate is fixed in this pull request; naming, duplication,
|
|
301
|
-
or wording cleanup is batched into the one `Fast-follow:` line instead of iterating per push.
|
|
302
|
-
- **The implementer pushes, then completes; it never waits for, watches or polls CI**, and never
|
|
303
|
-
sleeps in a loop: `skill://legion-worker/references/pr-body.md` (*Never waiting on CI*).
|
|
304
|
-
- **A red CI job** that failed on its own is re-run with
|
|
305
|
-
`gh run rerun <run-id> --failed`, never by pushing a new commit or bringing in the base.
|
|
306
|
-
- **A conflict or a retarget** is the only reason to bring the base into the branch, always as a
|
|
307
|
-
forward merge and never `jj rebase`; the unchanged-diff fingerprint each role compares
|
|
308
|
-
afterwards is in the same reference: `skill://legion-worker/references/conflicts-and-rewrites.md`.
|
|
309
|
-
- **The merge gate**, in order: the tester's evidence green → the reviewer's approval of the head
|
|
310
|
-
→ the architect's acceptance → retro → the merger's READY → the merge, which closes the issue →
|
|
311
|
-
the implementer's production check, after the close. On READY's acceptance the daemon submits
|
|
312
|
-
the merge of the head READY named, unless the answer's note begins `MANUAL_MERGE_REQUIRED:`,
|
|
313
|
-
where a person merges it; no role runs `gh pr merge`, and the repository's required reviews and
|
|
314
|
-
checks decide when it lands (`skill://legion-worker/references/merge-gate.md`). The reviewer's
|
|
315
|
-
submissions, the acceptance, retro's commit, READY, the daemon's submission, and the check follow the same reference.
|
|
316
|
-
- **No surface reaches the changed path** is a report to the architect, never a reason to
|
|
317
|
-
complete the phase: `skill://legion-worker/references/pr-body.md`.
|
|
318
|
-
|
|
319
|
-
## Completion gate: handoff write, verification, and persistence
|
|
320
|
-
|
|
321
|
-
The merger writes no handoff and pushes nothing, so this gate does not apply to it
|
|
322
|
-
(`packages/daemon/internal/prompts/roles/merger.md`).
|
|
323
|
-
|
|
324
|
-
A planner picking up after the issue moves back from implementing starts fresh on the remote
|
|
325
|
-
tip — `jj -R "$LEGION_WORKSPACE" new legion/<KEY>@origin` — since the implementer's unpushed
|
|
326
|
-
commits are no longer in the chain (*Every role pushes its own commits*, below).
|
|
327
|
-
|
|
328
|
-
Write the handoff, `$LEGION_WORKSPACE/.legion/<issue>/<phase>.json` (`plan`, `implement`, `test`
|
|
329
|
-
or `review`), with the ordinary `write` tool: a JSON object with `schemaVersion: 1`,
|
|
330
|
-
`phase: "<phase>"`, `issue: "<KEY>"`, `completed: "<RFC 3339 UTC time of writing>"`, and the
|
|
331
|
-
phase's own fields exactly as your role prompt spells them — the planner's `requiredSkills`,
|
|
332
|
-
`gapAnalysis`, `planReview` and `specDepartures` records; the implementer's `proof` array; the
|
|
333
|
-
tester's `implementerProof`, `failures` and, whenever it reports no failure, its own `proof`; the
|
|
334
|
-
reviewer's `decision`, counts and `keyFindings`. Nothing stamps the first four for you. Each `proof`
|
|
335
|
-
entry, in either phase, is an object of six non-empty strings: `criterion` (the acceptance line it
|
|
336
|
-
proves), `surface`, `command`, `observed`, `headSha` (the commit it ran at) and `negativeControl`.
|
|
337
|
-
A handoff built from the one already on disk (a test handoff that accumulates review rounds) is
|
|
338
|
-
read with `read`, edited, and written whole with `write`, its `completed` set to now.
|
|
339
|
-
|
|
340
|
-
Then commit that exact handoff file onto the issue branch:
|
|
341
|
-
|
|
342
|
-
```bash
|
|
343
|
-
cd -- "$LEGION_WORKSPACE" && \
|
|
344
|
-
jj -R "$LEGION_WORKSPACE" split -m "<phase>: record handoff" .legion/<issue>/<phase>.json
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
Then push (below) and report completion: call the `legion` tool with `op: "handoff_complete"` and
|
|
348
|
-
`summary` (two sentences for the architect; the tester, and no other role, adds `verdict: "pass"`
|
|
349
|
-
or `"fail"`; the merger `ready: true`). **Push before you complete is a hard rule.**
|
|
350
|
-
`handoff_complete` finds, with your pane's jj, the newest commit on the issue branch that carries
|
|
351
|
-
`.legion/<KEY>/<phase>.json` and reports it to the daemon, and refuses — posting nothing — while:
|
|
352
|
-
|
|
353
|
-
- the file has a change still in the working copy: commit it, then complete again;
|
|
354
|
-
- the file is missing from the workspace: write it, then commit and push it;
|
|
355
|
-
- the file is not committed on this branch (only the base carries it): write and commit it;
|
|
356
|
-
- the carrying commit was authored by another App (every role of an issue shares the workspace):
|
|
357
|
-
run `jj -R "$LEGION_WORKSPACE" new`, then write and commit this phase's handoff again;
|
|
358
|
-
- the carrying commit is not yet on `legion/<KEY>@origin`: push the issue branch, then complete
|
|
359
|
-
again.
|
|
54
|
+
- The implementer opens the pull request with the line `Dispatch: <KEY>` in its body, the daemon's link to the issue when the branch name is ambiguous. Later phases push to that branch and edit that pull request, never a new one.
|
|
55
|
+
- **No deferrals.** A finding that changes behaviour, hides an error, or breaks a gate is fixed in this pull request. Only cleanup that changes no behaviour (naming, duplication, wording) may wait, on the body's one `Fast-follow:` line.
|
|
56
|
+
- **The merge gate**, in order: the tester's evidence green → the reviewer's approval of the head → the architect's acceptance → retro → the merger's READY → the merge, which closes the issue → the implementer's production check, after the close. When the daemon accepts READY, it submits the merge of READY's head, unless the answer's note begins `MANUAL_MERGE_REQUIRED:`, where a person merges it; no role runs `gh pr merge`.
|
|
57
|
+
- Append `<!-- legion: {"session":"<session-id>","phase":"<phase>"} -->` to every pull-request comment and review you post: the daemon finds the session behind a review by it.
|
|
58
|
+
- Never write a GitHub issue, by `gh issue` or a non-GET `gh api` on `/issues` (post or edit a PR conversation comment with `gh pr comment`): Legion's issues live on Dispatch. Never run `gh config set` or `gh alias set`, and leave `GH_TOKEN`, `GITHUB_TOKEN` and `GH_HOST` empty: the daemon rewrites your gh directory in place, and a set variable outranks it.
|
|
59
|
+
- Before you report a resource unreachable, check `AGENT_SECRETS_URL` and `AGENT_SECRETS_KEY_DIR` (then `agent-secrets <SECRET> -- <command>`; sjawhar/legion `docs/kubernetes.md`, "Operator configuration") and `AWS_CONFIG_FILE` (read its profiles): a deployment can give your pod either. `agent-secrets` refuses a secret its grant lacks and names it; that refusal is final. Your `task` subagents and background jobs inherit both, and your `gh` and `git`.
|
|
360
60
|
|
|
361
|
-
|
|
362
|
-
The daemon reads no handoff file and no branch head; it refuses, before recording anything:
|
|
363
|
-
|
|
364
|
-
- `HANDOFF_NOT_NEW` — the commit is the one you reported for your previous phase: write and
|
|
365
|
-
commit this phase's handoff before completing.
|
|
366
|
-
- each `READY_…` refusal of the merger's READY — named, with its remedy, in the merger's role
|
|
367
|
-
prompt (`skill://legion-worker/references/merge-gate.md` says how READY is checked).
|
|
368
|
-
- `GITHUB_READ_FAILED` — GitHub's failure, not the head's, reading the pull request's head on
|
|
369
|
-
GitHub: complete again.
|
|
370
|
-
|
|
371
|
-
Such a refusal records nothing, so the corrected call at the same commit is applied. The answer
|
|
372
|
-
may carry a `note` (READY published on an already-merged pull request, or the
|
|
373
|
-
`MANUAL_MERGE_REQUIRED:` note of a pull request a person merges).
|
|
374
|
-
|
|
375
|
-
Retro's last commit removes `.legion/<issue>/` from the head that merges (`skill://legion-retro`);
|
|
376
|
-
a round after it, such as one a withdrawn READY sends back, writes and commits its own handoff
|
|
377
|
-
again, since `handoff_complete` reports the commit carrying the file. Retro and the merger write no
|
|
378
|
-
`.legion/<issue>/<phase>.json`, commit no handoff, and report with `handoff_complete` alone, which
|
|
379
|
-
reports the commit the workspace stands on; a look of the production check after the close reports with `handoff_complete` and a `verdict`, and no commit at all.
|
|
380
|
-
|
|
381
|
-
**Every role pushes its own commits.** After the handoff commit — and, for the tester, the red
|
|
382
|
-
tests it wrote — push the issue branch with the plain `jj` of your pane, from bash in your
|
|
383
|
-
workspace; `<KEY>` is your `LEGION_ISSUE`:
|
|
384
|
-
|
|
385
|
-
```bash
|
|
386
|
-
cd -- "$LEGION_WORKSPACE" && jj -R "$LEGION_WORKSPACE" bookmark set legion/<KEY> -r @- && jj -R "$LEGION_WORKSPACE" git push --bookmark legion/<KEY>
|
|
387
|
-
```
|
|
388
|
-
|
|
389
|
-
A push whose commits touch only `.legion/` (a handoff-only push) ends its head's commit message
|
|
390
|
-
with `skip-checks: true` as the last line, preceded by two empty lines, so GitHub starts no
|
|
391
|
-
workflow run for it and the daemon carries the code head's verdict to it.
|
|
392
|
-
Retro's push never carries the line, whatever paths it touches, because it is the last push before the merge and a base that requires a check will not merge a head whose checks never ran.
|
|
393
|
-
Every other push —
|
|
394
|
-
code, red tests, `docs/solutions/`, a forward merge, a rewrite — carries no such line. The daemon
|
|
395
|
-
classifies a push by the paths its commits touch, never by the trailer: a wrong trailer stalls
|
|
396
|
-
the issue and never passes it. Before you write one, read
|
|
397
|
-
`skill://legion-worker/references/skip-checks-trailer.md`: the shape GitHub honours, the
|
|
398
|
-
`describe` that writes it with trailers off, the bracket keywords banned with it, how a wrong
|
|
399
|
-
trailer stalls the issue, and when a pull-request body edit does and does not start a run.
|
|
400
|
-
|
|
401
|
-
Before the push, inspect `jj -R "$LEGION_WORKSPACE" log -r 'ancestors(@, 5)'` and run the
|
|
402
|
-
identity check above: the chain carries every earlier phase's pushed commits, and pushing them
|
|
403
|
-
with yours is expected. Your issue's roles share one clone (under tmux every issue does), so
|
|
404
|
-
another role's push moves `legion/<KEY>@origin` here at once, and `jj git push` refuses a remote
|
|
405
|
-
branch that moved: report the refusal to the architect with its output, never force. A handoff commit never
|
|
406
|
-
sits on an implementer's unpushed chain: when the issue moves back to planning, the implementer's
|
|
407
|
-
unpushed commits stay off the bookmark until the implementer returns, and the planner writes its
|
|
408
|
-
handoff on the remote tip. The one sanctioned non-fast-forward move is the rewrite of a commit you
|
|
409
|
-
already pushed — a `jj squash --into` one, or any other rewrite — and before it, read *Rewriting
|
|
410
|
-
pushed commits* in `skill://legion-worker/references/conflicts-and-rewrites.md`: its guard checks
|
|
411
|
-
that no other tree's work is built on that commit, and only after it clears is the bookmark moved
|
|
412
|
-
with `--allow-backwards`. The merger makes no commit and pushes nothing.
|
|
413
|
-
|
|
414
|
-
## Completion: report to the architect, then stay
|
|
415
|
-
|
|
416
|
-
Report completion to the architect: call the `legion` tool with `op: "handoff_complete"` and
|
|
417
|
-
`summary`: two sentences for the architect. The tool is your only way to the daemon
|
|
418
|
-
(`handoff_complete`; `read_record`, your issue's record, which is what "re-read your issue
|
|
419
|
-
record" means; and `request_backward_move`), and nothing of yours runs `legion` from bash. The
|
|
420
|
-
tool call is what the extension's phase stall records, and a turn that ends with the phase still
|
|
421
|
-
open gets one reminder (two when the first is answered with the tool call written as text again);
|
|
422
|
-
do not complete again on a reminder when your first completion was accepted — it stands, and a
|
|
423
|
-
second is refused because the issue has already left your phase.
|
|
424
|
-
|
|
425
|
-
This publishes your phase's completion to the architect's role and clears the daemon's
|
|
426
|
-
record of this issue's active phase. Do not add pipeline labels, run a controller loop, or
|
|
427
|
-
invent a different completion protocol — this is the whole contract.
|
|
428
|
-
|
|
429
|
-
A reviewer's phase ends with its completion, not with its review; the order of a review round
|
|
430
|
-
(the read of the code commit's checks on GitHub; the handoff push; the review of the head that
|
|
431
|
-
push made; then the completion) is in `skill://legion-worker/references/merge-gate.md`.
|
|
432
|
-
|
|
433
|
-
**A refused completion is information, not a retry loop.** The daemon attributes your report to
|
|
434
|
-
the run whose task you took, and answers with what it found. What each answer carries, and what to
|
|
435
|
-
do:
|
|
436
|
-
|
|
437
|
-
- `HANDOFF_STALE_GENERATION` — names the issue, the run it is on, and the run your completion
|
|
438
|
-
reported. The issue has moved to a newer run since your task was given, so the work you just
|
|
439
|
-
reported belongs to a run that is over. Nothing you can repeat changes that: stop, push nothing
|
|
440
|
-
further, and tell the architect what you completed and that its run has been superseded. A task
|
|
441
|
-
for the current run arrives in this same session if the phase still needs you. The same answer
|
|
442
|
-
comes when your turn started before the daemon recorded the current run's task as yours, so it
|
|
443
|
-
still holds you to the earlier run: that task is sent again. When a task arrives, do what it
|
|
444
|
-
asks; if the work it asks for is already committed, call `handoff_complete` again, and never redo
|
|
445
|
-
the work or write a second handoff.
|
|
446
|
-
- `HANDOFF_NOT_CURRENT_PHASE` — names your role, the issue, and the phase it is in now. The issue
|
|
447
|
-
has left your phase; report to the architect rather than completing again.
|
|
448
|
-
- `HANDOFF_NO_RUN` — names neither: it says this claim has taken no task, so the daemon cannot
|
|
449
|
-
tell which run you are reporting. Your pane is completing outside any assignment. Say so to the
|
|
450
|
-
architect; do not re-run the phase. The same answer comes when your turn started before your task
|
|
451
|
-
reached you: a notice or a message started it, and the task, refused while that turn ran, is sent
|
|
452
|
-
when the turn ends. When a task arrives, do what it asks; if the work it asks for is already
|
|
453
|
-
committed, call `handoff_complete` again, and never redo the work or write a second handoff.
|
|
454
|
-
- `HANDOFF_ALREADY_RECORDED` — names your role, the phase, the review round and the commit. This
|
|
455
|
-
exact call was received before, and its first answer stands: accepted, or a refusal the daemon
|
|
456
|
-
records with the call — `HANDOFF_STALE_GENERATION`, `HANDOFF_NOT_CURRENT_PHASE`,
|
|
457
|
-
`READY_REQUIRED` or `HANDOFF_NOT_NEW`. `HANDOFF_NO_RUN` is never that first answer, since it is
|
|
458
|
-
given before anything is recorded. Sending it again changes nothing; if you did not see that
|
|
459
|
-
first answer, tell the architect so and quote this one.
|
|
460
|
-
|
|
461
|
-
Quote the answer verbatim in what you tell the architect: with the run and phase it names, the
|
|
462
|
-
difference between "my work is lost" and "my work belongs to the previous run" is visible.
|
|
463
|
-
|
|
464
|
-
**Stay in this session afterward.** Your process does not exit when your phase completes; it
|
|
465
|
-
stays live until your issue leaves the workflow. No move between phases stops it, and only an
|
|
466
|
-
explicit stop does: the issue closing; a move to `backlog`, `icebox` or `triage` (a child by a
|
|
467
|
-
person or its architect's `park_child`, or the root, which stops the whole tree); a child set back
|
|
468
|
-
to `todo` (which stops the interrupted phase's worker, not earlier roles); or an operator stop.
|
|
469
|
-
A stop keeps your session, and a crash relaunches it. Your next assignment arrives in this same
|
|
470
|
-
session. Other roles on
|
|
471
|
-
this issue may reach you through Envoy with
|
|
472
|
-
questions about the work you did — answer them, reading `$LEGION_WORKSPACE` and your own
|
|
473
|
-
committed handoff as needed, without mutating anything (see Workspace and handoff
|
|
474
|
-
precedence above). You will also be the one resumed, with a new prompt in this same
|
|
475
|
-
session, if this phase's work needs to run again.
|
|
476
|
-
|
|
477
|
-
When blocked on a product, scope, design, lifecycle, or cross-phase decision, `envoy_publish` the
|
|
478
|
-
owning architect a concise message: issue, phase, verified observation, what you tried, and the
|
|
479
|
-
decision required.
|
|
61
|
+
## Deployment instructions
|
|
480
62
|
|
|
481
|
-
|
|
482
|
-
where its owner will see it: a product, scope, design, lifecycle, or cross-phase decision goes to
|
|
483
|
-
the owning architect as above, and a standalone human to-do goes in `dispatch ask`. Otherwise
|
|
484
|
-
proceed: proceeding is the default, and a phase that stops silently holds its issue until someone
|
|
485
|
-
notices.
|
|
63
|
+
Deployment instructions in your prompt override this skill where they conflict, except four rules: no deferrals; bringing the base into the branch only on a real conflict or a retarget (`skill://legion-worker/references/conflicts-and-rewrites.md#reintegrating-the-base`); the implementer's own proof on a production-like surface at the head that merges, an applied simplify head included (`skill://legion-worker/references/pr-body.md#what-a-proof-is`, `skill://legion-worker/references/pr-body.md#the-rules-every-phases-evidence-follows`); and the implementer's production check after the close (`skill://legion-worker/references/merge-gate.md#the-production-check-after-the-close`).
|
|
@@ -11,8 +11,8 @@ Every path it cites is in sjawhar/legion.
|
|
|
11
11
|
merge, never `jj rebase`.**
|
|
12
12
|
The implementer merges the base into the issue branch only when GitHub reports it `CONFLICTING`, the controller asks
|
|
13
13
|
because of a conflict, or after the pull request is retargeted to a new base. Otherwise, never reintegrate the base to
|
|
14
|
-
pick up the default branch or refresh CI (a single failed CI job is re-run on its own: *
|
|
15
|
-
`skill://legion-worker`). A conflict-forced rebase that leaves the branch's diff unchanged is a
|
|
14
|
+
pick up the default branch or refresh CI (a single failed CI job is re-run on its own: *Never waiting on CI* in
|
|
15
|
+
`skill://legion-worker/references/pr-body.md`). A conflict-forced rebase that leaves the branch's diff unchanged is a
|
|
16
16
|
confirmation, not a new round (see *The unchanged-diff check* below); that name is the event's,
|
|
17
17
|
kept by the rules below and the learnings that cite it, and the operation it names is always
|
|
18
18
|
the merge here. Before merging, record
|
|
@@ -35,3 +35,19 @@ never runs.
|
|
|
35
35
|
|
|
36
36
|
The output must show your role's App in both columns **on every commit you made** — not on the
|
|
37
37
|
whole list: earlier phases' commits are legitimately authored by their own role's App.
|
|
38
|
+
|
|
39
|
+
## Which App, and what a wrong one means
|
|
40
|
+
|
|
41
|
+
- Your role's App is the **implement** App for the implementer and the merger, and the **review**
|
|
42
|
+
App for the planner, tester, reviewer and architect; your pane's `JJ_USER` and `JJ_EMAIL` name
|
|
43
|
+
its bot account. A planner's commits authored by the review App are right.
|
|
44
|
+
- Never set `user.name` or `user.email` in any jj or Git scope (`jj config set`, `--config`,
|
|
45
|
+
`git config`): `--config` outranks the pane's identity and puts the wrong App on your commits,
|
|
46
|
+
and the repository-scoped jj config is one file shared by every issue workspace of the clone.
|
|
47
|
+
- A wrong identity on your own commit (the other App, or none) is a pane-environment problem:
|
|
48
|
+
report it to the architect, never pin it (sjawhar/legion
|
|
49
|
+
`docs/solutions/legion/shared-main-repo-hazards-for-concurrent-issue-workspaces.md`, Hazard 1).
|
|
50
|
+
- Another role's commit with you as committer, which you did not rewrite under the guard in
|
|
51
|
+
*Rewriting pushed commits* (`skill://legion-worker/references/conflicts-and-rewrites.md`), means
|
|
52
|
+
something rewrote commits it should not have: stop and send the architect this log. A forward
|
|
53
|
+
merge rewrites nothing, so it changes no committer.
|
|
@@ -13,8 +13,8 @@ whether it needs an issue, where, and whether Legion works it.
|
|
|
13
13
|
- A problem inside your issue is not such a finding: fix it in your change, since nothing needed
|
|
14
14
|
for correctness is deferred.
|
|
15
15
|
- A problem inside your tree is work its root spec's acceptance needs. A phase worker's such
|
|
16
|
-
problem outside its own issue goes to the tree's architect (`skill://legion-worker`,
|
|
17
|
-
|
|
16
|
+
problem outside its own issue goes to the tree's architect (`skill://legion-worker`, *Stop
|
|
17
|
+
rules*), which may file it as a child of the tree. Anything else, in the same
|
|
18
18
|
repository or not, is a finding.
|
|
19
19
|
- Search first (`skill://dispatch-first`): when an open issue already tracks the problem, comment
|
|
20
20
|
the evidence on that issue and ask nothing. When an open ask on the report issue already asks
|
|
@@ -57,7 +57,7 @@ Under the Go daemon a check or workflow the base branch requires that settles re
|
|
|
57
57
|
before the completion or after it, sends the work back to `implementing` with the failing checks
|
|
58
58
|
named, until `max_fix_attempts` is spent, when the architect decides. The one CI result an implementer waits for is a re-run: when its task names a red that
|
|
59
59
|
failed on its own, it re-runs the failed jobs once (`gh run rerun <run-id> --failed`) and completes once
|
|
60
|
-
the re-run settles green, woken by the pull request's checks event (`skill://envoy`, *
|
|
60
|
+
the re-run settles green, woken by the pull request's checks event (`skill://envoy`, *Wait for
|
|
61
61
|
CI or a merge*: subscribe, then end the turn), never by a sleep loop. A completion while that red
|
|
62
62
|
still stands is sent back, at once for a required check and at the daemon's next read of the runs
|
|
63
63
|
(within two minutes) for a required workflow.
|
|
@@ -45,7 +45,7 @@ Three facts govern every thread, whoever opened it.
|
|
|
45
45
|
Reply on each thread you answer, then tell the implementer the node ids of exactly the threads
|
|
46
46
|
you accepted — a bot's findings you adjudicated — never one you have not read: an
|
|
47
47
|
`envoy_publish` to the implementer's role topic (it is live on the issue and answers while you
|
|
48
|
-
wait; `
|
|
48
|
+
wait; its topic is yours from the `Legion addressing` line with `-implementer` as the last part), or your review body, which
|
|
49
49
|
it reads at its next round. The implementer resolves exactly those with its own `gh`. GitHub
|
|
50
50
|
cannot tell a CI bot from a person whose `gh` is routed to an App, so such a thread may be a
|
|
51
51
|
person's finding: accept it only when the finding itself is settled (a genuine Minor is settled
|