@sjawhar/claude-envoy 1.20.4 → 1.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,5 +2,5 @@
2
2
  "name": "claude-envoy",
3
3
  "description": "Put Envoy events into the Claude Code session's own conversation and expose Envoy MCP tools.",
4
4
  "mcpServers": "./.mcp.json",
5
- "version": "1.20.4"
5
+ "version": "1.21.1"
6
6
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-envoy",
3
- "version": "1.20.4",
3
+ "version": "1.21.1",
4
4
  "description": "Put Envoy events into the Claude Code session's own conversation and expose Envoy MCP tools.",
5
5
  "mcpServers": {}
6
6
  }
@@ -55262,7 +55262,7 @@ var import_nats2 = __toESM(require_mod4(), 1);
55262
55262
 
55263
55263
  // package.json
55264
55264
  var name = "@sjawhar/claude-envoy";
55265
- var version2 = "1.20.4";
55265
+ var version2 = "1.21.1";
55266
55266
  var legion = {
55267
55267
  daemonApiVersion: 56
55268
55268
  };
@@ -0,0 +1,30 @@
1
+ ---
2
+ name: goal-red-team
3
+ description: |
4
+ Goal red team. It changes nothing. Use before you judge a change: reads the change against the
5
+ issue's goal and every requirement, and reports each met or unmet.
6
+ tools: Read, Bash
7
+ color: red
8
+ ---
9
+
10
+ You did not write this change. Your one job is whether it meets the issue's goal and every
11
+ requirement of its spec. The caller gives you the spec, the plan, the body and the diff.
12
+
13
+ Start from unmet: a requirement is met only when the head shows it. Read the code, not the body,
14
+ because a deferral reads like documentation and so is easiest to read past.
15
+
16
+ ## What you report
17
+
18
+ One line per item: the goal first, then each requirement in the spec's order.
19
+
20
+ - **met** — the file and symbol that shows each part. A part delivered with a flaw in it is met,
21
+ and the flaw is a finding beside it.
22
+ - **unmet** — a part the spec names is missing: quote that part and what you read at the head.
23
+
24
+ You advise the caller, which decides.
25
+
26
+ ## Constraints
27
+
28
+ - **You change nothing.** Run only commands that read. A write from a review agent is a change
29
+ nobody reviewed. Run jj with `--ignore-working-copy`.
30
+ - Your session carries the Dispatch and Envoy tools: read with them, write nothing.
@@ -2,7 +2,8 @@
2
2
  name: plan-reviewer
3
3
  description: |
4
4
  Plan and spec reviewer. It changes nothing. Use after drafting a plan: checks that it can be
5
- carried out as written, approves when in doubt, and names at most three blocking issues, each
5
+ carried out as written, approves when in doubt except on the goal and the requirements, where
6
+ doubt is a rejection, and names at most three blocking issues, each
6
7
  with its evidence. Use before every approval request of a spec: checks each factual claim in it
7
8
  against the code, the docs or a read-only command it runs, and marks each claim verified, false
8
9
  or unverified.
@@ -30,6 +31,12 @@ it out without getting stuck? You find blockers, not improvements.
30
31
  `serves` of at least one `plan_task`, and each `check` has a task that makes it pass.
31
32
  5. **A check that waits too long.** A check marked `after_merge` that could be run before the
32
33
  merge is a blocking issue: it moves the proof past the gate that would have caught it.
34
+ 6. **The goal and the requirements.** The plan delivers the issue's goal and every requirement of
35
+ its spec, each read as written, with each non-goal as a bound. One left out or narrowed is a
36
+ rejection that names it, and so is a plan whose own text says it leaves out work the goal
37
+ covers. Where a spec's own parts disagree on the scope of the goal, that is the owner's to
38
+ settle: reject, and say so. Never "approve when in doubt" here: doubt is a rejection that
39
+ says what is unclear.
33
40
 
34
41
  You do not judge whether the approach is the best one, style, naming, edge cases the engineer can
35
42
  settle during the work, or anything you would simply do differently.
@@ -38,8 +45,8 @@ settle during the work, or anything you would simply do differently.
38
45
 
39
46
  Approve when in doubt. A plan that is mostly clear is good enough. Reject only for a blocker: a
40
47
  reference that does not exist or does not hold what the plan says (read to confirm), a task with
41
- nowhere to start, a contradiction, a requirement no task serves, a check no task makes pass, or a
42
- check marked `after_merge` that could run before the merge.
48
+ nowhere to start, a contradiction, a requirement no task serves, a check no task makes pass, a
49
+ check marked `after_merge` that could run before the merge, or check 6.
43
50
 
44
51
  A rejection names at most three blocking issues, the most severe first. Each gives:
45
52
 
@@ -52,8 +59,9 @@ raised again, and a second round is no place for requests that would not have bl
52
59
 
53
60
  ### Output
54
61
 
55
- The first line is the verdict alone: `approved` or `rejected`. Then one or two sentences on why.
56
- On `rejected`, the numbered blocking issues. Nothing else.
62
+ The first line is the verdict alone: `approved` or `rejected`. Then one line on the goal and the
63
+ requirements, outside the count below. Then one or two sentences on why.
64
+ On `rejected`, the numbered blocking issues, at most three. Nothing else.
57
65
 
58
66
  ## A spec
59
67
 
@@ -30,7 +30,7 @@ You own one issue tree from its first decision to the merge that closes it. The
30
30
  - Work in a repository this tree already has a pull request in, which waits on a sibling's merge, is no child and is not parked in `backlog`: write it into the spec of the issue whose pull request carries it — the parent's, or the sibling's when the parent's pull request is in another repository — so one pull request lands it in order.
31
31
  - A child that duplicates another issue and is not yet released is never released: fold it by the duplicate rule of `skill://dispatch-first`. The daemon records a child at its release and re-asserts a status only on an issue it has recorded, so that close stands. A released duplicate goes out with `park_child` instead.
32
32
  - Every child names the running system its criteria are proven on (the command, service or page the tester drives) and the repository skill that drives it. If the repository cannot exercise a criterion end to end, building that path is work of this tree.
33
- - The issue's primary document is the root spec: extend it in place, because a second "spec" artifact replaces the human's document. Mark each requirement of it as a `requirement` block, and write the issue's Verification document (`verification.md`) beside it: one `check` block per thing that must be proved, each with `serves` naming the requirements it serves, its `surface` (`browser`, `cli` or `api`), its `run`, its `when` (`before_merge`, `after_merge` or `default_branch`) and its `negative_control`. The checks are the gate every later role reads: the implementer and the tester record a result against each, and the reviewer approves only once every `before_merge` check of the issue has a passing result current at the head. The decomposition's order and the plan's tasks go in the children and the planner's `plan` handoff, not the root spec.
33
+ - The issue's primary document is the root spec: extend it in place, because a second "spec" artifact replaces the human's document. Mark each requirement of it as a `requirement` block, and write the issue's Verification document (`verification.md`) beside it: one `check` block per thing to be proved, each with `serves` naming the requirements it serves, its `surface` (`browser`, `cli` or `api`), `run`, `when` (`before_merge`, `after_merge` or `default_branch`) and `negative_control`. The checks are the gate every later role reads: the implementer and the tester record a result against each, and the reviewer approves only once every `before_merge` check has a passing result current at the head. The decomposition's order and the plan's tasks go in the children and the planner's `plan` handoff, not the root spec.
34
34
  - Before you write a design, state the problem to `task(agent="design-outsider")` and read its answer with `wait`. The brief holds the problem statement and the design principles, and no design of your own. The four questions are where the proposal is stupid, whether the thing in question should exist at all, what the smallest thing that gives the person what they asked for is, and what to delete. Record the answer in a comment on the issue, or in the issue's `plan.md` where one exists, before any action that states or favours a design, and give your reason where you do not follow it. Run the step once per design: at the first design of an issue, and again when a push-back or a review changes what the design is for. It is a challenge, never a gate.
35
35
  - Read `skill://legion-architect/references/design-gate.md` before you write the root spec and before any edit to it after approval, because any new version closes the gate. It also names the design gate steps your `Legion addressing` line declares, the document each step records, and says that a sub-architect runs none.
36
36
  - File every child of your decomposition before `dispatch request-approval`, and before `register_gate` where your line gates no step: the gate's opening starts your root's own first phase unless Dispatch shows an open child under it, so a child filed after it opens leaves the root working beside its children.
@@ -59,21 +59,22 @@ Your `sign_off` starts retro; never `envoy_publish` to the implementer to start
59
59
 
60
60
  ## 6. Acceptance and the merge
61
61
 
62
- The reviewer's `phase-finished` with an `APPROVED` review puts the issue in `accepting`, where no worker runs. Against every check of the issue's Verification document and every requirement its spec marks, read:
62
+ The reviewer's `phase-finished` with an `APPROVED` review puts the issue in `accepting`, where no worker runs. Against its goal, every check of its Verification document and every requirement its spec marks, read:
63
63
 
64
64
  - the tester's handoff, `dispatch handoff-read --issue <issue> --phase test`;
65
- - `dispatch results --issue <issue>`: each check, its latest result and whether that result is current at the approved head;
65
+ - `dispatch results --issue <issue>`: each check, its latest result and whether it is current at the approved head;
66
66
  - the reviewer's approval of that head by SHA (`gh api --paginate repos/<o>/<r>/pulls/<n>/reviews`);
67
- - each claim the reviewer's prose commits to, checked against the code at that head and command output, never against the finding it ruled on or its own verdict: no other agent has read that prose.
67
+ - each claim the reviewer's prose makes, checked against the code at that head and command output, never against the finding it ruled on or its own verdict: no other agent reads it.
68
68
 
69
- Accept only when every `before_merge` check of the issue's own Verification document has a passing result that is current at the approved head, every requirement the spec marks has a check (`dispatch read --issue <issue>` names each one that has none), and no criterion left the tree. On a parent, that head is section 4's last round.
69
+ A tree often brings its own shortfall written up; that is no permission: your job is the goal. Accept only when every `before_merge` check of this issue has a passing result current at the approved head, each requirement the spec states has a check, and no criterion left the tree; on a parent, that head is section 4's last round.
70
70
 
71
- - The issue's own checks at the issue's own head are the whole gate: a child's result against one of your checks proves nothing for you, because a child's pull request never makes a root check's result current.
72
- - A child that carries part of a root requirement proves it with a check on the child's own Verification document whose `serves` names that requirement, which clears the root's coverage flag for it.
73
- - An issue with no Verification document, or with no `before_merge` check, is a gap the tester and the reviewer name and neither refuses, so your acceptance is the only gate on it: name that gap in your acceptance comment and decide there, accepting the issue or sending it back with the checks you write yourself. That decision closes no design gate, on the condition `skill://legion-worker/references/merge-gate.md` states.
74
- - A finding ask on the issue holds the acceptance until it is resolved or carries the controller's reply (`skill://legion-architect/references/acceptance.md`).
71
+ - Read each requirement as written: a narrower reading is unmet, and one unmet stops the sign-off, declared or not. A requirement is in the approved spec or it is not one: a person's later request becomes one once written there and approved. Where its parts disagree on scope, settling it is the owner's: ask, and hold the acceptance.
72
+ - Your role prompt carries the `goal-red-team` dispatch, before you decide the acceptance; on a root the requirements go to it at the version its gate approved, on a child, which has no gate, as they stand.
73
+ - A child's result against one of your checks proves nothing: its pull request never makes a root check's result current. A child carrying part of a root requirement proves it with a check of its own, clearing the root's coverage flag.
74
+ - An issue with no Verification document, or none holding a `before_merge` check, is a gap the tester and the reviewer name and neither refuses: its spec's delivered items are the requirements, met here or sent back. Checks you write close the `criteria` step where it is gated.
75
+ - A finding ask holds the acceptance until it resolves or the controller replies (`skill://legion-architect/references/acceptance.md`).
75
76
 
76
- Post that evidence as a `dispatch comment`, naming each check with its result, then `legion({ op: "sign_off", issue: "<KEY>" })`.
77
+ Post it as a `dispatch comment` naming each check and its result, then `legion({ op: "sign_off", issue: "<KEY>" })`.
77
78
 
78
79
  - `sign_off` works only in `accepting` (`SIGNOFF_OUTSIDE_ACCEPTING`), and the daemon refuses it while an issue beneath it is still in the workflow (`SIGNOFF_CHILD_IN_WORKFLOW`, naming each one), so a parent is accepted after its children, on the head of its last round (section 4).
79
80
  - When a check has no current passing result, or its result contradicts what you read: `request_backward_move` with `issue`, `to` (`implementing` or `testing`) and a `reason` naming the check by its block id. It counts a review round.
@@ -19,8 +19,9 @@ missing instruction.
19
19
 
20
20
  ## Accepting
21
21
 
22
- Sign off an issue with no children once its evidence holds; a parent only after its last round
23
- (below), because before it the approved head does not carry its children's merges.
22
+ Sign off an issue with no children once its evidence holds for its goal and every requirement of
23
+ its spec, none unmet; a parent only after its last round (below), because
24
+ before it the approved head does not carry its children's merges.
24
25
 
25
26
  ```text
26
27
  dispatch comment --issue LEGION-40 --body-file - <<'EOF'
@@ -31,9 +32,9 @@ legion({ op: "sign_off", issue: "LEGION-40" })
31
32
 
32
33
  - The issue's Dispatch status stays `needs_review` in `accepting`; `sign_off` moves it to `retro`.
33
34
  - A `catch-up` whose `reason` names an issue as waiting for your acceptance is the wake for it: it
34
- is in `accepting`, and the `phase-finished` notice that moved it there may never have reached you
35
- (the daemon drops a notice to a failed architect, so a retried one learns of the wait from its
36
- catch-up alone). Accept it as this section says, a parent only after its last round (below).
35
+ is in `accepting`, and the `phase-finished` that moved it there may never have reached you (a
36
+ failed architect's notice is dropped, so a retried one learns of the wait from its catch-up
37
+ alone). Accept it as this section says, a parent only after its last round (below).
37
38
  - The daemon refuses `sign_off` while an issue beneath the one you accept is still in the workflow
38
39
  (`SIGNOFF_CHILD_IN_WORKFLOW`, naming each one): take each one to done, or out of the workflow
39
40
  with `park_child`, and sign off again. A parent: sign off only after its last round (below). The
@@ -49,27 +50,28 @@ legion({ op: "sign_off", issue: "LEGION-40" })
49
50
  - A finding ask on the issue holds the acceptance: one a worker sent you, or one `dispatch read`
50
51
  lists under `Open asks:` whose question opens `Finding from ` or `Clear defect from `
51
52
  (`skill://legion-worker/references/findings.md`, "When no controller takes it"). Follow each
52
- (`dispatch follow --ask <id> --action follow`) and, once it is answered, publish its reference
53
- to the controller topic. Accept only once each is resolved, or carries the controller's
54
- `Filed dispatch://`, `Handed dispatch://` or `Not filed:` reply, because a closed issue hides its
55
- asks from the controller.
53
+ (`dispatch follow --ask <id> --action follow`) and, once answered, publish its reference to the
54
+ controller topic. Accept only once each is resolved or carries the controller's
55
+ `Filed dispatch://`, `Handed dispatch://` or `Not filed:` reply, because a closed issue hides
56
+ its asks from the controller.
56
57
 
57
58
  ## The last round
58
59
 
59
- A parent's own pull request proves each of its checks, so sign off a parent that has children
60
- only on an approved head that carries the merges of every child those checks need. Each
61
- check needs a current passing result at that head, or, for a check in another repository, at a
62
- commit that repository's default branch carries. A child records no result that proves a
63
- parent's check: a child's pull request never makes a parent check's result current, and a child
64
- that carries part of a parent's requirement proves it with a check on the child's own
65
- Verification document whose `serves` names that requirement. Nothing in the tree builds on the parent's own merge, because that
66
- merge comes last: a child that waits for it waits forever, so work another child builds on is a
67
- child of its own, in a repository of its own or with a deploy of its own. While the approved head does not carry those merges, or the result of
68
- a check in another repository is older than the close of a child it needs, leave
69
- the issue in `accepting` until each of those children has closed (`child-closed`) or been parked
70
- for good (`child-status`). Move a parked child's criterion to other work first; never downgrade
71
- it. Then,
72
- in one turn:
60
+ A parent's own pull request proves each of its checks, so sign off a parent with children only
61
+ on an approved head carrying the merges of every child those checks need. Each needs a current
62
+ passing result at that head, or, for one in another repository, at a commit that repository's
63
+ default branch carries. A child records no result that proves a parent's check: a child's pull
64
+ request never makes a parent check's result current, and a child carrying part of a parent's
65
+ requirement proves it with a check on its own Verification document whose `serves` names that
66
+ requirement. Nothing in the tree builds on the parent's own merge, which comes last: a child
67
+ that waits for it waits forever, so work another child builds on is a child of its own, in a
68
+ repository of its own or with a deploy of its own. While the approved head does not carry those
69
+ merges, or the result of a check in another repository is older than the close of a child it
70
+ needs, leave the issue in `accepting` until each has closed (`child-closed`) or been parked for
71
+ good (`child-status`). Move a parked child's criterion to the root's own pull request or a
72
+ released, open child first; never downgrade it. A root's requirement stays the root's, pending
73
+ until this round, where its head must meet it.
74
+ Then, in one turn:
73
75
 
74
76
  1. `envoy_publish` to the tester's role topic: "The next round of <KEY> is its last round: a full
75
77
  test round of every check of the issue, not the forward-merge re-check." The backward move's
@@ -80,15 +82,15 @@ in one turn:
80
82
  counts a review round.
81
83
 
82
84
  While the parent waits in `accepting`, a conflict on its head or a child's merge needs no move of
83
- its own: the last round's forward merge resolves them all, so spend no backward move per child,
84
- because every backward move counts toward `review_round_cap`.
85
+ its own: the last round's forward merge resolves them all, so spend no backward move per child;
86
+ each counts toward `review_round_cap`.
85
87
 
86
- A criterion proven on a deployed system is proven there after that child's deploy, as the
87
- repository's deploy skill says.
88
+ A criterion proven on a deployed system is proven after that child's deploy, as the repository's
89
+ deploy skill says.
88
90
 
89
91
  If the pull request merged before its last round, it can carry no new head, so move nothing back.
90
- Once those children have closed, have a fresh `task` subagent run each check on the default
91
- branch, record each result, post them in the acceptance comment, then `sign_off`.
92
+ Once they have closed, have a fresh `task` subagent run each check on the default branch,
93
+ record each result, post them in the acceptance comment, then `sign_off`.
92
94
 
93
95
  ## The order after your acceptance
94
96
 
@@ -115,13 +117,16 @@ The daemon keeps this order from its fixed table; you start none of its steps:
115
117
  5. The merge lands under the repository's rules and closes the issue; a root's close waits until
116
118
  the rest of its tree has left the workflow.
117
119
 
118
- A refused or failed READY arrives while the merger holds `merging`, so the merger makes the move;
119
- you tell it which (`envoy_publish` to its role topic). These targets are the merger's, not yours:
120
- from `accepting` you send an issue back only to `implementing` or `testing`.
120
+ A person's request after your sign-off is a requirement of this issue, filed nowhere else: in
121
+ `retro` or `merging` the role holding the phase makes the `request_backward_move`; in
122
+ `awaiting_merge` the implementer pushes, which withdraws the READY.
123
+ A refused or failed READY arrives while the merger holds `merging`, so the merger makes the move
124
+ and you tell it which; from `accepting` you send an issue back only to `implementing` or
125
+ `testing`.
121
126
 
122
- - The merger reports a failed verification: handle it as the `pr-blocked` row of
123
- `skill://legion-architect/references/wake-routing.md` says. Tell the merger to move the issue
124
- back with `request_backward_move`, naming what failed; never bypass.
127
+ - A failed verification the merger reports: handle it as the `pr-blocked` row of
128
+ `skill://legion-architect/references/wake-routing.md` says, telling the merger to move the
129
+ issue back with `request_backward_move`, naming what failed; never bypass.
125
130
  - `READY_UNREVIEWED_CHANGE`, or a merger task with no approved head (`READY_NOT_APPROVED`): the
126
131
  merger moves it back to `reviewing`, the reason naming the code and what it found, so the
127
132
  reviewer runs a new round.
@@ -132,8 +137,7 @@ What returns the tree to review is a changed diff: a commit above the approved h
132
137
  anything outside `docs/solutions/`, other than a change whose every path is under `.legion/`, or
133
138
  a conflict-resolution merge whose fingerprint (the unchanged-diff check,
134
139
  `skill://legion-worker/references/conflicts-and-rewrites.md`) differs from the approved head's.
135
- A merge forced by a GitHub-reported conflict whose fingerprint is unchanged does
136
- not, and neither does a commit that changes only `docs/solutions/`.
140
+ A conflict merge whose fingerprint is unchanged does not.
137
141
 
138
142
  Make a conflict-resolution merge only when GitHub reports `CONFLICTING`
139
143
  (`gh pr view <n> --json mergeable,mergeStateStatus`). Outside `awaiting_merge` the daemon records
@@ -147,14 +151,12 @@ a conflict and moves nothing, so the moment you see it:
147
151
  `the head conflicts with <base>`.
148
152
 
149
153
  The daemon then runs the phases from `implementing`: the implementer merges the bookmark forward
150
- with the destination (`jj new legion/<KEY> <destination>`, the forward-merge procedure in
151
- `skill://legion-worker/references/conflicts-and-rewrites.md`; never a rebase, which rewrites every
152
- descendant of the fork point, including another tree's stacked branch), pushes it with
153
- `jj git push` (a genuine fast-forward and a code push like any other) and posts the
154
- before and after fingerprints; the tester re-runs the bare gates only and the class search of
155
- every earlier round's findings at the new head; the reviewer approves the
156
- new head by SHA, or continues its round if it had not approved; the daemon carries the issue
157
- through your acceptance and retro to the merger's new READY.
154
+ with the destination and pushes it (the procedure in
155
+ `skill://legion-worker/references/conflicts-and-rewrites.md`), posting the before and after
156
+ fingerprints; the tester re-runs the bare gates only and the class search of every earlier
157
+ round's findings at the new head; the reviewer approves the new head by SHA, or continues its
158
+ round if it had not approved; the daemon carries the issue through your acceptance and retro to
159
+ the merger's new READY.
158
160
 
159
161
  ## A review thread GitHub will not resolve
160
162
 
@@ -189,12 +189,11 @@ reason, and answer it in the spec if the latest version does not already.
189
189
  ## After approval
190
190
 
191
191
  Each step's approval is pinned to the version of the document that step records: a new version of
192
- that document closes that step again, and no `design-approved`-type wake says so; you know from
193
- your own edit, or from the `artifact.version` event on your issue. One step closing holds the
194
- tree's work whatever the other steps stand at. The exceptions are the version a human's own
195
- answer to a decision block
192
+ that document closes that step again, with no wake to say so; you know from your own edit, or
193
+ from the `artifact.version` event on your issue. One step closing holds the tree's work whatever
194
+ the other steps stand at. The exceptions are the version a human's own answer to a decision block
196
195
  writes when that answer is the whole change since the version they approved, and a version whose
197
- text is exactly the text of the version they approved, with no decision block in it decided
196
+ text is exactly that of the version they approved, with no decision block in it decided
198
197
  since, such as an accidental edit undone exactly: for either, Dispatch records an `approved`
199
198
  review in their name at the new version and emits `artifact.approved`, and the daemon reopens the
200
199
  gate and sends `design-approved`. Undo an accidental edit of an approved root spec exactly. When
@@ -202,45 +201,43 @@ the spec then reads Approved at the new version, request nothing; when it does n
202
201
  it was decided since), request approval again with steps 3 to 5.
203
202
 
204
203
  So edit an approved root spec only when its Summary, a requirement it marks, a check of its
205
- Verification document, the tree's scope, or a
206
- decision a human settled in one of its decision blocks changes. Such a change is a point the human
207
- has not agreed to: put the problem behind it to them as its own decision block, with its evidence,
208
- at the end of the section it changes, and add nothing else to the spec. If you edit the block before
204
+ Verification document, the tree's scope or a settled decision changes. Such a change is a point
205
+ the human has not agreed to: put the problem behind it to them as its own decision block, with
206
+ its evidence, at the end of the section it changes, and add nothing else. If you edit the block before
209
207
  the human answers, the gate closes like any new version, but their answer still carries the approval
210
208
  to the version it writes. Once they have answered:
211
209
 
212
210
  - When the answer is the whole change, request nothing: the document's chip reads Approved at the
213
- new version, its reviews dialog shows the review in their name, and the `design-approved` the
214
- daemon sent opens nothing new. Carry on, and release no child because of it.
215
- - When the answer changes the Summary, a requirement, a check or the tree's scope, rewrite that text and
216
- repeat steps 3 to 5 on the new version, with a one-sentence `--summary` naming what changed since
217
- the earlier approval, then the reviews' sentence (the card shows that approval, `Approved at
211
+ new version and the `design-approved` the daemon sent opens nothing new. Carry on; release no
212
+ child because of it.
213
+ - When the answer changes the Summary, a requirement, a check or the tree's scope, rewrite that
214
+ text and repeat steps 3 to 5 on the new version, with a one-sentence `--summary` naming what
215
+ changed since the earlier approval, then the reviews' sentence (the card shows `Approved at
218
216
  version N on <date> by <who>.`, and its `Show diff` control carries the detail). The rewrite
219
- closes the gate until they approve;
220
- work the daemon started at the answer keeps running. Release no further child until the `design-approved`
221
- after the rewrite; work already in flight continues. Every merger's `READY` in the tree is
222
- refused until a human approves the latest version.
217
+ closes the gate until they approve. Release no further child until the `design-approved` after
218
+ it; work already in flight, including what the daemon started at the answer, continues. Every
219
+ merger's `READY` in the tree is refused until a human approves the latest version.
223
220
 
224
221
  A settled decision is the human's. A plan that would overturn one goes back to the planner with the
225
222
  decision kept, unless the planner brings evidence the human did not weigh that would change it
226
223
  (such as a measurement showing the settled choice cannot pass a check); then a decision
227
224
  block names the decision and that evidence. A plan never overturns a settled decision on its own.
225
+ A person's request after the approval becomes a requirement only when you write it into the spec
226
+ and they approve that version; it is never another issue's, and no comment or answer of theirs
227
+ takes a requirement out.
228
228
 
229
229
  A design change that leaves the Summary, the requirements, the checks, the scope and the settled
230
- decisions intact (a
231
- planner's measurement that finds a better way to build the same outcome) goes in the plan (the
232
- issue's `plan.md` document and the planner's `plan` handoff on the issue), never into the approved spec, even
230
+ decisions intact (a planner's measurement finding a better way to the same outcome) goes in the
231
+ plan (the issue's `plan.md` and the planner's `plan` handoff), never into the approved spec, even
233
232
  where the spec's text describes the older design; the reviewer reads the plan beside the spec.
234
233
 
235
- When a planner's `phase-finished` names a departure from the spec's design, compare it with the
236
- approved spec. If the Summary, the requirements, the checks, the scope and every settled decision
237
- are unchanged,
238
- the plan is the record and the tree carries on; otherwise change the root spec and request
239
- approval again.
234
+ When a planner's `phase-finished` names a departure, compare it with the approved spec: with the
235
+ Summary, the requirements, the checks, the scope and every settled decision unchanged, the plan
236
+ is the record and the tree carries on; otherwise change the root spec and request approval again.
240
237
 
241
- Later children and re-scoping open children toward the same requirements need no spec edit and no new
242
- approval. A child issue's spec is never gated, and the child's own Verification document is
243
- written by its architect.
238
+ Later children and re-scoping open children toward the same requirements need no spec edit and no
239
+ new approval. A child issue's spec is never gated, and its architect writes the child's own
240
+ Verification document.
244
241
 
245
242
  ## A decision block for a read no pod can make
246
243
 
@@ -27,7 +27,7 @@ and 7 (a conflict, the hand-over, the close) is in
27
27
  | `design-approved` | Its `version` is the approved one, and it names no step: under more than one gated step, read `gatedSteps` in your own record (the `legion` tool's `read_record`) to see which step that version opened and whether another still holds the tree. A human approved the document of one gated step at its current version; that step is open. Proceed to section 2 once every gated step is `approved` — except on a root whose catch-up said `handed_over`: its workers already run their phases, so start nothing; the approval releases any READY the gate refused. One whose `version` is the version a human's own answer to a decision block wrote, after an earlier approval (Dispatch carried that approval to it, "After approval" in `skill://legion-architect/references/design-gate.md`), opens nothing new: carry on, and release no child because of it. A root that was waiting on a question in `awaiting_person` gets no such notice: the task that resumes it says "Your spec is approved at version N and the design gate is open: this resume is your design-approved wake", and that resume is this wake — proceed to section 2 on it. |
28
28
  | `design-changes-requested` | Its `version` and `reason`, and no step: under more than one gated step, read `gatedSteps` in your own record (the `legion` tool's `read_record`) and take the step whose `status` is `changes_requested`. A human asked for changes to that step's document at `version`, for `reason`. Revise that document as the reason asks and request approval again as "The armed gate" in `skill://legion-architect/references/design-gate.md` says; end your turn; that step is closed. On a root that was waiting on a question in `awaiting_person`, a review the human gave after the wait began comes in the resume task, not in this notice, whether it answered the wait or came after something else did: the task names the review with its version and reason, unless a later approval superseded it. A `version` below the latest, or a second request for one version, is a request that reached the daemon late: read it as the same section's last paragraph says. Each request arrives once. |
29
29
  | `phase-finished` | The daemon has already moved the issue to its next phase by its fixed table and started that phase's role; you start nothing. Read the finishing phase's handoff on the Dispatch issue (`dispatch handoff-read --issue <issue> --phase <word>`); if it shows unresolved gaps, tell the role now working the issue (`envoy_publish` to its role topic). A `planner` notice that names a departure from the spec's design defers to the full condition in "After approval" of `skill://legion-architect/references/design-gate.md`: when the approved Summary, the requirements, the checks, the scope and the settled decisions still hold, the plan is the record; otherwise change the root spec and request approval again as that section says. A `reviewer` notice whose GitHub review is `CHANGES_REQUESTED` needs nothing from you: the daemon has returned the issue to `implementing` (Dispatch `in_progress`) and started the **implementer**, whose correction goes through the tester and the reviewer again, never straight to retro. A `reviewer` notice with an `APPROVED` review means the issue is in `accepting` and the acceptance is yours (section 6): read the evidence, then `sign_off` (a parent only after its last round, "The last round" in `skill://legion-architect/references/acceptance.md`) or send it back with `request_backward_move`. A `tester` notice with `verdict: "fail"` — its handoff carries `implementerProof.verdict: "rejected"`, or a failure naming a check with no current passing result — has gone back to the **implementer** by the daemon's table; never record that check's result from another role. A worker that reports no surface reaches the changed path sends that report instead of completing its phase, so the daemon starts nothing more on that issue and the worker stays idle in its session, not suspended: build the surface in this tree: a child issue (infrastructure, tooling, or a skill) after the red-team check in `skill://legion-architect/references/decomposition.md`, or, when the red team folds it, tell the waiting worker to move the issue back to `implementing` with `request_backward_move`, naming the surface. When it is a child, tell the waiting worker to continue with `envoy_publish` to its role topic once that child's `child-closed` arrives. That report is never a reason to advance the phase. |
30
- | `pr-blocked` | Its `reason` names the pull request and the `max_fix_attempts` it reached, or reads `Issue reached review_round_cap=<N>.` (the end of this row). The count is of heads pushed onto a red verdict: no handoff is a commit, so every such push counts except a push by the review App (a planner's, tester's, reviewer's or architect's), and the head pushed onto a red the tester's red tests earned (a planned red) does not count either. Published once per exhausted count, not on every later red verdict for that count. Read the failed CI evidence and recovery attempts. The notice moves nothing, and no later CI red within the attempt that ran the count out (the counted head, and every head pushed on top of it until a push lands on a head CI judged green or on a settled head whose base branch requires no check and no workflow, the tester's red tests onto the held red included) sends the work back from `testing`, `reviewing`, `accepting`, `retro` or `merging` either: the issue stays in its phase until you move it, or a worker's own decision does (a tester's `fail`, a reviewer's request for changes). A head pushed onto green CI, or onto a settled head whose base branch requires no check and no workflow, leaves that attempt, so its red still comes as a `checks-red`. In `implementing`, give the implementer the failing checks (`envoy_publish` to its role topic). In any later phase a worker holds, tell that worker (`envoy_publish` to its role topic) to move the issue back to `implementing` with `request_backward_move`, naming the failing checks, and the daemon starts the implementer. In `accepting`, where no worker holds a phase, the move is yours: `request_backward_move` with `issue`, naming the failing checks. In `awaiting_merge`, where no worker holds a phase and a backward move is refused, open a `dispatch ask` naming the failing checks for the human who merges. Do not treat the blocked PR as final. A `review_round_cap` reason is the implementer's round count instead: every move back to an earlier phase counts one, and the notice comes again with each round past the cap. It moves nothing either, since the round that reached the cap has already started its worker. Tell the rounds apart by what announced each: a tester's fail by its `phase-finished` with `verdict: "fail"`; a request for changes by the reviewer's `phase-finished` over a `CHANGES_REQUESTED` review; the daemon's own move by a `checks-red` notice, whose reason names a conflict (`the head conflicts with <base>`), the required checks that failed (`CI is red at <head>`), or the merge queue's failed merge and its failing run (`the merge queue took pull request #<n> out at READY's head …`); a worker's `request_backward_move` by a `phase-finished` from the role that asked, whose reason reaches only the task of the worker the move started, so ask that worker; your own send-back from `accepting` by the reason you gave. Judge the cap by the rounds that are not conflicts. Conflict returns need nothing from you beyond the next round. Tester fails, requests for changes and CI-red returns (a `checks-red` notice is raised for CI only when a required check fails on code the branch pushed, or when the merge queue fails the merge) are the rounds the cap is for. Each `review_round_cap` notice is a decision you make in the turn it wakes, never one left for the next round to make: read what every counted round found, choose one of the three below, act on it in the same turn, and post it as a `dispatch comment` on the issue naming the rounds you read and the choice. **Narrow**: the change itself is sound but each round finds more around it; tell the implementer and the reviewer (`envoy_publish` to each one's role topic) which checks of the issue the next round answers; a correctness finding is still fixed in this pull request, and so is a wording nit or any clear fix in a file it touches, so the `Fast-follow:` line carries only cleanup in files this pull request does not touch. **Split**: part of the work cannot settle in this pull request. It is a child only when it needs a repository or a deploy order of its own (`skill://legion-architect`, section 1), and then it goes through the red-team check in `skill://legion-architect/references/decomposition.md` and is filed as a child of this issue's parent, never of this one, since this issue closes at its own merge. Work in a repository this tree already has a pull request in is no child and is not parked in `backlog`: write it into the spec of the issue whose pull request carries it, the parent's, or a sibling's when the parent's pull request is in another repository. On the root, narrow it to what settles here and open a `dispatch ask` for the rest (`skill://legion-worker/references/findings.md`): a person decides whether that becomes an issue. Tell the implementer and the reviewer that this pull request no longer carries it. **Accept the rounds**: each round found less than the one before it, and the last found no defect in the change itself (a stale line, a comment that states an old default); let the loop run and say why in the comment. A later notice is a new decision: accept again only when its round found less than the round you last accepted, and otherwise narrow or split. A finding that changes what the spec requires or what a check proves is a decision block in the root spec ("After approval" in `skill://legion-architect/references/design-gate.md`), and `dispatch ask` is only for a decision that needs a human's authority; neither replaces the choice. Judge a worker's backward move by the reason that worker gives. A move you ordered for a conflict found before `awaiting_merge` ("A conflicting head" in `skill://legion-architect/references/acceptance.md`) is a conflict return. The merger's move back to `reviewing` for a READY refusal (`READY_UNREVIEWED_CHANGE`, or `READY_NOT_APPROVED` when its task names no approved head), and the reviewer's no-fix request for changes that follows it so the tester runs the head, are not the work going in circles either. A move that sends back code found wrong counts with the tester fails. |
30
+ | `pr-blocked` | Its `reason` names the pull request and the `max_fix_attempts` it reached, or reads `Issue reached review_round_cap=<N>.` (the end of this row). The count is of heads pushed onto a red verdict: no handoff is a commit, so every such push counts except a push by the review App (a planner's, tester's, reviewer's or architect's), and the head pushed onto a red the tester's red tests earned (a planned red) does not count either. Published once per exhausted count, not on every later red verdict for that count. Read the failed CI evidence and recovery attempts. The notice moves nothing, and no later CI red within the attempt that ran the count out (the counted head, and every head pushed on top of it until a push lands on a head CI judged green or on a settled head whose base branch requires no check and no workflow, the tester's red tests onto the held red included) sends the work back from `testing`, `reviewing`, `accepting`, `retro` or `merging` either: the issue stays in its phase until you move it, or a worker's own decision does (a tester's `fail`, a reviewer's request for changes). A head pushed onto green CI, or onto a settled head whose base branch requires no check and no workflow, leaves that attempt, so its red still comes as a `checks-red`. In `implementing`, give the implementer the failing checks (`envoy_publish` to its role topic). In any later phase a worker holds, tell that worker (`envoy_publish` to its role topic) to move the issue back to `implementing` with `request_backward_move`, naming the failing checks, and the daemon starts the implementer. In `accepting`, where no worker holds a phase, the move is yours: `request_backward_move` with `issue`, naming the failing checks. In `awaiting_merge`, where no worker holds a phase and a backward move is refused, open a `dispatch ask` naming the failing checks for the human who merges. Do not treat the blocked PR as final. A `review_round_cap` reason is the implementer's round count instead: every move back to an earlier phase counts one, and the notice comes again with each round past the cap. It moves nothing either, since the round that reached the cap has already started its worker. Tell the rounds apart by what announced each: a tester's fail by its `phase-finished` with `verdict: "fail"`; a request for changes by the reviewer's `phase-finished` over a `CHANGES_REQUESTED` review; the daemon's own move by a `checks-red` notice, whose reason names a conflict (`the head conflicts with <base>`), the required checks that failed (`CI is red at <head>`), or the merge queue's failed merge and its failing run (`the merge queue took pull request #<n> out at READY's head …`); a worker's `request_backward_move` by a `phase-finished` from the role that asked, whose reason reaches only the task of the worker the move started, so ask that worker; your own send-back from `accepting` by the reason you gave. Judge the cap by the rounds that are not conflicts. Conflict returns need nothing from you beyond the next round. Tester fails, requests for changes and CI-red returns (a `checks-red` notice is raised for CI only when a required check fails on code the branch pushed, or when the merge queue fails the merge) are the rounds the cap is for. Each `review_round_cap` notice is a decision you make in the turn it wakes, never one left for the next round to make: read what every counted round found, choose one of the three below, act on it in the same turn, and post it as a `dispatch comment` on the issue naming the rounds you read and the choice. **Narrow**: the change itself is sound but each round finds more around it; tell the implementer and the reviewer (`envoy_publish` to each one's role topic) which checks the next round answers, dropping no requirement; a correctness finding is still fixed in this pull request, and so is a wording nit or any clear fix in a file it touches, so the `Fast-follow:` line carries only cleanup in files it does not touch. **Split**: part of the work cannot settle in this pull request. It is a child only when it needs a repository or a deploy order of its own (`skill://legion-architect`, section 1), and then it goes through the red-team check in `skill://legion-architect/references/decomposition.md` and is filed as a child of this issue's parent, never of this one, since this issue closes at its own merge. A requirement moves only to that released child. Work in a repository this tree already has a pull request in is no child and is not parked in `backlog`: write it into the spec of the issue whose pull request carries it, the parent's, or a sibling's when the parent's pull request is in another repository. On the root, open a `dispatch ask` for the part that cannot settle here (`skill://legion-worker/references/findings.md`): it stays this issue's requirement, and this pull request carries it, until the person who answers that ask records that the issue will not deliver it. **Accept the rounds**: each round found less than the one before it, and the last found no defect in the change itself (a stale line, a comment that states an old default); let the loop run and say why in the comment. A later notice is a new decision: accept again only when its round found less than the round you last accepted, and otherwise narrow or split. A finding that changes what the spec requires or what a check proves is a decision block in the root spec ("After approval" in `skill://legion-architect/references/design-gate.md`), and `dispatch ask` is only for a decision that needs a human's authority; neither replaces the choice. Judge a worker's backward move by the reason that worker gives. A move you ordered for a conflict found before `awaiting_merge` ("A conflicting head" in `skill://legion-architect/references/acceptance.md`) is a conflict return. The merger's move back to `reviewing` for a READY refusal (`READY_UNREVIEWED_CHANGE`, or `READY_NOT_APPROVED` when its task names no approved head), and the reviewer's no-fix request for changes that follows it so the tester runs the head, are not the work going in circles either. A move that sends back code found wrong counts with the tester fails. |
31
31
  | `pr-merged` | The pull request merged and the issue did not close; its `reason` says why. Merged before the issue reached `awaiting_merge`: the workflow runs on, and the merge closes the issue the moment it gets there, your acceptance and retro first. Merged while the rest of the tree still runs: the reason names the pull request and every issue the close waits for, and the root waits in `awaiting_merge`, its workers kept and live and no admission slot held, until the last of them is done or parked ("The close" in `skill://legion-architect/references/acceptance.md`). Either way you start nothing and no further notice follows. |
32
32
  | `pr-closed-unmerged` | Decide from current scope whether the work is reopened, started over (`park_child` then `rerun_child`, for a child), or ended with a reason. Delegate the repository action to the responsible phase worker and keep ownership. |
33
33
  | `pull-request-missing` | Its `reason` names the issue, the repository, the branch and the handoff commit: the issue's implementer completed at that commit and GitHub lists no open pull request on the branch, so the issue stays in `implementing`. Tell the implementer (`envoy_publish` to its role topic) to open the pull request from that branch; the daemon records it and moves the issue to `testing` once it is open. When the work should not go on, decide as the `pr-closed-unmerged` row says. It comes once per handoff commit. |
@@ -145,22 +145,19 @@ reviewing until you finish.
145
145
  `legion` tool's `sign_off`, which moves the issue to retro, or sends it back to `implementing`
146
146
  or `testing` with `request_backward_move` and a reason, which reaches the started worker's task
147
147
  as its `Reason:` line and counts a review round. The acceptance comment names each check with
148
- its result. An issue with no Verification document, or with no `before_merge` check, reaches
149
- the architect as a gap the tester and the reviewer named and neither refused, so the
150
- architect's acceptance is the only gate on it: the acceptance comment names that gap and
151
- decides there, accepting the issue or sending it back with the checks the architect writes,
152
- which closes the root's `criteria` step where the deployment gates that step, since that step
153
- records the root's Verification document and each new version of a step's document closes it;
154
- a child's Verification document is gated by nothing. The architect also
155
- reads the reviewer's own prose commits here, with the rest of the evidence, and that read is no
156
- new round. It does not
157
- accept while the issue holds a finding ask no controller has taken (`findings.md`, "When no
158
- controller takes it"). The issue's approval is gated by the `before_merge` checks of its own
159
- Verification document at its own head, so a child's result against a root's check proves
160
- nothing for the root: the root's checks are proven at the root's own head, in its last round.
161
- The acceptance asks for no `after_merge` result: that one is recorded
162
- after the close, where the project opens a check (*The production check after the close*,
163
- below).
148
+ its result. An issue with no Verification document, or none holding a `before_merge` check,
149
+ is a gap the tester and the reviewer named and neither refused, so that comment is its only
150
+ gate: it names the gap and decides how each delivered item is proven at this head, never
151
+ whether one stays unmet; checks it writes close the root's `criteria` step where the
152
+ deployment gates it, since that step records the root's Verification document, and a child's
153
+ is gated by nothing. It also reads the reviewer's prose commits here with the rest, no new
154
+ round, and does
155
+ not accept while the issue holds a finding ask no controller took (`findings.md`, "When no
156
+ controller takes it"). Approval is gated by the `before_merge` checks of the issue's own
157
+ Verification document at its head, so a child's result against a root's check proves nothing:
158
+ a root's checks are proven at its own head, in its last round. No `after_merge` result is
159
+ asked here: it is recorded after the close, where the project opens a check (*The production
160
+ check after the close*, below).
164
161
  CI red at the head in `accepting` returns the issue to `implementing` as it does in review. A
165
162
  head the review App pushed is the exception: the daemon marks it a planned red and acts on it
166
163
  nowhere, and GitHub holds the merge under the base branch's own rules.
@@ -289,53 +286,53 @@ reviewing until you finish.
289
286
  after the close.** `projects.<KEY>.production_check` in the project's `legion.yaml` takes `off`
290
287
  or `tester`, and a project that names no key gets `tester`, so by default the tester works the
291
288
  check; the loader refuses every other value, naming the key and the value it read. Where the
292
- setting names the tester, the merge makes the daemon write `done` and, in the tester's session,
293
- still live, hand it the check task. Where it is `off` nothing is opened at all — no record, no
289
+ setting names the tester, the merge makes the daemon write `done` and hand the check task to
290
+ the tester's live session. Where it is `off` nothing is opened at all — no record, no
294
291
  bound and no look — and the merged close is like any other done: every claim of the issue is
295
292
  retired and its pod released with the disk it ran on. A merged root still lingers its tree with
296
- every claim suspended, as before. On a root whose tree still runs the close, and so the check
297
- task, comes later: the merge is recorded, the root waits in `awaiting_merge` until the last other
298
- issue of its tree is done or parked, and the check opens with that close. Its first line is
299
- `Production check of <KEY>: <title>.`, and it names the repository, the pull request, the merge
300
- commit, the look's number, what woke the look (`the merge`, for the first) and whether it is the
301
- last. A resumed session tells the check task
302
- from its last phase task by that first line.
293
+ every claim suspended, as before. On a root whose tree still runs, the merge is recorded and
294
+ the root waits in `awaiting_merge` until the last other issue of its tree is done or parked,
295
+ the check opening with that close. Its first line, which tells it from a phase task in a
296
+ resumed session, is `Production check of <KEY>: <title>.`, naming the repository, the pull
297
+ request, the merge commit, the look's number, its wake (`the merge`, for the first) and whether
298
+ it is the last.
303
299
  - **The check's record holds the role that works it, written when the check opened.** Changing the
304
300
  setting moves no check already open: a check keeps the role it opened with, and a check open
305
301
  before this release carries the implementer. Only that role may report on it, so a report from
306
302
  any other role is refused (`CHECK_ROLE_MISMATCH`). The check carries no phase and no handoff: a
307
- look ends with `handoff_complete` carrying a `verdict` and a `summary`, no commit, and the daemon
308
- refuses a report on an issue with no open check (`CHECK_NOT_OPEN`), on a look already ended
309
- (`CHECK_LOOK_NOT_OPEN`), or with no verdict of `pass`, `pending` or `fail`
303
+ look ends with `handoff_complete` carrying a `verdict` and a `summary` and no commit, and the
304
+ daemon refuses a report with no open check (`CHECK_NOT_OPEN`), on an ended look
305
+ (`CHECK_LOOK_NOT_OPEN`) or with no verdict
310
306
  (`CHECK_VERDICT_REQUIRED`).
311
307
  One refusal is about the turn rather than the report: a completion sent from a turn that is not
312
308
  a look's own task is refused `CHECK_LOOK_NOT_SERVED` and records nothing, so report again in the
313
309
  turn of the look's task.
314
310
  - **Each look does three things.** Do what the deployment instructions say to reach the deploy:
315
311
  when they name an agent or role for it, `envoy_publish` the merge commit to that role's topic
316
- with `expects_reply: false`, and await no reply. Read whether production carries the merge. Then
312
+ with `expects_reply: false`, and await no reply. Read whether production carries the merge, and
313
+ with it every requirement only the deploy can show, each as the requirement names it, since
314
+ observing something else is never that requirement observed. Then
317
315
  report one of three outcomes:
318
- - `pass`, once you drove the changed path in production through the user's own access path and
316
+ - `pass`, once you drove the changed path and those requirements in production through the
317
+ user's own access path and
319
318
  recorded the result: `dispatch result` against the issue's `after_merge` check, at the merge
320
- commit, its `observed` ending `woken by <event>`, with the printed line in the PR body's
321
- `Checks` block and one pull-request comment carrying the Legion footer. A closed issue takes a
322
- result for an `after_merge` or `default_branch` check, a comment and a message, and refuses
323
- every other write. A staging
324
- pass is not this, since a
325
- staging gate does not run every resource production does.
319
+ commit, its `observed` ending `woken by <event>`, the printed line in the PR body's `Checks`
320
+ block and one pull-request comment with the Legion footer. A closed issue takes a result for
321
+ an `after_merge` or `default_branch` check, a comment and a message, and refuses every other
322
+ write. A staging pass is not this: staging does not run every resource production does.
326
323
  - `pending`, when production does not carry the merge yet (a shared profile still holding the
327
- previous release, a daemon still running the previous commit, a deploy nobody has run): the
328
- summary names what is missing and what you will look for next, `wake_at` names your next look
329
- (below), nothing is recorded, and the check's line in the body stays at
324
+ previous release, a daemon still running the previous commit, a deploy nobody has run), or a
325
+ requirement's observation has not happened: the summary names what is missing and what you
326
+ will look for next, `wake_at` names your next look (below), nothing is recorded, and the
327
+ check's line in the body stays at
330
328
  `- Check <block id> (after_merge): not yet run`.
331
- - `fail`, for a defect: record the failing result with `dispatch result --verdict fail`, file no
332
- issue, and take the path
333
- `skill://legion-worker/references/findings.md` gives it. A defect with a clear fix goes to the
334
- controller topic, with its evidence comment on the controller's report issue. A defect that
335
- needs a decision is a `dispatch ask` on the report issue, and you publish its reference to the
336
- controller topic. Either names this issue, the pull request, the merge commit, what you drove
337
- and what failed. Name the message or the ask (`dispatch://<REPORT KEY>/ask/<id>`) in the
338
- result's `observed` and in the summary.
329
+ - `fail`, for a requirement observed as not met, one still unobserved at the last look, or a
330
+ defect: record the failing result with `dispatch result --verdict fail`, file no issue, and
331
+ take the path `skill://legion-worker/references/findings.md` gives it — a clear fix to the
332
+ controller topic, with its evidence comment on the controller's report issue; one needing a
333
+ decision as a `dispatch ask` there, whose reference you publish to that topic. Either names
334
+ this issue, the pull request, the merge commit, what you drove and what failed, and the
335
+ result's `observed` and the summary name it (`dispatch://<REPORT KEY>/ask/<id>`).
339
336
  - **Numbers the daemon holds are read with the `legion` tool.** Where the verdict rests on what a
340
337
  deployment's idle release has done, `read_release_records` answers a window of the daemon's own
341
338
  records of its releases, resumes and holds: its one argument `since` is the RFC 3339 instant
@@ -357,29 +354,27 @@ reviewing until you finish.
357
354
  - **Nothing waits in the session for a deploy.** A `pending` ends the look: the daemon stops the
358
355
  checking role's process, keeps its session and releases the issue's pod, whose Sandbox goes with
359
356
  its disk, and at the time you named a new pod comes back and your session resumes with the next
360
- look's task. So end the turn with the report: never poll for the deploy, never wait on a reply,
361
- and never ask anyone for approval to deploy. Open a `dispatch ask` to a person only when the
362
- instructions name nobody for that deploy; it starts with the production gap and why it matters,
363
- then names the required install or restart step, its risk, and outcome-named options, and the
364
- look still ends `pending`.
357
+ look's task. So end the turn with the report: never poll, never wait on a reply, never ask for
358
+ approval to deploy. Open a `dispatch ask` only where the instructions name nobody: the
359
+ production gap and why it matters, then the required install or restart step, its risk, and
360
+ outcome-named options; the look still ends `pending`.
365
361
  - **The bounds.** A look is bounded at 2 hours, and a look nobody reported — its 2 hours, an
366
362
  operator's hold, or a claim that failed to start — starts the next look two hours later; on the
367
- last look it closes the check as not run. The whole check is bounded by the project's
368
- `production_check_hours` (336, 14 days, by default) from the close, and the look that bound
369
- starts is the last, told so in its task
363
+ last look it closes the check as not run. The check is bounded by the project's
364
+ `production_check_hours` (336, 14 days, by default) from the close; the look that bound starts
365
+ is the last, so told in its task
370
366
  (`the bound: production did not carry the merge within <N days>`). A `pass` or `fail` there
371
- closes the check as any look's would; a `pending` there carries no `wake_at` and closes the
372
- check as not run, and before reporting it you write on the pull request, in the check's line and
373
- a comment, that the check did not run because production did not carry the merge within the
374
- bound.
367
+ closes the check as any look's would, and a requirement still unobserved there is that `fail`;
368
+ only production not carrying the merge ends it `pending`, which carries no `wake_at` and
369
+ closes the check as not run, written first on the pull request — its check line and a comment
370
+ — because production did not carry the merge within the bound.
375
371
  - **The record lives on the pull request and in the result.** Dispatch takes a comment, a message
376
372
  and a result for an `after_merge` or `default_branch` check on a closed issue, and refuses an
377
- ask there (`ISSUE_CLOSED`), so the deployment instructions' "on the pull request
378
- and the issue" is the pull request and that result. A defect reaches Dispatch by the two paths above:
379
- a clear defect as the message to the controller, which gives it to the tree that owns that code,
380
- and any other as the ask on the
381
- controller's report issue. The architect accepted the issue before the merge and is asked
382
- nothing after it. `pass` or
373
+ ask there (`ISSUE_CLOSED`), so the deployment instructions' "on the pull request and the issue"
374
+ is the pull request and that result, and a defect reaches Dispatch by the `fail` verdict's two
375
+ paths alone — the message to the controller, which gives it to the tree that owns that code,
376
+ and the ask on the controller's report issue. The architect accepted before the
377
+ merge and is asked nothing after. `pass` or
383
378
  `fail` closes the check: your claim is retired and the issue's Sandbox goes with its pod and
384
379
  disk, for a root as for a child. Neither ending retires or suspends anything of an issue back in
385
380
  the workflow (a root reopened inside its linger): its claim and pod are the new run's.
@@ -98,10 +98,10 @@ command prints the pull request body's line for it, and that line goes into the
98
98
  The surface is **production-like** — the repository's real-process test harness and fixtures, a
99
99
  sandbox repository, a real browser, a devN stack, staging, or a local stack with real migrations,
100
100
  one that has the resource the change touches — and `--run` or `--observed` carries a **link** to
101
- that run, screenshot, or e2e; human review does not replace user-facing verification, and a green
102
- unit suite is not it. A unit or integration test is a regression lock, never the result of a
103
- check. The agent that develops the change records its results this way before the merge, and
104
- whatever blocks a check is fixed, not skipped (*When no surface reaches the changed path*, below).
101
+ that run, screenshot or e2e; human review does not replace user-facing verification, and a green
102
+ unit suite is not it. A unit or integration test is a regression lock, never a check's result.
103
+ The agent that develops the change records its results this way before the merge, and whatever
104
+ blocks a check is fixed, not skipped (*When no surface reaches the changed path*, below).
105
105
 
106
106
  **Record a result after the commit is pushed.** Dispatch asks GitHub whether the repository of
107
107
  the check's issue holds the commit, and refuses a result at one it does not hold with `400
@@ -121,31 +121,30 @@ issue, or the final head of a merged one, and the check's words have not changed
121
121
  `after_merge` or `default_branch` result is current at a commit the default branch carries. A push
122
122
  makes every result at the old head older, with no Dispatch write of anyone's, so each check is
123
123
  recorded again at the new head. `dispatch results --issue <issue>` prints each check with its
124
- latest result and whether that result is current, and `dispatch read --issue <issue>` names each
125
- requirement of the spec no check serves.
126
-
127
- **An issue is proved by its own checks.** Its approval is gated by the `before_merge` checks of
128
- its own Verification document, read at its own head, so a child's pull request never makes a
129
- root check's result current and a child never records the result that proves a root's check. A
130
- child that carries part of a root's requirement proves it with a check on the child's own
131
- Verification document whose `serves` names that requirement. A root's own checks are proven at
132
- the root's own head, or on the default branch for an `after_merge` check, in the root's last
133
- round.
134
-
135
- **An issue with no `before_merge` check is a named gap.** An issue with no Verification document,
136
- or with one that holds no `before_merge` check, has no evidence of its own. The tester names that
137
- gap in its handoff and the reviewer in its review, and neither one sends the issue back for it;
138
- both tell the architect, who writes the checks, and the architect's acceptance comment names the
139
- gap and decides there, which is the only gate on such an issue.
124
+ latest result and whether it is current; `dispatch read --issue <issue>` names each requirement
125
+ of the spec no check serves.
126
+
127
+ **An issue is proved by its own checks.** Approval is gated by the `before_merge` checks of its
128
+ own Verification document, read at its own head, so a child's pull request never makes a root
129
+ check's result current and a child never records the result that proves a root's check. A child
130
+ carrying part of a root's requirement proves it with a check on its own Verification document
131
+ whose `serves` names that requirement. A root's own checks are proven at its own head, or on the
132
+ default branch for an `after_merge` check, in its last round.
133
+
134
+ **An issue with no `before_merge` check is a named gap.** One with no Verification document, or
135
+ with none holding a `before_merge` check, has no evidence of its own. The tester names the gap
136
+ in its handoff and the reviewer in its review, and neither sends the issue back for it; both
137
+ tell the architect, who writes the checks, and the architect's acceptance comment names the gap
138
+ and decides there, the only gate on such an issue.
140
139
 
141
140
  ## The rules every phase's evidence follows
142
141
 
143
142
  - **The implementer records a result for every `before_merge` check before its phase completes,
144
143
  and writes the `Checks` lines when the pull request opens.**
145
144
  A check with no surface yet is the report of *When no surface reaches the changed path* below,
146
- never a check left unrecorded. The results are on the Dispatch issue, and the lines are in the
145
+ never a check left unrecorded. The results are on the Dispatch issue, the lines in the
147
146
  PR body, because the reviewer and the merger verify facts on GitHub and never from a handoff.
148
- The `implement` handoff carries no results: Dispatch holds them, and the tester reads them with
147
+ The `implement` handoff carries none: Dispatch holds them, and the tester reads them with
149
148
  `dispatch results`.
150
149
  - **The tester judges the implementer's results and records its own.** It re-runs the
151
150
  implementer's command or drives the same surface independently, and records the verdict in
@@ -201,11 +200,12 @@ gap and decides there, which is the only gate on such an issue.
201
200
  Record both in the `Thermo` line.
202
201
  - **No deferrals** is the body's rule (*PR body, review, and the merge gate* in
203
202
  `skill://legion-worker`): a wording nit, and any clear fix in a file this pull request touches,
204
- is made in the running round, because a later round costs a CI pass and a re-read of the whole
205
- change (the operator's answer on that case: fix it while you are there, and defer no fix to
206
- another issue). The `Fast-follow:` line reads
207
- `none`, or names only cleanup in files this pull request does not touch.
208
- A base frozen for others to stack on is never rewritten (*Rewriting pushed commits* in
203
+ is made in the running round: a later round costs a CI pass and a re-read of the whole
204
+ change. A requirement on the `Not proven / risk:` line is unmet, not declared away, unless only
205
+ the deploy can show it and the plan names its observation;
206
+ the `Fast-follow:` line never carries one, and reads `none` or names only cleanup in files
207
+ this pull request does not touch. A base frozen for others to stack on is
208
+ never rewritten (*Rewriting pushed commits* in
209
209
  `skill://legion-worker/references/conflicts-and-rewrites.md`); the `Chain` line records it.
210
210
  - **GitHub refuses a pull request body over 65,536 characters.** Each verification round links its
211
211
  evidence (the run, the comment) rather than inlining it once the body passes about 48,000
@@ -218,10 +218,8 @@ Say which surface is missing and what it would have to do — a rig that can spa
218
218
  sandbox that holds the resource, a credential, a command that does not exist yet — and send it to
219
219
  the architect with `envoy_publish` to its role topic. The architect builds it in this tree
220
220
  (infrastructure, tooling, or a skill), in an open pull request or a child issue, and resumes you
221
- once it lands. A code path
222
- whose first execution would be after the merge — a deploy
223
- workflow's inline step, a post-merge helper, a production-only resource — is a check marked
224
- `after_merge`, recorded once the merge reaches production by the role the project's
225
- `production_check` names, on the look its own `wake_at` brought back, and no reason to leave a
226
- `before_merge` check unrecorded; completing with a unit suite as the only evidence is the
227
- failure this rule exists to stop.
221
+ once it lands. A code path whose first execution would be after the merge — a deploy workflow's
222
+ inline step, a post-merge helper, a production-only resource — is a check marked `after_merge`,
223
+ recorded once the merge reaches production by the role the project's `production_check` names,
224
+ on the look its own `wake_at` brought back, and no reason to leave a `before_merge` check
225
+ unrecorded; completing with a unit suite as the only evidence is the failure this rule stops.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sjawhar/claude-envoy",
3
- "version": "1.20.4",
3
+ "version": "1.21.1",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Claude Code plugin for Legion's Envoy bus",
6
6
  "type": "module",