@codyswann/lisa 4.4.18 → 4.4.20
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/configs/eslint/expo.d.ts.map +1 -1
- package/dist/configs/eslint/expo.js +21 -1
- package/dist/configs/eslint/expo.js.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +1 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +10 -5
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/expo/create-only/.github/required-checks.json +4 -2
- package/nestjs/create-only/.github/required-checks.json +4 -2
- package/package.json +2 -1
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-agy/plugin.json +1 -1
- 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-cursor/.claude-plugin/plugin.json +1 -1
- 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/typescript/copy-overwrite/scripts/check-skipped-required-checks.mjs +593 -24
- package/typescript/create-only/.github/required-checks.json +4 -2
- package/typescript/create-only/.github/workflows/review-evidence.yml +122 -0
- package/typescript/package-lisa/package.lisa.json +1 -1
|
@@ -13,9 +13,11 @@
|
|
|
13
13
|
"`_example_required_contexts` below is a STARTING POINT FOR TYPING, never read by the guard. Verify every line against your own ruleset before promoting any of it.",
|
|
14
14
|
"THE FAMILY: required-and-red is loud; required-and-vacuous is not; advisory-and-stale is invisible. All three are one gate reporting satisfied without proving anything. `required_contexts` + `skip_job_declarations` above cover the SKIPPED variant; `evidence_bearing_checks` below covers the VACUOUS one.",
|
|
15
15
|
"VACUOUS, measured (CodySwannGT/lisa#2497): a required `CodeRabbit` context posted `success` with the description `Review rate limited`, having reviewed nothing, on two security-relevant PRs that then merged and shipped. `gh pr checks` prints `pass` for that exactly as it does for a real review — only the DESCRIPTION tells them apart.",
|
|
16
|
-
"
|
|
16
|
+
"NOTHING HAS TO REMEMBER A FLAG. `.github/workflows/review-evidence.yml` runs this arm on every pull request, and `npm run check:vacuous-required-checks` resolves the pull request itself: `--pr`, else the `pull_request` payload at GITHUB_EVENT_PATH, else `refs/pull/N/merge` in GITHUB_REF, else the checked-out branch. For one specific pull request by hand: `npm run check:vacuous-required-checks -- --pr=1234`.",
|
|
17
|
+
"It reads `gh pr checks --json name,state,bucket,description`, the only route that carries the description for a legacy commit status like CodeRabbit's, and falls back to the commit-status API when the token lacks `actions: read` (`gh pr checks` resolves the rollup through `checkSuite.workflowRun`, and without that scope it exits non-zero with EMPTY STDOUT — a failure shaped like a content problem that never says the word \"permission\").",
|
|
18
|
+
"IT REFUSES RATHER THAN REPORTING AN EMPTY INSPECTION. An unresolvable pull request, a `gh` it could not read, a roster with no checks in it, or an empty `evidence_bearing_checks` all print the same \"nothing vacuous here\" that a genuinely clean run prints — so the guard fails instead and names which of the four it hit (`vacuity_pr_unresolved`, `vacuity_checks_unreadable`, `vacuity_no_checks_reported`, `vacuity_none_declared`). A refusal is NOT a finding: NOBODY LOOKED and THE REVIEW WAS FAKE are opposite facts, and a single red job would otherwise report them identically.",
|
|
17
19
|
"`evidence_bearing_checks` names the checks whose GREEN is supposed to mean something reviewed the code. Use `{}` to accept the shipped description vocabulary, or add `proof` / `no_work` arrays to extend it — extensions ADD to the defaults, they do not replace them. Undeclared checks are never examined, because most CI jobs ship an empty description and flagging them all would bury the one finding that matters.",
|
|
18
|
-
"This arm REPORTS AND NEVER BLOCKS, in every enforcement mode. A review bot can go hollow because an org-wide SPENDING CAP was hit, and a gate that reddens every PR on a billing state is worse than the one it criticises. What it changes is what you may CLAIM: a PR carrying a `vacuous_required_check` finding has not been shown to be reviewed, so do not record it as reviewed."
|
|
20
|
+
"This arm REPORTS AND NEVER BLOCKS, in every enforcement mode. A review bot can go hollow because an org-wide SPENDING CAP was hit, and a gate that reddens every PR on a billing state is worse than the one it criticises. What it changes is what you may CLAIM: a PR carrying a `vacuous_required_check` finding has not been shown to be reviewed, so do not record it as reviewed. Once you have made the governance call, `--fail-on-vacuous` is the supported way to ask for an exit code — add it to the command in `review-evidence.yml`, instead of writing a wrapper that reads `--json`."
|
|
19
21
|
],
|
|
20
22
|
"enforcement": "warn",
|
|
21
23
|
"ruleset": {
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
# Seeded by Lisa on first setup — this file is YOURS.
|
|
2
|
+
# Lisa will not overwrite it. (copy-overwrite assets ARE replaced each run.)
|
|
3
|
+
# -----------------------------------------------------------------------------
|
|
4
|
+
# Review evidence — the VACUITY arm, wired to a pull request (#2928)
|
|
5
|
+
# -----------------------------------------------------------------------------
|
|
6
|
+
# `.github/required-checks.json` names, in `evidence_bearing_checks`, the checks
|
|
7
|
+
# whose GREEN is supposed to mean something reviewed the code. A review bot can
|
|
8
|
+
# report `success` with the description `Review rate limited` having reviewed
|
|
9
|
+
# NOTHING — `gh pr checks` prints `pass` for that exactly as it does for a real
|
|
10
|
+
# review, and only the description tells them apart.
|
|
11
|
+
#
|
|
12
|
+
# WHY THIS WORKFLOW EXISTS. The rule that detects it shipped long before
|
|
13
|
+
# anything invoked it: `quality.yml` runs the guard's OFFLINE arm with no `--pr`,
|
|
14
|
+
# `required-checks-drift.yml` runs `--remote` on a schedule, and the package
|
|
15
|
+
# script named for the vacuous check was a bare invocation. So the detection was
|
|
16
|
+
# `declared-but-uncallable` — the very family the guard exists to describe,
|
|
17
|
+
# one level up inside its own shipping. Measured on the repository that owns it:
|
|
18
|
+
# 23 of the last 25 merged pull requests had a REQUIRED review check that
|
|
19
|
+
# reviewed nothing, and nothing anywhere said so.
|
|
20
|
+
#
|
|
21
|
+
# WHY IT IS ITS OWN WORKFLOW AND NOT A JOB IN `ci.yml`. Reading checks needs
|
|
22
|
+
# scopes the reusable-quality caller does not grant, and a called workflow may
|
|
23
|
+
# only DOWNGRADE the caller's grant — asking for more is a startup_failure for
|
|
24
|
+
# the entire run (#2049). A standalone workflow declares its own permissions and
|
|
25
|
+
# constrains nothing else.
|
|
26
|
+
#
|
|
27
|
+
# THIS NEVER BLOCKS A MERGE, on purpose. A review bot can go hollow because an
|
|
28
|
+
# org-wide SPENDING CAP was hit, and a gate that reddens every pull request on a
|
|
29
|
+
# billing state is worse than the one it criticises. What the finding changes is
|
|
30
|
+
# what you may CLAIM: a pull request carrying it has not been shown to be
|
|
31
|
+
# reviewed, so do not record it as reviewed. Once you have made that governance
|
|
32
|
+
# call, add `--fail-on-vacuous` to the command below — that is the supported way
|
|
33
|
+
# to ask for an exit code, and it replaces the `--json`-reading wrapper every
|
|
34
|
+
# consumer used to have to write.
|
|
35
|
+
#
|
|
36
|
+
# It CAN still go red, for one reason that is not a finding: the arm inspected
|
|
37
|
+
# NOTHING. An unresolvable pull request, a `gh` it could not read, an empty
|
|
38
|
+
# check roster, or an empty `evidence_bearing_checks` all print the same
|
|
39
|
+
# "nothing vacuous here" as a genuinely clean run, so the guard refuses instead
|
|
40
|
+
# and names which one it hit. Read the `vacuity_*` token before reporting a red
|
|
41
|
+
# run here as a hollow review: `NOBODY LOOKED` and `THE REVIEW WAS FAKE` are
|
|
42
|
+
# opposite facts.
|
|
43
|
+
|
|
44
|
+
name: 🕵️ Review Evidence
|
|
45
|
+
|
|
46
|
+
on:
|
|
47
|
+
pull_request:
|
|
48
|
+
types: [opened, synchronize, reopened, ready_for_review]
|
|
49
|
+
workflow_dispatch:
|
|
50
|
+
inputs:
|
|
51
|
+
pr:
|
|
52
|
+
description: 'Pull request number to inspect'
|
|
53
|
+
required: true
|
|
54
|
+
type: string
|
|
55
|
+
|
|
56
|
+
# `actions: read` is what `gh pr checks` needs — it resolves the rollup through
|
|
57
|
+
# `checkSuite.workflowRun`, and without it `gh` exits non-zero with EMPTY
|
|
58
|
+
# STDOUT, a failure shaped like a content problem that never says the word
|
|
59
|
+
# "permission". `checks: read` + `statuses: read` are what the guard's
|
|
60
|
+
# permission-light fallback needs; a legacy commit status like CodeRabbit's is
|
|
61
|
+
# the only route that carries a description at all.
|
|
62
|
+
permissions:
|
|
63
|
+
contents: read
|
|
64
|
+
actions: read
|
|
65
|
+
checks: read
|
|
66
|
+
statuses: read
|
|
67
|
+
pull-requests: read
|
|
68
|
+
|
|
69
|
+
concurrency:
|
|
70
|
+
group: review-evidence-${{ github.event.pull_request.number || inputs.pr || github.ref }}
|
|
71
|
+
cancel-in-progress: true
|
|
72
|
+
|
|
73
|
+
jobs:
|
|
74
|
+
vacuity:
|
|
75
|
+
name: 🕵️ Did the required review checks do any work?
|
|
76
|
+
runs-on: ubuntu-latest
|
|
77
|
+
# The guard waits for the declared checks to settle before judging them: a
|
|
78
|
+
# review bot posts `pending — "Review queued"` and `pending — "Review in
|
|
79
|
+
# progress"` first, both of which are in the no-work vocabulary, so judging
|
|
80
|
+
# them on arrival manufactures a finding on EVERY pull request. Its default
|
|
81
|
+
# ceiling is five minutes; this leaves room for the wait plus the run.
|
|
82
|
+
timeout-minutes: 10
|
|
83
|
+
|
|
84
|
+
steps:
|
|
85
|
+
- name: 📥 Checkout repository
|
|
86
|
+
uses: actions/checkout@v6
|
|
87
|
+
with:
|
|
88
|
+
persist-credentials: false
|
|
89
|
+
|
|
90
|
+
- name: 🔧 Setup Node.js
|
|
91
|
+
uses: actions/setup-node@v6
|
|
92
|
+
with:
|
|
93
|
+
package-manager-cache: false
|
|
94
|
+
node-version: '22.21.1'
|
|
95
|
+
|
|
96
|
+
- name: 🕵️ Refuse a required check that reviewed nothing
|
|
97
|
+
env:
|
|
98
|
+
GH_TOKEN: ${{ github.token }}
|
|
99
|
+
# Absent on a `pull_request` run, where the guard reads the event
|
|
100
|
+
# payload instead; set only for the manual dispatch path.
|
|
101
|
+
VACUITY_PR: ${{ inputs.pr }}
|
|
102
|
+
run: |
|
|
103
|
+
set -eu
|
|
104
|
+
# An absent input is a FAILURE, never a skip — the same flip #2933
|
|
105
|
+
# made to the `🔒 Skipped Required Checks` job in quality.yml, for the
|
|
106
|
+
# same reason: this workflow is installed by the same `lisa apply`
|
|
107
|
+
# that installs the prover and the seed, so neither can be absent
|
|
108
|
+
# without the install being broken, and a green run that inspected
|
|
109
|
+
# nothing is the exact defect being checked for.
|
|
110
|
+
if [ ! -f scripts/check-skipped-required-checks.mjs ]; then
|
|
111
|
+
echo "::error title=Vacuity prover missing::scripts/check-skipped-required-checks.mjs does not exist, so no required check was read on this pull request. Run \`lisa apply\` to install the Lisa-managed script."
|
|
112
|
+
exit 1
|
|
113
|
+
fi
|
|
114
|
+
if [ ! -f .github/required-checks.json ]; then
|
|
115
|
+
echo "::error title=Required-checks declaration missing::.github/required-checks.json does not exist, so nothing names which checks are supposed to carry review evidence. It is create-only and Lisa ships a seed — run \`lisa apply\` to get it."
|
|
116
|
+
exit 1
|
|
117
|
+
fi
|
|
118
|
+
if [ -n "${VACUITY_PR:-}" ]; then
|
|
119
|
+
node scripts/check-skipped-required-checks.mjs --vacuity --pr="$VACUITY_PR"
|
|
120
|
+
else
|
|
121
|
+
node scripts/check-skipped-required-checks.mjs --vacuity
|
|
122
|
+
fi
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"nightly:health": "node scripts/check-nightly-e2e-health.mjs",
|
|
23
23
|
"check:skipped-required-checks": "node scripts/check-skipped-required-checks.mjs",
|
|
24
24
|
"check:skipped-required-checks:remote": "node scripts/check-skipped-required-checks.mjs --remote",
|
|
25
|
-
"check:vacuous-required-checks": "node scripts/check-skipped-required-checks.mjs",
|
|
25
|
+
"check:vacuous-required-checks": "node scripts/check-skipped-required-checks.mjs --vacuity",
|
|
26
26
|
"test:node": "node scripts/lisa-test-node.mjs",
|
|
27
27
|
"check:work-item": "node scripts/lisa-work-item.mjs validate-pr",
|
|
28
28
|
"check:conflict-markers": "node scripts/check-conflict-markers.mjs",
|