@sjawhar/pi-legion-envoy 5.16.3 → 5.16.5

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/envoy.js CHANGED
@@ -40373,7 +40373,7 @@ function natsAuthOptions(env) {
40373
40373
 
40374
40374
  // ../envoy-client/src/tool-contract.ts
40375
40375
  var DELIVERY_CONTRACT = "Delivery is at-least-once, possibly out of order across topics; use id for dedupe and at for freshness.";
40376
- var TOPIC_GUIDE = "Topic guide (all are under notifications.): agent.<session_id> (subscribe: own inbox); role.<role> " + "(publish-to; holders claim via envoy_role_set). > matches one or more trailing tokens and does not " + "match the base subject. Envoy registers the concrete base when you subscribe to <subject>.>, so " + "the recommended default remains github.<owner>.<repo>.pr.<n>.>. <owner> and <repo> are one token " + "each, with every dot in the name written _ (sjawhar/.github is github.sjawhar._github; " + "acme/site.io is github.acme.site_io), and a topic spelled with the dot receives nothing. " + "Default PR subscription: " + "github.<owner>.<repo>.pr.<n>.> (it receives the quiet PR family): pr.<n> (lifecycle: " + "opened/synchronize/closed; closed carries merged, merge_commit_sha, merged_by, head_sha), " + "pr.<n>.comment, pr.<n>.review, pr.<n>.mention, pr.<n>.checks (one head-checks settlement event: " + 'passed/failed/cancelled/skipped with failing names and URLs; re-fires with superseded_settlement: "true" ' + "when new runs appear for the same head). Other GitHub: issue.<n>, issue.<n>.comment, " + "issue.<n>.mention, mention, push.branch.<name>, push.tag.<name>, workflow.<file>.<action> (only " + "runs without an associated PR); slack.<team>.<channel>.message|mention and " + "slack.<team>.<channel>.thread.<ts>.message|mention; ghostwispr.<session>.<kind>; " + "whatsapp.<phone>.<jid>.<kind>; envoy.exceptions.<original-topic>.";
40376
+ var TOPIC_GUIDE = "Topic guide (all are under notifications.): agent.<session_id> (subscribe: own inbox); role.<role> " + "(publish-to; holders claim via envoy_role_set). > matches one or more trailing tokens and does not " + "match the base subject. Envoy registers the concrete base when you subscribe to <subject>.>, so " + "the recommended default remains github.<owner>.<repo>.pr.<n>.>. <owner> and <repo> are one token " + "each, with every dot in the name written _ (sjawhar/.github is github.sjawhar._github; " + "acme/site.io is github.acme.site_io), and a topic spelled with the dot receives nothing. " + "Default PR subscription: " + "github.<owner>.<repo>.pr.<n>.> (it receives the quiet PR family): pr.<n> (lifecycle: " + "opened/synchronize/closed; closed carries merged, merge_commit_sha, merged_by, head_sha), " + "pr.<n>.comment, pr.<n>.review, pr.<n>.mention, pr.<n>.checks (one settlement event per commit whose checks settle, the head or not, naming its sha: " + 'passed/failed/cancelled/skipped with failing names and URLs; re-fires with superseded_settlement: "true" ' + "when new runs appear for the same commit). Other GitHub: issue.<n>, issue.<n>.comment, " + "issue.<n>.mention, mention, push.branch.<name>, push.tag.<name>, workflow.<file>.<action> (only " + "runs without an associated PR); slack.<team>.<channel>.message|mention and " + "slack.<team>.<channel>.thread.<ts>.message|mention; ghostwispr.<session>.<kind>; " + "whatsapp.<phone>.<jid>.<kind>; envoy.exceptions.<original-topic>.";
40377
40377
  var URGENCY_VALUES = EnvelopeSchema.shape.urgency.unwrap().options;
40378
40378
  var EXPECTS_REPLY_VALUES = EnvelopeSchema.shape.expects_reply.unwrap().options;
40379
40379
  function messageMetadataShape(schema) {
package/dist/legion.js CHANGED
@@ -39253,7 +39253,7 @@ import { logger } from "@oh-my-pi/pi-utils";
39253
39253
  // package.json
39254
39254
  var package_default = {
39255
39255
  name: "@sjawhar/pi-legion-envoy",
39256
- version: "5.16.3",
39256
+ version: "5.16.5",
39257
39257
  type: "module",
39258
39258
  omp: {
39259
39259
  extensions: [
@@ -154,7 +154,7 @@ exactly one owner to every owner-scoped tool: `issue` for an issue, or `project`
154
154
  that GitHub issue or pull request. Only `dispatch_issue` with `external` creates a native issue; if no issue is linked, call
155
155
  `dispatch_issue({ external: "owner/repo#n", project: "<project>", title: "<title>" })` before addressing it.
156
156
 
157
- Issue reads include `rank`, the server-owned ordering key used by project boards; reorder through `PATCH /api/v1/issues/{key}` with neighboring issue keys. They also include nullable coarse priority (`P0` highest through `P3` lowest) and `assignee`: the lowercase GitHub login of the human who answers the issue's asks, or `null` when nobody holds it. `dispatch_read` of an issue prints it as `Assignee: <login>` or `Assignee: unassigned`.
157
+ Issue reads include `rank`, the server-owned ordering key used by project boards; reorder through `PATCH /api/v1/issues/{key}` with `{"rank": {"before": "<key>", "after": "<key>"}}`, either neighbor optional and both in the issue's project. A bearer caller also names its own session in that body, `"actor": {"kind": "session", "id": "<your session id>"}`, or the server refuses with `ACTOR_KIND`. They also include nullable coarse priority (`P0` highest through `P3` lowest) and `assignee`: the lowercase GitHub login of the human who answers the issue's asks, or `null` when nobody holds it. `dispatch_read` of an issue prints it as `Assignee: <login>` or `Assignee: unassigned`.
158
158
 
159
159
  ### Who answers an ask
160
160
 
@@ -172,6 +172,36 @@ dispatch_issue({ project, title, parent?, external?, spec?, force?, labels?: str
172
172
  `details` `{ issue }`; creating an issue does not subscribe you to it (see [Following](#following)). Use `dispatch_issue` only to create an issue; never use it to park a question. When `spec` is supplied,
173
173
  follow [Writing a spec](#writing-a-spec).
174
174
 
175
+ ## Choosing what to work on
176
+
177
+ When you finish an issue, or are told to work on the next thing, take the top ready issue of the
178
+ whole backlog, across every project: status `todo`, highest priority first, then board rank. There
179
+ are no areas: a standing role, a product owner and a lane each take the top issue like everyone
180
+ else (Sami, 2026-09-27, dispatch://AGENTC-34/ask/01ed2956-73cc-48d2-8ed4-7a86c6d439b1). `todo`
181
+ means ready: specced, unblocked, and waiting on neither a deploy nor a decision. An issue that
182
+ waits on one belongs in `backlog`, with what it waits on said on the issue.
183
+
184
+ Hold at most three issues in flight (`in_progress`, `testing`, `needs_review` or `retro`), of any
185
+ kind (Sami, 2026-09-27, answering dispatch://AGENTC-34/ask/1aeb8f2e-0950-4eaa-aaac-24286c9dd3ca;
186
+ the question proposed two, and his answer set three). The limit is per agent and has nothing to do
187
+ with the week's priorities (Sami, 2026-09-28, reply a7647eb0 on
188
+ dispatch://AGENTC-393/ask/b773d9f6): the priorities decide only what you pull next. Past three:
189
+ push any unfinished work, say where in one comment on the issue, move it to `backlog` and clear
190
+ its route. Each issue counts on its own; a child does not ride under its parent's slot.
191
+ In-flight issues with no owner at all go
192
+ back to `backlog` as well: no claim or route held by a live session, no Dispatch activity in the
193
+ last day, and no pull request moving on GitHub (an owner working there leaves no Dispatch trace).
194
+ The order keeper sweeps those. Never write the status of an issue that carries the `legion`
195
+ label, or of any issue under one: the Legion daemon writes those statuses, and moving one of its
196
+ admitted roots out of its flow parks the tree and stops its workers.
197
+
198
+ One agent keeps the backlog's order against those priorities, with Sami
199
+ (dispatch://AGENTC-34/ask/f6780f9e-8b96-49eb-9be7-7c7f2036d5cc). Setting an issue's priority
200
+ stays yours ([Priority is yours to set](#priority-is-yours-to-set)); reordering the board does not.
201
+ When the top of the backlog looks wrong, or a priority's next step is not yet a ready issue,
202
+ publish it to `notifications.role.backlog-order`, which the order keeper holds, instead of
203
+ reordering the board yourself.
204
+
175
205
  ## Claim the issue before you work it
176
206
 
177
207
  Two sessions once spent a night implementing the same issue, because nothing on it said who was
@@ -300,7 +330,7 @@ This is not search: it matches no text. Use `dispatch_search` for a keyword or p
300
330
 
301
331
  ### The owner audit
302
332
 
303
- As the owner of a surface, list your area's P0 and P1 issues and staff or close each one nobody
333
+ As the owner of a surface, list the project's P0 and P1 issues and staff or close each one nobody
304
334
  has started:
305
335
  ```ts
306
336
  dispatch_issues({ project, priority: [0, 1], limit: 250 })
@@ -28,7 +28,10 @@ NATS `>` matches **one or more** trailing tokens, so it does not match the lifec
28
28
  subject and its child events.
29
29
 
30
30
  For a typical push, this receives `pr.42` with `synchronize`, then any comments or reviews, then
31
- one `pr.42.checks` event when that head's checks settle. The family is `pr.42` (lifecycle),
31
+ one `pr.42.checks` event when that head's checks settle. A settlement is published for every
32
+ commit of the pull request whose checks settle, the current head or not (a head pushed with
33
+ GitHub's `skip-checks` trailer runs none, so the commit before it settles for it), and its `sha`
34
+ names the commit: compare it with the head you are waiting on. The family is `pr.42` (lifecycle),
32
35
  `pr.42.comment`, `pr.42.review`, `pr.42.mention`, and `pr.42.checks`. A closed lifecycle payload
33
36
  carries `merged`, `merge_commit_sha`, `merged_by`, and `head_sha`.
34
37
 
@@ -147,13 +150,14 @@ advertises.
147
150
  ## Waiting for CI or a merge
148
151
 
149
152
  Subscribe to `notifications.github.example-org.example-repo.pr.42.>` and end the turn. The single
150
- `pr.42.checks` event wakes you when the current head settles; a `pr.42` `closed` event with
153
+ `pr.42.checks` event whose `sha` is the current head wakes you when it settles (an earlier
154
+ commit's settlement can arrive first); a `pr.42` `closed` event with
151
155
  `merged: true` tells you the PR merged. Do not create `gh` pollers.
152
- Settlement waits for the head to be quiet for a few seconds, every reported check run to finish,
156
+ Settlement waits for the commit to be quiet for a few seconds, every reported check run to finish,
153
157
  and every recorded GitHub check suite to be `completed`. It covers those reported checks and suites
154
- for the head, not GitHub's required-checks set; until then, a silent subscription is normal.
158
+ for that commit, not GitHub's required-checks set; until then, a silent subscription is normal.
155
159
 
156
- Check settlement is at-least-once: a settlement can be followed by a `superseded_settlement: "true"` payload. Every settlement carries its attempt set `check_runs` — the latest GitHub check-run id per check name, sorted by name — plus the listener's `generation` (the record's state version) and `snapshot` (the record's hash). Consumers order same-head settlements by the attempt set, compared per shared name: no id lower and some id higher (or a new name — a new name counts as higher) is newer; every shared id equal and no new name is the same set; no id higher, no new name, and some id lower is older; anything else (a higher or new alongside a lower) is a mixed view and is dropped as a conflict (names only in the stored set are ignored — a check can vanish from GitHub's view, and a record recreated after the seven-day KV TTL starts sparse). Within one producer record per-name ids never decrease, and a consumer's fence is the per-name maximum over every view it has accepted — an accepted set merges into the fence, nothing is pruned — so the fence never decreases either: a newer attempt is newer whatever its completion time, no timestamps take part in ordering, and a name an incomplete view omitted cannot later reappear as new. At the same set the listener's `generation` orders its own settlements: lower is stale; equal is a duplicate when the `snapshot` matches and otherwise a conflict (an equal pair with a different snapshot cannot occur within one record's lifetime; a recreated record may reuse one and is dropped). A live settlement is a possibly incomplete view of the head (a missed webhook, a record recreated after the KV TTL): it decides the outcome of every name it reports — at any id the ordering accepted, including the same run observed in place — and says nothing about the rest: a known failure among them stands (the consumer keeps failure names, not a per-name status map), and the head is red while any failure remains. A consumer that reconciles a verdict from GitHub's rollup compares the rollup's attempt set the same way, but GitHub's read is complete: its failing check runs and failing commit statuses replace the stored ones wholesale. Statuses have no check run and the listener never sees them, so a consumer keeps them apart from check-run failures: a check run that shares a status's name cannot retire it — only GitHub does (likewise a deleted check's failure). A newer rollup set merges into the fence and takes the identity (no listener generation); the same set applies GitHub's verdict and keeps the listener identity for duplicate detection; an older, mixed, or empty-over-fenced set is ignored. A terminal read (green or red) then holds the tie at that set: a live settlement at the same set is accepted only if its effective outcome — the check-run failures it reports plus the stored ones it omits and the stored commit-status failures — agrees with the reconciled verdict, refreshing the listener identity without releasing GitHub's authority; a disagreeing one is stale whatever its generation until the set advances; a pending or cancelled-only read uncertifies a green head, leaves a red one untouched, and holds nothing — it releases any authority held at that set — so the terminal live settlement that follows applies at once, subject to the ordinary generation and duplicate rules (a replay or a lower generation still does not apply). Pending is therefore not a commutative join: a pending read after a live green uncertifies it until the next terminal view. Two remainders. An in-place conclusion change on an existing run id: GitHub's view stands and the listener's is recovered by the next successful, non-skipped read at that set — the dropped delivery is not replayed. A check whose highest run is deleted on GitHub: the fence keeps that id, so a rollup reporting a lower run under the same name is older until a newer run appears. A consumer that orders head changes by the PR's `updated_at` (GitHub's second resolution) accepts a read of a different head at an equal clock — a stale read returning the previous head within the same second as its replacement rewinds that consumer until its next accurate, non-skipped read. A head publishes only when at least one check has a positive run id; legacy checks without one remain in the status groups and failing names but not in `check_runs`. A legacy in-progress check whose completion is never observed holds the head unsettled until it reruns; rerun the affected check to release it.
160
+ Check settlement is at-least-once: a settlement can be followed by a `superseded_settlement: "true"` payload. Every settlement carries its attempt set `check_runs` — the latest GitHub check-run id per check name, sorted by name — plus the listener's `generation` (the record's state version) and `snapshot` (the record's hash). Consumers order settlements of one commit by the attempt set, compared per shared name: no id lower and some id higher (or a new name — a new name counts as higher) is newer; every shared id equal and no new name is the same set; no id higher, no new name, and some id lower is older; anything else (a higher or new alongside a lower) is a mixed view and is dropped as a conflict (names only in the stored set are ignored — a check can vanish from GitHub's view, and a record recreated after the seven-day KV TTL starts sparse). Within one producer record per-name ids never decrease, and a consumer's fence is the per-name maximum over every view it has accepted — an accepted set merges into the fence, nothing is pruned — so the fence never decreases either: a newer attempt is newer whatever its completion time, no timestamps take part in ordering, and a name an incomplete view omitted cannot later reappear as new. At the same set the listener's `generation` orders its own settlements: lower is stale; equal is a duplicate when the `snapshot` matches and otherwise a conflict (an equal pair with a different snapshot cannot occur within one record's lifetime; a recreated record may reuse one and is dropped). A live settlement is a possibly incomplete view of the head (a missed webhook, a record recreated after the KV TTL): it decides the outcome of every name it reports — at any id the ordering accepted, including the same run observed in place — and says nothing about the rest: a known failure among them stands (the consumer keeps failure names, not a per-name status map), and the head is red while any failure remains. A consumer that reconciles a verdict from GitHub's rollup compares the rollup's attempt set the same way, but GitHub's read is complete: its failing check runs and failing commit statuses replace the stored ones wholesale. Statuses have no check run and the listener never sees them, so a consumer keeps them apart from check-run failures: a check run that shares a status's name cannot retire it — only GitHub does (likewise a deleted check's failure). A newer rollup set merges into the fence and takes the identity (no listener generation); the same set applies GitHub's verdict and keeps the listener identity for duplicate detection; an older, mixed, or empty-over-fenced set is ignored. A terminal read (green or red) then holds the tie at that set: a live settlement at the same set is accepted only if its effective outcome — the check-run failures it reports plus the stored ones it omits and the stored commit-status failures — agrees with the reconciled verdict, refreshing the listener identity without releasing GitHub's authority; a disagreeing one is stale whatever its generation until the set advances; a pending or cancelled-only read uncertifies a green head, leaves a red one untouched, and holds nothing — it releases any authority held at that set — so the terminal live settlement that follows applies at once, subject to the ordinary generation and duplicate rules (a replay or a lower generation still does not apply). Pending is therefore not a commutative join: a pending read after a live green uncertifies it until the next terminal view. Two remainders. An in-place conclusion change on an existing run id: GitHub's view stands and the listener's is recovered by the next successful, non-skipped read at that set — the dropped delivery is not replayed. A check whose highest run is deleted on GitHub: the fence keeps that id, so a rollup reporting a lower run under the same name is older until a newer run appears. A consumer that orders head changes by the PR's `updated_at` (GitHub's second resolution) accepts a read of a different head at an equal clock — a stale read returning the previous head within the same second as its replacement rewinds that consumer until its next accurate, non-skipped read. A head publishes only when at least one check has a positive run id; legacy checks without one remain in the status groups and failing names but not in `check_runs`. A legacy in-progress check whose completion is never observed holds the head unsettled until it reruns; rerun the affected check to release it.
157
161
 
158
162
  ## When a subscription is silent
159
163
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjawhar/pi-legion-envoy",
3
- "version": "5.16.3",
3
+ "version": "5.16.5",
4
4
  "type": "module",
5
5
  "omp": {
6
6
  "extensions": [