@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.
- package/README.md +74 -0
- package/agents/deep-worker.md +64 -0
- package/agents/oracle.md +38 -0
- package/agents/plan-gap-analyst.md +59 -0
- package/agents/plan-reviewer.md +61 -0
- package/agents/thermonuclear-code-quality.md +28 -0
- package/agents/thermonuclear-deep-review.md +28 -0
- package/dist/THIRD_PARTY_NOTICES +30 -0
- package/dist/legion.js +16807 -0
- package/dist/skills/ce-simplify-code/LICENSE +21 -0
- package/dist/skills/ce-simplify-code/SKILL.md +64 -0
- package/dist/skills/ce-simplify-code/references/personas/code-quality-reviewer.md +17 -0
- package/dist/skills/ce-simplify-code/references/personas/code-reuse-reviewer.md +7 -0
- package/dist/skills/ce-simplify-code/references/personas/efficiency-reviewer.md +11 -0
- package/dist/skills/legion-architect/SKILL.md +370 -0
- package/dist/skills/legion-controller/SKILL.md +419 -0
- package/dist/skills/legion-oracle/SKILL.md +74 -0
- package/dist/skills/legion-retro/SKILL.md +196 -0
- package/dist/skills/legion-worker/SKILL.md +482 -0
- package/dist/skills/legion-worker/references/cleanup-deletion.md +22 -0
- package/dist/skills/legion-worker/references/conflicts-and-rewrites.md +126 -0
- package/dist/skills/legion-worker/references/merge-gate.md +117 -0
- package/dist/skills/legion-worker/references/pr-body.md +146 -0
- package/dist/skills/legion-worker/references/review-threads.md +101 -0
- package/dist/skills/legion-worker/references/systematic-rename.md +19 -0
- package/dist/skills/thermonuclear-code-quality/LICENSE +21 -0
- package/dist/skills/thermonuclear-code-quality/SKILL.md +192 -0
- package/dist/skills/thermonuclear-deep-review/LICENSE +21 -0
- package/dist/skills/thermonuclear-deep-review/SKILL.md +98 -0
- 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.
|