@sjawhar/opencode-legion-envoy 1.20.2 → 1.21.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.
@@ -13649,7 +13649,7 @@ var MessageEventPayloadSchema = object({
13649
13649
  });
13650
13650
  var DispatchTargetedMessagePayloadSchema = MessageEventPayloadSchema.extend({
13651
13651
  id: string2(),
13652
- issue_key: string2(),
13652
+ issue_key: string2().nullable(),
13653
13653
  author: object({ kind: string2(), id: string2() }),
13654
13654
  body: string2(),
13655
13655
  target: string2(),
@@ -13662,6 +13662,7 @@ var MessageDeliveryEventPayloadSchema = object({
13662
13662
  attempt: number2().int().positive().optional(),
13663
13663
  delivery: _enum2(["btw", "aside", "steer"]).optional(),
13664
13664
  session_id: string2().optional(),
13665
+ target: string2().optional(),
13665
13666
  title: string2().optional(),
13666
13667
  state: _enum2(["sent", "failed"]).optional(),
13667
13668
  error: string2().optional()
@@ -15634,17 +15635,18 @@ async function executeDispatchTool(input) {
15634
15635
  }
15635
15636
  case "dispatch_message": {
15636
15637
  const inReplyTo = messageInReplyTo(args);
15637
- const message = await client.message(issue(), {
15638
+ const issueKey = issue();
15639
+ const message = await client.message(issueKey, {
15638
15640
  body: stringArg(args, "body"),
15639
15641
  ...inReplyTo === undefined ? {} : { in_reply_to: inReplyTo },
15640
15642
  actor
15641
15643
  });
15642
- const messageRef = `dispatch://${message.issue_key}/message/${message.id}`;
15644
+ const messageRef = `dispatch://${issueKey}/message/${message.id}`;
15643
15645
  return {
15644
15646
  text: `Posted message ${message.id} (${messageRef})`,
15645
15647
  details: {
15646
- issue: message.issue_key,
15647
- topic: dispatchIssueSubject(message.issue_key, ">"),
15648
+ issue: issueKey,
15649
+ topic: dispatchIssueSubject(issueKey, ">"),
15648
15650
  message: message.id
15649
15651
  }
15650
15652
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjawhar/opencode-legion-envoy",
3
- "version": "1.20.2",
3
+ "version": "1.21.0",
4
4
  "type": "module",
5
5
  "main": "dist/src/server.js",
6
6
  "exports": {
@@ -45,7 +45,7 @@ before step 3. The design gate is not a substitute for review and retro.
45
45
 
46
46
  1. Re-read the issue, its acceptance criteria, the PR, test evidence, and review evidence.
47
47
  Confirm the PR carries both proofs: the implementer's own `E2E (implementer)` line and the tester's `E2E (tester)` line,
48
- each naming a production-like surface (a scratch daemon, a smoke rig, a sandbox repository, a devN
48
+ each naming a production-like surface (the daemon's test harness (`packages/daemon/src/daemon/__tests__/`) and real-process fixtures; a live check at the operator's next daemon restart, recorded on the PR; a sandbox repository, a devN
49
49
  stack, staging, or a local stack with real migrations), a command or run id, an observation, a head
50
50
  SHA, and a negative control. If either is missing, or links only a unit suite, the retro's first
51
51
  durable learning is that gap and the issue goes back — to the implementer for its own proof, to the
@@ -251,7 +251,7 @@ PR opens, and every later phase keeps it current rather than replacing it:
251
251
  ```
252
252
  ## Verification
253
253
 
254
- **CI:** `Tests` run <run-id> — jobs lint, pr-title, typecheck, test all success at <head-sha>.
254
+ **CI:** `Tests` run <run-id> — jobs lint, typecheck, test all success at <head-sha>; `PR Title` run <run-id> — job pr-title success at <head-sha>.
255
255
 
256
256
  **Threads:** <n> resolved, 0 unresolved. Each disposed individually, never in bulk:
257
257
  - Thread <id>: fixed in <commit-sha> — <one line>.
@@ -276,6 +276,7 @@ Verified the implementer's proof by <re-running its command | driving the same s
276
276
  **Fast-follow:** <one named cleanup item and where it will land>, or "none".
277
277
 
278
278
  **Chain:** stacked on <base bookmark> frozen at <sha> / not stacked.
279
+ **Retarget:** Retargeting a pull request to a new base does not re-run Tests; after a retarget, rebase onto the new base and push — the new head runs Tests against the new merge result — and cite that run in the PR body.
279
280
  ```
280
281
 
281
282
  - **Threads are dispositioned individually, never resolved in bulk.** Every open review
@@ -301,11 +302,11 @@ Verified the implementer's proof by <re-running its command | driving the same s
301
302
  changes behavior, hides an error, or breaks a gate is fixed here — never deferred.
302
303
  Findings about naming, duplication, or wording are batched into the single `Fast-follow`
303
304
  line instead of iterating per push.
304
- - **Rebase only on a real conflict.** Sami, 2026-09-11, verbatim:
305
+ - **Rebase only on a real conflict, except after a base retarget.** Sami, 2026-09-11, verbatim:
305
306
  "Please don't do unnecessary rebases (i.e. unless there are merge conflicts). The CI queue is too long and slow."
306
- The implementer rebases the issue branch only when GitHub reports it `CONFLICTING` or the
307
- controller asks because of a conflict — never to pick up `main` or to refresh CI. A single
308
- failed CI job is re-run on its own with `legion gh -- run rerun <run-id> --failed`, never by
307
+ The implementer rebases the issue branch only when GitHub reports it `CONFLICTING`, the controller asks
308
+ because of a conflict, or after the pull request is retargeted to a new base. Otherwise, never rebase to
309
+ pick up `main` or refresh CI. A single failed CI job is re-run on its own with `legion gh -- run rerun <run-id> --failed`, never by
309
310
  pushing a new commit. A conflict-forced rebase that leaves the branch's diff unchanged is a
310
311
  confirmation, not a new round (see *The unchanged-diff check* below). Before rebasing, record
311
312
  the fingerprint at the current tip; after pushing the rebased branch, record it at the new
@@ -317,9 +318,10 @@ Verified the implementer's proof by <re-running its command | driving the same s
317
318
  field names naming, duplication, or wording cleanup only; anything that changes behaviour,
318
319
  hides an error, or breaks a gate lands in this PR.
319
320
  - **The implementer proves the change before its phase completes, and writes the `E2E (implementer)` line when the pull request opens.**
320
- The proof is the changed behaviour exercised on the surface a user reaches it through — a
321
- scratch daemon, a smoke rig, a sandbox repository, a real browser, a devN stack, a local stack
322
- with real migrations — with the exact command or run id, what was observed, the head SHA, and
321
+ The proof is the changed behaviour exercised on the surface a user reaches it through — the daemon's
322
+ test harness (`packages/daemon/src/daemon/__tests__/`) and real-process fixtures; a live check at the
323
+ operator's next daemon restart, recorded on the PR; a sandbox repository, a real browser, a devN stack,
324
+ or a local stack with real migrations — with the exact command or run id, what was observed, the head SHA,
323
325
  one negative control. The same proof goes into `.legion/implement.json` as its required `proof`
324
326
  array (`legion handoff write --phase implement` refuses a payload without one and names the
325
327
  field), and into the PR body, because the reviewer and the merger verify facts on GitHub and