@codyswann/lisa 4.21.5 → 4.22.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 (130) hide show
  1. package/all/copy-overwrite/scripts/lisa-environment-prepare.mjs +28 -12
  2. package/dist/cli/doctor-nightly-e2e-guard-command-files.d.ts +19 -0
  3. package/dist/cli/doctor-nightly-e2e-guard-command-files.d.ts.map +1 -0
  4. package/dist/cli/doctor-nightly-e2e-guard-command-files.js +221 -0
  5. package/dist/cli/doctor-nightly-e2e-guard-command-files.js.map +1 -0
  6. package/dist/cli/doctor-nightly-e2e-guard-contract.d.ts +113 -0
  7. package/dist/cli/doctor-nightly-e2e-guard-contract.d.ts.map +1 -0
  8. package/dist/cli/doctor-nightly-e2e-guard-contract.js +87 -0
  9. package/dist/cli/doctor-nightly-e2e-guard-contract.js.map +1 -0
  10. package/dist/cli/doctor-nightly-e2e-guard-deadline.d.ts +61 -0
  11. package/dist/cli/doctor-nightly-e2e-guard-deadline.d.ts.map +1 -0
  12. package/dist/cli/doctor-nightly-e2e-guard-deadline.js +97 -0
  13. package/dist/cli/doctor-nightly-e2e-guard-deadline.js.map +1 -0
  14. package/dist/cli/doctor-nightly-e2e-guard-evidence.d.ts +52 -0
  15. package/dist/cli/doctor-nightly-e2e-guard-evidence.d.ts.map +1 -0
  16. package/dist/cli/doctor-nightly-e2e-guard-evidence.js +68 -0
  17. package/dist/cli/doctor-nightly-e2e-guard-evidence.js.map +1 -0
  18. package/dist/cli/doctor-nightly-e2e-guard-graph.d.ts +14 -0
  19. package/dist/cli/doctor-nightly-e2e-guard-graph.d.ts.map +1 -0
  20. package/dist/cli/doctor-nightly-e2e-guard-graph.js +130 -0
  21. package/dist/cli/doctor-nightly-e2e-guard-graph.js.map +1 -0
  22. package/dist/cli/doctor-nightly-e2e-guard-io.d.ts +41 -0
  23. package/dist/cli/doctor-nightly-e2e-guard-io.d.ts.map +1 -0
  24. package/dist/cli/doctor-nightly-e2e-guard-io.js +239 -0
  25. package/dist/cli/doctor-nightly-e2e-guard-io.js.map +1 -0
  26. package/dist/cli/doctor-nightly-e2e-guard-job.d.ts +31 -0
  27. package/dist/cli/doctor-nightly-e2e-guard-job.d.ts.map +1 -0
  28. package/dist/cli/doctor-nightly-e2e-guard-job.js +156 -0
  29. package/dist/cli/doctor-nightly-e2e-guard-job.js.map +1 -0
  30. package/dist/cli/doctor-nightly-e2e-guard-proof.d.ts +42 -0
  31. package/dist/cli/doctor-nightly-e2e-guard-proof.d.ts.map +1 -0
  32. package/dist/cli/doctor-nightly-e2e-guard-proof.js +57 -0
  33. package/dist/cli/doctor-nightly-e2e-guard-proof.js.map +1 -0
  34. package/dist/cli/doctor-nightly-e2e-guard-remediation.d.ts +32 -0
  35. package/dist/cli/doctor-nightly-e2e-guard-remediation.d.ts.map +1 -0
  36. package/dist/cli/doctor-nightly-e2e-guard-remediation.js +55 -0
  37. package/dist/cli/doctor-nightly-e2e-guard-remediation.js.map +1 -0
  38. package/dist/cli/doctor-nightly-e2e-guard-runtime.d.ts +34 -0
  39. package/dist/cli/doctor-nightly-e2e-guard-runtime.d.ts.map +1 -0
  40. package/dist/cli/doctor-nightly-e2e-guard-runtime.js +93 -0
  41. package/dist/cli/doctor-nightly-e2e-guard-runtime.js.map +1 -0
  42. package/dist/cli/doctor-nightly-e2e-guard-scan.d.ts +17 -0
  43. package/dist/cli/doctor-nightly-e2e-guard-scan.d.ts.map +1 -0
  44. package/dist/cli/doctor-nightly-e2e-guard-scan.js +86 -0
  45. package/dist/cli/doctor-nightly-e2e-guard-scan.js.map +1 -0
  46. package/dist/cli/doctor-nightly-e2e-guard-shell-lexer.d.ts +38 -0
  47. package/dist/cli/doctor-nightly-e2e-guard-shell-lexer.d.ts.map +1 -0
  48. package/dist/cli/doctor-nightly-e2e-guard-shell-lexer.js +160 -0
  49. package/dist/cli/doctor-nightly-e2e-guard-shell-lexer.js.map +1 -0
  50. package/dist/cli/doctor-nightly-e2e-guard-shell.d.ts +40 -0
  51. package/dist/cli/doctor-nightly-e2e-guard-shell.d.ts.map +1 -0
  52. package/dist/cli/doctor-nightly-e2e-guard-shell.js +201 -0
  53. package/dist/cli/doctor-nightly-e2e-guard-shell.js.map +1 -0
  54. package/dist/cli/doctor-nightly-e2e-guard.d.ts +36 -0
  55. package/dist/cli/doctor-nightly-e2e-guard.d.ts.map +1 -0
  56. package/dist/cli/doctor-nightly-e2e-guard.js +186 -0
  57. package/dist/cli/doctor-nightly-e2e-guard.js.map +1 -0
  58. package/dist/cli/doctor.d.ts.map +1 -1
  59. package/dist/cli/doctor.js +7 -0
  60. package/dist/cli/doctor.js.map +1 -1
  61. package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
  62. package/dist/core/lisa-owned-hash-ledger.js +2 -0
  63. package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
  64. package/dist/core/nightly-e2e-guard-behavior-certificate.d.ts +25 -0
  65. package/dist/core/nightly-e2e-guard-behavior-certificate.d.ts.map +1 -0
  66. package/dist/core/nightly-e2e-guard-behavior-certificate.js +30 -0
  67. package/dist/core/nightly-e2e-guard-behavior-certificate.js.map +1 -0
  68. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  69. package/dist/core/upstream-evidence-manifest.js +32 -5
  70. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  71. package/dist/migrations/ensure-playwright-dedicated-caller.d.ts +0 -2
  72. package/dist/migrations/ensure-playwright-dedicated-caller.d.ts.map +1 -1
  73. package/dist/migrations/ensure-playwright-dedicated-caller.js +12 -40
  74. package/dist/migrations/ensure-playwright-dedicated-caller.js.map +1 -1
  75. package/expo/create-only/.github/workflows/maestro-e2e.yml +6 -0
  76. package/expo/create-only/.github/workflows/playwright-e2e.yml +5 -5
  77. package/package.json +5 -3
  78. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  80. package/plugins/lisa-agy/plugin.json +1 -1
  81. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  83. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  84. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  85. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  86. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  90. package/plugins/lisa-expo-agy/plugin.json +1 -1
  91. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  95. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  96. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  97. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  98. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  99. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  100. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  101. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  102. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  103. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  104. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  105. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  106. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  107. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  108. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  109. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  110. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  111. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  112. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  113. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  114. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  115. package/plugins/lisa-rails-agy/plugin.json +1 -1
  116. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  117. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  118. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  119. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  120. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  121. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  122. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  123. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  124. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  125. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  126. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  127. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  128. package/scripts/check-derived-artifacts.mjs +32 -5
  129. package/scripts/generate-nightly-e2e-guard-certificate.mjs +370 -0
  130. package/scripts/two-channel-couplings.json +16 -4
@@ -0,0 +1,239 @@
1
+ /**
2
+ * @file doctor-nightly-e2e-guard-io.ts
3
+ * @description Bounded no-follow reads for hostile workflow and target paths
4
+ * @module cli/doctor-nightly-e2e-guard-io
5
+ */
6
+ import { constants } from "node:fs";
7
+ import { lstat, open, readdir, realpath } from "node:fs/promises";
8
+ import * as path from "node:path";
9
+ import { NightlyGuardDeadlineError, nightlyGuardRemaining, withinNightlyGuardDeadline, } from "./doctor-nightly-e2e-guard-deadline.js";
10
+ const errorCode = (error) => error.code;
11
+ const displayError = (error) => error instanceof Error ? error.message : String(error);
12
+ const rethrowDeadline = (error) => {
13
+ if (error instanceof NightlyGuardDeadlineError)
14
+ throw error;
15
+ };
16
+ const identity = (stats) => ({
17
+ device: stats.dev,
18
+ inode: stats.ino,
19
+ });
20
+ const sameIdentity = (left, right) => left.device === right.device && left.inode === right.inode;
21
+ const byteLimit = (bytes) => bytes === 1024 * 1024 ? "1 MiB" : `${bytes} byte`;
22
+ const safeParts = (relativePath) => {
23
+ if (path.isAbsolute(relativePath))
24
+ return undefined;
25
+ const parts = relativePath.split(/[\\/]/u);
26
+ return parts.length > 0 &&
27
+ parts.every(part => part !== "" && part !== "." && part !== "..")
28
+ ? parts
29
+ : undefined;
30
+ };
31
+ const unavailable = (reason) => ({
32
+ state: "unavailable",
33
+ reason,
34
+ });
35
+ /**
36
+ * Walk every project-relative component with lstat, rejecting symlinks before
37
+ * any directory or file operation can follow them.
38
+ * @param projectRoot - Logical project containment root
39
+ * @param relativePath - Validated relative path
40
+ * @param deadline - Shared whole-operation deadline
41
+ * @returns Final component identity or an exact refusal
42
+ */
43
+ async function inspectComponents(projectRoot, relativePath, deadline) {
44
+ const parts = safeParts(relativePath);
45
+ if (!parts)
46
+ return unavailable("path escapes the project root");
47
+ const inspect = async (index) => {
48
+ const current = path.join(projectRoot, ...parts.slice(0, index + 1));
49
+ if (nightlyGuardRemaining(deadline) <= 0) {
50
+ throw new NightlyGuardDeadlineError(deadline.reason);
51
+ }
52
+ const inspected = await withinNightlyGuardDeadline(deadline, () => lstat(current)).catch(error => {
53
+ rethrowDeadline(error);
54
+ const code = errorCode(error);
55
+ return code === "ENOENT"
56
+ ? { state: "missing", reason: `${relativePath} is missing` }
57
+ : unavailable(`${relativePath} is unreadable (${code ?? displayError(error)})`);
58
+ });
59
+ if ("state" in inspected)
60
+ return inspected;
61
+ const stats = inspected;
62
+ if (stats.isSymbolicLink()) {
63
+ return unavailable(`${parts.slice(0, index + 1).join("/")} is a symlink`);
64
+ }
65
+ if (index < parts.length - 1 && !stats.isDirectory()) {
66
+ return unavailable(`${parts.slice(0, index + 1).join("/")} is not a directory`);
67
+ }
68
+ return index === parts.length - 1
69
+ ? { state: "ok", final: stats }
70
+ : await inspect(index + 1);
71
+ };
72
+ return await inspect(0);
73
+ }
74
+ const isContained = (root, target) => {
75
+ const relative = path.relative(root, target);
76
+ return (relative !== "" &&
77
+ relative !== ".." &&
78
+ !relative.startsWith(`..${path.sep}`) &&
79
+ !path.isAbsolute(relative));
80
+ };
81
+ /**
82
+ * Verify the opened inode is still the contained, non-symlink path immediately
83
+ * before its bytes become proof evidence.
84
+ * @param projectRoot - Logical containment root
85
+ * @param relativePath - Path whose components are rechecked
86
+ * @param opened - Inode identity captured from the file descriptor
87
+ * @param deadline - Shared deadline
88
+ * @returns Reverified component result
89
+ */
90
+ async function verifyIdentity(projectRoot, relativePath, opened, deadline) {
91
+ const inspected = await inspectComponents(projectRoot, relativePath, deadline);
92
+ if (inspected.state !== "ok")
93
+ return inspected;
94
+ if (!sameIdentity(opened, identity(inspected.final))) {
95
+ return unavailable(`${relativePath} changed identity while it was read`);
96
+ }
97
+ try {
98
+ const [physicalRoot, physicalTarget] = await withinNightlyGuardDeadline(deadline, () => Promise.all([
99
+ realpath(projectRoot),
100
+ realpath(path.join(projectRoot, relativePath)),
101
+ ]));
102
+ return isContained(physicalRoot, physicalTarget)
103
+ ? inspected
104
+ : unavailable(`${relativePath} is not contained by the project root`);
105
+ }
106
+ catch (error) {
107
+ rethrowDeadline(error);
108
+ return unavailable(`${relativePath} containment is unreadable (${errorCode(error) ?? displayError(error)})`);
109
+ }
110
+ }
111
+ /**
112
+ * Read at most `maxBytes + 1` through an already no-follow file descriptor.
113
+ * @param handle - Open no-follow file descriptor
114
+ * @param maxBytes - Hard content ceiling
115
+ * @param deadline - Shared deadline
116
+ * @returns Bounded bytes, including one overflow sentinel byte when present
117
+ */
118
+ async function readBounded(handle, maxBytes, deadline) {
119
+ const buffer = Buffer.alloc(maxBytes + 1);
120
+ const readAt = async (offset) => {
121
+ if (offset >= buffer.length)
122
+ return offset;
123
+ if (nightlyGuardRemaining(deadline) <= 0) {
124
+ throw new NightlyGuardDeadlineError(deadline.reason);
125
+ }
126
+ const { bytesRead } = await withinNightlyGuardDeadline(deadline, () => handle.read(buffer, offset, buffer.length - offset, offset));
127
+ return bytesRead === 0 ? offset : await readAt(offset + bytesRead);
128
+ };
129
+ const used = await readAt(0);
130
+ return buffer.subarray(0, used);
131
+ }
132
+ const openNightlyGuardFile = async (projectRoot, relativePath, deadline) => await withinNightlyGuardDeadline(deadline, () => open(path.join(projectRoot, relativePath), constants.O_RDONLY | constants.O_NOFOLLOW)).then(handle => ({ state: "ok", handle }), error => {
133
+ rethrowDeadline(error);
134
+ const code = errorCode(error);
135
+ return code === "ENOENT"
136
+ ? { state: "missing", reason: `${relativePath} is missing` }
137
+ : {
138
+ state: "unavailable",
139
+ reason: `${relativePath} is unreadable (${code ?? displayError(error)})`,
140
+ };
141
+ });
142
+ /**
143
+ * Read one regular file without following any path component.
144
+ * @param projectRoot - Containment root
145
+ * @param relativePath - Project-relative path
146
+ * @param maxBytes - Hard byte ceiling
147
+ * @param deadline - Shared deadline
148
+ * @returns Bounded bytes or a precise availability class
149
+ */
150
+ export async function readNightlyGuardFile(projectRoot, relativePath, maxBytes, deadline) {
151
+ const inspected = await inspectComponents(projectRoot, relativePath, deadline);
152
+ if (inspected.state !== "ok")
153
+ return inspected;
154
+ if (!inspected.final.isFile()) {
155
+ return {
156
+ state: "unavailable",
157
+ reason: `${relativePath} is not a regular file`,
158
+ };
159
+ }
160
+ if (inspected.final.size > maxBytes) {
161
+ return {
162
+ state: "unavailable",
163
+ reason: `${relativePath} exceeds the ${byteLimit(maxBytes)} file limit`,
164
+ };
165
+ }
166
+ const opened = await openNightlyGuardFile(projectRoot, relativePath, deadline);
167
+ if (opened.state !== "ok")
168
+ return opened;
169
+ const handle = opened.handle;
170
+ try {
171
+ const stats = await withinNightlyGuardDeadline(deadline, () => handle.stat());
172
+ if (!stats.isFile()) {
173
+ return {
174
+ state: "unavailable",
175
+ reason: `${relativePath} is not a regular file`,
176
+ };
177
+ }
178
+ const bytes = await readBounded(handle, maxBytes, deadline);
179
+ if (bytes.length > maxBytes) {
180
+ return {
181
+ state: "unavailable",
182
+ reason: `${relativePath} exceeds the ${byteLimit(maxBytes)} file limit`,
183
+ };
184
+ }
185
+ const verified = await verifyIdentity(projectRoot, relativePath, identity(stats), deadline);
186
+ return verified.state === "ok" ? { state: "ok", bytes } : verified;
187
+ }
188
+ catch (error) {
189
+ rethrowDeadline(error);
190
+ return {
191
+ state: "unavailable",
192
+ reason: `${relativePath} is unreadable (${errorCode(error) ?? displayError(error)})`,
193
+ };
194
+ }
195
+ finally {
196
+ await handle.close();
197
+ }
198
+ }
199
+ /**
200
+ * List a directory only when every component and its identity remain safe.
201
+ * @param projectRoot - Containment root
202
+ * @param relativePath - Project-relative directory
203
+ * @param deadline - Shared deadline
204
+ * @returns Directory entries or an availability refusal
205
+ */
206
+ export async function readNightlyGuardDirectory(projectRoot, relativePath, deadline) {
207
+ const before = await inspectComponents(projectRoot, relativePath, deadline);
208
+ if (before.state !== "ok")
209
+ return before;
210
+ if (!before.final.isDirectory()) {
211
+ return {
212
+ state: "unavailable",
213
+ reason: `${relativePath} is not a directory`,
214
+ };
215
+ }
216
+ try {
217
+ const names = await withinNightlyGuardDeadline(deadline, () => readdir(path.join(projectRoot, relativePath)));
218
+ const after = await inspectComponents(projectRoot, relativePath, deadline);
219
+ if (after.state !== "ok")
220
+ return after;
221
+ return sameIdentity(identity(before.final), identity(after.final))
222
+ ? { state: "ok", names }
223
+ : {
224
+ state: "unavailable",
225
+ reason: `${relativePath} changed identity while it was listed`,
226
+ };
227
+ }
228
+ catch (error) {
229
+ rethrowDeadline(error);
230
+ const code = errorCode(error);
231
+ return code === "ENOENT"
232
+ ? { state: "missing", reason: `${relativePath} is missing` }
233
+ : {
234
+ state: "unavailable",
235
+ reason: `${relativePath} is unreadable (${code ?? displayError(error)})`,
236
+ };
237
+ }
238
+ }
239
+ //# sourceMappingURL=doctor-nightly-e2e-guard-io.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-nightly-e2e-guard-io.js","sourceRoot":"","sources":["../../src/cli/doctor-nightly-e2e-guard-io.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * @file doctor-nightly-e2e-guard-job.ts
3
+ * @description Executable-field parsing for one reachable workflow job
4
+ * @module cli/doctor-nightly-e2e-guard-job
5
+ */
6
+ import { type NightlyGuardScanFailure, type NightlyGuardWorkflowRecord } from "./doctor-nightly-e2e-guard-contract.js";
7
+ /** Supported active target resolved from one job. */
8
+ export interface NightlyGuardJobCaller {
9
+ /** Direct Node invocation or Lisa's exact official reusable endpoint. */
10
+ readonly kind: "official-reusable" | "direct";
11
+ /** Literal normalized target path. */
12
+ readonly target: string;
13
+ }
14
+ /** Executable interpretation of one reachable job. */
15
+ export interface NightlyGuardJobInspection {
16
+ /** Guard caller when this job directly invokes one. */
17
+ readonly caller?: NightlyGuardJobCaller;
18
+ /** Local reusable basename when this job calls one. */
19
+ readonly local?: string;
20
+ /** Fail-closed ambiguity or unsupported syntax. */
21
+ readonly failure?: NightlyGuardScanFailure;
22
+ }
23
+ /**
24
+ * Interpret one reachable executable job without scanning prose or comments.
25
+ * @param workflow - Parsed workflow containing the job
26
+ * @param jobId - Stable job mapping key
27
+ * @param job - Parsed job mapping
28
+ * @returns Direct caller, local edge, or an explicit refusal
29
+ */
30
+ export declare function inspectNightlyGuardJob(workflow: NightlyGuardWorkflowRecord, jobId: string, job: Readonly<Record<string, unknown>>): NightlyGuardJobInspection;
31
+ //# sourceMappingURL=doctor-nightly-e2e-guard-job.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-nightly-e2e-guard-job.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-nightly-e2e-guard-job.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAEL,KAAK,uBAAuB,EAC5B,KAAK,0BAA0B,EAIhC,MAAM,wCAAwC,CAAC;AAchD,qDAAqD;AACrD,MAAM,WAAW,qBAAqB;IACpC,yEAAyE;IACzE,QAAQ,CAAC,IAAI,EAAE,mBAAmB,GAAG,QAAQ,CAAC;IAC9C,sCAAsC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,sDAAsD;AACtD,MAAM,WAAW,yBAAyB;IACxC,uDAAuD;IACvD,QAAQ,CAAC,MAAM,CAAC,EAAE,qBAAqB,CAAC;IACxC,uDAAuD;IACvD,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB,mDAAmD;IACnD,QAAQ,CAAC,OAAO,CAAC,EAAE,uBAAuB,CAAC;CAC5C;AA4MD;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CACpC,QAAQ,EAAE,0BAA0B,EACpC,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,GACrC,yBAAyB,CAmB3B"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * @file doctor-nightly-e2e-guard-job.ts
3
+ * @description Executable-field parsing for one reachable workflow job
4
+ * @module cli/doctor-nightly-e2e-guard-job
5
+ */
6
+ import { NIGHTLY_GUARD_CANONICAL_TARGET, nightlyGuardObject, nightlyGuardText, normalizeNightlyGuardTarget, } from "./doctor-nightly-e2e-guard-contract.js";
7
+ import { bypassBearingMapping, hasAnyNightlyGuardBypassEvidence, inspectNightlyGuardJobEvidence, } from "./doctor-nightly-e2e-guard-evidence.js";
8
+ const OFFICIAL_PREFIX = "CodySwannGT/lisa/.github/workflows/nightly-e2e-health.yml@";
9
+ const OFFICIAL_REF = /^[^\s${}]+$/u;
10
+ const LOCAL = /^\.\/\.github\/workflows\/([A-Za-z0-9._-]+\.ya?ml)$/u;
11
+ const failure = (workflow, reason) => ({ workflow: workflow.file, reason });
12
+ const indirectReusableBypassEvidence = (evidence) => evidence.inheritedEnvironment || evidence.stepEnvironment || evidence.run;
13
+ const inspectOfficial = (workflow, jobId, job, evidence) => {
14
+ const uses = nightlyGuardText(job.uses);
15
+ if (!uses.startsWith(OFFICIAL_PREFIX))
16
+ return undefined;
17
+ if (evidence.condition) {
18
+ return {
19
+ failure: failure(workflow, `${jobId}: executable if bypass-label logic can skip the guard and is unsupported`),
20
+ };
21
+ }
22
+ if (indirectReusableBypassEvidence(evidence)) {
23
+ return {
24
+ failure: failure(workflow, `${jobId}: indirect bypass environment or run logic around the official reusable is unsupported`),
25
+ };
26
+ }
27
+ const reference = uses.slice(OFFICIAL_PREFIX.length);
28
+ if (!OFFICIAL_REF.test(reference)) {
29
+ return {
30
+ failure: failure(workflow, `${jobId}: official reusable reference is not a static literal`),
31
+ };
32
+ }
33
+ const input = nightlyGuardObject(job.with)?.guard_script;
34
+ const candidate = input === undefined
35
+ ? NIGHTLY_GUARD_CANONICAL_TARGET
36
+ : nightlyGuardText(input);
37
+ const target = normalizeNightlyGuardTarget(candidate);
38
+ return target
39
+ ? { caller: { kind: "official-reusable", target } }
40
+ : {
41
+ failure: failure(workflow, `${jobId}: with.guard_script must be one literal contained relative ASCII JavaScript path`),
42
+ };
43
+ };
44
+ const conditionalFailure = (workflow, jobId, evidence) => evidence.condition &&
45
+ (evidence.hasNode ||
46
+ evidence.inheritedEnvironment ||
47
+ evidence.stepEnvironment)
48
+ ? failure(workflow, `${jobId}: executable if bypass-label logic can skip the guard and is unsupported`)
49
+ : undefined;
50
+ const runBypassFailure = (workflow, jobId, evidence) => {
51
+ if (!evidence.run || !evidence.hasNode)
52
+ return undefined;
53
+ const guard = evidence.analyses.findIndex(analysis => analysis.target);
54
+ const bypassAnalysis = evidence.analyses.find((analysis, index) => analysis.bypassEvidence &&
55
+ !(guard >= 0 &&
56
+ index > guard &&
57
+ (analysis.commandFileWrites?.length ?? 0) > 0));
58
+ if (!bypassAnalysis)
59
+ return undefined;
60
+ return failure(workflow, bypassAnalysis.bypassWiring === "GITHUB_ENV"
61
+ ? `${jobId}: indirect GITHUB_ENV bypass wiring is unsupported; use a literal YAML env mapping`
62
+ : `${jobId}: executable run bypass wiring is unsupported; use a literal YAML env mapping`);
63
+ };
64
+ const commandFileFailure = (workflow, jobId, evidence) => {
65
+ const guard = evidence.analyses.findIndex(analysis => analysis.target);
66
+ if (guard < 0)
67
+ return undefined;
68
+ const write = evidence.analyses
69
+ .slice(0, guard)
70
+ .flatMap(analysis => analysis.commandFileWrites ?? [])
71
+ .find(candidate => candidate.safety !== "safe");
72
+ return write
73
+ ? failure(workflow, write.file === "GITHUB_PATH"
74
+ ? `${jobId}: ${write.safety} GITHUB_PATH write can change command resolution before guard execution`
75
+ : `${jobId}: ${write.safety} GITHUB_ENV write cannot prove a safe environment before guard execution`)
76
+ : undefined;
77
+ };
78
+ const directResult = (workflow, jobId, relevant) => {
79
+ const refused = relevant.find(item => item.reason)?.reason;
80
+ if (refused)
81
+ return { failure: failure(workflow, `${jobId}: ${refused}`) };
82
+ const targets = relevant.flatMap(item => (item.target ? [item.target] : []));
83
+ if (targets.length === 1) {
84
+ return { caller: { kind: "direct", target: targets[0] ?? "" } };
85
+ }
86
+ if (targets.length === 0 && relevant.every(step => step.reportingOnly)) {
87
+ return {};
88
+ }
89
+ return {
90
+ failure: failure(workflow, targets.length === 0
91
+ ? `${jobId}: bypass-bearing job has no supported literal Node guard target`
92
+ : `${jobId}: multiple Node guard targets are ambiguous`),
93
+ };
94
+ };
95
+ const inspectDirect = (workflow, jobId, evidence) => {
96
+ const condition = conditionalFailure(workflow, jobId, evidence);
97
+ if (condition)
98
+ return { failure: condition };
99
+ if (evidence.withMapping && evidence.hasNode) {
100
+ return {
101
+ failure: failure(workflow, `${jobId}: bypass-bearing with inputs on a direct job are unsupported`),
102
+ };
103
+ }
104
+ const commandFile = commandFileFailure(workflow, jobId, evidence);
105
+ if (commandFile)
106
+ return { failure: commandFile };
107
+ const runBypass = runBypassFailure(workflow, jobId, evidence);
108
+ if (runBypass)
109
+ return { failure: runBypass };
110
+ const relevant = evidence.analyses.filter((_analysis, index) => evidence.inheritedEnvironment ||
111
+ bypassBearingMapping(evidence.steps[index]?.env));
112
+ return relevant.length === 0 ? {} : directResult(workflow, jobId, relevant);
113
+ };
114
+ const inspectLocal = (workflow, jobId, uses, evidence) => {
115
+ if (evidence.condition ||
116
+ evidence.withMapping ||
117
+ indirectReusableBypassEvidence(evidence)) {
118
+ return {
119
+ failure: failure(workflow, evidence.condition
120
+ ? `${jobId}: executable if bypass logic around a local reusable is unsupported`
121
+ : `${jobId}: indirect bypass logic around a local reusable is unsupported`),
122
+ };
123
+ }
124
+ const local = LOCAL.exec(uses)?.[1];
125
+ return local
126
+ ? { local }
127
+ : {
128
+ failure: failure(workflow, `${jobId}: local reusable path is unsupported or escapes .github/workflows`),
129
+ };
130
+ };
131
+ /**
132
+ * Interpret one reachable executable job without scanning prose or comments.
133
+ * @param workflow - Parsed workflow containing the job
134
+ * @param jobId - Stable job mapping key
135
+ * @param job - Parsed job mapping
136
+ * @returns Direct caller, local edge, or an explicit refusal
137
+ */
138
+ export function inspectNightlyGuardJob(workflow, jobId, job) {
139
+ const evidence = inspectNightlyGuardJobEvidence(workflow, job);
140
+ const official = inspectOfficial(workflow, jobId, job, evidence);
141
+ if (official)
142
+ return official;
143
+ const uses = nightlyGuardText(job.uses);
144
+ if (uses.startsWith("./")) {
145
+ return inspectLocal(workflow, jobId, uses, evidence);
146
+ }
147
+ if (uses.length > 0) {
148
+ return hasAnyNightlyGuardBypassEvidence(evidence)
149
+ ? {
150
+ failure: failure(workflow, `${jobId}: bypass evidence on an unsupported remote reusable is unavailable`),
151
+ }
152
+ : {};
153
+ }
154
+ return inspectDirect(workflow, jobId, evidence);
155
+ }
156
+ //# sourceMappingURL=doctor-nightly-e2e-guard-job.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-nightly-e2e-guard-job.js","sourceRoot":"","sources":["../../src/cli/doctor-nightly-e2e-guard-job.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { HashLedger } from "../core/lisa-owned-provenance.js";
2
+ import { type NightlyGuardProbeResult } from "./doctor-nightly-e2e-guard-contract.js";
3
+ import { type NightlyGuardDeadline } from "./doctor-nightly-e2e-guard-deadline.js";
4
+ /** One digest whose actual Lisa package handler passed the behavior suite. */
5
+ export interface NightlyGuardBehaviorCertificate {
6
+ /** Major-1 contract emitted by the behavior-proven handler. */
7
+ readonly contractVersion: string;
8
+ }
9
+ /** Exact digest lookup; target paths never broaden certificate authority. */
10
+ export type NightlyGuardBehaviorCertificates = Readonly<Record<string, NightlyGuardBehaviorCertificate>>;
11
+ /** Optional proof collaborators for ledger and deadline bite controls. */
12
+ export interface NightlyGuardProofDependencies {
13
+ /** Behavior-proven exact digests; tests may inject a precise certificate. */
14
+ readonly certificates?: NightlyGuardBehaviorCertificates;
15
+ /** Legacy compatibility seam; generic ownership hashes grant no authority. */
16
+ readonly ledger?: HashLedger;
17
+ /** Whole-operation deadline, narrowed to the target ceiling here. */
18
+ readonly deadline?: NightlyGuardDeadline;
19
+ /** Standalone target ceiling override for deterministic tests. */
20
+ readonly timeoutMs?: number;
21
+ /** Monotonic clock for standalone proof tests. */
22
+ readonly now?: () => number;
23
+ }
24
+ /**
25
+ * Lower-case sha256 used as non-executing shipped provenance.
26
+ * @param bytes - Safely captured target bytes
27
+ * @returns Lower-case SHA-256 hex digest
28
+ */
29
+ export declare const digestNightlyGuardBytes: (bytes: Buffer) => string;
30
+ /**
31
+ * Prove a target by bounded no-follow hash and an exact behavior certificate.
32
+ *
33
+ * The target is deliberately never imported, spawned, or evaluated. A caller
34
+ * can therefore retain direct invocation while doctor itself grants untrusted
35
+ * bytes no filesystem, process, environment, or network capability.
36
+ * @param projectRoot - Project root forming the containment boundary
37
+ * @param target - Literal project-relative JavaScript file
38
+ * @param dependencies - Optional ledger/deadline collaborators
39
+ * @returns Compatible major-1 version, or an explicit failed proof
40
+ */
41
+ export declare function proveNightlyE2eGuardTarget(projectRoot: string, target: string, dependencies?: NightlyGuardProofDependencies): Promise<NightlyGuardProbeResult>;
42
+ //# sourceMappingURL=doctor-nightly-e2e-guard-proof.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-nightly-e2e-guard-proof.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-nightly-e2e-guard-proof.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAGL,KAAK,uBAAuB,EAC7B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAIL,KAAK,oBAAoB,EAC1B,MAAM,wCAAwC,CAAC;AAKhD,8EAA8E;AAC9E,MAAM,WAAW,+BAA+B;IAC9C,+DAA+D;IAC/D,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;CAClC;AAED,6EAA6E;AAC7E,MAAM,MAAM,gCAAgC,GAAG,QAAQ,CACrD,MAAM,CAAC,MAAM,EAAE,+BAA+B,CAAC,CAChD,CAAC;AAEF,0EAA0E;AAC1E,MAAM,WAAW,6BAA6B;IAC5C,6EAA6E;IAC7E,QAAQ,CAAC,YAAY,CAAC,EAAE,gCAAgC,CAAC;IACzD,8EAA8E;IAC9E,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC;IAC7B,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IACzC,kEAAkE;IAClE,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,kDAAkD;IAClD,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,eAAO,MAAM,uBAAuB,GAAI,OAAO,MAAM,KAAG,MACN,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,wBAAsB,0BAA0B,CAC9C,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,YAAY,GAAE,6BAAkC,GAC/C,OAAO,CAAC,uBAAuB,CAAC,CA8ClC"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * @file doctor-nightly-e2e-guard-proof.ts
3
+ * @description Non-executing provenance and contract proof for active targets
4
+ * @module cli/doctor-nightly-e2e-guard-proof
5
+ */
6
+ import { createHash } from "node:crypto";
7
+ import { NIGHTLY_E2E_GUARD_BEHAVIOR_CERTIFICATES, NIGHTLY_E2E_GUARD_CERTIFICATE_SCHEMA_VERSION, } from "../core/nightly-e2e-guard-behavior-certificate.js";
8
+ import { MAX_NIGHTLY_GUARD_FILE_BYTES, NIGHTLY_GUARD_TARGET_TIMEOUT_MS, } from "./doctor-nightly-e2e-guard-contract.js";
9
+ import { createNightlyGuardDeadline, limitNightlyGuardDeadline, nightlyGuardTargetDeadlineReason, } from "./doctor-nightly-e2e-guard-deadline.js";
10
+ import { readNightlyGuardFile } from "./doctor-nightly-e2e-guard-io.js";
11
+ const VERSION = /^1\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/u;
12
+ /**
13
+ * Lower-case sha256 used as non-executing shipped provenance.
14
+ * @param bytes - Safely captured target bytes
15
+ * @returns Lower-case SHA-256 hex digest
16
+ */
17
+ export const digestNightlyGuardBytes = (bytes) => createHash("sha256").update(bytes).digest("hex");
18
+ /**
19
+ * Prove a target by bounded no-follow hash and an exact behavior certificate.
20
+ *
21
+ * The target is deliberately never imported, spawned, or evaluated. A caller
22
+ * can therefore retain direct invocation while doctor itself grants untrusted
23
+ * bytes no filesystem, process, environment, or network capability.
24
+ * @param projectRoot - Project root forming the containment boundary
25
+ * @param target - Literal project-relative JavaScript file
26
+ * @param dependencies - Optional ledger/deadline collaborators
27
+ * @returns Compatible major-1 version, or an explicit failed proof
28
+ */
29
+ export async function proveNightlyE2eGuardTarget(projectRoot, target, dependencies = {}) {
30
+ const outer = dependencies.deadline ??
31
+ createNightlyGuardDeadline(dependencies.now, dependencies.timeoutMs ?? NIGHTLY_GUARD_TARGET_TIMEOUT_MS, nightlyGuardTargetDeadlineReason(dependencies.timeoutMs ?? NIGHTLY_GUARD_TARGET_TIMEOUT_MS));
32
+ const deadline = dependencies.deadline
33
+ ? limitNightlyGuardDeadline(outer, dependencies.timeoutMs ?? NIGHTLY_GUARD_TARGET_TIMEOUT_MS)
34
+ : outer;
35
+ const read = await readNightlyGuardFile(projectRoot, target, MAX_NIGHTLY_GUARD_FILE_BYTES, deadline);
36
+ if (read.state !== "ok") {
37
+ return { state: "failure", reason: read.reason };
38
+ }
39
+ const digest = digestNightlyGuardBytes(read.bytes);
40
+ const certificates = dependencies.certificates ?? NIGHTLY_E2E_GUARD_BEHAVIOR_CERTIFICATES;
41
+ const certificate = certificates[digest];
42
+ if (certificate === undefined) {
43
+ return {
44
+ state: "failure",
45
+ reason: "target bytes are not in Lisa's nightly guard behavior certificate; doctor refuses to execute untrusted JavaScript—upgrade Lisa and apply its exact guard",
46
+ };
47
+ }
48
+ if (NIGHTLY_E2E_GUARD_CERTIFICATE_SCHEMA_VERSION !== 1 ||
49
+ !VERSION.test(certificate.contractVersion)) {
50
+ return {
51
+ state: "failure",
52
+ reason: "nightly guard behavior certificate is malformed or incompatible",
53
+ };
54
+ }
55
+ return { state: "compatible", version: certificate.contractVersion };
56
+ }
57
+ //# sourceMappingURL=doctor-nightly-e2e-guard-proof.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-nightly-e2e-guard-proof.js","sourceRoot":"","sources":["../../src/cli/doctor-nightly-e2e-guard-proof.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EACL,uCAAuC,EACvC,4CAA4C,GAC7C,MAAM,mDAAmD,CAAC;AAE3D,OAAO,EACL,4BAA4B,EAC5B,+BAA+B,GAEhC,MAAM,wCAAwC,CAAC;AAChD,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,gCAAgC,GAEjC,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kCAAkC,CAAC;AAExE,MAAM,OAAO,GAAG,kCAAkC,CAAC;AA2BnD;;;;GAIG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,KAAa,EAAU,EAAE,CAC/D,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAEnD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,WAAmB,EACnB,MAAc,EACd,eAA8C,EAAE;IAEhD,MAAM,KAAK,GACT,YAAY,CAAC,QAAQ;QACrB,0BAA0B,CACxB,YAAY,CAAC,GAAG,EAChB,YAAY,CAAC,SAAS,IAAI,+BAA+B,EACzD,gCAAgC,CAC9B,YAAY,CAAC,SAAS,IAAI,+BAA+B,CAC1D,CACF,CAAC;IACJ,MAAM,QAAQ,GAAG,YAAY,CAAC,QAAQ;QACpC,CAAC,CAAC,yBAAyB,CACvB,KAAK,EACL,YAAY,CAAC,SAAS,IAAI,+BAA+B,CAC1D;QACH,CAAC,CAAC,KAAK,CAAC;IACV,MAAM,IAAI,GAAG,MAAM,oBAAoB,CACrC,WAAW,EACX,MAAM,EACN,4BAA4B,EAC5B,QAAQ,CACT,CAAC;IACF,IAAI,IAAI,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;QACxB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC;IACnD,CAAC;IACD,MAAM,MAAM,GAAG,uBAAuB,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnD,MAAM,YAAY,GAChB,YAAY,CAAC,YAAY,IAAI,uCAAuC,CAAC;IACvE,MAAM,WAAW,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACzC,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,MAAM,EACJ,0JAA0J;SAC7J,CAAC;IACJ,CAAC;IACD,IACE,4CAA4C,KAAK,CAAC;QAClD,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,eAAe,CAAC,EAC1C,CAAC;QACD,OAAO;YACL,KAAK,EAAE,SAAS;YAChB,MAAM,EAAE,iEAAiE;SAC1E,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,CAAC,eAAe,EAAE,CAAC;AACvE,CAAC"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @file doctor-nightly-e2e-guard-remediation.ts
3
+ * @description Provenance-aware repair guidance for nightly guard findings
4
+ * @module cli/doctor-nightly-e2e-guard-remediation
5
+ */
6
+ import { type HashLedger } from "../core/lisa-owned-provenance.js";
7
+ import { type NightlyGuardCaller } from "./doctor-nightly-e2e-guard-contract.js";
8
+ import type { NightlyGuardDeadline } from "./doctor-nightly-e2e-guard-deadline.js";
9
+ import { type NightlyGuardBehaviorCertificates } from "./doctor-nightly-e2e-guard-proof.js";
10
+ /** Inputs shared by every caller-specific remediation decision. */
11
+ export interface NightlyGuardRemediationInput {
12
+ /** Host project under inspection. */
13
+ readonly projectRoot: string;
14
+ /** Installed Lisa package root. */
15
+ readonly lisaRoot: string;
16
+ /** Active caller whose target failed proof. */
17
+ readonly caller: NightlyGuardCaller;
18
+ /** Shared whole-operation deadline. */
19
+ readonly deadline: NightlyGuardDeadline;
20
+ /** Optional shipped provenance fixture. */
21
+ readonly ledger?: HashLedger;
22
+ /** Optional exact behavior-certificate fixture. */
23
+ readonly certificates?: NightlyGuardBehaviorCertificates;
24
+ }
25
+ /**
26
+ * Produce exact repair guidance without collapsing missing, unreadable, stale,
27
+ * and deliberately modified files into the same destructive instruction.
28
+ * @param input - Caller, package, provenance, and deadline context
29
+ * @returns One bounded operator-readable remediation
30
+ */
31
+ export declare function nightlyGuardRemediation(input: NightlyGuardRemediationInput): Promise<string>;
32
+ //# sourceMappingURL=doctor-nightly-e2e-guard-remediation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-nightly-e2e-guard-remediation.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-nightly-e2e-guard-remediation.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAEL,KAAK,UAAU,EAChB,MAAM,kCAAkC,CAAC;AAG1C,OAAO,EAIL,KAAK,kBAAkB,EACxB,MAAM,wCAAwC,CAAC;AAChD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,wCAAwC,CAAC;AAEnF,OAAO,EAEL,KAAK,gCAAgC,EACtC,MAAM,qCAAqC,CAAC;AAO7C,mEAAmE;AACnE,MAAM,WAAW,4BAA4B;IAC3C,qCAAqC;IACrC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,mCAAmC;IACnC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,+CAA+C;IAC/C,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC;IACpC,uCAAuC;IACvC,QAAQ,CAAC,QAAQ,EAAE,oBAAoB,CAAC;IACxC,2CAA2C;IAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC;IAC7B,mDAAmD;IACnD,QAAQ,CAAC,YAAY,CAAC,EAAE,gCAAgC,CAAC;CAC1D;AAOD;;;;;GAKG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAAC,MAAM,CAAC,CAmDjB"}