@codyswann/lisa 4.87.5 → 4.87.7
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 +568 -80
- package/dist/cli/doctor-seeded-artifacts.d.ts.map +1 -1
- package/dist/cli/doctor-seeded-artifacts.js +10 -3
- package/dist/cli/doctor-seeded-artifacts.js.map +1 -1
- package/dist/cli/doctor-third-party-evidence-seed.d.ts +32 -0
- package/dist/cli/doctor-third-party-evidence-seed.d.ts.map +1 -0
- package/dist/cli/doctor-third-party-evidence-seed.js +239 -0
- package/dist/cli/doctor-third-party-evidence-seed.js.map +1 -0
- package/dist/cli/doctor.js +2 -2
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +6 -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/third-party-evidence-seed.d.ts +42 -0
- package/dist/core/third-party-evidence-seed.d.ts.map +1 -0
- package/dist/core/third-party-evidence-seed.js +233 -0
- package/dist/core/third-party-evidence-seed.js.map +1 -0
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +23 -4
- 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 +59 -31
- package/plugins/lisa/.codex-plugin/skills/lisa-pull-request-review/SKILL.md +11 -5
- package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +59 -31
- package/plugins/lisa/skills/lisa-pull-request-review/SKILL.md +11 -5
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +59 -31
- package/plugins/lisa-agy/skills/lisa-pull-request-review/SKILL.md +11 -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-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 +59 -31
- package/plugins/lisa-copilot/skills/lisa-pull-request-review/SKILL.md +11 -5
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +59 -31
- package/plugins/lisa-cursor/skills/lisa-pull-request-review/SKILL.md +11 -5
- 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 +59 -31
- package/plugins/lisa-devin/skills/lisa-pull-request-review/SKILL.md +11 -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-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 +59 -31
- package/plugins/src/base/skills/lisa-pull-request-review/SKILL.md +11 -5
- package/typescript/create-only/.github/workflows/third-party-review-evidence.yml +62 -30
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-seeded-artifacts.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-seeded-artifacts.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"doctor-seeded-artifacts.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-seeded-artifacts.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC,CAwBjC"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
2
|
+
* The five checks that ask what Lisa SEEDED into this repository, and whether
|
|
3
3
|
* what it seeded still says what it meant.
|
|
4
4
|
*
|
|
5
|
-
* They are grouped because they are one operator question asked
|
|
5
|
+
* They are grouped because they are one operator question asked five ways, and
|
|
6
6
|
* because each of them exists for the same structural reason: the write path
|
|
7
7
|
* that could have prevented the defect is reached exactly once, before the file
|
|
8
8
|
* exists. A repository that received the template earlier therefore has no
|
|
9
9
|
* signal of any kind — the seeding postinstall is skipped under CI, the file is
|
|
10
10
|
* untracked, and the tool the file disables reports only that it found nothing.
|
|
11
|
-
* A fix on the write path reaches the NEXT adoption; these
|
|
11
|
+
* A fix on the write path reaches the NEXT adoption; these five are how an
|
|
12
12
|
* existing one finds itself.
|
|
13
13
|
*
|
|
14
14
|
* `doctor-lisa-owned-artifacts` is the inverse and deliberately stays where it
|
|
@@ -23,6 +23,7 @@ import { checkCdkPresetAdoption } from "./doctor-cdk-preset-adoption.js";
|
|
|
23
23
|
import { checkConfigShadowing } from "./doctor-config-shadowing.js";
|
|
24
24
|
import { checkRailsDeployIntent } from "./doctor-rails-deploy-intent.js";
|
|
25
25
|
import { checkStaleManagedBanner } from "./doctor-stale-managed-banner.js";
|
|
26
|
+
import { checkThirdPartyEvidenceSeed } from "./doctor-third-party-evidence-seed.js";
|
|
26
27
|
/**
|
|
27
28
|
* Run every seeded-artifact check, in the order an operator reads them.
|
|
28
29
|
*
|
|
@@ -41,6 +42,12 @@ export async function checkSeededArtifacts(targetPath) {
|
|
|
41
42
|
// The seed fix reaches new adoptions only and the apply path will not
|
|
42
43
|
// rewrite a host-owned workflow (CodySwannGT/lisa#3779).
|
|
43
44
|
await checkRailsDeployIntent(targetPath),
|
|
45
|
+
// Whether a host-owned workflow Lisa is FORBIDDEN to refresh still runs at
|
|
46
|
+
// all. The evidence workflow woke only on `status`, and a reviewer that
|
|
47
|
+
// reports through a check run fires none, so seeded copies silently
|
|
48
|
+
// stopped running; the seed fix reaches new adoptions only
|
|
49
|
+
// (CodySwannGT/lisa#4553).
|
|
50
|
+
await checkThirdPartyEvidenceSeed(targetPath),
|
|
44
51
|
// Whether a whole stack preset was delivered to a repository that never
|
|
45
52
|
// qualified for it. The detection fix reaches the next decision only, and
|
|
46
53
|
// the dead-code gate it skewed reports SUCCESS (CodySwannGT/lisa#3711).
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"doctor-seeded-artifacts.js","sourceRoot":"","sources":["../../src/cli/doctor-seeded-artifacts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;
|
|
1
|
+
{"version":3,"file":"doctor-seeded-artifacts.js","sourceRoot":"","sources":["../../src/cli/doctor-seeded-artifacts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,EAAE,sBAAsB,EAAE,MAAM,iCAAiC,CAAC;AACzE,OAAO,EAAE,uBAAuB,EAAE,MAAM,kCAAkC,CAAC;AAC3E,OAAO,EAAE,2BAA2B,EAAE,MAAM,uCAAuC,CAAC;AAGpF;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,UAAkB;IAElB,OAAO;QACL,wEAAwE;QACxE,2BAA2B;QAC3B,MAAM,oBAAoB,CAAC,UAAU,CAAC;QACtC,yEAAyE;QACzE,sEAAsE;QACtE,yDAAyD;QACzD,MAAM,sBAAsB,CAAC,UAAU,CAAC;QACxC,2EAA2E;QAC3E,wEAAwE;QACxE,oEAAoE;QACpE,2DAA2D;QAC3D,2BAA2B;QAC3B,MAAM,2BAA2B,CAAC,UAAU,CAAC;QAC7C,wEAAwE;QACxE,0EAA0E;QAC1E,wEAAwE;QACxE,MAAM,sBAAsB,CAAC,UAAU,CAAC;QACxC,qEAAqE;QACrE,yEAAyE;QACzE,4DAA4D;QAC5D,MAAM,uBAAuB,CAAC,UAAU,CAAC;KAC1C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { type EvidenceSeedReading } from "../core/third-party-evidence-seed.js";
|
|
2
|
+
import type { DoctorCheck } from "./doctor.js";
|
|
3
|
+
/** Name of the check as doctor reports it. */
|
|
4
|
+
export declare const THIRD_PARTY_EVIDENCE_SEED_CHECK_NAME = "Third-party review evidence wakes on check runs?";
|
|
5
|
+
/** The trigger lines to add under `on:`. */
|
|
6
|
+
export declare const CHECK_RUN_TRIGGER_LINES: readonly [" check_run:", " types: [completed]"];
|
|
7
|
+
/** The permission line to add under an existing `permissions:` block. */
|
|
8
|
+
export declare const CHECKS_READ_LINE = " checks: read";
|
|
9
|
+
/** The whole block, for a copy missing any scope the prover reads with. */
|
|
10
|
+
export declare const PERMISSIONS_BLOCK_LINES: readonly ["permissions:", " contents: read", " statuses: read", " checks: read", " pull-requests: read"];
|
|
11
|
+
/** The values that carry the run's commit and reviewer to the prover. */
|
|
12
|
+
export declare const RUN_IDENTITY_LINES: readonly [" EVIDENCE_SHA: ${{ github.event.check_run.head_sha || github.event.sha || inputs.sha }}", " EVIDENCE_CONTEXT: ${{ github.event.check_run.name || github.event.context }}"];
|
|
13
|
+
/** The concurrency key that keeps one run from cancelling another's verdict. */
|
|
14
|
+
export declare const CONCURRENCY_GROUP_LINE = " group: third-party-review-evidence-${{ github.event_name }}-${{ github.event.check_run.head_sha || github.event.sha || inputs.sha }}-${{ github.event.check_run.name || github.event.context }}";
|
|
15
|
+
/**
|
|
16
|
+
* The operator-facing finding and its exact remedy.
|
|
17
|
+
* @param reading - What the copy does
|
|
18
|
+
* @returns The detail for a stale copy
|
|
19
|
+
*/
|
|
20
|
+
export declare function describeStaleSeed(reading: EvidenceSeedReading): string;
|
|
21
|
+
/**
|
|
22
|
+
* Report whether the seeded evidence workflow wakes on, can read, and safely
|
|
23
|
+
* judges the reviewer's check run.
|
|
24
|
+
*
|
|
25
|
+
* Warns rather than fails on a stale copy: the remedy is an edit to a
|
|
26
|
+
* host-owned file, and nothing about the project is broken locally. Fails when
|
|
27
|
+
* the question could not be answered.
|
|
28
|
+
* @param targetPath - Project path to inspect
|
|
29
|
+
* @returns Doctor check result
|
|
30
|
+
*/
|
|
31
|
+
export declare function checkThirdPartyEvidenceSeed(targetPath: string): Promise<DoctorCheck>;
|
|
32
|
+
//# sourceMappingURL=doctor-third-party-evidence-seed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-third-party-evidence-seed.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-third-party-evidence-seed.ts"],"names":[],"mappings":"AA4BA,OAAO,EAML,KAAK,mBAAmB,EACzB,MAAM,sCAAsC,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,8CAA8C;AAC9C,eAAO,MAAM,oCAAoC,qDACG,CAAC;AAwBrD,4CAA4C;AAC5C,eAAO,MAAM,uBAAuB,qDAG1B,CAAC;AAEX,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,mBAAmB,CAAC;AAEjD,2EAA2E;AAC3E,eAAO,MAAM,uBAAuB,8GAM1B,CAAC;AAEX,yEAAyE;AACzE,eAAO,MAAM,kBAAkB,yLAGrB,CAAC;AAEX,gFAAgF;AAChF,eAAO,MAAM,sBAAsB,sMAA2G,CAAC;AAsH/I;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,mBAAmB,GAAG,MAAM,CAOtE;AAED;;;;;;;;;GASG;AACH,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,WAAW,CAAC,CAiCtB"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `lisa doctor` check: does this repository's seeded third-party review
|
|
3
|
+
* evidence workflow still run — and judge safely — now that the reviewer
|
|
4
|
+
* reports through a check run?
|
|
5
|
+
*
|
|
6
|
+
* The workflow woke only on `status` events. A reviewer that reports through a
|
|
7
|
+
* check run fires none, so the workflow stopped running in every repository it
|
|
8
|
+
* was seeded into, and nothing said so — a workflow that never starts produces
|
|
9
|
+
* no red run to notice (CodySwannGT/lisa#4553). The seed is fixed, but it is
|
|
10
|
+
* `create-only`: Lisa wrote it once, the host owns it, and `lisa apply` never
|
|
11
|
+
* refreshes it.
|
|
12
|
+
*
|
|
13
|
+
* This check REPORTS and names the exact lines to change. It edits nothing, for
|
|
14
|
+
* the reason `doctor-skip-jobs-migration` gives: `lisa apply` runs on
|
|
15
|
+
* postinstall, and a repair that edits a host-owned workflow there and gets it
|
|
16
|
+
* wrong is silent. `retireUnmodified` can only delete, and nothing upgrades a
|
|
17
|
+
* create-only file in place. The prover the workflow runs is copy-overwrite, so
|
|
18
|
+
* it is already current; only the workflow's own trigger, token, wiring and
|
|
19
|
+
* checkout are stale.
|
|
20
|
+
*
|
|
21
|
+
* Every filesystem answer is three-valued — present, absent, or
|
|
22
|
+
* undeterminable — and the last one fails rather than passing quietly: a
|
|
23
|
+
* workflow this check could not read is not a workflow with nothing missing.
|
|
24
|
+
* @module cli/doctor-third-party-evidence-seed
|
|
25
|
+
*/
|
|
26
|
+
import { readFile, stat } from "node:fs/promises";
|
|
27
|
+
import * as path from "node:path";
|
|
28
|
+
import { CHECK_RUN_HEAD, CHECK_RUN_NAME, isCurrentEvidenceSeed, readEvidenceSeed, THIRD_PARTY_EVIDENCE_WORKFLOW, } from "../core/third-party-evidence-seed.js";
|
|
29
|
+
/** Name of the check as doctor reports it. */
|
|
30
|
+
export const THIRD_PARTY_EVIDENCE_SEED_CHECK_NAME = "Third-party review evidence wakes on check runs?";
|
|
31
|
+
/** Where the current seed ships inside the package, for a full comparison. */
|
|
32
|
+
const SHIPPED_SEED = "typescript/create-only/.github/workflows/third-party-review-evidence.yml";
|
|
33
|
+
/**
|
|
34
|
+
* Errno codes that ANSWER the question rather than refusing it: the file is
|
|
35
|
+
* genuinely not there. Anything else — a permission denial, an I/O error, a
|
|
36
|
+
* symlink loop — means the probe could not look.
|
|
37
|
+
*
|
|
38
|
+
* `ENAMETOOLONG` is deliberately NOT here, although sibling doctor checks list
|
|
39
|
+
* it. It describes the path this check built, not the file: a project nested
|
|
40
|
+
* past the platform's path limit can still hold the workflow, and calling that
|
|
41
|
+
* "never seeded" would pass a copy nobody read.
|
|
42
|
+
*/
|
|
43
|
+
const ABSENT_CODES = new Set(["ENOENT", "ENOTDIR"]);
|
|
44
|
+
/** The commit to judge, from whichever event woke the run. */
|
|
45
|
+
const SHA_EXPRESSION = `\${{ ${CHECK_RUN_HEAD} || github.event.sha || inputs.sha }}`;
|
|
46
|
+
/** The reviewer to judge, from whichever event woke the run. */
|
|
47
|
+
const CONTEXT_EXPRESSION = `\${{ ${CHECK_RUN_NAME} || github.event.context }}`;
|
|
48
|
+
/** The trigger lines to add under `on:`. */
|
|
49
|
+
export const CHECK_RUN_TRIGGER_LINES = [
|
|
50
|
+
" check_run:",
|
|
51
|
+
" types: [completed]",
|
|
52
|
+
];
|
|
53
|
+
/** The permission line to add under an existing `permissions:` block. */
|
|
54
|
+
export const CHECKS_READ_LINE = " checks: read";
|
|
55
|
+
/** The whole block, for a copy missing any scope the prover reads with. */
|
|
56
|
+
export const PERMISSIONS_BLOCK_LINES = [
|
|
57
|
+
"permissions:",
|
|
58
|
+
" contents: read",
|
|
59
|
+
" statuses: read",
|
|
60
|
+
CHECKS_READ_LINE,
|
|
61
|
+
" pull-requests: read",
|
|
62
|
+
];
|
|
63
|
+
/** The values that carry the run's commit and reviewer to the prover. */
|
|
64
|
+
export const RUN_IDENTITY_LINES = [
|
|
65
|
+
` EVIDENCE_SHA: ${SHA_EXPRESSION}`,
|
|
66
|
+
` EVIDENCE_CONTEXT: ${CONTEXT_EXPRESSION}`,
|
|
67
|
+
];
|
|
68
|
+
/** The concurrency key that keeps one run from cancelling another's verdict. */
|
|
69
|
+
export const CONCURRENCY_GROUP_LINE = ` group: third-party-review-evidence-\${{ github.event_name }}-${SHA_EXPRESSION}-${CONTEXT_EXPRESSION}`;
|
|
70
|
+
/**
|
|
71
|
+
* Read the workflow, REJECTING when the filesystem declines to say.
|
|
72
|
+
* @param projectRoot - Absolute project root
|
|
73
|
+
* @returns Workflow source, or null when the file is provably absent
|
|
74
|
+
* @throws {Error} When the file exists but could not be read
|
|
75
|
+
*/
|
|
76
|
+
async function readWorkflow(projectRoot) {
|
|
77
|
+
try {
|
|
78
|
+
return await readFile(path.join(projectRoot, THIRD_PARTY_EVIDENCE_WORKFLOW), "utf8");
|
|
79
|
+
}
|
|
80
|
+
catch (error) {
|
|
81
|
+
const code = typeof error === "object" && error !== null && "code" in error
|
|
82
|
+
? String(error.code)
|
|
83
|
+
: undefined;
|
|
84
|
+
if (code !== undefined && ABSENT_CODES.has(code))
|
|
85
|
+
return null;
|
|
86
|
+
throw new Error(`could not read ${THIRD_PARTY_EVIDENCE_WORKFLOW}: ${code ?? String(error)}`, { cause: error });
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* The plain-language gaps a copy has, in the order an operator fixes them.
|
|
91
|
+
* @param reading - What the copy does
|
|
92
|
+
* @returns One clause per gap
|
|
93
|
+
*/
|
|
94
|
+
function gapsOf(reading) {
|
|
95
|
+
return [
|
|
96
|
+
...(reading.wakesOnCheckRun
|
|
97
|
+
? []
|
|
98
|
+
: [
|
|
99
|
+
"it has no `check_run` trigger, so it never starts when the reviewer reports through a check run",
|
|
100
|
+
]),
|
|
101
|
+
...(reading.readsChecks
|
|
102
|
+
? []
|
|
103
|
+
: [
|
|
104
|
+
"it does not grant `checks: read`, so its prover cannot read the reviewer's check run",
|
|
105
|
+
]),
|
|
106
|
+
...(reading.readsStatusesAndPullRequests
|
|
107
|
+
? []
|
|
108
|
+
: [
|
|
109
|
+
"its token cannot read statuses and pull requests, so every run would read as not being a pull request head and judge nothing",
|
|
110
|
+
]),
|
|
111
|
+
...(reading.readsRunIdentity
|
|
112
|
+
? []
|
|
113
|
+
: [
|
|
114
|
+
"it never reads the check run's head SHA and name, so on a check run it would pass an empty --sha and judge nothing",
|
|
115
|
+
]),
|
|
116
|
+
...(reading.keysConcurrencyPerRun
|
|
117
|
+
? []
|
|
118
|
+
: [
|
|
119
|
+
"its concurrency group is not keyed on the check run's head and name, so any app's check run can cancel the run judging the reviewer",
|
|
120
|
+
]),
|
|
121
|
+
...(reading.checksOutEventHead
|
|
122
|
+
? [
|
|
123
|
+
"it checks out the head of the event that woke it, so a pull request's own code — a fork's included — runs with this repository's token and cache scope",
|
|
124
|
+
]
|
|
125
|
+
: []),
|
|
126
|
+
];
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* The exact lines that grant what the prover reads with.
|
|
130
|
+
*
|
|
131
|
+
* Only a copy whose block already reads statuses and pull requests gets the one
|
|
132
|
+
* `checks: read` line. Every other copy gets the whole block: a block holding
|
|
133
|
+
* only `checks: read` sets every other scope to none, and the prover could then
|
|
134
|
+
* no longer find the pull request it is judging.
|
|
135
|
+
* @param reading - What the copy does
|
|
136
|
+
* @returns The permission remedy, or nothing when the grants are there
|
|
137
|
+
*/
|
|
138
|
+
function permissionRemedyOf(reading) {
|
|
139
|
+
if (reading.readsChecks && reading.readsStatusesAndPullRequests)
|
|
140
|
+
return [];
|
|
141
|
+
if (reading.declaresPermissions && reading.readsStatusesAndPullRequests) {
|
|
142
|
+
return ["Add under `permissions:`:", CHECKS_READ_LINE];
|
|
143
|
+
}
|
|
144
|
+
return [
|
|
145
|
+
reading.declaresPermissions
|
|
146
|
+
? "Make the `permissions:` block that governs the prover's job read:"
|
|
147
|
+
: "Add this block at the top level, where the file declares none:",
|
|
148
|
+
...PERMISSIONS_BLOCK_LINES,
|
|
149
|
+
];
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* The exact lines that close each gap.
|
|
153
|
+
* @param reading - What the copy does
|
|
154
|
+
* @returns The remedy, one line per array entry
|
|
155
|
+
*/
|
|
156
|
+
function remedyOf(reading) {
|
|
157
|
+
return [
|
|
158
|
+
...(reading.wakesOnCheckRun
|
|
159
|
+
? []
|
|
160
|
+
: ["Add under `on:`:", ...CHECK_RUN_TRIGGER_LINES]),
|
|
161
|
+
...permissionRemedyOf(reading),
|
|
162
|
+
...(reading.readsRunIdentity
|
|
163
|
+
? []
|
|
164
|
+
: [
|
|
165
|
+
"Set these values in the prover step's `env:`:",
|
|
166
|
+
...RUN_IDENTITY_LINES,
|
|
167
|
+
]),
|
|
168
|
+
...(reading.keysConcurrencyPerRun
|
|
169
|
+
? []
|
|
170
|
+
: ["Set the `concurrency:` group to:", CONCURRENCY_GROUP_LINE]),
|
|
171
|
+
...(reading.checksOutEventHead
|
|
172
|
+
? [
|
|
173
|
+
"Delete the `ref:` line under the `actions/checkout` step. The default branch is then checked out, and the commit to judge still arrives as --sha.",
|
|
174
|
+
]
|
|
175
|
+
: []),
|
|
176
|
+
];
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* The operator-facing finding and its exact remedy.
|
|
180
|
+
* @param reading - What the copy does
|
|
181
|
+
* @returns The detail for a stale copy
|
|
182
|
+
*/
|
|
183
|
+
export function describeStaleSeed(reading) {
|
|
184
|
+
return [
|
|
185
|
+
`${THIRD_PARTY_EVIDENCE_WORKFLOW} is not ready for a reviewer that reports through a check run: ${gapsOf(reading).join("; and ")}. ` +
|
|
186
|
+
"Lisa seeded this file once and will not rewrite it; the prover it runs is already current.",
|
|
187
|
+
...remedyOf(reading),
|
|
188
|
+
`The current seed, ${SHIPPED_SEED} in the @codyswann/lisa package, is the full reference.`,
|
|
189
|
+
].join("\n");
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Report whether the seeded evidence workflow wakes on, can read, and safely
|
|
193
|
+
* judges the reviewer's check run.
|
|
194
|
+
*
|
|
195
|
+
* Warns rather than fails on a stale copy: the remedy is an edit to a
|
|
196
|
+
* host-owned file, and nothing about the project is broken locally. Fails when
|
|
197
|
+
* the question could not be answered.
|
|
198
|
+
* @param targetPath - Project path to inspect
|
|
199
|
+
* @returns Doctor check result
|
|
200
|
+
*/
|
|
201
|
+
export async function checkThirdPartyEvidenceSeed(targetPath) {
|
|
202
|
+
try {
|
|
203
|
+
const root = await stat(targetPath);
|
|
204
|
+
if (!root.isDirectory()) {
|
|
205
|
+
throw new Error(`${targetPath} is not a directory`);
|
|
206
|
+
}
|
|
207
|
+
const workflowText = await readWorkflow(targetPath);
|
|
208
|
+
if (workflowText === null) {
|
|
209
|
+
return ok(`No ${THIRD_PARTY_EVIDENCE_WORKFLOW} in this project`);
|
|
210
|
+
}
|
|
211
|
+
const reading = readEvidenceSeed(workflowText);
|
|
212
|
+
if (isCurrentEvidenceSeed(reading)) {
|
|
213
|
+
return ok(`${THIRD_PARTY_EVIDENCE_WORKFLOW} wakes on a completed check run, can read it, and judges it from the default branch`);
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
name: THIRD_PARTY_EVIDENCE_SEED_CHECK_NAME,
|
|
217
|
+
status: "warn",
|
|
218
|
+
detail: describeStaleSeed(reading),
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
return {
|
|
223
|
+
name: THIRD_PARTY_EVIDENCE_SEED_CHECK_NAME,
|
|
224
|
+
status: "fail",
|
|
225
|
+
detail: `Could not determine whether ${THIRD_PARTY_EVIDENCE_WORKFLOW} wakes ` +
|
|
226
|
+
`on check runs: ${error instanceof Error ? error.message : String(error)}. Treated as a failure rather than a pass: a workflow that could ` +
|
|
227
|
+
"not be read is not one with nothing missing",
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
/**
|
|
232
|
+
* A passing line for this check.
|
|
233
|
+
* @param detail - What was found
|
|
234
|
+
* @returns Doctor check result
|
|
235
|
+
*/
|
|
236
|
+
function ok(detail) {
|
|
237
|
+
return { name: THIRD_PARTY_EVIDENCE_SEED_CHECK_NAME, status: "ok", detail };
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=doctor-third-party-evidence-seed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor-third-party-evidence-seed.js","sourceRoot":"","sources":["../../src/cli/doctor-third-party-evidence-seed.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/doctor.js
CHANGED
|
@@ -283,8 +283,8 @@ export async function runDoctor(targetPath, options, dependencies = {}) {
|
|
|
283
283
|
await checkSonarProvider(resolvedTarget, deps),
|
|
284
284
|
await checkLegacyMonitorThresholds(resolvedTarget),
|
|
285
285
|
await checkLisaOwnedArtifacts(resolvedTarget),
|
|
286
|
-
// The
|
|
287
|
-
// operator question asked
|
|
286
|
+
// The five seeded-artifact checks, in one call because they are one
|
|
287
|
+
// operator question asked five ways: what did Lisa write into this
|
|
288
288
|
// repository, and does it still say what it meant. Each is unreachable
|
|
289
289
|
// from the write path that could have prevented it — that path runs once,
|
|
290
290
|
// before the file exists — so an already-seeded project has no other way
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lisa-owned-hash-ledger.d.ts","sourceRoot":"","sources":["../../src/core/lisa-owned-hash-ledger.ts"],"names":[],"mappings":"AACA,6EAA6E;AAE7E;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"lisa-owned-hash-ledger.d.ts","sourceRoot":"","sources":["../../src/core/lisa-owned-hash-ledger.ts"],"names":[],"mappings":"AACA,6EAA6E;AAE7E;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAC3C,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CA8sEjC,CAAC;AAEH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,+BAA+B,EAAE,QAAQ,CACpD,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAinEjC,CAAC"}
|
|
@@ -414,6 +414,9 @@ export const LISA_OWNED_HASH_LEDGER = Object.freeze({
|
|
|
414
414
|
]),
|
|
415
415
|
"scripts/check-third-party-review-evidence.mjs": Object.freeze([
|
|
416
416
|
"225e69c41b56f2eb82cdc1a16da26770090c3ccac85fe0dad278938d8ae4f769",
|
|
417
|
+
"404b5b002d0d639fd862e19c7e136b708a81409df0c14f9f808a6400b39643f2",
|
|
418
|
+
"444fdab01527fda3ce2bb4f5177bac2079cded0ba8f0166d71fda7ec2e8dc7b3",
|
|
419
|
+
"61c6896f81d4ceec1f292cd80527a62dea3d985477a26d937d6359d129755713",
|
|
417
420
|
"95f91f2a74ed4e523d064d5d374eadd1c1114f03a3a4fa41532c9b0fd32089de",
|
|
418
421
|
]),
|
|
419
422
|
"scripts/check-threshold-ratchet.mjs": Object.freeze([
|
|
@@ -2662,6 +2665,9 @@ export const LISA_OWNED_HASH_HISTORY_DERIVED = Object.freeze({
|
|
|
2662
2665
|
]),
|
|
2663
2666
|
"scripts/check-third-party-review-evidence.mjs": Object.freeze([
|
|
2664
2667
|
"225e69c41b56f2eb82cdc1a16da26770090c3ccac85fe0dad278938d8ae4f769",
|
|
2668
|
+
"404b5b002d0d639fd862e19c7e136b708a81409df0c14f9f808a6400b39643f2",
|
|
2669
|
+
"444fdab01527fda3ce2bb4f5177bac2079cded0ba8f0166d71fda7ec2e8dc7b3",
|
|
2670
|
+
"61c6896f81d4ceec1f292cd80527a62dea3d985477a26d937d6359d129755713",
|
|
2665
2671
|
"95f91f2a74ed4e523d064d5d374eadd1c1114f03a3a4fa41532c9b0fd32089de",
|
|
2666
2672
|
]),
|
|
2667
2673
|
"scripts/check-threshold-ratchet.mjs": Object.freeze([
|