@sjawhar/pi-legion 0.0.0 → 8.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 (30) hide show
  1. package/README.md +74 -0
  2. package/agents/deep-worker.md +64 -0
  3. package/agents/oracle.md +38 -0
  4. package/agents/plan-gap-analyst.md +59 -0
  5. package/agents/plan-reviewer.md +61 -0
  6. package/agents/thermonuclear-code-quality.md +28 -0
  7. package/agents/thermonuclear-deep-review.md +28 -0
  8. package/dist/THIRD_PARTY_NOTICES +30 -0
  9. package/dist/legion.js +16807 -0
  10. package/dist/skills/ce-simplify-code/LICENSE +21 -0
  11. package/dist/skills/ce-simplify-code/SKILL.md +64 -0
  12. package/dist/skills/ce-simplify-code/references/personas/code-quality-reviewer.md +17 -0
  13. package/dist/skills/ce-simplify-code/references/personas/code-reuse-reviewer.md +7 -0
  14. package/dist/skills/ce-simplify-code/references/personas/efficiency-reviewer.md +11 -0
  15. package/dist/skills/legion-architect/SKILL.md +370 -0
  16. package/dist/skills/legion-controller/SKILL.md +419 -0
  17. package/dist/skills/legion-oracle/SKILL.md +74 -0
  18. package/dist/skills/legion-retro/SKILL.md +196 -0
  19. package/dist/skills/legion-worker/SKILL.md +482 -0
  20. package/dist/skills/legion-worker/references/cleanup-deletion.md +22 -0
  21. package/dist/skills/legion-worker/references/conflicts-and-rewrites.md +126 -0
  22. package/dist/skills/legion-worker/references/merge-gate.md +117 -0
  23. package/dist/skills/legion-worker/references/pr-body.md +146 -0
  24. package/dist/skills/legion-worker/references/review-threads.md +101 -0
  25. package/dist/skills/legion-worker/references/systematic-rename.md +19 -0
  26. package/dist/skills/thermonuclear-code-quality/LICENSE +21 -0
  27. package/dist/skills/thermonuclear-code-quality/SKILL.md +192 -0
  28. package/dist/skills/thermonuclear-deep-review/LICENSE +21 -0
  29. package/dist/skills/thermonuclear-deep-review/SKILL.md +98 -0
  30. package/package.json +43 -1
@@ -0,0 +1,117 @@
1
+ # The merge gate: review, retro, READY, and the production check
2
+
3
+ Part of `skill://legion-worker`. Read it when you are the reviewer submitting a review or an
4
+ approval, the implementer recording the production check, or the merger building READY. Every
5
+ path it cites is in sjawhar/legion.
6
+
7
+ The order, in full: the tester's evidence green → the reviewer's approval of the head →
8
+ retro → the merger's READY → the human merge → the implementer's production check. No role
9
+ removes `.legion/` before the merge: the approved head carries it. The daemon strips whatever
10
+ `.legion/` main still carries from the next issue's branch before any of its roles start
11
+ (dispatch://LEGION-565), so that tree's own merge carries the removal onto the default branch; no
12
+ operator sweep follows. After the approval, only retro's `docs/solutions/` commit leaves it
13
+ standing on its own (*Retro*, below). A conflict-forced merge goes back to the reviewer for a
14
+ confirmation or a new round, as the fingerprint decides (*The reviewer*, below, and
15
+ `skill://legion-worker/references/conflicts-and-rewrites.md`), and any other change to the head
16
+ voids it.
17
+
18
+ ## The reviewer
19
+
20
+ - The reviewer verifies the `CI`, `Threads`, and `E2E` facts against GitHub directly —
21
+ never from a handoff — then runs `task(agent="thermonuclear-deep-review")` and
22
+ `task(agent="thermonuclear-code-quality")` once at that head — the head the round reviews —
23
+ and records the verdict.
24
+ Approval is refused while either `E2E (implementer)` or `E2E (tester)` is missing: `REQUEST_CHANGES` naming the missing line.
25
+ Skip the `Thermo` line entirely on a docs-only PR. Submit **one review per round** —
26
+ `REQUEST_CHANGES` when any correctness finding stands, otherwise `APPROVE` of the head you
27
+ reviewed — always named by SHA — carrying every inline comment in that single
28
+ call: `legion gh -- api --method POST repos/{owner}/{repo}/pulls/{number}/reviews --input body.json`
29
+ with `commit_id`, `event` (`REQUEST_CHANGES` or `APPROVE`), `body` (with the
30
+ Legion footer), and a `comments[]` array of `{path, line, side, body}`, one entry per
31
+ finding — never one `pr review` call per finding (each submission fires a `pr-review` wake).
32
+ A `COMMENT` decides nothing. After a
33
+ conflict-forced rebase, compute the fingerprint (*The unchanged-diff check* in
34
+ `skill://legion-worker/references/conflicts-and-rewrites.md`) at the
35
+ `commit_id` of your last submitted review and at the new head. Equal and that review was
36
+ `APPROVE`: submit one more `APPROVE` naming the new head by SHA, its body naming both SHAs
37
+ and the fingerprint — a confirmation, not a round; no thermo pass, no thread pass. Equal and
38
+ that review was `COMMENT` or `REQUEST_CHANGES`: continue that round against the new head;
39
+ nothing restarts. Different: a new round — thermo again, one review.
40
+ - Answer every thread you opened, and every thread a bot opened that is none of Legion's role
41
+ Apps, as `skill://legion-worker/references/review-threads.md` says; the same reference says
42
+ when every thread is settled enough to approve, and resolving one never gates your approval.
43
+
44
+ A reviewer's phase ends with its completion, not with its review. Every round writes a handoff
45
+ and takes this order: write, commit and push the handoff; submit the review of the head that push
46
+ made, by its SHA; then complete. An approval waits for the CI verdict to settle green at that head
47
+ before you submit it, since an approval stands only on green checks and GitHub can dismiss one
48
+ once the head moves, and a verdict that settles red there makes the round's decision a request for
49
+ changes naming the failing checks, unless only review workflows the project declares
50
+ (`projects.<KEY>.review_workflows`) are red on their own findings: then you answer their threads,
51
+ have them resolved with `legion threads resolve` and re-run the failed run, as your role prompt
52
+ says, and approve once it passes. Any other red required workflow is a failing check like any
53
+ other. A request for changes does not wait, since it stands whatever CI says and the issue leaves
54
+ reviewing with it. The verdict is of the checks and workflows the base branch requires, the set
55
+ READY checks: red when one of them failed, and never red for a check the base branch does not
56
+ require. A required check that was cancelled, or that the head's checks
57
+ settled without, leaves no verdict until a later settlement decides it, since a run can be
58
+ cancelled or not yet queued when the head settles; a required workflow's run on the head that is
59
+ still going or has not happened leaves none either. A review of a head the handoff push
60
+ then replaces names a head the pull request no longer has. The daemon moves the issue
61
+ once both are in — the decision GitHub reports and your completion, in either order — so a
62
+ review posted without a completion leaves the issue in reviewing until you finish.
63
+
64
+ ## Retro
65
+
66
+ - **Retro's commit does not void the reviewer's approval.** After the reviewer approves the
67
+ head, retro commits its learnings under `docs/solutions/` on top of it; that commit
68
+ stays, the approval stands, and the tree goes to the merger — never back to the tester or
69
+ reviewer. Anything else above the approved head does void it, and the merger tells the
70
+ architect the head must return to review instead of completing. A conflict-forced rebase
71
+ after retro moves those documents with the branch; retro never re-runs.
72
+ - **Retro brings the PR body's path-derived content up to date before its push.** Whatever the
73
+ repository's instructions derive from the pull request's changed paths (a checklist named for
74
+ each class of path, read by a required check), retro recomputes for the whole diff at its commit
75
+ and writes into the live body before `legion push` (`skill://legion-retro`), since the merger
76
+ reports a stale body rather than rewriting it. A body edit changes no commit, so the approval
77
+ stands.
78
+
79
+ ## The merger
80
+
81
+ - The merger runs `legion threads resolve --pr <n> --repo <owner>/<repo>` (it acts as the same
82
+ code-writing App as the implementer; resolving a thread changes no commit, so this run never
83
+ invalidates the approval), does not complete while any `left open` line remains or the command
84
+ exits 1 (report the thread to the architect instead), then proves that rule with two commands.
85
+ First `cd -- "$LEGION_WORKSPACE" && jj -R "$LEGION_WORKSPACE" git fetch && jj -R
86
+ "$LEGION_WORKSPACE" diff --from <approved-sha> --to <tip-sha> --summary`, whose output is quoted
87
+ in READY (an empty output is quoted as `no file changes above the approved head`); then the same
88
+ with `'~docs/solutions'` appended, which must print nothing. *The READY packet* is
89
+ `READY #<n> at <current sha> (approved at <approved sha>) for <KEY> (<pr url>)`
90
+ (the shape `packages/daemon/internal/prompts/roles/merger.md` defines), then the PR body's
91
+ `Outcome:` line and its `Not proven / risk:` value — every bullet under that label joined with
92
+ `; ` on the one READY line, or `none` — quoted from the `## For the reviewer` block at that same
93
+ head (or one line saying the body carries no brief — the packet still goes out), then the
94
+ `--summary` output and the PR body's gate facts. The merger sends it as the `summary` of its
95
+ `handoff_complete` with `ready: true`; the daemon posts it as a `dispatch_message` on the issue,
96
+ publishes it to the project's merge queue role when one is set, and says on the issue when that
97
+ role has no live holder. The READY packet names both the implementer's and tester's `E2E` lines;
98
+ a missing one is reported to the architect instead of completing. Legion never merges.
99
+
100
+ ## After the human merge
101
+
102
+ - **After a human merges, the implementer verifies in production.**
103
+ The daemon starts the implementer again once the merge lands; the implementer watches the
104
+ deploy slot that carries the merge to `production-apply` (or the equivalent publish step),
105
+ drives the changed path in production through the user's own access path, and records the
106
+ observation on the PR and the issue before the architect signs off. A staging pass is not
107
+ this, since a staging gate does not run every resource production does. If the slot fails on
108
+ the change, the implementer owns the fix and the next slot.
109
+ The record has three places: the PR body's `Production:` line, one pull-request comment
110
+ carrying the Legion footer, and a `dispatch_message` on the issue — the reviewer and merger
111
+ read GitHub, the architect reads the issue. When the deploy that carries the merge has not
112
+ happened (a shared profile still holding the previous plugin release, a daemon still running
113
+ the previous commit, a slot nobody has run), open a `dispatch_ask` that starts with the
114
+ production gap and why it matters, then names the required install or restart step, its risk,
115
+ and outcome-named options. Keep the `Production:` line at `pending <what is missing>`, and
116
+ complete the check once the human answers. Never record a staging pass as the production check,
117
+ and never let the architect sign off on a `pending` line.
@@ -0,0 +1,146 @@
1
+ # PR body, proofs, and the simplify pass
2
+
3
+ Part of `skill://legion-worker`. Read it before you write or edit any line of the pull request
4
+ body, put a `proof` array in a handoff, verify another phase's proof, or run the simplify pass.
5
+ Every path it cites is in sjawhar/legion.
6
+
7
+ ## The pull request body template
8
+
9
+ The implementer writes the PR body from this template from the moment the PR opens, and every
10
+ later phase keeps it current rather than replacing it:
11
+
12
+ ```
13
+ ## For the reviewer
14
+
15
+ **Outcome:** <one sentence a user of this repository would recognise: what someone can now do, or what stops going wrong>
16
+ **Why:** <the problem, one or two sentences, ending with the Dispatch key in parentheses — the key only, never a URL>
17
+ **Change:**
18
+ - <two to five bullets, each one behaviour a user or operator meets, never a file name>
19
+ **Look at first:** <one to three `path:line` places where a wrong decision would hurt> (the reviewer writes this line)
20
+ **Proven by:** <the `E2E (implementer)` line's surface and run, one line>
21
+ **Not proven / risk:**
22
+ - <one line per claim recorded as unproven before READY>, or the single word `none` (the reviewer writes this line; `none` is invalid while such a claim stands)
23
+ **Size:** <files changed, +added/−removed>
24
+
25
+ ## Verification
26
+
27
+ **CI:** `Tests` run <run-id> — jobs lint, typecheck, test all success at <head-sha>; `PR Title` run <run-id> — job pr-title success at <head-sha>.
28
+
29
+ **Threads:** <n> resolved, 0 unresolved. Each disposed individually, never in bulk:
30
+ - Thread <id>: fixed in <commit-sha> — <one line>.
31
+ - Thread <id>: not a defect — <reason>.
32
+ `legion threads resolve --pr <n> --repo <owner>/<repo>`, run after the push that made <head-sha>:
33
+ resolved <thread URL> — its opener's acceptance
34
+ resolved <thread URL> — the Legion reviewer's acceptance of a bot's thread
35
+ left open <thread URL> — newest reply by <login> is not an acceptance
36
+ left open <thread URL> — newest reply by <login> is an unsubmitted draft in a pending review
37
+ left open <thread URL> — newest reply by <login> is not its opener's or the Legion reviewer's acceptance
38
+
39
+ **Thermo:** `ce-simplify-code` once at <head-sha>: <0 applied | applied → new head <sha>>; thermonuclear pair at the reviewed head <sha>:
40
+ <verdict>. (omitted entirely on a docs-only PR — there is no code for either pass, so neither runs)
41
+
42
+ **E2E (implementer):** <surface> — ran `<command or run id>`, observed <result>, at head <sha>.
43
+ Negative control: <deliberately broken input or call> → <refusal or failure observed>.
44
+
45
+ **E2E (tester):** <surface> — ran `<command or run id>`, observed <result>, at head <sha>.
46
+ Negative control: <deliberately broken input or call> → <refusal or failure observed>.
47
+ Verified the implementer's proof by <re-running its command | driving the same surface independently>.
48
+
49
+ **Production:** <what was checked in production, how, what was observed> — merge commit <sha>.
50
+ (written by the implementer after the merge lands; `pending <what is missing>` until then)
51
+
52
+ **Fast-follow:** <one named cleanup item and where it will land>, or "none".
53
+
54
+ **Chain:** stacked on <base bookmark> frozen at <sha> / not stacked.
55
+ ```
56
+
57
+ ## The brief for the human
58
+
59
+ `## For the reviewer` is written for the person who merges; `## Verification` below it stays the
60
+ ledger the reviewer and merger check against GitHub. The implementer writes `Outcome`, `Why`,
61
+ `Change`, `Proven by`, and `Size` when the pull request opens, and keeps them true after every
62
+ push; `Outcome` is a sentence a user of the repository would recognise, never "fix bug" or a file
63
+ name, and `Why` ends with the Dispatch key, never a URL. The reviewer writes `Look at first` and
64
+ `Not proven / risk` at each round, into the live body (`legion gh -- api
65
+ repos/{owner}/{repo}/pulls/{number} --jq .body`, edit, then `--method PATCH ... -F body=@body.md`);
66
+ `Not proven / risk` copies every claim recorded as unproven before READY — the tester's
67
+ `failures`, the reviewer's own review, any proof-check comment already on the pull request —
68
+ word for word, and `none` is a finding while one stands. The merger quotes `Outcome` and
69
+ `Not proven / risk` from the body at the head its READY packet names
70
+ (*The READY packet* in `skill://legion-worker/references/merge-gate.md`); a stale `Outcome` that no
71
+ longer describes the diff is a finding against the implementer, not a line the merger rewrites.
72
+
73
+ ## What a proof is
74
+
75
+ **A proof** is the changed behaviour exercised on the surface a user reaches it through, recorded
76
+ as the exact command or run id, what was observed, the head SHA, and one negative control —
77
+ a deliberately broken input or call and the refusal or failure observed. The surface is
78
+ **production-like** — the repository's real-process test harness and fixtures, a sandbox
79
+ repository, a real browser, a devN stack, staging, or a local stack with real migrations, one that
80
+ has the resource the change touches — and each `E2E` line carries a **link** to that run,
81
+ screenshot, or e2e; human review does not replace user-facing verification, and a green unit suite
82
+ is not it. A unit or integration test is a regression lock, never proof of a criterion. The agent
83
+ that develops the change proves it this way before the merge, and whatever blocks that proof is
84
+ fixed, not skipped (*When no surface reaches the changed path*, below). The implementer's proof
85
+ and the tester's proof below are both this proof.
86
+
87
+ ## The rules every phase's evidence follows
88
+
89
+ - **The implementer proves the change before its phase completes, and writes the `E2E (implementer)` line when the pull request opens.**
90
+ The proof is the one defined above. It goes into `.legion/<issue>/implement.json` as the required `proof`
91
+ array (`handoff_write` for phase `implement` refuses a payload without one, or with a blank or
92
+ whitespace-only field, and names the field), and into the PR body, because the reviewer and the
93
+ merger verify facts on GitHub and never from a handoff.
94
+ - **The tester verifies the implementer's proof and adds its own `E2E (tester)` line.** It re-runs
95
+ the implementer's command or drives the same surface independently, and records the verdict in
96
+ `.legion/<issue>/test.json` as `implementerProof` (`{verdict, how}`).
97
+ A test handoff whose predecessor carried no proof is a test failure, not a gap for the tester to fill:
98
+ record it in `failures` with `implementerProof.verdict: "rejected"`, complete the phase with
99
+ `verdict: "fail"`, and the daemon returns the issue to the implementer — the agent that developed the change owns
100
+ proving it (`handoff_write` for phase `test` refuses a rejected verdict, or `failed > 0`,
101
+ with no recorded failure). Otherwise, add your own proof before completing — a proof as defined
102
+ above — as the `E2E (tester)` line and the `proof` array `handoff_write` for
103
+ phase `test` requires whenever you report no failure. A code path whose first execution is after merge — a
104
+ deploy workflow's inline step, a post-merge helper, a production-only resource — is untested
105
+ until the implementer has executed it against a devN stack; if no surface can reach it, the
106
+ tester names that missing surface as the blocker instead of passing the phase. Environment or
107
+ secret-scrub evidence (e.g. "`LEGION_*`/`DISPATCH_*`/`ENVOY_*` unset") is recorded once, in
108
+ `.legion/<issue>/test.json`, and only when the issue's acceptance criteria call for it — never
109
+ re-pasted into the PR body each round. After a conflict-forced rebase, compute the
110
+ fingerprint (*The unchanged-diff check* in
111
+ `skill://legion-worker/references/conflicts-and-rewrites.md`) at the head your `E2E` line
112
+ names and at the new head. Equal: re-run only the
113
+ bare gates — the repository's CI green at the new head and its smoke check — and change the
114
+ `E2E` line's head to the new SHA with
115
+ `rebase re-check <old-sha> → <new-sha>: fingerprint unchanged, bare gates only`; the
116
+ real-surface verification is not repeated. Different: a full test round.
117
+ - **The implementer runs `skill://ce-simplify-code` once per pull request, in its first
118
+ implementing round, after its own proof and before it completes that round, when the diff
119
+ touches runtime code; a docs-only diff gets none.** The daemon starts no implementing round
120
+ between a clean review and the approval, so this is the one slot before the tester and the
121
+ reviewer read the head; a later round answering a review runs no second pass. It is scoped to
122
+ the pull request's own diff at that head: nothing applied leaves the head as it is; applied →
123
+ the implementer re-runs the repository's checks and its own proof on the applied head for the
124
+ surface the simplify diff touched, since a refactor that "preserves behaviour" is a claim until
125
+ it is executed, and re-cites the `CI` line and `E2E (implementer)` there before it completes.
126
+ That cost is why 0-applied is the expected outcome and a pass that applies is spent sparingly.
127
+ The reviewer's pair runs at the head each round reviews. Record both in the `Thermo` line.
128
+ - **No deferrals** is the body's rule (*PR body, review, and the merge gate* in
129
+ `skill://legion-worker`): the `Fast-follow:` line holds naming, duplication, or wording cleanup
130
+ only. A base frozen for others to stack on is never rewritten (*Rewriting pushed commits* in
131
+ `skill://legion-worker/references/conflicts-and-rewrites.md`); the `Chain` line records it.
132
+ - **GitHub refuses a pull request body over 65,536 characters.** Each verification round links its
133
+ evidence (the run, the comment) rather than inlining it once the body passes about 48,000
134
+ characters; the `Production` line's record always links.
135
+
136
+ ## When no surface reaches the changed path
137
+
138
+ No surface reaches the changed path is a report to the architect, never a reason to complete the phase.
139
+ Say which surface is missing and what it would have to do — a rig that can spawn the role, a
140
+ sandbox that holds the resource, a credential, a command that does not exist yet — and send it to
141
+ the architect with `envoy_publish` to its role topic. The architect creates a child issue in this
142
+ tree to build it (infrastructure, tooling, or a skill) and resumes you once it lands. A code path
143
+ whose first execution would be after the merge — a deploy
144
+ workflow's inline step, a post-merge helper, a production-only resource — is untested until you
145
+ have executed it somewhere production-like; completing with a unit-test-only handoff is the
146
+ failure this rule exists to stop.
@@ -0,0 +1,101 @@
1
+ # Review threads
2
+
3
+ Part of `skill://legion-worker`. Read it when you reply to, accept, or resolve a review thread,
4
+ or run `legion threads resolve`: the implementer after every push that answers a review, the
5
+ merger before READY, and the reviewer, who answers threads on every re-review and runs the command
6
+ only when a review workflow the project declares is red on a bot's findings.
7
+ Every path it cites is in sjawhar/legion.
8
+
9
+ - **Threads are dispositioned individually, never resolved in bulk.** Every open review
10
+ thread gets its own line naming the fixing commit or the reason it isn't a defect. The
11
+ reviewer answers each thread it opened, and each thread a bot opened that is none of Legion's
12
+ role Apps, with exactly one of `Accepted: fixed in <commit> — <one line>`,
13
+ `Accepted: not a defect — <reason>`, or `Still open: <what remains>`; nothing else is an
14
+ acceptance, and nobody replies after an `Accepted:` (any later reply that is not itself an
15
+ `Accepted:` — the opener's own follow-up included — leaves the thread open, because resolution
16
+ considers only the newest comment). The review App can reply on a thread but cannot resolve it:
17
+ GitHub grants resolving a review thread to the pull request's author, and the implementer opens
18
+ every Legion pull request (`docs/site/src/content/docs/legion/running-legion.md`, "The two
19
+ GitHub Apps"). In the reviewer's pane (`LEGION_ROLE=reviewer`), `legion threads resolve` asks
20
+ the daemon instead (`POST /legion/v1/threads/resolve`), which resolves as the implementer's App
21
+ only the threads a bot outside Legion's role Apps opened whose newest submitted comment is the
22
+ reviewer's `Accepted:`, on the pull request of the reviewer's own issue, and prints the same
23
+ lines; the reviewer never holds the implementer's token. A thread whose newest comment is a
24
+ draft in the implement App's pending review (the implementer's or the merger's: GitHub shows it
25
+ to that App alone, as which the daemon reads) is left open and never named: the command prints
26
+ only how many there are (`<n> unresolved threads hold the implement App's pending draft and
27
+ were left open`) and exits 1, as it does on a refusal. Report that count to the architect before
28
+ you spend your one re-run of the failed workflow; the architect sends the issue back so the
29
+ implementer submits or discards its pending review. Once the review is submitted, the
30
+ implementer's reply is the thread's newest comment, which leaves it open: answer the thread
31
+ again, then run the command again. Once the review is discarded, your `Accepted:` is the newest
32
+ comment again, and running the command again closes the thread.
33
+ When `LEGION_GRANT_FILE` or `LEGION_GRANT` is set, use `legion threads resolve --pr <number> --repo <owner>/<repo>`.
34
+ When neither is set, add `--gh` to that command, which applies the fallback's rule below through
35
+ your own `gh`; where no `legion` command is installed, use `gh api graphql` with the session's
36
+ GitHub credential and the fallback below.
37
+ In a Legion pane, the **implementer** runs the command after every push that answers a review
38
+ and before its `handoff_complete`, and pastes its output, stamped with the head it just pushed, into
39
+ the `Threads` section. The output is then recorded against the head the reviewer will read, and
40
+ nothing reads thread state before the implementer's completion. The command resolves each
41
+ unresolved thread whose newest submitted comment is the opener's own `Accepted:` reply. On a
42
+ thread a bot account opened that is none of Legion's role Apps (the daemon names them, keyed by
43
+ App role), the Legion reviewer's `Accepted:` also closes it. GitHub cannot tell a CI bot, which
44
+ never accepts, from a person whose `gh` is routed to an App, so the reviewer adjudicates such a
45
+ finding, and it may accept one an App-routed person raised. The subject of a finding never
46
+ closes it: the implementer's `Fixed in <commit>: …` or `Declined: …` answers a thread and closes
47
+ none. A thread either Legion App opened, a reviewer's finding included, still needs its opener's
48
+ `Accepted:`. It makes one `resolveReviewThread` per
49
+ thread, prints `resolved <url> — <whose acceptance>` (its opener's, or the Legion reviewer's on a
50
+ bot's thread, so the ledger shows which) or `left open <url> — newest reply by <login> is …`
51
+ naming why, and exits 1 naming the thread's URL and GitHub's message when GitHub refuses one.
52
+
53
+ Without a grant, page through `reviewThreads`, skip `isResolved: true`, and compare the opener
54
+ with the newest comment. Query shape, inside `repository { pullRequest { … } }`:
55
+
56
+ ```graphql
57
+ reviewThreads(first: 100, after: $after) {
58
+ pageInfo { hasNextPage endCursor }
59
+ nodes {
60
+ id isResolved
61
+ opener: comments(first: 1) { nodes { author { __typename login } } }
62
+ newest: comments(last: 1) { nodes { author { __typename login } body state } }
63
+ }
64
+ }
65
+ ```
66
+
67
+ Resolve only when the newest comment is submitted, its `author` is the opener's account (the same
68
+ `__typename` and `login`: a login alone is a string anyone may register), and its `body`, after
69
+ removing leading spaces, tabs, CR, and LF, begins `Accepted:`. Without a
70
+ grant nothing names Legion's own App logins, so this route closes a bot's thread only on its
71
+ opener's `Accepted:`: leave one the Legion reviewer accepted for the implementer's or merger's
72
+ run in a pane, or report it. For each thread to resolve:
73
+
74
+ ```graphql
75
+ mutation($threadId: ID!) {
76
+ resolveReviewThread(input: { threadId: $threadId }) { thread { isResolved } }
77
+ }
78
+ ```
79
+
80
+ Re-read `reviewThreads` and confirm that thread's `isResolved` is true. In either route, report
81
+ a refused resolution to the architect, which opens an ask for a human to resolve the thread by
82
+ hand — never skip it silently. The merger runs the command once more before its READY
83
+ completion and does not complete while any `left open` line remains. That run is where every accepted
84
+ thread's resolution is guaranteed, since the merge queue's gate counts the unresolved threads at
85
+ the head. Acceptances posted after the implementer's last run are resolved here.
86
+
87
+ - **The reviewer, on a re-review.** When you re-review after a corrective push, answer every
88
+ thread you opened, and every thread a bot opened that is none of Legion's role Apps, in one of
89
+ the three forms above — `Accepted:` is the only reply `legion threads resolve` acts on. A bot's
90
+ finding you cannot accept becomes your own: leave it `Still open:` and request changes.
91
+ Approve once each of those threads has your own `Accepted:` as its newest submitted comment,
92
+ whether or not GitHub shows the thread resolved yet, and every other unresolved thread its
93
+ opener's (read the newest comments with `gh api graphql`, never from the PR body). Another
94
+ opener's thread that a person resolved with GitHub's button, with no `Accepted:`, gates nothing:
95
+ neither `legion threads resolve` nor the merge queue's gate counts a resolved thread. Resolution
96
+ is the pull request author's App's, so your approval never waits on it, except when a review
97
+ workflow the project declares (`projects.<KEY>.review_workflows`) is red on its findings: such a
98
+ workflow passes on a re-run only once its threads are resolved, so you run `legion threads
99
+ resolve` (the daemon resolves the bot threads you accepted) and re-run the failed run before you
100
+ approve, as your role prompt says.
101
+ The merger resolves accepted threads that remain open before its READY completion.
@@ -0,0 +1,19 @@
1
+ # Strategy: Systematic Rename
2
+
3
+ When a repo, package, or URL is renamed across a codebase.
4
+
5
+ ## Checklist
6
+
7
+ 1. **Scope by file type** — grep all text-bearing extensions, not just the obvious ones:
8
+ - Source code (`.ts`, `.js`, `.py`, `.sh`) — functional, must update
9
+ - CI/CD configs (`.yml`, `.yaml`) — functional, must update
10
+ - Documentation (`.md`) — correctness, should update
11
+ - Config files (`.json`, `.toml`) — check but may be immutable
12
+
13
+ 2. **Classify matches as mutable vs immutable** — historical records (transcripts, test snapshots, progress logs) must NOT be modified. Changing them falsifies history.
14
+
15
+ 3. **Check comments for semantic context** — a comment mentioning the old name may still be correct in intent. Update the name but preserve the reasoning.
16
+
17
+ 4. **Verify with grep before AND after** — capture pre-edit state as a baseline for comparison.
18
+
19
+ 5. **Use `jj diff --git`** for verification — plain `jj diff` without color concatenates old/new text confusingly (e.g., `old-nameNEW-name` without color codes).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Cursor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,192 @@
1
+ ---
2
+ name: thermonuclear-code-quality
3
+ description: Run a strict maintainability review for abstraction quality, oversized files, and ad-hoc branching growth. Use for a thermonuclear code-quality review or a deep maintainability audit.
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # Thermonuclear Code Quality
8
+
9
+ Use this skill for an unusually strict review focused on implementation quality, maintainability, abstraction quality, and codebase health.
10
+
11
+ Look for structural simplifications that preserve behavior while making the implementation smaller, more direct, and easier to maintain. Do not stop at local cleanup when a coherent simplification is available.
12
+
13
+ ## Core Prompt
14
+
15
+ Start from this baseline:
16
+
17
+ > Perform a deep code quality audit of the current branch's changes.
18
+ > Rethink how to structure / implement the changes to meaningfully improve code quality without impacting behavior.
19
+ > Work to improve abstractions, modularity, reduce Spaghetti code, improve succinctness and legibility.
20
+ > Restructure when there is a clear path to a simpler implementation.
21
+ > Be thorough and rigorous. Verify claims before reporting them.
22
+
23
+ ## Non-Negotiable Additional Standards
24
+
25
+ Apply the baseline prompt above, plus these explicit review rules:
26
+
27
+ 0. **Be ambitious about structural simplification.**
28
+ - Do not stop at "this could be a bit cleaner."
29
+ - Look for opportunities to reframe the change so that whole branches, helpers, modes, conditionals, or layers disappear entirely.
30
+ - Prefer the solution that makes the code feel inevitable in hindsight.
31
+ - Assume there is often a "code judo" move available: a re-organization that uses the existing architecture more effectively and makes the change dramatically simpler and more elegant.
32
+ - If you see a path to delete complexity rather than rearrange it, push hard for that path.
33
+
34
+ 1. **Do not let a PR push a file from under 1k lines to over 1k lines without a very strong reason.**
35
+ - Treat this as a strong code-quality smell by default.
36
+ - Prefer extracting helpers, subcomponents, modules, or local abstractions instead of letting a file sprawl past 1000 lines.
37
+ - If the diff crosses that threshold, explicitly ask whether the code should be decomposed first.
38
+ - Depart from this only if there is a compelling structural reason and the resulting file remains well organized.
39
+
40
+ 2. **Do not allow random spaghetti growth in existing code.**
41
+ - Be highly suspicious of new ad-hoc conditionals, scattered special cases, or one-off branches inserted into unrelated flows.
42
+ - If a change adds "weird if statements in random places", treat that as a design problem, not a stylistic nit.
43
+ - Prefer pushing the logic into a dedicated abstraction, helper, state machine, policy object, or separate module instead of tangling an existing path.
44
+ - Call out changes that make the surrounding code harder to reason about, even if they technically work.
45
+
46
+ 3. **Bias toward cleaning the design, not just accepting working code.**
47
+ - If behavior can stay the same while the structure becomes meaningfully cleaner, push for the cleaner version.
48
+ - Do not rubber-stamp "it works" implementations that leave the codebase messier.
49
+ - Strongly prefer simplifications that remove moving pieces altogether over refactors that merely spread the same complexity around.
50
+
51
+ 4. **Prefer direct, boring, maintainable code over hacky or magical code.**
52
+ - Treat brittle, ad-hoc, or "magic" behavior as a code-quality problem.
53
+ - Be skeptical of generic mechanisms that hide simple data-shape assumptions.
54
+ - Flag thin abstractions, identity wrappers, or pass-through helpers that add indirection without buying clarity.
55
+
56
+ 5. **Push hard on type and boundary cleanliness when they affect maintainability.**
57
+ - Question unnecessary optionality, `unknown`, `any`, or cast-heavy code when a clearer type boundary could exist.
58
+ - Prefer explicit typed models or shared contracts over loosely-shaped ad-hoc objects.
59
+ - If a branch relies on silent fallback to paper over an unclear invariant, ask whether the boundary should be made explicit instead.
60
+
61
+ 6. **Keep logic in the canonical layer and reuse existing helpers.**
62
+ - Call out feature logic leaking into shared paths or implementation details leaking through APIs.
63
+ - Prefer existing canonical utilities/helpers over bespoke one-offs.
64
+ - Push code toward the right package, service, or module instead of normalizing architectural drift.
65
+
66
+ 7. **Treat unnecessary sequential orchestration and non-atomic updates as design smells when the cleaner structure is obvious.**
67
+ - If independent work is serialized for no good reason, ask whether the flow should run in parallel instead.
68
+ - If related updates can leave state half-applied, push for a more atomic structure.
69
+ - Do not over-index on micro-optimizations, but do flag avoidable orchestration complexity that makes the implementation more brittle.
70
+
71
+ ## Primary Review Questions
72
+
73
+ For every meaningful change, ask:
74
+
75
+ - Is there a "code judo" move that would make this dramatically simpler?
76
+ - Can this change be reframed so fewer concepts, branches, or helper layers are needed?
77
+ - Does this improve or worsen the local architecture?
78
+ - Did the diff add branching complexity where a better abstraction should exist?
79
+ - Did a previously cohesive module become more coupled, more stateful, or harder to scan?
80
+ - Is this logic living in the right file and layer?
81
+ - Did this change enlarge a file or component past a healthy size boundary?
82
+ - Are there repeated conditionals that signal a missing model or missing helper?
83
+ - Is the implementation direct and legible, or does it rely on special cases and incidental control flow?
84
+ - Is this abstraction actually earning its keep, or is it just a wrapper?
85
+ - Did the diff introduce casts, optionality, or ad-hoc object shapes that obscure the real invariant?
86
+ - Is this logic living in the canonical layer, or did the diff leak details across a boundary?
87
+ - Is this orchestration more sequential or less atomic than it needs to be?
88
+
89
+ ## What to Flag Aggressively
90
+
91
+ Escalate findings when you see:
92
+
93
+ - A complicated implementation where a cleaner reframing could delete whole categories of complexity.
94
+ - Refactors that move code around but fail to reduce the number of concepts a reader must hold in their head.
95
+ - A file crossing 1000 lines due to the PR, especially if the new code could be split out.
96
+ - New conditionals bolted onto unrelated code paths.
97
+ - One-off booleans, nullable modes, or flags that complicate existing control flow.
98
+ - Feature-specific logic leaking into general-purpose modules.
99
+ - Generic "magic" handling that hides simple structure and makes the code harder to reason about.
100
+ - Thin wrappers or identity abstractions that add indirection without simplifying anything.
101
+ - Unnecessary casts, `any`, `unknown`, or optional params that muddy the real contract.
102
+ - Copy-pasted logic instead of extracted helpers.
103
+ - Narrow edge-case handling implemented in the middle of an already busy function.
104
+ - Refactors that technically pass tests but make the code less modular or less readable.
105
+ - "Temporary" branching that is likely to become permanent debt.
106
+ - Bespoke helpers where the codebase already has a canonical utility for the job.
107
+ - Logic added in the wrong layer/package when it should live somewhere more central.
108
+ - Sequential async flow where independent work could use simpler parallel execution.
109
+ - Partial-update logic that leaves state less atomic than necessary.
110
+
111
+ ## Preferred Remedies
112
+
113
+ When you identify a code-quality problem, prefer suggestions like:
114
+
115
+ - Delete a whole layer of indirection rather than polishing it.
116
+ - Reframe the state model so conditionals disappear instead of getting centralized.
117
+ - Change the ownership boundary so the feature becomes a natural extension of an existing abstraction.
118
+ - Turn special-case logic into a simpler default flow with fewer exceptions.
119
+ - Extract a helper or pure function.
120
+ - Split a large file into smaller focused modules.
121
+ - Move feature-specific logic behind a dedicated abstraction.
122
+ - Replace condition chains with a typed model or explicit dispatcher.
123
+ - Separate orchestration from business logic.
124
+ - Collapse duplicate branches into a single clearer flow.
125
+ - Delete wrappers that do not meaningfully clarify the API.
126
+ - Reuse the existing canonical helper instead of introducing a near-duplicate.
127
+ - Make type boundaries more explicit so the control flow gets simpler.
128
+ - Move the logic to the package/module/layer that already owns the concept.
129
+ - Parallelize independent work when that also simplifies the orchestration.
130
+ - Restructure related updates into a more atomic flow when partial state would be harder to reason about.
131
+
132
+ Do not be satisfied with "maybe rename this" feedback when the real issue is structural.
133
+ Do not be satisfied with a merely cleaner version of the same messy idea if there is a plausible path to a much simpler idea.
134
+
135
+ ## Review Tone
136
+
137
+ Be direct, serious, and demanding about quality.
138
+ Do not be rude, but do not soften major maintainability issues into mild suggestions.
139
+ If the code makes the codebase messier, say so.
140
+ If the implementation missed a substantial simplification, state it.
141
+
142
+ Good phrases:
143
+
144
+ - `this pushes the file past 1k lines. can we decompose this first?`
145
+ - `this adds another special-case branch into an already busy flow. can we move this behind its own abstraction?`
146
+ - `this works, but it makes the surrounding code more spaghetti. let's keep the behavior and restructure the implementation.`
147
+ - `this feels like feature logic leaking into a shared path. can we isolate it?`
148
+ - `this abstraction seems unnecessary. can we just keep the direct flow?`
149
+ - `why does this need a cast / optional here? can we make the boundary more explicit instead?`
150
+ - `this looks like a bespoke helper for something we already have elsewhere. can we reuse the canonical one?`
151
+ - `i think there's a code-judo move here that makes this much simpler. can we reframe this so these branches disappear?`
152
+ - `this refactor moves complexity around, but doesn't really delete it. is there a way to make the model itself simpler?`
153
+
154
+ ## Output Expectations
155
+
156
+ Prioritize findings in this order:
157
+
158
+ 1. Structural code-quality regressions
159
+ 2. Missed opportunities for dramatic simplification / code-judo restructuring
160
+ 3. Spaghetti / branching complexity increases
161
+ 4. Boundary / abstraction / type-contract problems that make the code harder to reason about
162
+ 5. File-size and decomposition concerns
163
+ 6. Modularity and abstraction issues
164
+ 7. Legibility and maintainability concerns
165
+
166
+ Do not flood the review with low-value nits if there are larger structural issues.
167
+ Prefer a smaller number of high-conviction comments over a long list of cosmetic notes.
168
+
169
+ ## Approval Bar
170
+
171
+ Do not approve merely because behavior seems correct.
172
+ The bar for approval is:
173
+
174
+ - no clear structural regression
175
+ - no obvious missed opportunity to make the implementation dramatically simpler when such a path is visible
176
+ - no unjustified file-size explosion
177
+ - no obvious spaghetti-growth from special-case branching
178
+ - no hacky or magical abstraction that makes the code harder to reason about
179
+ - no unnecessary wrapper/cast/optionality churn obscuring the real design
180
+ - no clear architecture-boundary leak or avoidable canonical-helper duplication
181
+ - no missed opportunity for an obvious decomposition that would materially improve maintainability
182
+
183
+ Treat these as presumptive blockers unless the author can justify them with evidence:
184
+
185
+ - the PR preserves a lot of incidental complexity when there is a plausible code-judo move that would delete it
186
+ - the PR pushes a file from below 1000 lines to above 1000 lines
187
+ - the PR adds ad-hoc branching that makes an existing flow more tangled
188
+ - the PR solves a local problem by scattering feature checks across shared code
189
+ - the PR adds an unnecessary abstraction, wrapper, or cast-heavy contract that makes the design more indirect
190
+ - the PR duplicates an existing helper or puts logic in the wrong layer when there is a clear canonical home
191
+
192
+ If those conditions are not met, leave explicit, actionable feedback and push for a cleaner decomposition.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Cursor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.