@codyswann/lisa 4.42.6 → 4.43.0

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 (186) hide show
  1. package/README.md +4 -0
  2. package/all/copy-overwrite/scripts/check-orphaned-branches.mjs +7 -0
  3. package/all/copy-overwrite/scripts/lib/process-tree-runner.mjs +12 -2
  4. package/all/copy-overwrite/scripts/lisa-cross-worktree-guard.mjs +4 -0
  5. package/all/copy-overwrite/scripts/lisa-environment-prepare.mjs +2 -0
  6. package/all/copy-overwrite/scripts/lisa-hooks/worktree-binding-guard.mjs +31 -3
  7. package/all/copy-overwrite/scripts/lisa-run-gates.mjs +4 -0
  8. package/all/copy-overwrite/scripts/lisa-work-item.mjs +13 -0
  9. package/dist/cli/doctor-readiness-delivery.d.ts.map +1 -1
  10. package/dist/cli/doctor-readiness-delivery.js +13 -6
  11. package/dist/cli/doctor-readiness-delivery.js.map +1 -1
  12. package/dist/cli/doctor-readiness-deploy-outcome.d.ts +9 -0
  13. package/dist/cli/doctor-readiness-deploy-outcome.d.ts.map +1 -0
  14. package/dist/cli/doctor-readiness-deploy-outcome.js +87 -0
  15. package/dist/cli/doctor-readiness-deploy-outcome.js.map +1 -0
  16. package/dist/cli/doctor-readiness-workflows.d.ts +8 -0
  17. package/dist/cli/doctor-readiness-workflows.d.ts.map +1 -1
  18. package/dist/cli/doctor-readiness-workflows.js +1 -0
  19. package/dist/cli/doctor-readiness-workflows.js.map +1 -1
  20. package/dist/configs/vitest/base.d.ts +1 -1
  21. package/dist/configs/vitest/base.d.ts.map +1 -1
  22. package/dist/configs/vitest/base.js +1 -0
  23. package/dist/configs/vitest/base.js.map +1 -1
  24. package/dist/configs/vitest/cdk.d.ts +2 -2
  25. package/dist/configs/vitest/cdk.d.ts.map +1 -1
  26. package/dist/configs/vitest/cdk.js +5 -2
  27. package/dist/configs/vitest/cdk.js.map +1 -1
  28. package/dist/configs/vitest/coverage-reports-directory.d.ts +47 -0
  29. package/dist/configs/vitest/coverage-reports-directory.d.ts.map +1 -0
  30. package/dist/configs/vitest/coverage-reports-directory.js +131 -0
  31. package/dist/configs/vitest/coverage-reports-directory.js.map +1 -0
  32. package/dist/configs/vitest/harper-fabric.d.ts +2 -2
  33. package/dist/configs/vitest/harper-fabric.d.ts.map +1 -1
  34. package/dist/configs/vitest/harper-fabric.js +5 -2
  35. package/dist/configs/vitest/harper-fabric.js.map +1 -1
  36. package/dist/configs/vitest/nestjs.d.ts +2 -2
  37. package/dist/configs/vitest/nestjs.d.ts.map +1 -1
  38. package/dist/configs/vitest/nestjs.js +5 -2
  39. package/dist/configs/vitest/nestjs.js.map +1 -1
  40. package/dist/configs/vitest/phaser.d.ts +2 -2
  41. package/dist/configs/vitest/phaser.d.ts.map +1 -1
  42. package/dist/configs/vitest/phaser.js +5 -2
  43. package/dist/configs/vitest/phaser.js.map +1 -1
  44. package/dist/configs/vitest/typescript.d.ts +2 -2
  45. package/dist/configs/vitest/typescript.d.ts.map +1 -1
  46. package/dist/configs/vitest/typescript.js +5 -2
  47. package/dist/configs/vitest/typescript.js.map +1 -1
  48. package/dist/core/deploy-release-dependence.d.ts +72 -0
  49. package/dist/core/deploy-release-dependence.d.ts.map +1 -0
  50. package/dist/core/deploy-release-dependence.js +236 -0
  51. package/dist/core/deploy-release-dependence.js.map +1 -0
  52. package/dist/core/github-actions-condition.d.ts +78 -0
  53. package/dist/core/github-actions-condition.d.ts.map +1 -0
  54. package/dist/core/github-actions-condition.js +307 -0
  55. package/dist/core/github-actions-condition.js.map +1 -0
  56. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  57. package/dist/core/lisa-owned-hash-ledger.js +24 -0
  58. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  59. package/dist/core/nightly-e2e-guard-behavior-certificate.js +2 -2
  60. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  61. package/dist/core/upstream-evidence-manifest.js +45 -24
  62. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  63. package/dist/migrations/deploy-outcome-guard-edit.d.ts +11 -0
  64. package/dist/migrations/deploy-outcome-guard-edit.d.ts.map +1 -0
  65. package/dist/migrations/deploy-outcome-guard-edit.js +184 -0
  66. package/dist/migrations/deploy-outcome-guard-edit.js.map +1 -0
  67. package/dist/migrations/deploy-outcome-guard-yaml.d.ts +91 -0
  68. package/dist/migrations/deploy-outcome-guard-yaml.d.ts.map +1 -0
  69. package/dist/migrations/deploy-outcome-guard-yaml.js +180 -0
  70. package/dist/migrations/deploy-outcome-guard-yaml.js.map +1 -0
  71. package/dist/migrations/ensure-deploy-outcome-guard.d.ts +41 -0
  72. package/dist/migrations/ensure-deploy-outcome-guard.d.ts.map +1 -0
  73. package/dist/migrations/ensure-deploy-outcome-guard.js +238 -0
  74. package/dist/migrations/ensure-deploy-outcome-guard.js.map +1 -0
  75. package/dist/migrations/index.d.ts +1 -0
  76. package/dist/migrations/index.d.ts.map +1 -1
  77. package/dist/migrations/index.js +3 -0
  78. package/dist/migrations/index.js.map +1 -1
  79. package/expo/copy-overwrite/scripts/bdd/baseline.mjs +26 -7
  80. package/package.json +5 -4
  81. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  83. package/plugins/lisa/.codex-plugin/skills/lisa-drive-pr-to-merge/SKILL.md +11 -0
  84. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/bootstrap-store.mjs +3 -0
  85. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/preflight-secrets.mjs +3 -0
  86. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/providers.mjs +4 -0
  87. package/plugins/lisa/.codex-plugin/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -0
  88. package/plugins/lisa/hooks/threshold-ratchet.mjs +6 -0
  89. package/plugins/lisa/hooks/worktree-binding-guard.mjs +31 -3
  90. package/plugins/lisa/scripts/design-variable-ids.mjs +2 -0
  91. package/plugins/lisa/skills/lisa-drive-pr-to-merge/SKILL.md +11 -0
  92. package/plugins/lisa/skills/lisa-secrets-access/scripts/bootstrap-store.mjs +3 -0
  93. package/plugins/lisa/skills/lisa-secrets-access/scripts/preflight-secrets.mjs +3 -0
  94. package/plugins/lisa/skills/lisa-secrets-access/scripts/providers.mjs +4 -0
  95. package/plugins/lisa/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -0
  96. package/plugins/lisa-agy/plugin.json +1 -1
  97. package/plugins/lisa-agy/scripts/design-variable-ids.mjs +2 -0
  98. package/plugins/lisa-agy/skills/lisa-drive-pr-to-merge/SKILL.md +11 -0
  99. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/bootstrap-store.mjs +3 -0
  100. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/preflight-secrets.mjs +3 -0
  101. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/providers.mjs +4 -0
  102. package/plugins/lisa-agy/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -0
  103. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  104. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  105. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  106. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  107. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  108. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  109. package/plugins/lisa-copilot/hooks/threshold-ratchet.mjs +6 -0
  110. package/plugins/lisa-copilot/hooks/worktree-binding-guard.mjs +31 -3
  111. package/plugins/lisa-copilot/scripts/design-variable-ids.mjs +2 -0
  112. package/plugins/lisa-copilot/skills/lisa-drive-pr-to-merge/SKILL.md +11 -0
  113. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/bootstrap-store.mjs +3 -0
  114. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/preflight-secrets.mjs +3 -0
  115. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/providers.mjs +4 -0
  116. package/plugins/lisa-copilot/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -0
  117. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  118. package/plugins/lisa-cursor/hooks/threshold-ratchet.mjs +6 -0
  119. package/plugins/lisa-cursor/hooks/worktree-binding-guard.mjs +31 -3
  120. package/plugins/lisa-cursor/scripts/design-variable-ids.mjs +2 -0
  121. package/plugins/lisa-cursor/skills/lisa-drive-pr-to-merge/SKILL.md +11 -0
  122. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/bootstrap-store.mjs +3 -0
  123. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/preflight-secrets.mjs +3 -0
  124. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/providers.mjs +4 -0
  125. package/plugins/lisa-cursor/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -0
  126. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  127. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  128. package/plugins/lisa-expo-agy/plugin.json +1 -1
  129. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  130. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  131. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  132. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  133. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  134. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  135. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  136. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  137. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  138. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  139. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  140. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  141. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  142. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  143. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  144. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  145. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  146. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  147. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  148. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  149. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  150. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  151. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  152. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  153. package/plugins/lisa-rails-agy/plugin.json +1 -1
  154. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  155. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  156. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  157. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  158. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  159. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  160. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  161. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  162. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  163. package/plugins/lisa-wiki/scripts/ingest-git.mjs +2 -0
  164. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  165. package/plugins/lisa-wiki-agy/scripts/ingest-git.mjs +2 -0
  166. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  167. package/plugins/lisa-wiki-copilot/scripts/ingest-git.mjs +2 -0
  168. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  169. package/plugins/lisa-wiki-cursor/scripts/ingest-git.mjs +2 -0
  170. package/plugins/src/base/hooks/threshold-ratchet.mjs +6 -0
  171. package/plugins/src/base/hooks/worktree-binding-guard.mjs +31 -3
  172. package/plugins/src/base/scripts/design-variable-ids.mjs +2 -0
  173. package/plugins/src/base/skills/lisa-drive-pr-to-merge/SKILL.md +11 -0
  174. package/plugins/src/base/skills/lisa-secrets-access/scripts/bootstrap-store.mjs +3 -0
  175. package/plugins/src/base/skills/lisa-secrets-access/scripts/preflight-secrets.mjs +3 -0
  176. package/plugins/src/base/skills/lisa-secrets-access/scripts/providers.mjs +4 -0
  177. package/plugins/src/base/skills/lisa-setup-workstation/scripts/workstation.mjs +3 -0
  178. package/plugins/src/wiki/scripts/ingest-git.mjs +2 -0
  179. package/rails/copy-overwrite/scripts/check-threshold-ratchet.mjs +6 -0
  180. package/scripts/check-merge-driver-registration.mjs +2 -0
  181. package/scripts/check-probe-absence-direction.mjs +611 -0
  182. package/scripts/check-test-case-executed.mjs +184 -0
  183. package/scripts/install-generated-artifact-merge-driver.mjs +7 -1
  184. package/scripts/lib/shell-guard-refusal-coverage.mjs +18 -19
  185. package/typescript/copy-overwrite/scripts/check-threshold-ratchet.mjs +6 -0
  186. package/typescript/copy-overwrite/scripts/lisa-mutation.mjs +4 -0
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Decide whether a job SKIPS because its release job did not succeed
3
+ * (CodySwannGT/lisa#3740).
4
+ *
5
+ * ## The shape being detected
6
+ *
7
+ * GitHub renders a skipped job as neutral and counts a skipped required check
8
+ * as satisfied. So a deploy that never happened leaves no signal anywhere: the
9
+ * branch still carries its release commit, every status field still says green,
10
+ * and nothing prompts anyone to go read CI history for skipped Deploy jobs. A
11
+ * consuming repository ran eight days that way (#3467).
12
+ *
13
+ * Two spellings produce it, and neither says anything about skipping:
14
+ *
15
+ * - **No `if:` at all.** GitHub ANDs an implicit `success()` onto the job, so a
16
+ * failed release skips it silently. (The rails template's form.)
17
+ * - **An `if:` that names a status function but conjoins
18
+ * `needs.<release>.result == 'success'`.** The status function suppresses the
19
+ * implicit AND, and then the conjunct reintroduces it by hand. (The expo
20
+ * template's form.)
21
+ *
22
+ * ## Why this is answered semantically rather than by pattern
23
+ *
24
+ * Matching those two spellings would find the two templates and miss the third
25
+ * spelling a host wrote by hand — and, worse, would flag a job that skips for a
26
+ * reason having nothing to do with the release. The question is not "does this
27
+ * condition contain a string" but **"does the release result decide whether
28
+ * this job runs"**, and that is answered by evaluating the condition twice:
29
+ *
30
+ * - **released:** the release job reports `success`.
31
+ * - **failed:** the release job reports `failure`.
32
+ *
33
+ * A job that runs under the first and skips under the second is skipping
34
+ * because of the release. A job that skips under both — an unconfigured
35
+ * stack, a path filter, a deliberate `if:` about something else — is skipping
36
+ * for its own reasons and is not this defect. That is the acceptance criteria's
37
+ * third scenario satisfied by construction rather than by a special case.
38
+ *
39
+ * ## The most-permissive assignment, and what it can miss
40
+ *
41
+ * Both evaluations need values for the paths the condition reads that are not
42
+ * the release result — another job's output, a `github.*` field, an input.
43
+ * Those are assigned the value that makes the surrounding comparison hold: a
44
+ * path compared for equality against a literal takes that literal, and anything
45
+ * else takes a non-empty placeholder. The reading is "assuming everything else
46
+ * about this repository is configured, does the release result decide it".
47
+ *
48
+ * Stated rather than implied: this is one assignment, not a search. A condition
49
+ * whose release dependence only appears under some *other* combination of
50
+ * values is not reported. Under-reporting is the deliberate direction — a check
51
+ * that flags a deploy job for a skip it does not have is one that gets turned
52
+ * off, and then the real instances go unreported too.
53
+ *
54
+ * A condition the evaluator cannot parse yields `unreadable`, never `false`.
55
+ * @module core/deploy-release-dependence
56
+ */
57
+ import { jobRuns, tokenize, } from "./github-actions-condition.js";
58
+ /** Job ids and names that identify the job which cuts the release. */
59
+ const RELEASE_JOB = /(^|[_\-\s])(release|publish)([_\-\s]|$)/i;
60
+ /** Job ids and names that identify a job which ships to an environment. */
61
+ const DEPLOY_JOB = /deploy/i;
62
+ /** The value assigned to a free path with no equality comparison to borrow. */
63
+ const PLACEHOLDER = "lisa-permissive-placeholder";
64
+ /** Context roots whose values this analysis chooses, beyond `github.*`. */
65
+ const FREE_ROOTS = ["inputs"];
66
+ /**
67
+ * Whether an upstream job is the one that cuts the release.
68
+ *
69
+ * Name-based, and that is a stated limit rather than an oversight: a host free
70
+ * to name its jobs anything can name this one something with neither word in
71
+ * it, and such a job is not recognised. The alternative — treating every
72
+ * upstream job as release-like — would report a deploy that skips because an
73
+ * unrelated optional job failed, which is a different property.
74
+ * @param job - The candidate upstream job
75
+ * @returns True when the job looks like the release
76
+ */
77
+ export function isReleaseJob(job) {
78
+ return RELEASE_JOB.test(job.id) || RELEASE_JOB.test(job.name ?? "");
79
+ }
80
+ /**
81
+ * Whether a job ships something to an environment.
82
+ *
83
+ * A declared `environment:` is the name-independent half: GitHub's deployment
84
+ * environments exist for exactly this kind of job, so a host that used one has
85
+ * said what the job is without Lisa having to guess from its id.
86
+ * @param job - The candidate job
87
+ * @returns True when the job looks like a deploy
88
+ */
89
+ export function isDeployJob(job) {
90
+ return (DEPLOY_JOB.test(job.id) ||
91
+ DEPLOY_JOB.test(job.name ?? "") ||
92
+ (job.environment ?? []).length > 0);
93
+ }
94
+ /**
95
+ * The literal a path is compared against, when the comparison is an equality.
96
+ * @param tokens - The tokenized condition
97
+ * @param index - Position of the path token
98
+ * @returns The literal without its quotes, or null when there is none
99
+ */
100
+ function comparedLiteral(tokens, index) {
101
+ const quoted = (token) => token !== undefined && token.startsWith("'") ? token.slice(1, -1) : null;
102
+ if (tokens[index + 1] === "==")
103
+ return quoted(tokens[index + 2]);
104
+ if (tokens[index - 1] === "==")
105
+ return quoted(tokens[index - 2]);
106
+ return null;
107
+ }
108
+ /**
109
+ * Choose a value for every non-`needs.*.result` path the condition reads.
110
+ *
111
+ * A path compared for equality against a string literal takes that literal, so
112
+ * the comparison holds; every other path takes a non-empty placeholder, which
113
+ * is truthy and satisfies an inequality. The result is the run in which
114
+ * everything except the release is configured as the condition wants it.
115
+ * @param condition - The raw `if:` text
116
+ * @returns The chosen values, keyed by full dotted path
117
+ */
118
+ function permissiveAssignment(condition) {
119
+ const tokens = tokenize(condition
120
+ .trim()
121
+ .replace(/^\$\{\{/, "")
122
+ .replace(/\}\}$/, ""));
123
+ const isPath = (token) => /^[A-Za-z_][A-Za-z0-9_.-]*$/.test(token) && !token.endsWith(".result");
124
+ return Object.fromEntries(tokens.flatMap((token, index) => isPath(token)
125
+ ? [[token, comparedLiteral(tokens, index) ?? PLACEHOLDER]]
126
+ : []));
127
+ }
128
+ /** An assignment with nothing in it, and the seed for the fold below. */
129
+ const EMPTY_ASSIGNMENT = {
130
+ outputs: {},
131
+ github: {},
132
+ inputs: {},
133
+ };
134
+ /**
135
+ * Route one chosen path into the half of the scenario that owns it.
136
+ * @param split - The assignment built so far
137
+ * @param entry - One `[path, value]` pair
138
+ * @returns The assignment with that pair routed
139
+ */
140
+ function routePath(split, entry) {
141
+ const [path, value] = entry;
142
+ const segments = path.split(".");
143
+ const root = segments[0] ?? "";
144
+ if (root === "needs" && segments[2] === "outputs") {
145
+ const job = segments[1] ?? "";
146
+ return {
147
+ ...split,
148
+ outputs: {
149
+ ...split.outputs,
150
+ [job]: { ...split.outputs[job], [segments[3] ?? ""]: value },
151
+ },
152
+ };
153
+ }
154
+ if (root === "github") {
155
+ return { ...split, github: { ...split.github, [path]: value } };
156
+ }
157
+ return FREE_ROOTS.includes(root)
158
+ ? { ...split, inputs: { ...split.inputs, [segments[1] ?? ""]: value } }
159
+ : split;
160
+ }
161
+ /**
162
+ * Split the permissive assignment into the shapes the evaluator consumes.
163
+ * @param chosen - The permissive assignment
164
+ * @returns The `needs` outputs, `github.*` values and `inputs.*` values
165
+ */
166
+ function splitAssignment(chosen) {
167
+ return Object.entries(chosen).reduce((split, entry) => routePath(split, entry), EMPTY_ASSIGNMENT);
168
+ }
169
+ /**
170
+ * Build the run state for one release outcome.
171
+ * @param job - The job under analysis
172
+ * @param release - The release job's id
173
+ * @param releaseResult - What the release job reports in this scenario
174
+ * @param chosen - The permissive assignment
175
+ * @returns A scenario the evaluator can be run against
176
+ */
177
+ function scenarioFor(job, release, releaseResult, chosen) {
178
+ const { outputs, github, inputs } = splitAssignment(chosen);
179
+ return {
180
+ needs: Object.fromEntries(job.needs.map(id => [
181
+ id,
182
+ {
183
+ result: id === release ? releaseResult : "success",
184
+ outputs: outputs[id] ?? {},
185
+ },
186
+ ])),
187
+ github,
188
+ inputs,
189
+ cancelled: false,
190
+ };
191
+ }
192
+ /**
193
+ * Decide whether the release result is what makes this job skip.
194
+ * @param job - The job under analysis
195
+ * @param release - The id of the upstream release job
196
+ * @returns What the two evaluations established
197
+ */
198
+ export function releaseDependence(job, release) {
199
+ try {
200
+ const chosen = permissiveAssignment(job.ifCondition);
201
+ const runsWhenReleased = jobRuns(job.ifCondition, scenarioFor(job, release, "success", chosen));
202
+ const runsWhenFailed = jobRuns(job.ifCondition, scenarioFor(job, release, "failure", chosen));
203
+ return runsWhenReleased && !runsWhenFailed
204
+ ? { kind: "skips-on-failed-release", release }
205
+ : { kind: "independent" };
206
+ }
207
+ catch (error) {
208
+ return {
209
+ kind: "unreadable",
210
+ reason: error.message,
211
+ };
212
+ }
213
+ }
214
+ /**
215
+ * Find every deploy job in one workflow that skips when its release fails.
216
+ * @param jobs - Every job the workflow declares
217
+ * @returns The deploy jobs that go silent on a failed release
218
+ */
219
+ export function deployJobsSkippedByFailedRelease(jobs) {
220
+ const releases = new Set(jobs.filter(isReleaseJob).map(job => job.id));
221
+ return jobs.flatMap(job => {
222
+ if (releases.has(job.id) || !isDeployJob(job))
223
+ return [];
224
+ // Every release-like upstream, not merely the first. A deploy that needs
225
+ // two of them gates on ONE, and which one is not the order `needs:` happens
226
+ // to list. Taking the first and stopping reported `independent` whenever the
227
+ // gating release was listed second — the defect silently unreported, and the
228
+ // migration declining to repair it (CodeRabbit on CodySwannGT/lisa#3740).
229
+ const release = job.needs.find(id => releases.has(id) &&
230
+ releaseDependence(job, id).kind === "skips-on-failed-release");
231
+ if (release === undefined)
232
+ return [];
233
+ return [{ job, release }];
234
+ });
235
+ }
236
+ //# sourceMappingURL=deploy-release-dependence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy-release-dependence.js","sourceRoot":"","sources":["../../src/core/deploy-release-dependence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * A deliberately small evaluator for the subset of GitHub Actions expression
3
+ * syntax that Lisa's deploy workflows use in a job-level `if:`, plus the rule
4
+ * that turns the result into "this job RAN" or "this job was SKIPPED".
5
+ *
6
+ * It exists because the defect in #3467 is invisible to anything that only
7
+ * reads the YAML for the presence or absence of a substring. What went wrong
8
+ * was a job OUTCOME — a deploy that was skipped rather than failed — and an
9
+ * outcome is what has to be established. Lisa never runs a host's deploy
10
+ * workflow itself, so no observation of CI can stand in for that; the
11
+ * expression has to be evaluated against a scenario.
12
+ *
13
+ * ## Why this is production code and not a test helper
14
+ *
15
+ * It began as one, under `tests/integration/`. It moved here when #3740 needed
16
+ * the same question answered in a host repository — *would this job skip
17
+ * because the release failed?* — by `lisa doctor` and by the migration that
18
+ * repairs an already-seeded `deploy.yml`. Reimplementing GitHub's implicit
19
+ * `success()` rule a second time in `src/` would have put two subtly different
20
+ * copies of one semantics in the tree, which is the drift this repository
21
+ * repeatedly pays for. There is one implementation, and the test that made it
22
+ * imports it from here.
23
+ *
24
+ * The evaluator THROWS on anything outside the supported subset rather than
25
+ * guessing. An expression it cannot parse must never quietly evaluate to a
26
+ * plausible-looking boolean: a caller that cannot read a condition must say so,
27
+ * because reporting a confident verdict about an expression nobody understood
28
+ * is the failure mode this whole family of checks exists to catch.
29
+ *
30
+ * Supported: `&&`, `||`, `!`, `==`, `!=`, parentheses, single-quoted strings,
31
+ * `true`/`false`, the status functions `always()` / `cancelled()` / `success()`
32
+ * / `failure()`, the string functions `startsWith()` / `contains()`, and
33
+ * context paths under `needs.`, `github.` and `inputs.`.
34
+ * @module core/github-actions-condition
35
+ */
36
+ /** The four conclusions a `needs` job can report to a dependent job. */
37
+ export type JobResult = "success" | "failure" | "cancelled" | "skipped";
38
+ /** One upstream job as a dependent job sees it. */
39
+ export interface NeedsEntry {
40
+ readonly result: JobResult;
41
+ readonly outputs?: Readonly<Record<string, string>>;
42
+ }
43
+ /** The run state a job-level `if:` is evaluated against. */
44
+ export interface RunScenario {
45
+ readonly needs: Readonly<Record<string, NeedsEntry>>;
46
+ /** Flattened `github.*` paths, e.g. `github.event.head_commit.message`. */
47
+ readonly github: Readonly<Record<string, string>>;
48
+ /** Flattened `inputs.*` values. */
49
+ readonly inputs?: Readonly<Record<string, string>>;
50
+ /** Whether an operator cancelled the run. */
51
+ readonly cancelled: boolean;
52
+ }
53
+ /**
54
+ * Split an expression into tokens.
55
+ * @param source - Raw `if:` text, with any `${{ }}` wrapper already stripped
56
+ * @returns The token list
57
+ */
58
+ export declare function tokenize(source: string): readonly string[];
59
+ /**
60
+ * Evaluate a job-level `if:` under one scenario.
61
+ * @param condition - The raw `if:` text
62
+ * @param scenario - The run state
63
+ * @returns Whether the condition holds
64
+ */
65
+ export declare function evaluateCondition(condition: string, scenario: RunScenario): boolean;
66
+ /**
67
+ * Whether a job with this `if:` runs, applying GitHub's rule that an implicit
68
+ * `success()` is ANDed on unless the condition names a status function.
69
+ *
70
+ * That implicit AND is the whole mechanism behind the rails half of #3467: the
71
+ * condition there said nothing about the release at all, and still skipped when
72
+ * the release failed.
73
+ * @param condition - The raw `if:` text, or `""` when the job has none
74
+ * @param scenario - The run state
75
+ * @returns True when the job runs, false when GitHub skips it
76
+ */
77
+ export declare function jobRuns(condition: string, scenario: RunScenario): boolean;
78
+ //# sourceMappingURL=github-actions-condition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-actions-condition.d.ts","sourceRoot":"","sources":["../../src/core/github-actions-condition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,wEAAwE;AACxE,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;AAExE,mDAAmD;AACnD,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACrD;AAED,4DAA4D;AAC5D,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;IACrD,2EAA2E;IAC3E,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,mCAAmC;IACnC,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,6CAA6C;IAC7C,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;CAC7B;AA6CD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAO1D;AAyOD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,WAAW,GACpB,OAAO,CAYT;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,GAAG,OAAO,CAYzE"}
@@ -0,0 +1,307 @@
1
+ /**
2
+ * A deliberately small evaluator for the subset of GitHub Actions expression
3
+ * syntax that Lisa's deploy workflows use in a job-level `if:`, plus the rule
4
+ * that turns the result into "this job RAN" or "this job was SKIPPED".
5
+ *
6
+ * It exists because the defect in #3467 is invisible to anything that only
7
+ * reads the YAML for the presence or absence of a substring. What went wrong
8
+ * was a job OUTCOME — a deploy that was skipped rather than failed — and an
9
+ * outcome is what has to be established. Lisa never runs a host's deploy
10
+ * workflow itself, so no observation of CI can stand in for that; the
11
+ * expression has to be evaluated against a scenario.
12
+ *
13
+ * ## Why this is production code and not a test helper
14
+ *
15
+ * It began as one, under `tests/integration/`. It moved here when #3740 needed
16
+ * the same question answered in a host repository — *would this job skip
17
+ * because the release failed?* — by `lisa doctor` and by the migration that
18
+ * repairs an already-seeded `deploy.yml`. Reimplementing GitHub's implicit
19
+ * `success()` rule a second time in `src/` would have put two subtly different
20
+ * copies of one semantics in the tree, which is the drift this repository
21
+ * repeatedly pays for. There is one implementation, and the test that made it
22
+ * imports it from here.
23
+ *
24
+ * The evaluator THROWS on anything outside the supported subset rather than
25
+ * guessing. An expression it cannot parse must never quietly evaluate to a
26
+ * plausible-looking boolean: a caller that cannot read a condition must say so,
27
+ * because reporting a confident verdict about an expression nobody understood
28
+ * is the failure mode this whole family of checks exists to catch.
29
+ *
30
+ * Supported: `&&`, `||`, `!`, `==`, `!=`, parentheses, single-quoted strings,
31
+ * `true`/`false`, the status functions `always()` / `cancelled()` / `success()`
32
+ * / `failure()`, the string functions `startsWith()` / `contains()`, and
33
+ * context paths under `needs.`, `github.` and `inputs.`.
34
+ * @module core/github-actions-condition
35
+ */
36
+ /** The status functions whose presence removes GitHub's implicit `success()`. */
37
+ const STATUS_FUNCTIONS = ["always", "cancelled", "success", "failure"];
38
+ /** The two-character operators, matched before the single-character ones. */
39
+ const PAIR_OPERATORS = ["&&", "||", "==", "!="];
40
+ /**
41
+ * Read the single token at the head of the text.
42
+ * @param text - Expression text with leading whitespace already removed
43
+ * @returns The token, quotes included for a string literal
44
+ */
45
+ function headToken(text) {
46
+ if (text.startsWith("'")) {
47
+ const close = text.indexOf("'", 1);
48
+ if (close < 0) {
49
+ throw new Error(`unterminated string in expression: ${text}`);
50
+ }
51
+ return text.slice(0, close + 1);
52
+ }
53
+ if (PAIR_OPERATORS.includes(text.slice(0, 2))) {
54
+ return text.slice(0, 2);
55
+ }
56
+ if ("()!,".includes(text.slice(0, 1))) {
57
+ return text.slice(0, 1);
58
+ }
59
+ const word = /^[A-Za-z0-9_.-]+/.exec(text)?.[0];
60
+ if (!word) {
61
+ throw new Error(`unsupported character '${text.slice(0, 1)}' in expression`);
62
+ }
63
+ return word;
64
+ }
65
+ /**
66
+ * Split an expression into tokens.
67
+ * @param source - Raw `if:` text, with any `${{ }}` wrapper already stripped
68
+ * @returns The token list
69
+ */
70
+ export function tokenize(source) {
71
+ const text = source.trimStart();
72
+ if (text === "") {
73
+ return [];
74
+ }
75
+ const token = headToken(text);
76
+ return [token, ...tokenize(text.slice(token.length))];
77
+ }
78
+ /**
79
+ * GitHub's string-to-boolean cast: only the empty string is falsy.
80
+ * @param value - An evaluated operand
81
+ * @returns Its truthiness
82
+ */
83
+ function truthy(value) {
84
+ return typeof value === "boolean" ? value : value !== "";
85
+ }
86
+ /**
87
+ * GitHub compares strings case-insensitively; every operand here is a string or
88
+ * a boolean, so a normalized string comparison is the whole rule.
89
+ * @param left - Left operand
90
+ * @param right - Right operand
91
+ * @returns Whether the two are equal
92
+ */
93
+ function equal(left, right) {
94
+ return String(left).toLowerCase() === String(right).toLowerCase();
95
+ }
96
+ /**
97
+ * Resolve one `needs.*` path.
98
+ * @param segments - The dot-split path
99
+ * @param scenario - The run state
100
+ * @returns The value
101
+ */
102
+ function resolveNeeds(segments, scenario) {
103
+ const entry = scenario.needs[segments[1] ?? ""];
104
+ if (!entry) {
105
+ throw new Error(`expression reads ${segments.join(".")}, absent from needs`);
106
+ }
107
+ if (segments[2] === "result") {
108
+ return entry.result;
109
+ }
110
+ if (segments[2] !== "outputs") {
111
+ throw new Error(`unsupported needs path: ${segments.join(".")}`);
112
+ }
113
+ // A job that did not succeed publishes no outputs at all. Modelling that is
114
+ // load-bearing: `needs.x.outputs.y == 'true'` is the shape that silently
115
+ // turns an upstream failure into a skipped dependent.
116
+ return entry.result === "success"
117
+ ? (entry.outputs?.[segments[3] ?? ""] ?? "")
118
+ : "";
119
+ }
120
+ /**
121
+ * Resolve one dotted context path against the scenario.
122
+ * @param path - A path such as `needs.release.result`
123
+ * @param scenario - The run state
124
+ * @returns The value, or `""` for a path that resolves to nothing
125
+ */
126
+ function resolvePath(path, scenario) {
127
+ if (path === "true" || path === "false") {
128
+ return path === "true";
129
+ }
130
+ const segments = path.split(".");
131
+ if (segments[0] === "needs") {
132
+ return resolveNeeds(segments, scenario);
133
+ }
134
+ if (segments[0] === "github") {
135
+ return scenario.github[path] ?? "";
136
+ }
137
+ if (segments[0] === "inputs") {
138
+ return scenario.inputs?.[segments[1] ?? ""] ?? "";
139
+ }
140
+ throw new Error(`unsupported context path: ${path}`);
141
+ }
142
+ /**
143
+ * Evaluate a call to one of the supported functions.
144
+ * @param name - Function name
145
+ * @param args - Already-evaluated arguments
146
+ * @param scenario - The run state
147
+ * @returns The call's value
148
+ */
149
+ function callFunction(name, args, scenario) {
150
+ const results = Object.values(scenario.needs).map(entry => entry.result);
151
+ const first = String(args[0] ?? "").toLowerCase();
152
+ const second = String(args[1] ?? "").toLowerCase();
153
+ switch (name) {
154
+ case "always":
155
+ return true;
156
+ case "cancelled":
157
+ return scenario.cancelled;
158
+ case "success":
159
+ return !scenario.cancelled && results.every(r => r === "success");
160
+ case "failure":
161
+ return results.includes("failure");
162
+ case "startsWith":
163
+ return first.startsWith(second);
164
+ case "contains":
165
+ return first.includes(second);
166
+ default:
167
+ throw new Error(`unsupported function: ${name}()`);
168
+ }
169
+ }
170
+ /**
171
+ * Collect and evaluate a function call's arguments.
172
+ * @param tokens - The token list
173
+ * @param index - Position just after the opening parenthesis
174
+ * @param scenario - The run state
175
+ * @param collected - Arguments parsed so far
176
+ * @returns The arguments and the position just after the closing parenthesis
177
+ */
178
+ function callArguments(tokens, index, scenario, collected) {
179
+ if (tokens[index] === ")") {
180
+ return { args: collected, index: index + 1 };
181
+ }
182
+ const argument = expression(tokens, index, scenario);
183
+ const next = tokens[argument.index] === "," ? argument.index + 1 : argument.index;
184
+ return callArguments(tokens, next, scenario, [...collected, argument.value]);
185
+ }
186
+ /**
187
+ * Parse and evaluate a primary term: a negation, a parenthesized expression, a
188
+ * string literal, a function call, or a context path.
189
+ * @param tokens - The token list
190
+ * @param index - Position of the term's first token
191
+ * @param scenario - The run state
192
+ * @returns The term's value and the position after it
193
+ */
194
+ function primary(tokens, index, scenario) {
195
+ const token = tokens[index];
196
+ if (token === undefined) {
197
+ throw new Error("expression ended early");
198
+ }
199
+ if (token === "!") {
200
+ const inner = primary(tokens, index + 1, scenario);
201
+ return { value: !truthy(inner.value), index: inner.index };
202
+ }
203
+ if (token === "(") {
204
+ const inner = expression(tokens, index + 1, scenario);
205
+ if (tokens[inner.index] !== ")") {
206
+ throw new Error("unbalanced parentheses in expression");
207
+ }
208
+ return { value: inner.value, index: inner.index + 1 };
209
+ }
210
+ if (token.startsWith("'")) {
211
+ return { value: token.slice(1, -1), index: index + 1 };
212
+ }
213
+ if (tokens[index + 1] === "(") {
214
+ const call = callArguments(tokens, index + 2, scenario, []);
215
+ return {
216
+ value: callFunction(token, call.args, scenario),
217
+ index: call.index,
218
+ };
219
+ }
220
+ return { value: resolvePath(token, scenario), index: index + 1 };
221
+ }
222
+ /**
223
+ * Parse and evaluate an equality comparison.
224
+ * @param tokens - The token list
225
+ * @param index - Position of the comparison's first token
226
+ * @param scenario - The run state
227
+ * @returns The comparison's value and the position after it
228
+ */
229
+ function comparison(tokens, index, scenario) {
230
+ const left = primary(tokens, index, scenario);
231
+ const operator = tokens[left.index];
232
+ if (operator !== "==" && operator !== "!=") {
233
+ return left;
234
+ }
235
+ const right = primary(tokens, left.index + 1, scenario);
236
+ const same = equal(left.value, right.value);
237
+ return { value: operator === "==" ? same : !same, index: right.index };
238
+ }
239
+ /**
240
+ * Fold the `&&` / `||` operators that follow an already-parsed operand.
241
+ * @param left - The operand parsed so far
242
+ * @param tokens - The token list
243
+ * @param scenario - The run state
244
+ * @returns The folded value and the position after it
245
+ */
246
+ function logicalTail(left, tokens, scenario) {
247
+ const operator = tokens[left.index];
248
+ if (operator !== "&&" && operator !== "||") {
249
+ return left;
250
+ }
251
+ const right = comparison(tokens, left.index + 1, scenario);
252
+ const value = operator === "&&"
253
+ ? truthy(left.value) && truthy(right.value)
254
+ : truthy(left.value) || truthy(right.value);
255
+ return logicalTail({ value, index: right.index }, tokens, scenario);
256
+ }
257
+ /**
258
+ * Parse and evaluate a full expression.
259
+ * @param tokens - The token list
260
+ * @param index - Position of the expression's first token
261
+ * @param scenario - The run state
262
+ * @returns The expression's value and the position after it
263
+ */
264
+ function expression(tokens, index, scenario) {
265
+ return logicalTail(comparison(tokens, index, scenario), tokens, scenario);
266
+ }
267
+ /**
268
+ * Evaluate a job-level `if:` under one scenario.
269
+ * @param condition - The raw `if:` text
270
+ * @param scenario - The run state
271
+ * @returns Whether the condition holds
272
+ */
273
+ export function evaluateCondition(condition, scenario) {
274
+ const stripped = condition
275
+ .trim()
276
+ .replace(/^\$\{\{/, "")
277
+ .replace(/\}\}$/, "")
278
+ .trim();
279
+ const tokens = tokenize(stripped);
280
+ const parsed = expression(tokens, 0, scenario);
281
+ if (parsed.index !== tokens.length) {
282
+ throw new Error(`unparsed tail in expression: ${condition}`);
283
+ }
284
+ return truthy(parsed.value);
285
+ }
286
+ /**
287
+ * Whether a job with this `if:` runs, applying GitHub's rule that an implicit
288
+ * `success()` is ANDed on unless the condition names a status function.
289
+ *
290
+ * That implicit AND is the whole mechanism behind the rails half of #3467: the
291
+ * condition there said nothing about the release at all, and still skipped when
292
+ * the release failed.
293
+ * @param condition - The raw `if:` text, or `""` when the job has none
294
+ * @param scenario - The run state
295
+ * @returns True when the job runs, false when GitHub skips it
296
+ */
297
+ export function jobRuns(condition, scenario) {
298
+ const results = Object.values(scenario.needs).map(entry => entry.result);
299
+ const dependenciesSucceeded = !scenario.cancelled && results.every(result => result === "success");
300
+ if (condition.trim() === "") {
301
+ return dependenciesSucceeded;
302
+ }
303
+ const namesStatusFunction = STATUS_FUNCTIONS.some(name => new RegExp(`\\b${name}\\s*\\(`).test(condition));
304
+ const holds = evaluateCondition(condition, scenario);
305
+ return namesStatusFunction ? holds : holds && dependenciesSucceeded;
306
+ }
307
+ //# sourceMappingURL=github-actions-condition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-actions-condition.js","sourceRoot":"","sources":["../../src/core/github-actions-condition.ts"],"names":[],"mappings":"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"}
@@ -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,CAyiCjC,CAAC;AAEH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,+BAA+B,EAAE,QAAQ,CACpD,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CA48BjC,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,CAqjCjC,CAAC;AAEH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,+BAA+B,EAAE,QAAQ,CACpD,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC,CAw9BjC,CAAC"}