@sjawhar/opencode-legion-envoy 1.21.1 → 1.23.0
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/src/server.js
CHANGED
|
@@ -14194,6 +14194,19 @@ var stateRole = strictObject({
|
|
|
14194
14194
|
launchFailures: number2().int().nonnegative().optional(),
|
|
14195
14195
|
locator: stateLocator.optional()
|
|
14196
14196
|
});
|
|
14197
|
+
var stateQueuedWorkerIdentity = {
|
|
14198
|
+
roleToken: nonEmptyString,
|
|
14199
|
+
issue: nonEmptyString,
|
|
14200
|
+
role: nonEmptyString
|
|
14201
|
+
};
|
|
14202
|
+
var stateQueuedWorker = union([
|
|
14203
|
+
strictObject(stateQueuedWorkerIdentity),
|
|
14204
|
+
strictObject({
|
|
14205
|
+
...stateQueuedWorkerIdentity,
|
|
14206
|
+
kind: _enum2(["assignment", "catchup"]),
|
|
14207
|
+
queuedAt: nonEmptyString
|
|
14208
|
+
})
|
|
14209
|
+
]);
|
|
14197
14210
|
var LegionDaemonApi = {
|
|
14198
14211
|
State: {
|
|
14199
14212
|
response: strictObject({
|
|
@@ -14210,7 +14223,8 @@ var LegionDaemonApi = {
|
|
|
14210
14223
|
controllerLocator: stateLocator.optional(),
|
|
14211
14224
|
roles: record(string2(), stateRole),
|
|
14212
14225
|
controllerPendingNotices: number2().int().nonnegative(),
|
|
14213
|
-
pendingStatusWrites: array(nonEmptyString)
|
|
14226
|
+
pendingStatusWrites: array(nonEmptyString),
|
|
14227
|
+
workerAdmission: strictObject({ queue: array(stateQueuedWorker) })
|
|
14214
14228
|
})
|
|
14215
14229
|
},
|
|
14216
14230
|
ControllerReady: {
|
|
@@ -14297,7 +14311,8 @@ var LegionDaemonApi = {
|
|
|
14297
14311
|
request: architectCapability.extend({
|
|
14298
14312
|
issue: nonEmptyString,
|
|
14299
14313
|
role: legionRole,
|
|
14300
|
-
task: nonEmptyString
|
|
14314
|
+
task: nonEmptyString,
|
|
14315
|
+
requestId: uuid2()
|
|
14301
14316
|
}),
|
|
14302
14317
|
response: object({
|
|
14303
14318
|
status: _enum2(["spawned", "resumed", "queued"]),
|
|
@@ -16031,10 +16046,16 @@ class EnvoyApiError extends Error {
|
|
|
16031
16046
|
this.expected = parsed?.expected;
|
|
16032
16047
|
}
|
|
16033
16048
|
}
|
|
16049
|
+
function resolveEnvoyToken(env) {
|
|
16050
|
+
const { ENVOY_TOKEN_FILE: file, ENVOY_TOKEN: plain } = env;
|
|
16051
|
+
if (file !== undefined && file !== "")
|
|
16052
|
+
return readSecretFile("ENVOY_TOKEN_FILE", file);
|
|
16053
|
+
return plain || undefined;
|
|
16054
|
+
}
|
|
16034
16055
|
function createEnvoyClient(config) {
|
|
16035
16056
|
const baseUrl = normalizeEnvoyUrl(config.baseUrl);
|
|
16036
16057
|
const timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
16037
|
-
const
|
|
16058
|
+
const apiToken = resolveEnvoyToken(process.env);
|
|
16038
16059
|
const request = async (path, init) => {
|
|
16039
16060
|
const url = `${baseUrl}${path}`;
|
|
16040
16061
|
for (let attempt = 0;attempt < 2; attempt += 1) {
|
package/package.json
CHANGED
|
@@ -301,7 +301,7 @@ active phase worker.
|
|
|
301
301
|
| `design-approved` | Payload `{type:"design-approved"}`. A human approved the root spec document at its current version; the gate is open. Proceed to section 2. |
|
|
302
302
|
| `design-changes-requested` | Payload `{type:"design-changes-requested", version, reason, author?}`. A human asked for changes to the root spec at `version`, for `reason`. Revise the spec, call `dispatch_request_approval` again, and stay parked; the gate is closed. |
|
|
303
303
|
| `phase-complete` | Payload `{type:"phase-complete", issue, role, summary}`. May arrive live or via `catchup-overseer`'s `phaseCompletions`. Read the committed handoff for that phase, then spawn the next phase's owner, or `spawn_worker` on the same role again to resume it with corrections if the handoff shows unresolved gaps. A `reviewer` completion whose GitHub review is `CHANGES_REQUESTED` (the daemon returns the issue's Dispatch status to `in_progress` for this, on the reviewer's completion and again when you spawn the corrective implementer unless the daemon already knows the issue is `in_progress`) means `spawn_worker` the **implementer** again with the review findings — thread URLs and blocking items — as its task, then route back through tester and reviewer in order; never `spawn_worker` the reviewer directly off this wake and never proceed to retro on this verdict. A reviewer completion with an `APPROVED` review proceeds to retro (step 5). A `reviewer` completion after a conflict-forced rebase whose review body names an unchanged fingerprint is a confirmation, not a round: if retro already completed, `spawn_worker` the merger; otherwise resume the step you were on. An `implementer` completion that follows the merge is its production report: read the record on the pull request and the issue, then run step 7 — the issue is already at `retro`, the daemon writes no status for this completion, and you set `done` yourself. A `tester` completion whose handoff carries `implementerProof.verdict: "rejected"`, or a failure naming the production-like proof, goes back to the **implementer** with that finding — never forward to the reviewer, and never by supplying the proof from another role. A worker that reports no surface reaches the changed path gets a child issue in this tree (infrastructure, tooling, or a skill) and a resume once it lands; that report is never a reason to advance the phase. |
|
|
304
|
-
| `worker-queued` | Payload `{type:"worker-queued", issue, role}`. This role's task is queued for promotion — either the deployment's worker cap is full, or the live worker acknowledged the task without starting a turn and the daemon is retrying it (counted; the worker is replaced after three such failures, still with the same task). Do not respawn or retry — wait for `worker-started`. |
|
|
304
|
+
| `worker-queued` | Payload `{type:"worker-queued", issue, role}`. This role's task is queued for promotion — either the deployment's worker cap is full, or the live worker acknowledged the task without starting a turn and the daemon is retrying it (counted; the worker is replaced after three such failures, still with the same task). Do not respawn or retry — wait for `worker-started`. `legion state` shows the queue (`workerAdmission.queue`: role token, issue, role, kind, and the time the task was first queued — never the task text); read it before re-sending. A `spawn_worker` identical to the queued task changes nothing and is not announced again. Different text replaces the queued task silently in the same FIFO slot and retains its original queue time. A `spawn_worker` that fails with "got no response in 3 attempts" was already retried by the plugin under one request id and may still have reached the daemon: read the queue and the role's claim in `legion state` before sending it again. |
|
|
305
305
|
| `worker-started` | Payload `{type:"worker-started", issue, role}`. A previously queued role has been promoted and is now running. Treat it exactly as a normal spawn: resume tracking that role's live session. |
|
|
306
306
|
| `pr-ready` | Verify the live PR head, green status, and review state. Continue the review/retro/merger order only for that current head. |
|
|
307
307
|
| `pr-review` | Payload `{type:"pr-review", state, author, body}`. Delivered to whichever role is currently active for the issue, falling back to you when no worker phase is active. Follows the same verdict rule as a reviewer's `phase-complete`: `state: "changes_requested"` sends the implementer back in with the review findings, then tester, then reviewer — never the reviewer again and never retro; that `spawn_worker` returns the issue to `in_progress` on its own (the daemon writes it for a corrective implementer whenever the PR's latest recorded review is changes requested, a human's after approval included), so you set nothing by hand; `state: "approved"` proceeds toward retro (step 5) once the step 6 integration/merge-gate conditions are met. `state: "approved"` on a rebased head whose body names an unchanged fingerprint is that confirmation: proceed to retro if it has not run, otherwise to the merger — never to a second retro or test round. |
|
|
@@ -62,7 +62,8 @@ override a Sami ruling quoted here.
|
|
|
62
62
|
| New issue created in the Dispatch project (`issue.created`, status `triage`; resync heals misses) | issue key + triage context (incl. pre-existing children) | Triage: `legion({ op: "set_status", issue, status: "todo" })` to admit, or set `backlog`/`icebox` to park |
|
|
63
63
|
| Backlog eligibility | slot freed / priority change | Reconsider parked items and move the eligible root to `todo` |
|
|
64
64
|
| Architect escalation (controller-actionable only: re-file a child as a root issue, capacity, cross-tree conflicts) | request + context | Judge and act; issue-scoped human Q&A goes through `dispatch_ask` from the owning architect, not here |
|
|
65
|
-
| Resync report | artifact-driven anomaly list (zero-owner trees, untriaged-open, launch-failed) | Verify against fresh state, then heal |
|
|
65
|
+
| Resync report | artifact-driven anomaly list (zero-owner trees, untriaged-open, launch-failed, admission-drift) | Verify against fresh state, then heal |
|
|
66
|
+
| Resync report: `admission-drift` entry | issue key + whether the daemon added it to, or removed it from, its admission list (the detail says which) | No action: the daemon already repaired it in the same run. An issue that reappears in consecutive reports is a live leak — file a LEGION issue on Dispatch with both reports pasted as evidence (never a GitHub issue) |
|
|
66
67
|
| `child-status` | child key + status transition | Not controller-actionable by default; if the daemon could not route it to the parent's architect role, verify the transition and forward it with `envoy_publish` |
|
|
67
68
|
| Mention | Slack/GitHub PR @mention text | Answer, or route to the owning issue's architect role |
|
|
68
69
|
| Closed-tree activity (comment, review, CI on a closed tree) | issue, root, event summary | Read the artifact; if work should resume, `legion({ op: "set_status", issue: root, status: "todo" })`; otherwise no action — the event is not held or redelivered |
|
|
@@ -124,7 +125,10 @@ Treat a resync report as an anomaly list, not an instruction. For every zero-own
|
|
|
124
125
|
untriaged-open, or launch-failed issue it names, verify `legion state --json` and the
|
|
125
126
|
current Dispatch issue first. Then heal the verified condition: admit an eligible root, move
|
|
126
127
|
an issue back to its intended status, or use the applicable daemon control path. Do not act
|
|
127
|
-
on stale entries until their source artifact explains the anomaly.
|
|
128
|
+
on stale entries until their source artifact explains the anomaly. An `admission-drift` entry
|
|
129
|
+
needs no healing — the daemon added the tree back to (or removed it from) its admission list in
|
|
130
|
+
the same run; verify only that the same issue does not recur in the next report, and file a
|
|
131
|
+
LEGION issue with both reports if it does.
|
|
128
132
|
|
|
129
133
|
## Mentions
|
|
130
134
|
|