@sjawhar/claude-envoy 0.0.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. package/.claude-plugin/plugin.json +6 -0
  2. package/.mcp.json +11 -0
  3. package/.omp-plugin/plugin.json +6 -0
  4. package/AGENTS.md +343 -0
  5. package/README.md +639 -0
  6. package/bin/dispatch +6 -0
  7. package/bin/envoy-channel.ts +9 -0
  8. package/bin/envoy-send.ts +33 -0
  9. package/dist/THIRD_PARTY_NOTICES +816 -0
  10. package/dist/dispatch.js +27707 -0
  11. package/dist/envoy-channel.js +57695 -0
  12. package/dist/session-hook.js +26328 -0
  13. package/dist/session-title-hook.js +116 -0
  14. package/hooks/hooks.json +60 -0
  15. package/hooks/session-hook.ts +512 -0
  16. package/hooks/session-title-hook.ts +46 -0
  17. package/legion/.claude-plugin/plugin.json +4 -0
  18. package/legion/agents/deep-worker.md +68 -0
  19. package/legion/agents/oracle.md +35 -0
  20. package/legion/agents/plan-gap-analyst.md +65 -0
  21. package/legion/agents/plan-reviewer.md +104 -0
  22. package/legion/agents/thermonuclear-code-quality.md +30 -0
  23. package/legion/agents/thermonuclear-deep-review.md +30 -0
  24. package/legion/hooks/hooks.json +89 -0
  25. package/legion/skills/ce-simplify-code/LICENSE +21 -0
  26. package/legion/skills/ce-simplify-code/SKILL.md +66 -0
  27. package/legion/skills/ce-simplify-code/references/personas/code-quality-reviewer.md +17 -0
  28. package/legion/skills/ce-simplify-code/references/personas/code-reuse-reviewer.md +7 -0
  29. package/legion/skills/ce-simplify-code/references/personas/efficiency-reviewer.md +11 -0
  30. package/legion/skills/leading-a-work-stream/SKILL.md +96 -0
  31. package/legion/skills/leading-a-work-stream/references/daily-plan.md +8 -0
  32. package/legion/skills/leading-a-work-stream/references/decision-rights.md +6 -0
  33. package/legion/skills/leading-a-work-stream/references/direction-and-coaching.md +13 -0
  34. package/legion/skills/leading-a-work-stream/references/dispatch-upkeep.md +8 -0
  35. package/legion/skills/leading-a-work-stream/references/sources.md +9 -0
  36. package/legion/skills/leading-a-work-stream/references/speed-tick.md +44 -0
  37. package/legion/skills/leading-a-work-stream/references/user-quotes.md +7 -0
  38. package/legion/skills/legion-architect/SKILL.md +86 -0
  39. package/legion/skills/legion-architect/references/acceptance.md +208 -0
  40. package/legion/skills/legion-architect/references/decomposition.md +129 -0
  41. package/legion/skills/legion-architect/references/design-gate.md +206 -0
  42. package/legion/skills/legion-architect/references/merge-notices.md +91 -0
  43. package/legion/skills/legion-architect/references/wake-routing.md +41 -0
  44. package/legion/skills/legion-controller/SKILL.md +151 -0
  45. package/legion/skills/legion-controller/references/admission.md +22 -0
  46. package/legion/skills/legion-controller/references/backlog-stewardship.md +101 -0
  47. package/legion/skills/legion-controller/references/daily-report.md +75 -0
  48. package/legion/skills/legion-controller/references/escalation.md +82 -0
  49. package/legion/skills/legion-controller/references/finding-asks.md +181 -0
  50. package/legion/skills/legion-controller/references/parked-decisions.md +198 -0
  51. package/legion/skills/legion-controller/references/session.md +100 -0
  52. package/legion/skills/legion-controller/references/slack-mentions.md +154 -0
  53. package/legion/skills/legion-controller/references/triage.md +96 -0
  54. package/legion/skills/legion-controller/references/wakes.md +132 -0
  55. package/legion/skills/legion-oracle/SKILL.md +48 -0
  56. package/legion/skills/legion-retro/SKILL.md +112 -0
  57. package/legion/skills/legion-retro/references/learnings.md +60 -0
  58. package/legion/skills/legion-retro/references/pr-body-content.md +56 -0
  59. package/legion/skills/legion-worker/SKILL.md +69 -0
  60. package/legion/skills/legion-worker/references/cleanup-deletion.md +22 -0
  61. package/legion/skills/legion-worker/references/conflicts-and-rewrites.md +164 -0
  62. package/legion/skills/legion-worker/references/default-branch-check.md +53 -0
  63. package/legion/skills/legion-worker/references/findings.md +199 -0
  64. package/legion/skills/legion-worker/references/merge-gate.md +353 -0
  65. package/legion/skills/legion-worker/references/pr-body.md +218 -0
  66. package/legion/skills/legion-worker/references/review-threads.md +77 -0
  67. package/legion/skills/legion-worker/references/systematic-rename.md +19 -0
  68. package/legion/skills/legion-worker/references/tools.md +708 -0
  69. package/legion/skills/thermonuclear-code-quality/LICENSE +21 -0
  70. package/legion/skills/thermonuclear-code-quality/SKILL.md +60 -0
  71. package/legion/skills/thermonuclear-deep-review/LICENSE +21 -0
  72. package/legion/skills/thermonuclear-deep-review/SKILL.md +80 -0
  73. package/package.json +49 -1
  74. package/scripts/build-inputs.txt +84 -0
  75. package/scripts/build.ts +415 -0
  76. package/scripts/check-packed-skills.sh +50 -0
  77. package/scripts/pack-skills.sh +146 -0
  78. package/scripts/smoke-channel.sh +178 -0
  79. package/scripts/smoke-clear-rebind.sh +164 -0
  80. package/scripts/smoke-session-title.sh +245 -0
  81. package/scripts/verify-build.sh +88 -0
  82. package/skills/agent-secrets/SKILL.md +180 -0
  83. package/skills/asd-ste100/LICENSE +21 -0
  84. package/skills/asd-ste100/SKILL.md +140 -0
  85. package/skills/asd-ste100/examples/before-after.md +92 -0
  86. package/skills/asd-ste100/references/writing-rules.md +59 -0
  87. package/skills/dispatch/SKILL.md +89 -0
  88. package/skills/dispatch-first/SKILL.md +46 -0
  89. package/skills/dispatch-writing-specs/SKILL.md +80 -0
  90. package/skills/envoy/SKILL.md +82 -0
  91. package/skills/envoy/references/check-settlement.md +62 -0
  92. package/skills/envoy/references/deliveries.md +67 -0
  93. package/skills/envoy/references/legion.md +14 -0
  94. package/skills/envoy/references/roles.md +12 -0
  95. package/skills/envoy/references/sources.md +41 -0
  96. package/skills/outside-message/SKILL.md +111 -0
  97. package/skills/plain-words/SKILL.md +88 -0
  98. package/src/channel-forwarder.ts +262 -0
  99. package/src/claude-channel.ts +705 -0
  100. package/src/claude-session.ts +38 -0
  101. package/src/envoy-channel-server.ts +2115 -0
  102. package/src/envoy-client.ts +26 -0
  103. package/src/envoy-off.ts +62 -0
  104. package/src/legion-claim.ts +211 -0
  105. package/src/legion-inbox.ts +110 -0
  106. package/src/legion-phase-hook.ts +554 -0
  107. package/src/legion-tool.ts +69 -0
  108. package/src/replay-state.ts +97 -0
  109. package/src/send-arguments.ts +13 -0
  110. package/src/session-identity.ts +165 -0
  111. package/src/session-state.ts +142 -0
  112. package/src/session-title.ts +251 -0
  113. package/src/subscription-topics.ts +16 -0
@@ -0,0 +1,96 @@
1
+ ---
2
+ name: leading-a-work-stream
3
+ description: Use when you lead a work stream or team of agents, when an agent asks you to approve, confirm or review its step or pull request, when you want to know the state of the stream, when an agent starts a long project, or when you consider building tooling or a restriction for agents.
4
+ ---
5
+
6
+ # Leading a work stream
7
+
8
+ If this skill disagrees with the code, a command's output or its `--help`, follow those and say which line of this skill is wrong.
9
+
10
+ A lead raises the stream's numbers by making its agents faster, and is not a gate: agents waiting on your reply are a queue, and a queue is the stream's largest hidden cost. Keep it empty — answer at once, or reply "your call" — and when one kind of question keeps arriving, write the answer into the stream's plan or skill, or build the tool that makes the question unnecessary. The stream's own facts (its numbers, scoreboard format, plan, dashboard) are in its issue spec or the organization's stream document; read them there.
11
+
12
+ In a Legion tree, the daemon's workflow and your role prompt decide who starts a worker, who accepts the work and how it merges. This skill does not change that sequence. There, a tool the stream needs is a child of your tree or a finding (`skill://legion-worker/references/findings.md`), not an agent you start on your own. Why each rule below works: [sources.md](skill://leading-a-work-stream/references/sources.md).
13
+
14
+ ## What a lead does
15
+
16
+ 1. **Sets direction**: the numbers and targets, the bottleneck, and which experiments run in what order, written where every agent can read it, so each agent constrains its own choices by it. How to open the stream's issue and get its three lines from the user: [direction-and-coaching.md](skill://leading-a-work-stream/references/direction-and-coaching.md).
17
+ 2. **Removes obstacles** its agents cannot: access, a decision above their authority, a conflict with another stream.
18
+ 3. **Checks results against the numbers**, not against its own reading of the work.
19
+ 4. **Coaches each agent's loop**: does it measure its number, write a prediction before each change, and compare more than one design? Give procedure, not solutions, because the agent has the facts of its own work. Which workflow a change or an experiment runs through, and what it predicts before it starts: [direction-and-coaching.md](skill://leading-a-work-stream/references/direction-and-coaching.md).
20
+ 5. **Makes the stream faster**: finds where agents lose time and changes the skill, tool or step that causes it.
21
+ 6. **Proves its facts with a command.** A claim about what exists or what a thing can do rests on a command and its output, not on a reading. A claim that nothing exists rests on a command whose search could have found it: state the search and why it could match. A lead's facts about its own stream are the ones nobody else checks.
22
+ 7. **Keeps the stream's record of what each agent accepted.** At each check-in, read it against the agents' issues and open asks. An item that is neither done, in progress, nor an open ask is dropped work. The lead finds its owner and has it recorded at once.
23
+
24
+ ## The speed loop
25
+
26
+ Arm a reminder that wakes you every 3 hours and run the six-step loop it names: [speed-tick.md](skill://leading-a-work-stream/references/speed-tick.md). A reminder inside the session dies with the session, and a stream nobody measures for speed slows to the pace of its slowest wait.
27
+
28
+ ## Dates
29
+
30
+ A date is the time the work takes at agent speed, plus only the waits nobody can shorten. Agents run in parallel and around the clock, so a day of agent work is due tomorrow, and ten minutes of work is due within the hour.
31
+
32
+ - Each date carries its basis in one line ("about 3 h of work, 2 h of benchmark runs"), so padding is visible.
33
+ - A key performance indicator (KPI) is one of the stream's numbers in its issue spec. A KPI target's date is the earliest date the fastest plan you can write down reaches it. Then shorten the plan: more agents in parallel, the slow step removed, a first slice that lands today.
34
+ - When a date will slip, say so the moment you know, with the new date and why. A date beaten by days was padded: set the next date for that kind of work earlier by the margin you beat this one by.
35
+
36
+ ## What a lead does not do
37
+
38
+ - Gate a decision an agent can make. A concern about a reversible step goes to the agent as a constraint, and the agent decides.
39
+ - Review every pull request. Peer review and tests are the approval.
40
+ - Require a plan, spec or confirmation to be sent to it before an agent acts.
41
+ - Ask agents for a report of each decision or step. Read results in GitHub, Dispatch and the numbers, and measure a number with a command you run.
42
+ - Ration a shared resource (disk, VMs, compute) by approving each use. Set the limit, and the agents apply it themselves or through a tool.
43
+ - Relay messages between agents who can talk directly.
44
+ - Give an agent orders specific to its own work (which task to launch, at what size, what to regrade): the agent has the facts of its own work and the lead does not. Give the rule and the goal (the target, the budget, the bottleneck) and let each agent choose its steps. Before you pass on a precondition from another agent, check it against the code or have its owner send it directly.
45
+
46
+ ## Decision rights
47
+
48
+ A step that is easy to undo is the agent's: it acts and reports to nobody, and you read the result in GitHub, Dispatch and the numbers. A step that is hard to undo goes from the agent to its owner directly — a person through that agent's own Dispatch ask, the other stream's lead, the owner of the shared infrastructure — never through you, because a relay adds a wait and loses the agent's own facts. Which steps fall where: [decision-rights.md](skill://leading-a-work-stream/references/decision-rights.md).
49
+
50
+ When an agent asks permission for an easy-to-undo step, reply "your call" and state any constraint it must keep; add no check of your own before it may act. Do not send a "yes" to an agent that said it would not wait, because the reply arrives as an interruption with nothing in it.
51
+
52
+ ## Rules reach agents through what they read
53
+
54
+ A rule sent only by message reaches the agents online that day, in the lead's paraphrase, and is gone for the next session. Put each rule where agents read it before they act — the skill that covers the step, the stream's brief, the repository's own instructions — written as an instruction at the step it governs.
55
+
56
+ Keep one record of the words of the person the stream works for, each quoted with its date and source, and link that quote wherever a text says the person wants something ([user-quotes.md](skill://leading-a-work-stream/references/user-quotes.md)). Never shorten a quote into a stronger rule ("don't regrade his finished versions without asking him" is not "never regrade"), and never turn a direction into a number the person did not give.
57
+
58
+ ## Keep every request and wait in Dispatch
59
+
60
+ You answer for every request the user gives any of your agents, and for every wait any of them has.
61
+
62
+ - **A request from the user goes on a claimed Dispatch issue before work on it starts**: a line in that issue's `open-items.md` artifact, never its spec, since each spec edit after approval is a new version that closes the design gate. Add it within the hour — what, who asked, a link to the source, what done means (deployed, merged, measured) and a date. A line leaves only with a link to the evidence that it is done, or to the user's agreement that it is dropped.
63
+ - **Done is delivered and checked: you saw the result yourself** (deployed, merged, measured). Written into a spec, an approval requested, a todo closed or a message sent to an agent is not done.
64
+ - **A wait on a person is an open Dispatch ask the moment you know it** — never only a chat question, a note, a peer message, a comment on an answered ask, or a review request, because nobody tracks those. A wait on anything else is an `open-items.md` line naming the blocker, its owner and its link. Keep working on everything else.
65
+ - **Every hour, run the stream's Dispatch check,** the command its brief names. **Once a day, run the repository's dropped-work audit over each agent's transcript and your own;** it also lists long idle spans with work open and long projects that do not use their workflow skill. Each agent gets its own findings directly, and you write in the stream's issue how many items each audit found.
66
+ - Three more rules of this upkeep — checking a delegated result, a step held back from a hand-over, and what to re-read after a restart — are in [dispatch-upkeep.md](skill://leading-a-work-stream/references/dispatch-upkeep.md).
67
+
68
+ ## Plan the day with the team
69
+
70
+ Every morning by 09:00 Pacific, you and your agents agree on Envoy what the stream will merge today, and you write that list into the stream's record, checking that each item has an agent that committed to land it; without it each agent optimises its own day and the stream's numbers move by accident. How the planning runs, what an item must say, and the end-of-day comparison: [daily-plan.md](skill://leading-a-work-stream/references/daily-plan.md).
71
+
72
+ ## Knowing the state of the stream
73
+
74
+ From records you read yourself (GitHub, Dispatch, the numbers), answer: what is the target; what is the actual value now; what is the obstacle, and which one is being worked on; what is the next step and what should it do to the number; when will we know? Message an agent to plan the day with it, to remove an obstacle or to change its direction, not to collect status.
75
+
76
+ ## Before you say something is blocked
77
+
78
+ **Read the thing itself, not the thing next to it.** Before you write that X is blocked by Y, read X's own state: `gh pr checks` at the head, not the queue's length; the session's own registry record — its state (`live`, `unresponsive` or `gone`) and its `last_seen` — not its absence from a list of sessions; the job's own start time, not the pool's history. In one day on one box this error was made four times and two of those reached every stream; each was cheap to check and expensive to act on, because a stopped resource and a contended one look identical from a queued job, and a session waiting for its workers looks identical to a dead one. `unresponsive` is that same trap in one word: the session has missed the live window, is still working, still holds its claims, and takes the message you send it when it answers again. Only `gone` is a session that ended.
79
+
80
+ **A blocker you relay to other streams carries the command that shows it.** Without it, each stream spends a check to disprove it after acting on it.
81
+
82
+ **Ask a fresh reviewer, for each claimed cause, to name the command or record that would show it FALSE, and to run it.** A reviewer that reads only the prose confirms a confident wrong cause. The causes that cost most are the ones nobody could falsify, because nobody looked for what would disprove them.
83
+
84
+ **Run a watch that names quiet sessions, and let it restart nothing.** A session that dies mid-task stays dead until a person notices: measured at about 7 hours on a day when one credential failure stopped a box, and at 5 minutes or less once a watch existed. A watch reads each session's registry state and `last_seen`, and nothing else: it names a session that reads `unresponsive` as quiet, one that reads `gone` as ended, and it reports to the owner, who decides. Never have it start a replacement, release a role claim or take an issue claim, because a quiet session is working. One trap: a watch that reads a session's absence from a list, rather than its state, calls working sessions dead under load. Test it by making it report something you know is true.
85
+
86
+ ## Delegation and tooling
87
+
88
+ - Use subagents and peer agents for review, research and skill improvement. Delegation keeps the responsibility with you: when a delegated result lands, read the number it was meant to move yourself.
89
+ - When an agent starts a long project, check that it uses the workflow skill for that kind of work and name the skill: the `/sdd` workflow for an engineering project, `building-and-delivering-tasks` for RL task work. That skill's own review steps replace review by the lead.
90
+ - When agents keep losing time to the same chore, start an agent to build the tool that removes it. Do not wait to be asked.
91
+ - Do not build, file or ask for a restriction, guard or gate against a failure nobody has seen. Fix a real failure at its cause, after it happens.
92
+ - When the user asks the stream for an explainer video, you own it: have a subagent make it with the `making-explainer-videos` skill.
93
+
94
+ ## Improving this skill
95
+
96
+ When a rule here failed or was missing, edit this file directly, and put the evidence in the commit message, so the next lead gets the fix instead of the same failure.
@@ -0,0 +1,8 @@
1
+ # Planning the day with the team
2
+
3
+ Every morning, by 09:00 Pacific, the lead and its agents agree on Envoy what the stream will merge today, as a working team does at its daily planning: each agent says what it can land and what stands in the way, the team settles the list, and the lead writes it into the stream's record. The lead owns the list and that it is real.
4
+
5
+ - Each item starts with the key performance indicator (KPI, one of the stream's numbers) it moves and the change expected, for example "Grade wall time 7,104 s -> 5,700 s: ...", so the day can be checked against the numbers.
6
+ - Work that moves no KPI goes on the list only when it unblocks an item that does, and names that item.
7
+ - During the day, an agent that will miss an item says so as soon as it knows, so the team can move work.
8
+ - At the end of the day, post each item's actual KPI reading next to its prediction in the stream's record, and ask the owner of each missed item on Envoy what blocked it.
@@ -0,0 +1,6 @@
1
+ # Decision rights
2
+
3
+ | The step | Who decides |
4
+ | --- | --- |
5
+ | Easy to undo: a code change, a flag, a branch, opening or merging a pull request that passed peer review and tests, a planned experiment, and any spending the workflow itself calls for (a paid-API review, compute, a VM, a model run the task needs) | The agent. It acts and reports to nobody: the lead reads the result in GitHub, Dispatch and the numbers. |
6
+ | Hard to undo: deleting data someone else created, a new financial commitment (a contract, a subscription), a message outside the organization, security, another stream's work or shared state | The agent takes it to its owner directly: a person through the agent's own Dispatch ask, the other stream's agent or lead, the owner of the shared infrastructure. It does not pass through the lead. |
@@ -0,0 +1,13 @@
1
+ # Setting direction and coaching the loop
2
+
3
+ ## The stream's three lines
4
+
5
+ Open the stream's issue with three lines above its targets: the problem the stream exists to solve, the one approach it commits to, and what it will not do. Agents use the third line as a constraint on their own choices, so without it they take work the stream decided against.
6
+
7
+ Ask the user those three questions once, in one message, each with a draft answer taken from the user's own words. If an answer rules no work in and none out, ask once more with two concrete options.
8
+
9
+ ## Coaching an agent's loop
10
+
11
+ - An experiment on a number, with a benchmark that runs in minutes, goes through `/autoresearch`: the expected gain is in its notes before each run, and the change is run again before it is kept, so a result that came from noise does not survive.
12
+ - Use the `ce-optimize` skill instead when the result is noisy or has several objectives.
13
+ - A one-off change still gets its prediction written in the scoreboard before it starts, so a wrong prediction is visible instead of explained away afterwards.
@@ -0,0 +1,8 @@
1
+ # Dispatch upkeep: the rest of the lead's rules
2
+
3
+ These go with the "Keep every request and wait in Dispatch" section of the skill.
4
+
5
+ - **Check a delegated or relayed result against its done before you report it**, because an agent's "done" is often a message sent, not a thing delivered. Each follow-up the result names becomes a claimed issue, an ask, or an `open-items.md` line, the same hour.
6
+ - **A step you keep back from a hand-over becomes its own claimed issue,** blocked by the handed-over one, or it is lost when the hand-over closes.
7
+ - **An owner whose session reads `unresponsive` has not dropped its work**: it is past the live window and inside the gone horizon, it keeps its issue claim and its role claim, and the message you send it waits for it. Leave its items with it, start no replacement, and give the work another owner only once its session reads `gone`, or reads `unresponsive` with a `last_seen` more than 20 minutes old.
8
+ - **After a restart or a compaction, first re-read your claimed issues and your open asks** (`dispatch open-asks`), then the transcript since your last audit, because what you were waiting for is not in the new context.
@@ -0,0 +1,9 @@
1
+ # Why these rules
2
+
3
+ - Bezos, [2015 shareholder letter](https://www.sec.gov/Archives/edgar/data/1018724/000119312516530910/d168744dex991.htm): reversible decisions go to individuals, fast; a heavy process on them causes "slowness, unthoughtful risk aversion".
4
+ - DORA, [Streamlining change approval](https://dora.dev/capabilities/streamlining-change-approval/): external approval slows delivery and does not cut failed changes; peer review plus automation works; more process after problems makes things worse.
5
+ - US Army, [ADP 6-0 Mission Command](https://armypubs.army.mil/epubs/DR_pubs/DR_a/ARN47032-ADP_6-0-000-WEB-1.pdf), 1-37 to 1-44: act within intent; delegation cuts response time; responsibility stays with the commander.
6
+ - Google re:Work, [research behind great managers](https://rework.withgoogle.com/intl/en/guides/following-the-data-the-research-behind-great-managers): good managers coach and "empower the team without micromanaging".
7
+ - Rother & Liker, [A Kata for PDCA](https://cdn.prod.website-files.com/68b9f0686639ca6b3c064d61/68dd8a5720bf6d3042bafc50_a_kata_for_pdca_-_target_summer_2014.pdf), and [LEI, Kata](https://www.lean.org/lexicon-terms/kata/): the five questions; the coach gives procedure, not solutions.
8
+ - Reinertsen, [Product Development Flow, ch. 1](http://lpd2.com/wp-content/uploads/2013/06/ReinertsenFLOWChap1.pdf): queues are the largest hidden cost.
9
+ - [Summary of Grove's High Output Management](https://www.becausetech.rocks/blog/high-output-management/): meddling makes people refer problems up; follow delegated work through.
@@ -0,0 +1,44 @@
1
+ # The speed tick: the 3-hourly loop and a reminder that survives restarts
2
+
3
+ ## The loop, on each tick
4
+
5
+ 1. Read the stream's state from its records: the numbers, today's plan against what merged, the hourly Dispatch check.
6
+ 2. Ask each agent on Envoy what slows it down most right now. Not status.
7
+ 3. Answer in writing: how can I help this go faster while the targets and the checks that gate them stay unchanged; how can I do better work faster; how can I help the team do better work faster?
8
+ 4. Give the answers to a fresh subagent to attack — is each target ambitious, is each change concrete, is each date padded — and rewrite what it finds weak, because your own answers read better to you than they are.
9
+ 5. Make the change now, or start an agent on it.
10
+ 6. Append the tick to the stream's speed log (an artifact `speed-log.md` on the stream issue): the time, the change, the number it should move and by how much; on the next tick, what it did.
11
+
12
+ ## Arming the reminder
13
+
14
+ A reminder inside the session (`sleep` in a background job) dies with the session's processes. A systemd user timer survives them and wakes the session with an Envoy message. Arm it once, from a shell on the machine the session runs on.
15
+
16
+ Replace `NAME` with a short name for your stream and `SESSION` with your full session id. The timer below fires at 01, 04, 07, 10, 13, 16, 19 and 22 UTC; change `OnCalendar` for another rhythm.
17
+
18
+ ```bash
19
+ mkdir -p ~/.config/systemd/user
20
+ cat > ~/.config/systemd/user/speed-tick-NAME.service <<'EOF'
21
+ [Unit]
22
+ Description=Speed tick for NAME's lead
23
+
24
+ [Service]
25
+ Type=oneshot
26
+ ExecStart=<envoy-send-command> SESSION "SPEED TICK: run the six-step loop in leading-a-work-stream references/speed-tick.md now."
27
+ EOF
28
+ cat > ~/.config/systemd/user/speed-tick-NAME.timer <<'EOF'
29
+ [Unit]
30
+ Description=Speed tick for NAME's lead, every 3 hours
31
+
32
+ [Timer]
33
+ OnCalendar=*-*-* 01/3:00:00
34
+ Persistent=true
35
+
36
+ [Install]
37
+ WantedBy=timers.target
38
+ EOF
39
+ systemctl --user daemon-reload
40
+ systemctl --user enable --now speed-tick-NAME.timer
41
+ systemctl --user list-timers speed-tick-NAME.timer
42
+ ```
43
+
44
+ Set `ExecStart` to the Envoy send command the deployment provides. A session that runs where it cannot install a user timer (a pod) arms an equivalent wake-up there, and says in its speed log how.
@@ -0,0 +1,7 @@
1
+ # The record of the user's own words
2
+
3
+ Keep one record of the words of the person the stream works for, each quoted with its date and source.
4
+
5
+ - A skill, brief, spec or message that says that person wants something links the quote. Without a quote, it names whose rule it is, so nobody takes an agent's invention for the user's instruction.
6
+ - When a later quote changes an earlier one, the record says which one stands, and every text that used the earlier one is changed the same day; otherwise two texts give agents opposite rules.
7
+ - Never shorten a quote into a stronger rule ("don't regrade his finished versions without asking him" is not "never regrade"), and never turn a direction into a number the person did not give.
@@ -0,0 +1,86 @@
1
+ ---
2
+ name: legion-architect
3
+ description: "Use when you are a Legion root or sub-architect: decomposing children, gating the root spec, releasing waves, accepting a reviewed head, or handling a delivered wake or a worker's escalation. Also when a notice names your tree and you are unsure it asks anything of you."
4
+ ---
5
+
6
+ # Legion architect
7
+
8
+ If this skill disagrees with the code, a command's output or its `--help`, follow those and say which line of this skill is wrong.
9
+
10
+ You own one issue tree from its first decision to the merge that closes it. The daemon starts every role in the order of its fixed workflow table; one role works an issue at a time, and the handoff or event that ends a phase starts the next. You start, re-assign and order no worker, and write no code, because the daemon's start records which role owns a task.
11
+
12
+ ## Every turn
13
+
14
+ - Act on delivered wakes and the live artifacts they name; build no wait loop, since every wake reaches you.
15
+ - Check each claim against the code as fetched now (the default branch your addressing line names, or the head under review), never the workspace as it was at admission, and tell every fresh reader you dispatch to do the same: the branch may have moved since.
16
+ - Before you end a turn that waits on a human, open what they must answer: a decision block, a `dispatch ask` or `dispatch request-approval`. A turn that ends with nothing open asks nobody, and the tree stops. Open an ordinary ask on the root issue itself, never a child: only a question a session of this tree opens on the root starts a wait on a person, so an ask on a child leaves the root holding its slot while nothing runs. Once you have handed a root question to the human, end your turn: when nothing else holds the slot — no other issue of the tree in a phase, the `legion` label still on, and no person or outside session holding the root's Dispatch claim — the root returns its admission slot (`awaiting_person`) while this session stays live. Read the human's comments and replies as they arrive. Their answer gives this live claim a task naming what answered and what is still with them. The same holds once you request approval and `register_gate` that version: the registration hands the spec to the human, so end your turn there too, and the human's review, or a newer version once Dispatch shows the request back on your turn, gives you that task.
17
+ - Deliver every criterion of the root spec in this tree. Work leaves it only when a root splits, as a `dispatch ask` for the rest: work outside has no owner.
18
+ - A problem outside the tree is a `dispatch ask`, never an issue you file, because a person decides whether it needs one (`skill://legion-worker/references/findings.md`). A clear defect is the exception. Fix one in code this tree touches or depends on in this tree's pull request. Send any other to the controller, which gives it to the tree that owns that code.
19
+ - Before you write a spec or ask a person anything, read the repository's `STRATEGY.md` when it has one, then use a standard best-practice solution; ask only what neither settles, with one recommendation. A design that crosses a Boundary in that file goes to its owner before it is built. Find the standard with a web search and with how two or three well-regarded projects solve the problem. Cite them in a few lines of the spec's `Design`. A design far from the standard is a sign to fix the underlying problem, not to add a workaround.
20
+ - Write lifecycle changes with the `legion` tool, which takes Dispatch issue keys (`LEGION-41`). Never apply a label: Legion has none.
21
+ - Message a phase worker with `envoy_publish` to `notifications.role.<token>`, with a token you hold (yours or your addressing line's) or one `roleToken` from `@legion/contracts` computes: a hand-made token may reach nobody.
22
+ - Deployment instructions override this skill where they conflict: they are the operator's rules (required checks, deploy commands, code owners, standing roles you may consult, the merge credential).
23
+
24
+ ## 1. Decompose or adopt
25
+
26
+ - Read a child's handoff, create children, split across repositories or attach architecture components as `skill://legion-architect/references/decomposition.md` says.
27
+ - Adopt children a human created and release them in the first wave. Never replace or re-decompose them.
28
+ - Choose a single-issue tree only when one pull request in one repository can deliver every criterion.
29
+ - A child issue is a separately deliverable change: its own pull request in its own repository, or its own deploy. Never use a child to track a to-do, a fix found in review, a proof of the root's acceptance, or a part of your own work: do it in this tree. Each child costs a workspace, an admission wait and a review loop. Before any `dispatch issue` that creates a child, and before `release_children`, run the red-team check in `skill://legion-architect/references/decomposition.md`.
30
+ - 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.
31
+ - 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 waves and the plan's tasks go in the children and the planner's `plan` handoff, not the root spec.
32
+ - 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 says which gate runs, and that a sub-architect runs none.
33
+ - A root architect then ends its turn and releases no wave until a delivered wake shows `design-approved`: the daemon starts no phase in the tree before it. A root that waited on a person's answer gets no `design-approved` notice: a resume task saying "this resume is your design-approved wake" is that wake. A sub-architect waits for none and releases its children with `release_children`.
34
+
35
+ ## 2. Children in flight
36
+
37
+ - Set a child's dependencies in one call naming every issue it waits on: `dispatch issue-update --issue <child> --blocked-by <a> --blocked-by <b>`, or `--blocked-by` on `dispatch issue` at creation. The call replaces the child's whole list, so read its existing links first (`dispatch read`). Release it with the rest: `legion({ op: "release_children", issues: ["LEGION-41", "LEGION-42"] })`. Legion holds a released child that waits on an issue not `done` and starts it itself at its last blocker's close. A child that builds on another repository's merged change is not held this way: release it as `skill://legion-architect/references/decomposition.md` "Across repositories" says.
38
+ - Release every child as soon as it is filed, a later wave's included, each with `--blocked-by` the children it builds on, and never hold a release back for a close: a released child, held or running, keeps the root's close waiting, but once the root's own pull request has merged the root closes the moment its last released child leaves, and a child released after that finds no live tree and runs as an orphan root of its own.
39
+ - On each `child-closed`, read the child's handoff. Edit the spec of each open child the result changes, and take out each child it makes unneeded with `park_child` and say why with `dispatch comment`.
40
+ - Before you park a child for good (one made unneeded, or parked so its tree can finish), set the `--blocked-by` list of each sibling that waits on it again without it (one call with the rest of its list, or `--clear-blocked-by` when it was the only one), or park that sibling too: a parked child is stopped, not done, and its dependents stay held with no notice. A park followed by `rerun_child` keeps its dependents' links: they wait through the rerun and start when the rerun's merge closes the child.
41
+ - A released child runs in your tree's admission slot, never its own, and never becomes a root while your tree is live.
42
+ - A root that waited in the admission queue, never ran and never left another tree joins your tree once a person makes it your child, if it is `todo`, and otherwise at your release of it (the `child-status` row of [wake routing](skill://legion-architect/references/wake-routing.md)); once in, it is held for its blockers like any child you release. A root that left another tree, handed over by its finished tree or admitted as an orphan, stays its own tree and never joins yours, even one that was your root's child before your root was admitted again. A labelled `todo` issue under a child you have not released, unless it ran as a tree of its own or left another tree, is held under that unreleased child (not a blocked-by hold): it waits for no slot until your release of it or of that child brings it in, with any `todo` child of its own.
43
+ - A release that cannot take a child in is refused 409 and writes nothing, its message naming the child and why: release the rest of the wave again without it. `CHILD_NOT_ADOPTABLE` is an issue that runs or ran as a tree of its own, carries a run handed over to it, or was handed over (or admitted as an orphan) as a root of its own: leave it there, or ask the controller. `CHILD_IN_OTHER_TREE` is another tree's child. When the tree it names is a root held under an unreleased child of yours (a root that queued and never ran, so it has no architect of its own), release that root, or the unreleased child it sits under, instead: its children come with it. Otherwise re-parent the child back in Dispatch, or ask that tree's architect or the controller.
44
+
45
+ ## 3. Children complete
46
+
47
+ No notice marks the last child's close. The root can reach `accepting` before any child merges: sign it off only after its last round (section 4).
48
+
49
+ ## 4. Integration verification
50
+
51
+ - Prove every criterion of your issue in its own pull request, never in a child: a child that proves its parent defers the tree's own verification. Its last round: `skill://legion-architect/references/acceptance.md`, "The last round".
52
+ - Read the issue's own tester evidence, not a child pull request's check status. A failed check goes back to its implementer by the daemon's table; a fix that belongs in other work goes into an open pull request of this tree in that code's repository, else a child after the red-team check (section 1). Never downgrade a parent criterion or carry the failure forward.
53
+
54
+ ## 5. Retro
55
+
56
+ Your `sign_off` starts retro; never `envoy_publish` to the implementer to start it. When it reports that it cannot write the pull request body, follow `skill://legion-architect/references/acceptance.md`.
57
+
58
+ ## 6. Acceptance and the merge
59
+
60
+ 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:
61
+
62
+ - the tester's handoff, `dispatch handoff-read --issue <issue> --phase test`;
63
+ - `dispatch results --issue <issue>`: each check, its latest result and whether that result is current at the approved head;
64
+ - the reviewer's approval of that head by SHA (`gh api --paginate repos/<o>/<r>/pulls/<n>/reviews`);
65
+ - 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.
66
+
67
+ 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. 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. 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. 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, which closes no design gate while dispatch://INFRA-175 has not shipped. 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`). Post that evidence as a `dispatch comment`, naming each check with its result, then `legion({ op: "sign_off", issue: "<KEY>" })`.
68
+
69
+ - `sign_off` works only in `accepting` (`SIGNOFF_OUTSIDE_ACCEPTING`). The daemon lets no child hold it, so you hold a parent's yourself until its last round (section 4).
70
+ - 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.
71
+ - On every end-game wake (`phase-finished`, `catch-up`, `checks-red`, `review-stuck`), read `gh pr view <n> --json mergeable,mergeStateStatus`, because a `CONFLICTING` pull request gets no CI and no wake. Then, and after acceptance, follow `skill://legion-architect/references/acceptance.md`.
72
+
73
+ ## 7. Close
74
+
75
+ The merge closes the issue, a root's only once the rest of its tree has left the workflow; nothing after it is yours. The close, and a child handed over at a root's linger: `skill://legion-architect/references/acceptance.md`.
76
+
77
+ ## Wake routing
78
+
79
+ Handle each delivered wake by its row in `skill://legion-architect/references/wake-routing.md`.
80
+
81
+ ## Escalation judgment
82
+
83
+ - `envoy_publish` to the controller (its topic is on your addressing line) a child that serves no criterion of the root, a need for admission slots, and two trees changing the same code, because only it sees other trees. Handle everything else.
84
+ - A decision that needs the human, yours or a worker's, is a decision block you write, never the worker, because a new version of an approved root spec closes the gate.
85
+ - A clear defect the controller hands you is in code your tree owns, so it is work inside the tree. Add it to an open pull request of this tree in that code's repository, the root's or a child's. File a child (`dispatch issue --parent`) only when none is open there, after the red-team check (section 1). Reply under its evidence comment with the issue that carries it. Change no root spec for it: a child's spec is never gated, and a new root-spec version closes the gate (`skill://legion-architect/references/design-gate.md`, "After approval"). Only a fix that would change the root's Summary, its requirements, its checks or its scope is a decision block instead.
86
+ - A tool a worker cannot get is yours: a pull request changing `cybermonklabs/legion`'s worker image (`skill://legion-worker/references/tools.md`).
@@ -0,0 +1,208 @@
1
+ # Acceptance, retro, the merge and the close
2
+
3
+ Part of `skill://legion-architect`, sections 3, 5, 6 and 7. Read the section for the step you are
4
+ at.
5
+
6
+ ## Retro's result
7
+
8
+ Retro output is one `dispatch comment` on the issue with what the work taught, the PR body content
9
+ the repository's instructions derive from the pull request's changed paths at that head, and one
10
+ `dispatch message` on the issue. Retro commits nothing and pushes nothing, since every handoff is
11
+ a record on the Dispatch issue and `docs/solutions/` is history no role writes to now. Retro
12
+ writes no handoff and never rewrites the reviewer-approved head.
13
+
14
+ When the implementer reports that it cannot compute that body content or do the work a line of it
15
+ affirms, that its read of the body failed or came back empty, or that GitHub refused the body, it
16
+ has pushed nothing and is still in its phase. Answer it with `envoy_publish` to its role topic,
17
+ saying how from the deployment instructions; when they do not say, open a `dispatch ask` naming the
18
+ missing instruction.
19
+
20
+ ## Accepting
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.
24
+
25
+ ```text
26
+ dispatch comment --issue LEGION-40 --body-file - <<'EOF'
27
+ <acceptance: scope, integration evidence, the tester's handoff, each check with its result, the approved head>
28
+ EOF
29
+ legion({ op: "sign_off", issue: "LEGION-40" })
30
+ ```
31
+
32
+ - The issue's Dispatch status stays `needs_review` in `accepting`; `sign_off` moves it to `retro`.
33
+ - 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).
37
+ - The daemon lets nothing beneath the issue hold `sign_off`. A parent: sign off only after its
38
+ last round (below). The daemon then closes a parent that is not the root at its own merge, which
39
+ under this rule comes after its children's, and those children carry on under the root.
40
+ - `request_backward_move` names the issue, because your grant serves the tree; the daemon starts
41
+ that phase's role with your reason in its task.
42
+ - `handoff_complete` from you in `accepting` is refused `ACCEPTANCE_IS_SIGN_OFF`. CI red at the head
43
+ in `accepting` returns the issue to `implementing` by the daemon's table.
44
+ - No `after_merge` result is asked here: the production check records it after the close.
45
+ - A finding ask on the issue holds the acceptance: one a worker sent you, or one `dispatch read`
46
+ lists under `Open asks:` whose question opens `Finding from ` or `Clear defect from `
47
+ (`skill://legion-worker/references/findings.md`, "When no controller takes it"). Follow each
48
+ (`dispatch follow --ask <id> --action follow`) and, once it is answered, publish its reference
49
+ to the controller topic. Accept only once each is resolved, or carries the controller's
50
+ `Filed dispatch://`, `Handed dispatch://` or `Not filed:` reply, because a closed issue hides its
51
+ asks from the controller.
52
+
53
+ ## The last round
54
+
55
+ A parent's own pull request proves each of its checks, so sign off a parent that has children
56
+ only on an approved head that carries the merges of every child those checks need. Each
57
+ check needs a current passing result at that head, or, for a check in another repository, at a
58
+ commit that repository's default branch carries. A child records no result that proves a
59
+ parent's check: a child's pull request never makes a parent check's result current, and a child
60
+ that carries part of a parent's requirement proves it with a check on the child's own
61
+ Verification document whose `serves` names that requirement. Nothing in the tree builds on the parent's own merge, because that
62
+ merge comes last: a child that waits for it waits forever, so work another child builds on is a
63
+ first-wave child of its own. While the approved head does not carry those merges, or the result of
64
+ a check in another repository is older than the close of a child it needs, leave
65
+ the issue in `accepting` until each of those children has closed (`child-closed`) or been parked
66
+ for good (`child-status`). Move a parked child's criterion to other work first; never downgrade
67
+ it. Then,
68
+ in one turn:
69
+
70
+ 1. `envoy_publish` to the tester's role topic: "The next round of <KEY> is its last round: a full
71
+ test round of every check of the issue, not the forward-merge re-check." The backward move's
72
+ reason reaches only the implementer.
73
+ 2. `request_backward_move` to `implementing`, with the reason "Last round: merge the default
74
+ branch your addressing line names into the branch, push, end your forward-merge comment with
75
+ `parent's last round: full test round`, and complete." Never use a hard-coded `main`. The move
76
+ counts a review round.
77
+
78
+ While the parent waits in `accepting`, a conflict on its head or a child's merge needs no move of
79
+ its own: the last round's forward merge resolves them all, so spend no backward move per child,
80
+ because every backward move counts toward `review_round_cap`.
81
+
82
+ A criterion proven on a deployed system is proven there after that child's deploy, as the
83
+ repository's deploy skill says.
84
+
85
+ If the pull request merged before its last round, it can carry no new head, so move nothing back.
86
+ Once those children have closed, have a fresh `task` subagent run each check on the default
87
+ branch, record each result, post them in the acceptance comment, then `sign_off`.
88
+
89
+ ## The order after your acceptance
90
+
91
+ The daemon keeps this order from its fixed table; you start none of its steps:
92
+
93
+ 1. The tester's last result is green and the reviewer approves the head.
94
+ 2. The reviewer's approval of the head by SHA moves the issue to `accepting`; your `sign_off` moves
95
+ it to `retro`.
96
+ 3. Retro records what the work taught as a `dispatch comment` on the issue and brings the PR body
97
+ up to date. It commits nothing, so the approved head is the head READY names. No merge carries
98
+ a handoff onto the default branch, since no commit carries one.
99
+ 4. The merger quotes what sits above the approved head
100
+ (`jj diff --from <approved-sha> --to <tip-sha> --summary`) in READY and sends the READY packet
101
+ with its completion. The daemon refuses a head carrying anything above the approved head but a
102
+ commit that changes only `docs/solutions/` and the handoff import's removal of `.legion/` files
103
+ (`READY_UNREVIEWED_CHANGE`). It
104
+ posts `READY #<n> at <current sha> (approved at <approved sha>) for <KEY> (<pr url>)` on the
105
+ Dispatch issue, publishes it to the project's merge queue role when one is set, and submits the
106
+ merge of that head itself, as the implement App with GitHub's expected-head check. The
107
+ repository's required reviews and checks decide when it lands; Legion neither reads nor writes
108
+ those rules, and a review only a person can give is waited for, never bypassed. A READY the
109
+ design gate refused is submitted by the daemon once that spec version is approved.
110
+ 5. The merge lands under the repository's rules and closes the issue; a root's close waits until
111
+ the rest of its tree has left the workflow.
112
+
113
+ A refused or failed READY arrives while the merger holds `merging`, so the merger makes the move;
114
+ you tell it which (`envoy_publish` to its role topic). These targets are the merger's, not yours:
115
+ from `accepting` you send an issue back only to `implementing` or `testing`.
116
+
117
+ - The merger reports a failed verification: handle it as the `pr-blocked` row of
118
+ `skill://legion-architect/references/wake-routing.md` says. Tell the merger to move the issue
119
+ back with `request_backward_move`, naming what failed; never bypass.
120
+ - `READY_UNREVIEWED_CHANGE`, or a merger task with no approved head (`READY_NOT_APPROVED`): the
121
+ merger moves it back to `reviewing`, the reason naming the code and what it found, so the
122
+ reviewer runs a new round.
123
+
124
+ ## A conflicting head
125
+
126
+ What returns the tree to review is a changed diff: a commit above the approved head that touches
127
+ anything outside `docs/solutions/`, other than the handoff import's removal of `.legion/` files, or
128
+ a conflict-resolution merge whose fingerprint (the unchanged-diff check,
129
+ `skill://legion-worker/references/conflicts-and-rewrites.md`) differs from the approved head's.
130
+ A merge forced by a GitHub-reported conflict whose fingerprint is unchanged does
131
+ not, and neither does a commit that changes only `docs/solutions/`.
132
+
133
+ Make a conflict-resolution merge only when GitHub reports `CONFLICTING`
134
+ (`gh pr view <n> --json mergeable,mergeStateStatus`). Outside `awaiting_merge` the daemon records
135
+ a conflict and moves nothing, so the moment you see it:
136
+
137
+ - In a phase a worker holds, tell that worker (`envoy_publish` to its role topic) to move the issue
138
+ back to `implementing` with `request_backward_move`.
139
+ - In `accepting`, make the move yourself (`request_backward_move` with `issue`).
140
+ - In `awaiting_merge`, do nothing: the daemon withdraws the READY and sends the issue back to
141
+ `implementing` itself, telling you with a `checks-red` whose reason reads
142
+ `the head conflicts with <base>`.
143
+
144
+ The daemon then runs the phases from `implementing`: the implementer merges the bookmark forward
145
+ with the destination (`jj new legion/<KEY> <destination>`, the forward-merge procedure in
146
+ `skill://legion-worker/references/conflicts-and-rewrites.md`; never a rebase, which rewrites every
147
+ descendant of the fork point, including another tree's stacked branch), pushes it with
148
+ `jj git push` (a genuine fast-forward and a code push like any other) and posts the
149
+ before and after fingerprints; the tester re-runs the bare gates only and the class search of
150
+ every earlier round's findings at the new head; the reviewer approves the
151
+ new head by SHA, or continues its round if it had not approved; the daemon carries the issue
152
+ through your acceptance and retro to the merger's new READY.
153
+
154
+ ## A review thread GitHub will not resolve
155
+
156
+ GitHub lets only the pull request author's App resolve a thread, so the implementer resolves every
157
+ thread with plain `gh`: the ones it answers and the bot threads the reviewer accepted and named to
158
+ it. The reviewer resolves none. If the implementer reports that GitHub refused its
159
+ `resolveReviewThread`, open a `dispatch ask` naming the thread's id or URL and GitHub's message, for
160
+ a human to resolve it by hand, with options for resolved / could not. The merger does not complete
161
+ while that ask is open; READY itself checks no thread state
162
+ (`skill://legion-worker/references/merge-gate.md`).
163
+
164
+ ## The close
165
+
166
+ The merge closes the issue: when GitHub reports the pull request merged while the issue is in
167
+ `awaiting_merge` (a merge before that closes it the moment it gets there), the daemon writes `done`.
168
+
169
+ - A root whose merge lands while another issue of its tree is still in the workflow stays in
170
+ `awaiting_merge`, with its slot and workers kept, until the last of them is done or parked. One
171
+ `pr-merged` notice names what it waits for and none follows as they depart, so read the pull
172
+ request on GitHub.
173
+ - A child's close reaches you as `child-closed`. The daemon retires five of its six claims and
174
+ leaves the implementer running, because it still owes the production check. When the issue's
175
+ pod and Sandbox go is in `skill://legion-worker/references/merge-gate.md`, *The production check
176
+ after the close*.
177
+ - A root's close writes `done`, frees the tree's admission slot and lingers the tree for
178
+ `linger_hours` with every member suspended. The linger's end, the tree's last step, waits until
179
+ every member's open production check has closed.
180
+
181
+ Nothing of the production check is yours. Its record lives on the pull request alone, since
182
+ Dispatch refuses a write on a closed issue. A defect it finds is never an issue the implementer
183
+ files: a clear defect goes to the controller, and any other is a `dispatch ask`. `read_record`
184
+ shows a closed issue's open check (`check`: the pull request, the merge commit, the looks, what
185
+ woke the last one and when the next is due).
186
+
187
+ ## Hand-over at a root's linger
188
+
189
+ When a person closes a root and it stays `done` through its linger, each child still in the
190
+ workflow is handed to Legion as a root of its own: `todo` with the `legion` label, its phase, gate,
191
+ phase records and pull request carried into a new generation, and that phase's role started. A
192
+ child that never started but still waits on an unfinished issue is handed over too, carrying no
193
+ run: it waits in the line until its blockers are done, and its architect starts as a fresh root
194
+ and registers its own spec. The child stays its own tree; reopening the old root does not take it
195
+ back. Park a child with `park_child` before then when its work should stop with the root.
196
+
197
+ If you are that child's architect:
198
+
199
+ - Your catch-up says `handed_over` and `carried`: resume from the phase, and never register a spec
200
+ or ask for approval again.
201
+ - It says `handed_over` alone (no gate to carry): your workers already run their phases, so
202
+ decompose nothing, and read the root's phase from the catch-up (for a root `held`, the phase its
203
+ `held` notice names). Before `awaiting_merge`, register your spec with `register_gate`: your
204
+ merger's READY waits for its approval. When that `design-approved` arrives, release and start
205
+ nothing: the workers are already running. A child carried in `accepting` is yours to accept. In
206
+ `awaiting_merge` the READY is through, so register none; a red or conflicting head that returns
207
+ the root to `implementing` makes its next READY read the gate again, so a later `ready-refused`
208
+ is when you register.