@codyswann/lisa 4.29.9 → 4.29.11
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/all/copy-overwrite/scripts/check-third-party-review-evidence.mjs +706 -0
- package/all/copy-overwrite/scripts/lisa-gates.mjs +55 -1
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +10 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
- package/dist/core/nightly-e2e-guard-behavior-certificate.js.map +1 -1
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +12 -6
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- 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 +138 -37
- package/plugins/lisa/.codex-plugin/skills/lisa-parity-sentry-sdk-setup/SKILL.md +27 -2
- package/plugins/lisa/.codex-plugin/skills/lisa-parity-sentry-seer/SKILL.md +16 -5
- package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +138 -37
- package/plugins/lisa/skills/lisa-parity-sentry-sdk-setup/SKILL.md +27 -2
- package/plugins/lisa/skills/lisa-parity-sentry-seer/SKILL.md +16 -5
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +138 -37
- package/plugins/lisa-agy/skills/lisa-parity-sentry-sdk-setup/SKILL.md +27 -2
- package/plugins/lisa-agy/skills/lisa-parity-sentry-seer/SKILL.md +16 -5
- 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-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +138 -37
- package/plugins/lisa-copilot/skills/lisa-parity-sentry-sdk-setup/SKILL.md +27 -2
- package/plugins/lisa-copilot/skills/lisa-parity-sentry-seer/SKILL.md +16 -5
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +138 -37
- package/plugins/lisa-cursor/skills/lisa-parity-sentry-sdk-setup/SKILL.md +27 -2
- package/plugins/lisa-cursor/skills/lisa-parity-sentry-seer/SKILL.md +16 -5
- 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-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-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-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-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-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-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-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/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +138 -37
- package/plugins/src/base/skills/lisa-parity-sentry-sdk-setup/SKILL.md +27 -2
- package/plugins/src/base/skills/lisa-parity-sentry-seer/SKILL.md +16 -5
- package/scripts/two-channel-couplings.json +1 -1
- package/typescript/copy-overwrite/.prettierignore +1 -0
- package/typescript/create-only/.github/workflows/third-party-review-evidence.yml +114 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.29.
|
|
3
|
+
"version": "4.29.11",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.29.
|
|
3
|
+
"version": "4.29.11",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, across Claude and Codex.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.29.
|
|
3
|
+
"version": "4.29.11",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.29.
|
|
3
|
+
"version": "4.29.11",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "lisa-openclaw",
|
|
3
|
-
"version": "4.29.
|
|
3
|
+
"version": "4.29.11",
|
|
4
4
|
"description": "Connect staff roles to Telegram or Slack via OpenClaw — facilitator/specialist hub-and-spoke routing and repo-coding topics, for Claude Code and Codex",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Cody Swann"
|
|
@@ -320,51 +320,123 @@ shipped-verification checks what you pushed. When the root cause is an upstream
|
|
|
320
320
|
rather than this project's code, fix it upstream and propagate down rather than
|
|
321
321
|
patching only here.
|
|
322
322
|
|
|
323
|
-
### d. Review comments — human and bot
|
|
323
|
+
### d. Review comments — human and bot
|
|
324
324
|
Delegate to the `pull-request-review` skill with the PR number. It owns the whole
|
|
325
325
|
comment cycle: fetch every unresolved human + bot thread (with resolution state via
|
|
326
326
|
GraphQL), implement valid feedback (commit + push), reply to invalid feedback, and
|
|
327
327
|
resolve every thread via `resolveReviewThread` so the branch-protection
|
|
328
328
|
thread-resolution gate clears.
|
|
329
329
|
|
|
330
|
-
**A green review check is not proof a review happened.**
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
330
|
+
**A green review check is not proof a review happened.** A third-party review
|
|
331
|
+
app posts a **commit status** on the PR head; when it is throttled or declines,
|
|
332
|
+
it still reports `success` and never blocks. Only the status **description**
|
|
333
|
+
tells the two apart. Measured over the last 30 merged PRs in one repository: 24
|
|
334
|
+
of 30 merges passed a required review gate that had reviewed nothing, every one
|
|
335
|
+
of them `success`. A second repository sampled `success` on 50 of 50.
|
|
336
336
|
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
337
|
+
**Read the description from the commit status API, never from the rollup.**
|
|
338
|
+
`gh pr view --json statusCheckRollup` returns a `StatusContext` with **no
|
|
339
|
+
`description` key at all** — verified — so a hollow green is invisible there:
|
|
340
|
+
|
|
341
|
+
```bash
|
|
342
|
+
gh api repos/<owner>/<repo>/commits/<head-sha>/status \
|
|
343
|
+
--jq '.statuses[] | {context, state, description}'
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
For a quick human look at one context, `gh pr checks <pr> --json name,state,description,bucket`
|
|
347
|
+
prints the same description — but the prover and CI read the commit-status API,
|
|
348
|
+
because `gh pr checks` resolves the rollup through the workflow run and exits
|
|
349
|
+
non-zero with EMPTY stdout when it lacks `actions: read`, which reads as a
|
|
350
|
+
content problem and never says "permission".
|
|
351
|
+
|
|
352
|
+
**Which reviewers to read is configuration, never a vendor name.** Each gate in
|
|
353
|
+
`.lisa.config.json` that declares `evidence.reviewer: true` on its
|
|
354
|
+
`pull-request` moment names one third-party reviewer: `await` is its status
|
|
355
|
+
context, and `evidence.proof` is the exact **reviewed-when** description. The
|
|
356
|
+
shipped prover resolves them and returns the whole verdict:
|
|
353
357
|
|
|
354
358
|
```bash
|
|
355
|
-
|
|
356
|
-
--jq '.[] | select(.name == "CodeRabbit")'
|
|
359
|
+
node scripts/check-third-party-review-evidence.mjs --sha <head-sha> --json
|
|
357
360
|
```
|
|
358
361
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
+
Three cases, and each is handled differently:
|
|
363
|
+
|
|
364
|
+
1. **`satisfied`** — every configured reviewer's description matched its
|
|
365
|
+
reviewed-when phrase. Nothing further; record `reviewed` and the phrase.
|
|
366
|
+
2. **`no-reviewer-configured`** — no gate declares one. This is a legitimate
|
|
367
|
+
state, **not** a pass: say so explicitly in the report ("no third-party
|
|
368
|
+
reviewer configured; nothing read this diff on that path"), and do not
|
|
369
|
+
invent a substitute for a reviewer the project never asked for.
|
|
370
|
+
3. **anything else** — throttled, skipped, absent, empty, or a description in
|
|
371
|
+
no configured list. **Treat every one of these as NOT REVIEWED.** The
|
|
372
|
+
allowlist is the only thing that grants credit; a denylist of known-bad
|
|
373
|
+
phrases fails open, and the vocabulary is open-ended — four distinct strings
|
|
374
|
+
are known already, from two repositories. An unrecognised string costs an
|
|
375
|
+
extra local review, never a free pass.
|
|
376
|
+
|
|
377
|
+
**In case 3, substitute — do not block, and do not wait.** Before merging, run
|
|
378
|
+
the local adversarial review over the PR diff and **post it on the PR**, so the
|
|
379
|
+
code that merges has been read by something. The comment must:
|
|
380
|
+
|
|
381
|
+
- carry the marker `<!-- lisa:review-substitute context="<context>" head="<head-sha>" -->`
|
|
382
|
+
as its first line, so CI can find it for this reviewer at this head;
|
|
383
|
+
- state plainly that it is a **self-review substitute**, not a third-party
|
|
384
|
+
review;
|
|
385
|
+
- **record the actual description string observed, verbatim**, so the trail says
|
|
386
|
+
*why* it was substituted rather than only that it was;
|
|
387
|
+
- **name the observed condition, not a guessed cause.** The prover returns a
|
|
388
|
+
`reading` per reviewer and a sentence for it; copy that sentence in. In
|
|
389
|
+
particular `absent` must read as *no third-party status was present at this
|
|
390
|
+
head at all* — an operator seeing an empty pair of quotes cannot tell that
|
|
391
|
+
apart from a status whose description was blank.
|
|
392
|
+
|
|
393
|
+
**Several different causes produce the same reading, and you cannot tell them
|
|
394
|
+
apart from here.** A quota throttle, a per-repository decline, and **auto-review
|
|
395
|
+
being disabled for pull requests whose base is not the default branch** all end
|
|
396
|
+
with no evidence at the head. The last one is worth knowing about because it is
|
|
397
|
+
**permanent** for the pull requests it affects rather than transient — a project
|
|
398
|
+
whose PRs target an integration branch would never be reviewed, and from outside
|
|
399
|
+
that looks identical to the healthy case. It gets **no special case**: the
|
|
400
|
+
allowlist already handles it, because it produces no declared proof phrase.
|
|
401
|
+
Report what was observed and let a human read the cause off it.
|
|
402
|
+
|
|
403
|
+
Re-read `headRefOid` first and post against the head that will actually merge —
|
|
404
|
+
review evidence decays on every push, and a substitute written for an earlier
|
|
405
|
+
head reviewed code that is no longer what merges. If the PR gains a commit
|
|
406
|
+
afterwards, substitute again for the new head.
|
|
407
|
+
|
|
408
|
+
**Never re-request a review to "refresh" it.** Re-requesting **overwrites** the
|
|
409
|
+
existing status rather than adding to it, so under a throttle it destroys a real
|
|
410
|
+
review, one-way. Do not post a review-request comment, and do not add a workflow
|
|
411
|
+
that does.
|
|
412
|
+
|
|
413
|
+
Whether the quota is scoped per repository, per organisation, or per account is
|
|
414
|
+
**unmeasured** — one lane reports a rolling window, another says explicitly that
|
|
415
|
+
it did not test it. Do not depend on a quota shape, and do not assert one.
|
|
416
|
+
|
|
417
|
+
If the review skill needs to push a commit, leave auto-merge armed (section 1);
|
|
418
|
+
when it returns, re-read `headRefOid` and
|
|
419
|
+
reset `verify_commit` to the returned/pushed head, then continue. Do not re-implement review handling here —
|
|
420
|
+
that skill is the single source of truth for review-thread handling.
|
|
421
|
+
|
|
422
|
+
`NOT REVIEWED` is **not a blocker** — do not hold the merge on it, do not treat
|
|
423
|
+
it as a failing check. A hollow review check is usually a vendor entitlement or
|
|
424
|
+
throttle, which is a billing matter no amount of driving will clear. It is a
|
|
425
|
+
**substitution** obligation followed by a **reporting** obligation: something
|
|
426
|
+
read the diff, and the report says what did.
|
|
427
|
+
|
|
428
|
+
**Merging past a hollow review is permitted — but ONLY when that review is the
|
|
429
|
+
sole gate still blocking the merge, and only after the substitute is posted.**
|
|
430
|
+
Prove the hollow signal from the commit status API as above; a
|
|
431
|
+
merely pending or queued check is not proof of anything and must keep polling. Once that signal is explicit,
|
|
432
|
+
and with `auto_merge=true`, the PR already has auto-merge enabled (section 1), so
|
|
362
433
|
leave the latch armed and merge directly with `gh pr merge <pr> --<merge_method>`
|
|
363
|
-
(pass `--admin` only if branch protection lists the
|
|
434
|
+
(pass `--admin` only if branch protection lists the hollow context as
|
|
364
435
|
required and refuses the plain merge). "Sole gate" means every one of these is
|
|
365
436
|
already true at the moment you merge — verify each against the live poll, never
|
|
366
437
|
from memory:
|
|
367
438
|
|
|
439
|
+
- the adversarial-review substitute is posted for the current head;
|
|
368
440
|
- every other required check in `statusCheckRollup` is green (no FAILURE, no
|
|
369
441
|
other PENDING);
|
|
370
442
|
- zero unresolved review threads (human or bot);
|
|
@@ -380,13 +452,37 @@ from memory:
|
|
|
380
452
|
- `mergeable == MERGEABLE` and `mergeStateStatus` is not `BEHIND`/`DIRTY`;
|
|
381
453
|
- no pending auto-fix PR into this branch (step f).
|
|
382
454
|
|
|
455
|
+
**A review OBJECT is not a status CONTEXT.** Everything above is about status
|
|
456
|
+
descriptions. An **empty-bodied `APPROVED` review is an ordinary approval** and
|
|
457
|
+
is never hollow — do not let empty-description reasoning leak onto review
|
|
458
|
+
objects. A `CHANGES_REQUESTED` is a blocking objection **whatever its body**,
|
|
459
|
+
because its content commonly lives entirely in inline threads.
|
|
460
|
+
|
|
461
|
+
**Filter review objects on `commit_id == head`, in BOTH directions.** Writing the
|
|
462
|
+
filter for one direction only is the easy bug, and each direction fails a
|
|
463
|
+
different way:
|
|
464
|
+
|
|
465
|
+
- a stale `APPROVED` from an older commit reads as fresh approval of code it
|
|
466
|
+
never saw;
|
|
467
|
+
- a stale `CHANGES_REQUESTED` reads as a current objection and blocks work a
|
|
468
|
+
newer head already fixed.
|
|
469
|
+
|
|
470
|
+
**And "no review object" is not "unreviewed".** These are different
|
|
471
|
+
propositions, and collapsing them is a measured incident rather than a
|
|
472
|
+
hypothetical: a lane counted the absence of a *third-party* review object across
|
|
473
|
+
15 PRs, read it as "12 of 15 have no approving review", and froze merging
|
|
474
|
+
fleet-wide. A PR carrying a genuine human approval at head and no third-party
|
|
475
|
+
object **is reviewed**. Answer the two questions separately, from their two
|
|
476
|
+
separate data sources.
|
|
477
|
+
|
|
383
478
|
If *anything* else is also blocking, the exception does not apply: clear that
|
|
384
479
|
blocker through its own step first, re-poll, and only then re-evaluate whether
|
|
385
|
-
|
|
480
|
+
the review is the last gate standing. The exception never stacks with another
|
|
386
481
|
bypass, never fires under `auto_merge=false` (that mode stops at
|
|
387
482
|
`awaiting-human`, and a human decides), and never fires in `on_blocker=report`
|
|
388
|
-
mode. Record the result as `MERGED — NOT REVIEWED
|
|
389
|
-
|
|
483
|
+
mode. Record the result as `MERGED — NOT REVIEWED (<context> "<observed
|
|
484
|
+
description>"), local adversarial review substituted and posted` in the terminal
|
|
485
|
+
report (section 4).
|
|
390
486
|
|
|
391
487
|
### e. Review gate stall (`reviewDecision == CHANGES_REQUESTED`)
|
|
392
488
|
After the requested changes are addressed and threads resolved, the prior
|
|
@@ -608,8 +704,9 @@ Loop until one of:
|
|
|
608
704
|
needs design input, or genuine unresolved human objection (not a bot gate). Stop
|
|
609
705
|
and report exactly what is blocking and what was already tried — never force the
|
|
610
706
|
merge or weaken a gate to get past it. The one sanctioned exception is a
|
|
611
|
-
|
|
612
|
-
enabled PR
|
|
707
|
+
hollow third-party review that is the *sole* remaining gate on an auto-merge
|
|
708
|
+
enabled PR, and only once the adversarial-review substitute is posted (step
|
|
709
|
+
d); it never extends to any other gate.
|
|
613
710
|
|
|
614
711
|
At every terminal state, release the babysitter lease
|
|
615
712
|
(`gh pr edit <pr> --remove-label "lisa:babysitter-on-duty"`) so the CI
|
|
@@ -622,9 +719,13 @@ successful `MERGED`. "Merged, all checks green" is exactly the sentence that hid
|
|
|
622
719
|
anything. Green means *no gate objected*; it does not mean *something looked*.
|
|
623
720
|
So state the verdict alongside the outcome:
|
|
624
721
|
|
|
625
|
-
- `MERGED — reviewed (
|
|
626
|
-
- `MERGED — NOT REVIEWED
|
|
627
|
-
- `MERGED — NOT REVIEWED
|
|
722
|
+
- `MERGED — reviewed (<context> "Review completed")`
|
|
723
|
+
- `MERGED — NOT REVIEWED (<context> "Review rate limited"), local adversarial review substituted and posted`
|
|
724
|
+
- `MERGED — NOT REVIEWED (<context> "<unrecognised description>"), local adversarial review substituted and posted`
|
|
725
|
+
- `MERGED — no third-party reviewer configured; local review not substituted for one that was never declared`
|
|
726
|
+
|
|
727
|
+
Spell the reviewer as the configured context, not a vendor name: a project may
|
|
728
|
+
declare none, one, or several, and each shows its own evidence.
|
|
628
729
|
|
|
629
730
|
This is reporting, never a terminal state of its own. `NOT REVIEWED` does not
|
|
630
731
|
turn a merged PR into a blocked one, and it must never be used to withhold a
|