@codyswann/lisa 4.87.0 → 4.87.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/upstream-evidence-manifest.js +2 -2
- package/package.json +4 -4
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
- package/plugins/lisa/.codex-plugin/skills/lisa-pull-request-review/SKILL.md +8 -0
- package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
- package/plugins/lisa/skills/lisa-pull-request-review/SKILL.md +8 -0
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
- package/plugins/lisa-agy/skills/lisa-pull-request-review/SKILL.md +8 -0
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
- package/plugins/lisa-copilot/skills/lisa-pull-request-review/SKILL.md +8 -0
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
- package/plugins/lisa-cursor/skills/lisa-pull-request-review/SKILL.md +8 -0
- package/plugins/lisa-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-devin/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
- package/plugins/lisa-devin/skills/lisa-pull-request-review/SKILL.md +8 -0
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-devin/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-devin/.devin-plugin/plugin.json +1 -1
- package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +79 -22
- package/plugins/src/base/skills/lisa-pull-request-review/SKILL.md +8 -0
|
@@ -391,15 +391,16 @@ declared, arm normally (the scope rule above). Where one IS declared, absent a
|
|
|
391
391
|
description that positively states a review ran, treat the context as vacuous.
|
|
392
392
|
Fail closed: absence of evidence is not evidence of a review.
|
|
393
393
|
|
|
394
|
-
#### Vacuous
|
|
394
|
+
#### Vacuous, transient or standing: the response is the same
|
|
395
395
|
|
|
396
|
-
A vacuous context is
|
|
397
|
-
|
|
398
|
-
|
|
396
|
+
A vacuous context is never something to wait out. Waiting looks like progress
|
|
397
|
+
but it is a stall, and on a repository where the state never clears it waits
|
|
398
|
+
forever. Some vacuities clear on their own and some do not. **That changes what
|
|
399
|
+
the report says, not what you do:**
|
|
399
400
|
|
|
400
401
|
| description | vacuous? | clears on its own? |
|
|
401
402
|
| --- | --- | --- |
|
|
402
|
-
| `Review rate limited` | yes |
|
|
403
|
+
| `Review rate limited` (and decorated forms such as `Review rate limited (retry in 12m)`) | yes | eventually — a throughput window of unknown length |
|
|
403
404
|
| `Review skipped: manual review required for this OSS repository` | yes | **no** — a standing vendor policy for public repositories |
|
|
404
405
|
| `Review skipped: N files exceed the limit of M` | yes | **no** — not without splitting the pull request |
|
|
405
406
|
| `Review skipped` (bare, no stated reason) | yes | **unknown — treat as standing** |
|
|
@@ -408,17 +409,33 @@ A bare skip carries no machine-readable reason, so nothing distinguishes it from
|
|
|
408
409
|
the standing forms. Requiring a stated reason before treating a skip as vacuous
|
|
409
410
|
is how the commonest form gets missed.
|
|
410
411
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
412
|
+
**Every row, the rate limit included: do not wait, and do not re-request.** Do
|
|
413
|
+
not arm. Go straight to the watch loop, run the local adversarial review over the
|
|
414
|
+
PR diff at the current head **now**, post it with the substitute marker (step
|
|
415
|
+
(d), "In case 3, substitute"), and keep driving. Fix what it finds, substitute
|
|
416
|
+
again on each new head, and let step (d) merge when the vacuous context is the
|
|
417
|
+
sole remaining gate.
|
|
418
|
+
|
|
419
|
+
The rate limit used to get a wait-the-window-out-and-re-request-once exception.
|
|
420
|
+
That exception is removed, for three reasons:
|
|
421
|
+
|
|
422
|
+
- **The window is not short.** Agents waiting it out stalled for an hour or more
|
|
423
|
+
per pull request, across a whole portfolio of repositories, and nothing about
|
|
424
|
+
the wait made the merge safer than a substitute review would.
|
|
425
|
+
- **Re-requesting does not work under a throttle.** Measured on #3220, a single
|
|
426
|
+
explicit re-request was acknowledged, went `Review in progress`, and settled
|
|
427
|
+
back at `Review rate limited` two seconds later having reviewed nothing. That
|
|
428
|
+
minted a second hollow green.
|
|
429
|
+
- **Re-requesting destroys evidence.** It overwrites the existing status (see
|
|
430
|
+
"Never re-request a review to 'refresh' it" in step (d)), so the exception
|
|
431
|
+
contradicted a rule this file states with no exceptions.
|
|
432
|
+
|
|
433
|
+
If the reviewer later reviews on its own, nothing special happens. Its threads
|
|
434
|
+
are review threads like any other, and step (d) handles them. A `CHANGES_REQUESTED`
|
|
435
|
+
it leaves is a real blocker (step (e)), and the substitute never overrides it.
|
|
436
|
+
If it now proves work, arm, per the table above. That is a re-classification
|
|
437
|
+
the watch loop makes on what it reads anyway. It is never a reason to wait or
|
|
438
|
+
re-request.
|
|
422
439
|
|
|
423
440
|
#### A latch somebody else armed
|
|
424
441
|
|
|
@@ -1046,10 +1063,11 @@ configured reviewed-when phrase says what "did work" looks like for this
|
|
|
1046
1063
|
project.
|
|
1047
1064
|
|
|
1048
1065
|
Prove the signal from the commit status API as above; a merely pending or queued
|
|
1049
|
-
check is not proof of anything and must keep polling. **A
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1066
|
+
check is not proof of anything and must keep polling. **A settled vacuity, the
|
|
1067
|
+
rate limit included, arrives here immediately.** There is no wait to spend first
|
|
1068
|
+
and no re-request to try: a rate limit's window is of unknown length, and
|
|
1069
|
+
waiting it out stalls the pull request without reading a line of the diff. The
|
|
1070
|
+
substitute is what makes the merge safe, not the passage of time.
|
|
1053
1071
|
|
|
1054
1072
|
Once the signal is explicit, merge directly with `gh pr merge <pr>
|
|
1055
1073
|
--<merge_method>` (pass `--admin` only if branch protection lists the vacuous
|
|
@@ -1170,6 +1188,34 @@ Deleting the fallback outright would over-correct: it is the only remedy a lane
|
|
|
1170
1188
|
without dismissal permission has, and that permission is not universal. This
|
|
1171
1189
|
narrows it to the case that costs nothing.
|
|
1172
1190
|
|
|
1191
|
+
**A stale bot verdict under a rate limit: substitute, then stop and report.**
|
|
1192
|
+
Under a rate limit or an exhausted review allowance, a bot's old
|
|
1193
|
+
`CHANGES_REQUESTED` on an outdated head can end up as the only thing blocking
|
|
1194
|
+
the merge. The bot cannot post a fresh review to replace it, so the verdict
|
|
1195
|
+
will not clear by itself while the throttle lasts. This was measured on a
|
|
1196
|
+
caller repo in the portfolio: every check green, zero unresolved threads, and
|
|
1197
|
+
the bot's verdict from an earlier head as the only blocker. In that case:
|
|
1198
|
+
|
|
1199
|
+
1. **Do not wait for the window to reset, and do not re-request.** Waiting
|
|
1200
|
+
leaves the pull request wedged for an hour or more. A re-request under the
|
|
1201
|
+
throttle settles hollow and can take away the bot's standing review (see
|
|
1202
|
+
above).
|
|
1203
|
+
2. Post the local adversarial review substitute for the **current** head, as
|
|
1204
|
+
step (d) case 3 describes, if one is not already there.
|
|
1205
|
+
3. **Then stop** with `blocked:stale-bot-verdict` (section 4). Report exactly
|
|
1206
|
+
that blocker: the bot reviewer, the review id, the outdated head it reviewed
|
|
1207
|
+
and the current head, the unresolved thread count, and that the substitute
|
|
1208
|
+
is posted for the current head. Name the decision that is needed: a human
|
|
1209
|
+
with dismissal rights dismisses that review, or decides it must stand.
|
|
1210
|
+
|
|
1211
|
+
Do not dismiss it on the strength of your own substitute. Here the bot's review
|
|
1212
|
+
is the only third-party review on the pull request. Dismissing it because of a
|
|
1213
|
+
review this run wrote would make the agent both author and judge of the change.
|
|
1214
|
+
That is the escalation the bullet above requires, reached right away instead of
|
|
1215
|
+
after a wait. A stranded verdict that is **not** the only substantive review, or
|
|
1216
|
+
one left by a reviewer that is not throttled, is still handled by the
|
|
1217
|
+
dismissal rule above.
|
|
1218
|
+
|
|
1173
1219
|
**Unverified, and stated as such rather than asserted:** that a bot's re-review
|
|
1174
1220
|
REPLACES its predecessor in the effective set is inferred from the observed
|
|
1175
1221
|
consequence, not measured against the vendor. It has not been tested here, and
|
|
@@ -1453,7 +1499,7 @@ Loop until one of:
|
|
|
1453
1499
|
the mode forbids acting on them: `on_blocker=report`). The latch is
|
|
1454
1500
|
deliberately not armed, so the PR sits OPEN rather than merging on a review
|
|
1455
1501
|
nothing performed. Report the PR URL, the review context's settled
|
|
1456
|
-
description, whether it
|
|
1502
|
+
description, whether it clears on its own (a rate limit) or is standing, and which sole-gate
|
|
1457
1503
|
condition failed. This is an outcome that needs an operator, stated in one
|
|
1458
1504
|
line a non-technical reader can act on — for example: *"PR #123 is ready to
|
|
1459
1505
|
merge but nobody reviewed it: the review tool says it skips public
|
|
@@ -1483,6 +1529,16 @@ Loop until one of:
|
|
|
1483
1529
|
— but a review asked for changes and that is still on record, so it will sit
|
|
1484
1530
|
there forever. Someone needs to clear that review or resolve the open
|
|
1485
1531
|
comments."* Never report this PR as merging.
|
|
1532
|
+
- **`blocked:stale-bot-verdict`** — the only thing blocking the merge is a
|
|
1533
|
+
bot's `CHANGES_REQUESTED` on an outdated head, the bot is rate limited or out
|
|
1534
|
+
of review allowance so it cannot replace that verdict, and the local
|
|
1535
|
+
adversarial review substitute is posted for the current head (step (e)).
|
|
1536
|
+
Report the reviewer, the review id, both heads, the unresolved thread count,
|
|
1537
|
+
and the dismissal decision a human needs to make. For example: *"PR #123 is
|
|
1538
|
+
ready except for an old review from the review bot on an earlier version. The
|
|
1539
|
+
bot is rate limited and cannot re-review, and I posted my own review of the
|
|
1540
|
+
current version. Someone with dismissal rights needs to dismiss review 456,
|
|
1541
|
+
or decide it should stand."* Do not wait for the bot's window to reset.
|
|
1486
1542
|
- **`CLOSED`** → report (PR was closed without merge).
|
|
1487
1543
|
- **Hard block needing a human**: an unresolvable conflict, a failing check that
|
|
1488
1544
|
needs design input, or genuine unresolved human objection (not a bot gate). Stop
|
|
@@ -1591,7 +1647,8 @@ declare none, one, or several, and each shows its own evidence.
|
|
|
1591
1647
|
|
|
1592
1648
|
Quote the description that was actually read. A report that says "rate limited"
|
|
1593
1649
|
on a policy skip is a wrong record, and the two call for different operator
|
|
1594
|
-
actions: one clears itself, the other never will.
|
|
1650
|
+
actions: one clears itself, the other never will. Neither changes what this
|
|
1651
|
+
skill does in the meantime: it substitutes and keeps driving in both cases.
|
|
1595
1652
|
|
|
1596
1653
|
`NOT REVIEWED` is reporting, and on a merged PR it is never a terminal state of
|
|
1597
1654
|
its own: it does not turn a merged PR into a blocked one. What it does gate is
|
|
@@ -73,6 +73,14 @@ node scripts/check-skipped-required-checks.mjs --pr=<pr> --json
|
|
|
73
73
|
It reports and never fails — a hollow check is often a vendor spending cap, not
|
|
74
74
|
a repository defect, and it is not this skill's call to block on one.
|
|
75
75
|
|
|
76
|
+
**Do not wait for a rate limit to reset, and do not re-request the review.** A
|
|
77
|
+
`Review rate limited` status, including decorated forms such as
|
|
78
|
+
`Review rate limited (retry in 12m)`, is handled like every other vacuous
|
|
79
|
+
review. Report it here. `lisa-drive-pr-to-merge` then posts a local adversarial
|
|
80
|
+
review substitute for the current head right away and keeps driving. Waiting
|
|
81
|
+
out the window stalls the pull request for an hour or more and reads no code.
|
|
82
|
+
Re-requesting overwrites the status and can destroy a real review.
|
|
83
|
+
|
|
76
84
|
Carry the finding into your Step 4 report. **Do not write "no unresolved review
|
|
77
85
|
threads" on its own** — it is true of an unreviewed PR too. Say which you
|
|
78
86
|
observed:
|
|
@@ -391,15 +391,16 @@ declared, arm normally (the scope rule above). Where one IS declared, absent a
|
|
|
391
391
|
description that positively states a review ran, treat the context as vacuous.
|
|
392
392
|
Fail closed: absence of evidence is not evidence of a review.
|
|
393
393
|
|
|
394
|
-
#### Vacuous
|
|
394
|
+
#### Vacuous, transient or standing: the response is the same
|
|
395
395
|
|
|
396
|
-
A vacuous context is
|
|
397
|
-
|
|
398
|
-
|
|
396
|
+
A vacuous context is never something to wait out. Waiting looks like progress
|
|
397
|
+
but it is a stall, and on a repository where the state never clears it waits
|
|
398
|
+
forever. Some vacuities clear on their own and some do not. **That changes what
|
|
399
|
+
the report says, not what you do:**
|
|
399
400
|
|
|
400
401
|
| description | vacuous? | clears on its own? |
|
|
401
402
|
| --- | --- | --- |
|
|
402
|
-
| `Review rate limited` | yes |
|
|
403
|
+
| `Review rate limited` (and decorated forms such as `Review rate limited (retry in 12m)`) | yes | eventually — a throughput window of unknown length |
|
|
403
404
|
| `Review skipped: manual review required for this OSS repository` | yes | **no** — a standing vendor policy for public repositories |
|
|
404
405
|
| `Review skipped: N files exceed the limit of M` | yes | **no** — not without splitting the pull request |
|
|
405
406
|
| `Review skipped` (bare, no stated reason) | yes | **unknown — treat as standing** |
|
|
@@ -408,17 +409,33 @@ A bare skip carries no machine-readable reason, so nothing distinguishes it from
|
|
|
408
409
|
the standing forms. Requiring a stated reason before treating a skip as vacuous
|
|
409
410
|
is how the commonest form gets missed.
|
|
410
411
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
412
|
+
**Every row, the rate limit included: do not wait, and do not re-request.** Do
|
|
413
|
+
not arm. Go straight to the watch loop, run the local adversarial review over the
|
|
414
|
+
PR diff at the current head **now**, post it with the substitute marker (step
|
|
415
|
+
(d), "In case 3, substitute"), and keep driving. Fix what it finds, substitute
|
|
416
|
+
again on each new head, and let step (d) merge when the vacuous context is the
|
|
417
|
+
sole remaining gate.
|
|
418
|
+
|
|
419
|
+
The rate limit used to get a wait-the-window-out-and-re-request-once exception.
|
|
420
|
+
That exception is removed, for three reasons:
|
|
421
|
+
|
|
422
|
+
- **The window is not short.** Agents waiting it out stalled for an hour or more
|
|
423
|
+
per pull request, across a whole portfolio of repositories, and nothing about
|
|
424
|
+
the wait made the merge safer than a substitute review would.
|
|
425
|
+
- **Re-requesting does not work under a throttle.** Measured on #3220, a single
|
|
426
|
+
explicit re-request was acknowledged, went `Review in progress`, and settled
|
|
427
|
+
back at `Review rate limited` two seconds later having reviewed nothing. That
|
|
428
|
+
minted a second hollow green.
|
|
429
|
+
- **Re-requesting destroys evidence.** It overwrites the existing status (see
|
|
430
|
+
"Never re-request a review to 'refresh' it" in step (d)), so the exception
|
|
431
|
+
contradicted a rule this file states with no exceptions.
|
|
432
|
+
|
|
433
|
+
If the reviewer later reviews on its own, nothing special happens. Its threads
|
|
434
|
+
are review threads like any other, and step (d) handles them. A `CHANGES_REQUESTED`
|
|
435
|
+
it leaves is a real blocker (step (e)), and the substitute never overrides it.
|
|
436
|
+
If it now proves work, arm, per the table above. That is a re-classification
|
|
437
|
+
the watch loop makes on what it reads anyway. It is never a reason to wait or
|
|
438
|
+
re-request.
|
|
422
439
|
|
|
423
440
|
#### A latch somebody else armed
|
|
424
441
|
|
|
@@ -1046,10 +1063,11 @@ configured reviewed-when phrase says what "did work" looks like for this
|
|
|
1046
1063
|
project.
|
|
1047
1064
|
|
|
1048
1065
|
Prove the signal from the commit status API as above; a merely pending or queued
|
|
1049
|
-
check is not proof of anything and must keep polling. **A
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1066
|
+
check is not proof of anything and must keep polling. **A settled vacuity, the
|
|
1067
|
+
rate limit included, arrives here immediately.** There is no wait to spend first
|
|
1068
|
+
and no re-request to try: a rate limit's window is of unknown length, and
|
|
1069
|
+
waiting it out stalls the pull request without reading a line of the diff. The
|
|
1070
|
+
substitute is what makes the merge safe, not the passage of time.
|
|
1053
1071
|
|
|
1054
1072
|
Once the signal is explicit, merge directly with `gh pr merge <pr>
|
|
1055
1073
|
--<merge_method>` (pass `--admin` only if branch protection lists the vacuous
|
|
@@ -1170,6 +1188,34 @@ Deleting the fallback outright would over-correct: it is the only remedy a lane
|
|
|
1170
1188
|
without dismissal permission has, and that permission is not universal. This
|
|
1171
1189
|
narrows it to the case that costs nothing.
|
|
1172
1190
|
|
|
1191
|
+
**A stale bot verdict under a rate limit: substitute, then stop and report.**
|
|
1192
|
+
Under a rate limit or an exhausted review allowance, a bot's old
|
|
1193
|
+
`CHANGES_REQUESTED` on an outdated head can end up as the only thing blocking
|
|
1194
|
+
the merge. The bot cannot post a fresh review to replace it, so the verdict
|
|
1195
|
+
will not clear by itself while the throttle lasts. This was measured on a
|
|
1196
|
+
caller repo in the portfolio: every check green, zero unresolved threads, and
|
|
1197
|
+
the bot's verdict from an earlier head as the only blocker. In that case:
|
|
1198
|
+
|
|
1199
|
+
1. **Do not wait for the window to reset, and do not re-request.** Waiting
|
|
1200
|
+
leaves the pull request wedged for an hour or more. A re-request under the
|
|
1201
|
+
throttle settles hollow and can take away the bot's standing review (see
|
|
1202
|
+
above).
|
|
1203
|
+
2. Post the local adversarial review substitute for the **current** head, as
|
|
1204
|
+
step (d) case 3 describes, if one is not already there.
|
|
1205
|
+
3. **Then stop** with `blocked:stale-bot-verdict` (section 4). Report exactly
|
|
1206
|
+
that blocker: the bot reviewer, the review id, the outdated head it reviewed
|
|
1207
|
+
and the current head, the unresolved thread count, and that the substitute
|
|
1208
|
+
is posted for the current head. Name the decision that is needed: a human
|
|
1209
|
+
with dismissal rights dismisses that review, or decides it must stand.
|
|
1210
|
+
|
|
1211
|
+
Do not dismiss it on the strength of your own substitute. Here the bot's review
|
|
1212
|
+
is the only third-party review on the pull request. Dismissing it because of a
|
|
1213
|
+
review this run wrote would make the agent both author and judge of the change.
|
|
1214
|
+
That is the escalation the bullet above requires, reached right away instead of
|
|
1215
|
+
after a wait. A stranded verdict that is **not** the only substantive review, or
|
|
1216
|
+
one left by a reviewer that is not throttled, is still handled by the
|
|
1217
|
+
dismissal rule above.
|
|
1218
|
+
|
|
1173
1219
|
**Unverified, and stated as such rather than asserted:** that a bot's re-review
|
|
1174
1220
|
REPLACES its predecessor in the effective set is inferred from the observed
|
|
1175
1221
|
consequence, not measured against the vendor. It has not been tested here, and
|
|
@@ -1453,7 +1499,7 @@ Loop until one of:
|
|
|
1453
1499
|
the mode forbids acting on them: `on_blocker=report`). The latch is
|
|
1454
1500
|
deliberately not armed, so the PR sits OPEN rather than merging on a review
|
|
1455
1501
|
nothing performed. Report the PR URL, the review context's settled
|
|
1456
|
-
description, whether it
|
|
1502
|
+
description, whether it clears on its own (a rate limit) or is standing, and which sole-gate
|
|
1457
1503
|
condition failed. This is an outcome that needs an operator, stated in one
|
|
1458
1504
|
line a non-technical reader can act on — for example: *"PR #123 is ready to
|
|
1459
1505
|
merge but nobody reviewed it: the review tool says it skips public
|
|
@@ -1483,6 +1529,16 @@ Loop until one of:
|
|
|
1483
1529
|
— but a review asked for changes and that is still on record, so it will sit
|
|
1484
1530
|
there forever. Someone needs to clear that review or resolve the open
|
|
1485
1531
|
comments."* Never report this PR as merging.
|
|
1532
|
+
- **`blocked:stale-bot-verdict`** — the only thing blocking the merge is a
|
|
1533
|
+
bot's `CHANGES_REQUESTED` on an outdated head, the bot is rate limited or out
|
|
1534
|
+
of review allowance so it cannot replace that verdict, and the local
|
|
1535
|
+
adversarial review substitute is posted for the current head (step (e)).
|
|
1536
|
+
Report the reviewer, the review id, both heads, the unresolved thread count,
|
|
1537
|
+
and the dismissal decision a human needs to make. For example: *"PR #123 is
|
|
1538
|
+
ready except for an old review from the review bot on an earlier version. The
|
|
1539
|
+
bot is rate limited and cannot re-review, and I posted my own review of the
|
|
1540
|
+
current version. Someone with dismissal rights needs to dismiss review 456,
|
|
1541
|
+
or decide it should stand."* Do not wait for the bot's window to reset.
|
|
1486
1542
|
- **`CLOSED`** → report (PR was closed without merge).
|
|
1487
1543
|
- **Hard block needing a human**: an unresolvable conflict, a failing check that
|
|
1488
1544
|
needs design input, or genuine unresolved human objection (not a bot gate). Stop
|
|
@@ -1591,7 +1647,8 @@ declare none, one, or several, and each shows its own evidence.
|
|
|
1591
1647
|
|
|
1592
1648
|
Quote the description that was actually read. A report that says "rate limited"
|
|
1593
1649
|
on a policy skip is a wrong record, and the two call for different operator
|
|
1594
|
-
actions: one clears itself, the other never will.
|
|
1650
|
+
actions: one clears itself, the other never will. Neither changes what this
|
|
1651
|
+
skill does in the meantime: it substitutes and keeps driving in both cases.
|
|
1595
1652
|
|
|
1596
1653
|
`NOT REVIEWED` is reporting, and on a merged PR it is never a terminal state of
|
|
1597
1654
|
its own: it does not turn a merged PR into a blocked one. What it does gate is
|
|
@@ -73,6 +73,14 @@ node scripts/check-skipped-required-checks.mjs --pr=<pr> --json
|
|
|
73
73
|
It reports and never fails — a hollow check is often a vendor spending cap, not
|
|
74
74
|
a repository defect, and it is not this skill's call to block on one.
|
|
75
75
|
|
|
76
|
+
**Do not wait for a rate limit to reset, and do not re-request the review.** A
|
|
77
|
+
`Review rate limited` status, including decorated forms such as
|
|
78
|
+
`Review rate limited (retry in 12m)`, is handled like every other vacuous
|
|
79
|
+
review. Report it here. `lisa-drive-pr-to-merge` then posts a local adversarial
|
|
80
|
+
review substitute for the current head right away and keeps driving. Waiting
|
|
81
|
+
out the window stalls the pull request for an hour or more and reads no code.
|
|
82
|
+
Re-requesting overwrites the status and can destroy a real review.
|
|
83
|
+
|
|
76
84
|
Carry the finding into your Step 4 report. **Do not write "no unresolved review
|
|
77
85
|
threads" on its own** — it is true of an unreviewed PR too. Say which you
|
|
78
86
|
observed:
|
|
@@ -391,15 +391,16 @@ declared, arm normally (the scope rule above). Where one IS declared, absent a
|
|
|
391
391
|
description that positively states a review ran, treat the context as vacuous.
|
|
392
392
|
Fail closed: absence of evidence is not evidence of a review.
|
|
393
393
|
|
|
394
|
-
#### Vacuous
|
|
394
|
+
#### Vacuous, transient or standing: the response is the same
|
|
395
395
|
|
|
396
|
-
A vacuous context is
|
|
397
|
-
|
|
398
|
-
|
|
396
|
+
A vacuous context is never something to wait out. Waiting looks like progress
|
|
397
|
+
but it is a stall, and on a repository where the state never clears it waits
|
|
398
|
+
forever. Some vacuities clear on their own and some do not. **That changes what
|
|
399
|
+
the report says, not what you do:**
|
|
399
400
|
|
|
400
401
|
| description | vacuous? | clears on its own? |
|
|
401
402
|
| --- | --- | --- |
|
|
402
|
-
| `Review rate limited` | yes |
|
|
403
|
+
| `Review rate limited` (and decorated forms such as `Review rate limited (retry in 12m)`) | yes | eventually — a throughput window of unknown length |
|
|
403
404
|
| `Review skipped: manual review required for this OSS repository` | yes | **no** — a standing vendor policy for public repositories |
|
|
404
405
|
| `Review skipped: N files exceed the limit of M` | yes | **no** — not without splitting the pull request |
|
|
405
406
|
| `Review skipped` (bare, no stated reason) | yes | **unknown — treat as standing** |
|
|
@@ -408,17 +409,33 @@ A bare skip carries no machine-readable reason, so nothing distinguishes it from
|
|
|
408
409
|
the standing forms. Requiring a stated reason before treating a skip as vacuous
|
|
409
410
|
is how the commonest form gets missed.
|
|
410
411
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
412
|
+
**Every row, the rate limit included: do not wait, and do not re-request.** Do
|
|
413
|
+
not arm. Go straight to the watch loop, run the local adversarial review over the
|
|
414
|
+
PR diff at the current head **now**, post it with the substitute marker (step
|
|
415
|
+
(d), "In case 3, substitute"), and keep driving. Fix what it finds, substitute
|
|
416
|
+
again on each new head, and let step (d) merge when the vacuous context is the
|
|
417
|
+
sole remaining gate.
|
|
418
|
+
|
|
419
|
+
The rate limit used to get a wait-the-window-out-and-re-request-once exception.
|
|
420
|
+
That exception is removed, for three reasons:
|
|
421
|
+
|
|
422
|
+
- **The window is not short.** Agents waiting it out stalled for an hour or more
|
|
423
|
+
per pull request, across a whole portfolio of repositories, and nothing about
|
|
424
|
+
the wait made the merge safer than a substitute review would.
|
|
425
|
+
- **Re-requesting does not work under a throttle.** Measured on #3220, a single
|
|
426
|
+
explicit re-request was acknowledged, went `Review in progress`, and settled
|
|
427
|
+
back at `Review rate limited` two seconds later having reviewed nothing. That
|
|
428
|
+
minted a second hollow green.
|
|
429
|
+
- **Re-requesting destroys evidence.** It overwrites the existing status (see
|
|
430
|
+
"Never re-request a review to 'refresh' it" in step (d)), so the exception
|
|
431
|
+
contradicted a rule this file states with no exceptions.
|
|
432
|
+
|
|
433
|
+
If the reviewer later reviews on its own, nothing special happens. Its threads
|
|
434
|
+
are review threads like any other, and step (d) handles them. A `CHANGES_REQUESTED`
|
|
435
|
+
it leaves is a real blocker (step (e)), and the substitute never overrides it.
|
|
436
|
+
If it now proves work, arm, per the table above. That is a re-classification
|
|
437
|
+
the watch loop makes on what it reads anyway. It is never a reason to wait or
|
|
438
|
+
re-request.
|
|
422
439
|
|
|
423
440
|
#### A latch somebody else armed
|
|
424
441
|
|
|
@@ -1046,10 +1063,11 @@ configured reviewed-when phrase says what "did work" looks like for this
|
|
|
1046
1063
|
project.
|
|
1047
1064
|
|
|
1048
1065
|
Prove the signal from the commit status API as above; a merely pending or queued
|
|
1049
|
-
check is not proof of anything and must keep polling. **A
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1066
|
+
check is not proof of anything and must keep polling. **A settled vacuity, the
|
|
1067
|
+
rate limit included, arrives here immediately.** There is no wait to spend first
|
|
1068
|
+
and no re-request to try: a rate limit's window is of unknown length, and
|
|
1069
|
+
waiting it out stalls the pull request without reading a line of the diff. The
|
|
1070
|
+
substitute is what makes the merge safe, not the passage of time.
|
|
1053
1071
|
|
|
1054
1072
|
Once the signal is explicit, merge directly with `gh pr merge <pr>
|
|
1055
1073
|
--<merge_method>` (pass `--admin` only if branch protection lists the vacuous
|
|
@@ -1170,6 +1188,34 @@ Deleting the fallback outright would over-correct: it is the only remedy a lane
|
|
|
1170
1188
|
without dismissal permission has, and that permission is not universal. This
|
|
1171
1189
|
narrows it to the case that costs nothing.
|
|
1172
1190
|
|
|
1191
|
+
**A stale bot verdict under a rate limit: substitute, then stop and report.**
|
|
1192
|
+
Under a rate limit or an exhausted review allowance, a bot's old
|
|
1193
|
+
`CHANGES_REQUESTED` on an outdated head can end up as the only thing blocking
|
|
1194
|
+
the merge. The bot cannot post a fresh review to replace it, so the verdict
|
|
1195
|
+
will not clear by itself while the throttle lasts. This was measured on a
|
|
1196
|
+
caller repo in the portfolio: every check green, zero unresolved threads, and
|
|
1197
|
+
the bot's verdict from an earlier head as the only blocker. In that case:
|
|
1198
|
+
|
|
1199
|
+
1. **Do not wait for the window to reset, and do not re-request.** Waiting
|
|
1200
|
+
leaves the pull request wedged for an hour or more. A re-request under the
|
|
1201
|
+
throttle settles hollow and can take away the bot's standing review (see
|
|
1202
|
+
above).
|
|
1203
|
+
2. Post the local adversarial review substitute for the **current** head, as
|
|
1204
|
+
step (d) case 3 describes, if one is not already there.
|
|
1205
|
+
3. **Then stop** with `blocked:stale-bot-verdict` (section 4). Report exactly
|
|
1206
|
+
that blocker: the bot reviewer, the review id, the outdated head it reviewed
|
|
1207
|
+
and the current head, the unresolved thread count, and that the substitute
|
|
1208
|
+
is posted for the current head. Name the decision that is needed: a human
|
|
1209
|
+
with dismissal rights dismisses that review, or decides it must stand.
|
|
1210
|
+
|
|
1211
|
+
Do not dismiss it on the strength of your own substitute. Here the bot's review
|
|
1212
|
+
is the only third-party review on the pull request. Dismissing it because of a
|
|
1213
|
+
review this run wrote would make the agent both author and judge of the change.
|
|
1214
|
+
That is the escalation the bullet above requires, reached right away instead of
|
|
1215
|
+
after a wait. A stranded verdict that is **not** the only substantive review, or
|
|
1216
|
+
one left by a reviewer that is not throttled, is still handled by the
|
|
1217
|
+
dismissal rule above.
|
|
1218
|
+
|
|
1173
1219
|
**Unverified, and stated as such rather than asserted:** that a bot's re-review
|
|
1174
1220
|
REPLACES its predecessor in the effective set is inferred from the observed
|
|
1175
1221
|
consequence, not measured against the vendor. It has not been tested here, and
|
|
@@ -1453,7 +1499,7 @@ Loop until one of:
|
|
|
1453
1499
|
the mode forbids acting on them: `on_blocker=report`). The latch is
|
|
1454
1500
|
deliberately not armed, so the PR sits OPEN rather than merging on a review
|
|
1455
1501
|
nothing performed. Report the PR URL, the review context's settled
|
|
1456
|
-
description, whether it
|
|
1502
|
+
description, whether it clears on its own (a rate limit) or is standing, and which sole-gate
|
|
1457
1503
|
condition failed. This is an outcome that needs an operator, stated in one
|
|
1458
1504
|
line a non-technical reader can act on — for example: *"PR #123 is ready to
|
|
1459
1505
|
merge but nobody reviewed it: the review tool says it skips public
|
|
@@ -1483,6 +1529,16 @@ Loop until one of:
|
|
|
1483
1529
|
— but a review asked for changes and that is still on record, so it will sit
|
|
1484
1530
|
there forever. Someone needs to clear that review or resolve the open
|
|
1485
1531
|
comments."* Never report this PR as merging.
|
|
1532
|
+
- **`blocked:stale-bot-verdict`** — the only thing blocking the merge is a
|
|
1533
|
+
bot's `CHANGES_REQUESTED` on an outdated head, the bot is rate limited or out
|
|
1534
|
+
of review allowance so it cannot replace that verdict, and the local
|
|
1535
|
+
adversarial review substitute is posted for the current head (step (e)).
|
|
1536
|
+
Report the reviewer, the review id, both heads, the unresolved thread count,
|
|
1537
|
+
and the dismissal decision a human needs to make. For example: *"PR #123 is
|
|
1538
|
+
ready except for an old review from the review bot on an earlier version. The
|
|
1539
|
+
bot is rate limited and cannot re-review, and I posted my own review of the
|
|
1540
|
+
current version. Someone with dismissal rights needs to dismiss review 456,
|
|
1541
|
+
or decide it should stand."* Do not wait for the bot's window to reset.
|
|
1486
1542
|
- **`CLOSED`** → report (PR was closed without merge).
|
|
1487
1543
|
- **Hard block needing a human**: an unresolvable conflict, a failing check that
|
|
1488
1544
|
needs design input, or genuine unresolved human objection (not a bot gate). Stop
|
|
@@ -1591,7 +1647,8 @@ declare none, one, or several, and each shows its own evidence.
|
|
|
1591
1647
|
|
|
1592
1648
|
Quote the description that was actually read. A report that says "rate limited"
|
|
1593
1649
|
on a policy skip is a wrong record, and the two call for different operator
|
|
1594
|
-
actions: one clears itself, the other never will.
|
|
1650
|
+
actions: one clears itself, the other never will. Neither changes what this
|
|
1651
|
+
skill does in the meantime: it substitutes and keeps driving in both cases.
|
|
1595
1652
|
|
|
1596
1653
|
`NOT REVIEWED` is reporting, and on a merged PR it is never a terminal state of
|
|
1597
1654
|
its own: it does not turn a merged PR into a blocked one. What it does gate is
|
|
@@ -73,6 +73,14 @@ node scripts/check-skipped-required-checks.mjs --pr=<pr> --json
|
|
|
73
73
|
It reports and never fails — a hollow check is often a vendor spending cap, not
|
|
74
74
|
a repository defect, and it is not this skill's call to block on one.
|
|
75
75
|
|
|
76
|
+
**Do not wait for a rate limit to reset, and do not re-request the review.** A
|
|
77
|
+
`Review rate limited` status, including decorated forms such as
|
|
78
|
+
`Review rate limited (retry in 12m)`, is handled like every other vacuous
|
|
79
|
+
review. Report it here. `lisa-drive-pr-to-merge` then posts a local adversarial
|
|
80
|
+
review substitute for the current head right away and keeps driving. Waiting
|
|
81
|
+
out the window stalls the pull request for an hour or more and reads no code.
|
|
82
|
+
Re-requesting overwrites the status and can destroy a real review.
|
|
83
|
+
|
|
76
84
|
Carry the finding into your Step 4 report. **Do not write "no unresolved review
|
|
77
85
|
threads" on its own** — it is true of an unreviewed PR too. Say which you
|
|
78
86
|
observed:
|