@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.
Files changed (106) hide show
  1. package/all/copy-overwrite/scripts/check-third-party-review-evidence.mjs +568 -80
  2. package/dist/cli/doctor-seeded-artifacts.d.ts.map +1 -1
  3. package/dist/cli/doctor-seeded-artifacts.js +10 -3
  4. package/dist/cli/doctor-seeded-artifacts.js.map +1 -1
  5. package/dist/cli/doctor-third-party-evidence-seed.d.ts +32 -0
  6. package/dist/cli/doctor-third-party-evidence-seed.d.ts.map +1 -0
  7. package/dist/cli/doctor-third-party-evidence-seed.js +239 -0
  8. package/dist/cli/doctor-third-party-evidence-seed.js.map +1 -0
  9. package/dist/cli/doctor.js +2 -2
  10. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  11. package/dist/core/lisa-owned-hash-ledger.js +6 -0
  12. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  13. package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
  14. package/dist/core/third-party-evidence-seed.d.ts +42 -0
  15. package/dist/core/third-party-evidence-seed.d.ts.map +1 -0
  16. package/dist/core/third-party-evidence-seed.js +233 -0
  17. package/dist/core/third-party-evidence-seed.js.map +1 -0
  18. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  19. package/dist/core/upstream-evidence-manifest.js +23 -4
  20. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  21. package/package.json +4 -4
  22. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  23. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  24. package/plugins/lisa/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +59 -31
  25. package/plugins/lisa/.codex-plugin/skills/lisa-pull-request-review/SKILL.md +11 -5
  26. package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +59 -31
  27. package/plugins/lisa/skills/lisa-pull-request-review/SKILL.md +11 -5
  28. package/plugins/lisa-agy/plugin.json +1 -1
  29. package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +59 -31
  30. package/plugins/lisa-agy/skills/lisa-pull-request-review/SKILL.md +11 -5
  31. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  32. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  33. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  34. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  35. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  36. package/plugins/lisa-cdk-devin/.claude-plugin/plugin.json +1 -1
  37. package/plugins/lisa-cdk-devin/.devin-plugin/plugin.json +1 -1
  38. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  39. package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +59 -31
  40. package/plugins/lisa-copilot/skills/lisa-pull-request-review/SKILL.md +11 -5
  41. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  42. package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +59 -31
  43. package/plugins/lisa-cursor/skills/lisa-pull-request-review/SKILL.md +11 -5
  44. package/plugins/lisa-devin/.claude-plugin/plugin.json +1 -1
  45. package/plugins/lisa-devin/.devin-plugin/plugin.json +1 -1
  46. package/plugins/lisa-devin/skills/lisa-drive-pr-to-merge/SKILL.md +59 -31
  47. package/plugins/lisa-devin/skills/lisa-pull-request-review/SKILL.md +11 -5
  48. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  49. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  50. package/plugins/lisa-expo-agy/plugin.json +1 -1
  51. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  52. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  53. package/plugins/lisa-expo-devin/.claude-plugin/plugin.json +1 -1
  54. package/plugins/lisa-expo-devin/.devin-plugin/plugin.json +1 -1
  55. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  56. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  57. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  58. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  59. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  60. package/plugins/lisa-harper-fabric-devin/.claude-plugin/plugin.json +1 -1
  61. package/plugins/lisa-harper-fabric-devin/.devin-plugin/plugin.json +1 -1
  62. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  63. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  64. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  65. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  66. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  67. package/plugins/lisa-nestjs-devin/.claude-plugin/plugin.json +1 -1
  68. package/plugins/lisa-nestjs-devin/.devin-plugin/plugin.json +1 -1
  69. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  70. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  71. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  72. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  73. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  74. package/plugins/lisa-openclaw-devin/.claude-plugin/plugin.json +1 -1
  75. package/plugins/lisa-openclaw-devin/.devin-plugin/plugin.json +1 -1
  76. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  77. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  78. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  79. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  80. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  81. package/plugins/lisa-phaser-devin/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa-phaser-devin/.devin-plugin/plugin.json +1 -1
  83. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  85. package/plugins/lisa-rails-agy/plugin.json +1 -1
  86. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-rails-devin/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-rails-devin/.devin-plugin/plugin.json +1 -1
  90. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  91. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  92. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  93. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  95. package/plugins/lisa-typescript-devin/.claude-plugin/plugin.json +1 -1
  96. package/plugins/lisa-typescript-devin/.devin-plugin/plugin.json +1 -1
  97. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  98. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  99. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  100. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  101. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  102. package/plugins/lisa-wiki-devin/.claude-plugin/plugin.json +1 -1
  103. package/plugins/lisa-wiki-devin/.devin-plugin/plugin.json +1 -1
  104. package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +59 -31
  105. package/plugins/src/base/skills/lisa-pull-request-review/SKILL.md +11 -5
  106. 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":"AAyBA,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,CAkBjC"}
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 four checks that ask what Lisa SEEDED into this repository, and whether
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 four ways, and
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 four are how an
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;AAG3E;;;;;;;;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,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"}
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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"}
@@ -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 four seeded-artifact checks, in one call because they are one
287
- // operator question asked four ways: what did Lisa write into this
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,CA2sEjC,CAAC;AAEH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,+BAA+B,EAAE,QAAQ,CACpD,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CA8mEjC,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([