@codyswann/lisa 4.21.4 → 4.21.6

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 (126) hide show
  1. package/dist/cli/doctor-nightly-e2e-guard-command-files.d.ts +19 -0
  2. package/dist/cli/doctor-nightly-e2e-guard-command-files.d.ts.map +1 -0
  3. package/dist/cli/doctor-nightly-e2e-guard-command-files.js +221 -0
  4. package/dist/cli/doctor-nightly-e2e-guard-command-files.js.map +1 -0
  5. package/dist/cli/doctor-nightly-e2e-guard-contract.d.ts +113 -0
  6. package/dist/cli/doctor-nightly-e2e-guard-contract.d.ts.map +1 -0
  7. package/dist/cli/doctor-nightly-e2e-guard-contract.js +87 -0
  8. package/dist/cli/doctor-nightly-e2e-guard-contract.js.map +1 -0
  9. package/dist/cli/doctor-nightly-e2e-guard-deadline.d.ts +61 -0
  10. package/dist/cli/doctor-nightly-e2e-guard-deadline.d.ts.map +1 -0
  11. package/dist/cli/doctor-nightly-e2e-guard-deadline.js +97 -0
  12. package/dist/cli/doctor-nightly-e2e-guard-deadline.js.map +1 -0
  13. package/dist/cli/doctor-nightly-e2e-guard-evidence.d.ts +52 -0
  14. package/dist/cli/doctor-nightly-e2e-guard-evidence.d.ts.map +1 -0
  15. package/dist/cli/doctor-nightly-e2e-guard-evidence.js +68 -0
  16. package/dist/cli/doctor-nightly-e2e-guard-evidence.js.map +1 -0
  17. package/dist/cli/doctor-nightly-e2e-guard-graph.d.ts +14 -0
  18. package/dist/cli/doctor-nightly-e2e-guard-graph.d.ts.map +1 -0
  19. package/dist/cli/doctor-nightly-e2e-guard-graph.js +130 -0
  20. package/dist/cli/doctor-nightly-e2e-guard-graph.js.map +1 -0
  21. package/dist/cli/doctor-nightly-e2e-guard-io.d.ts +41 -0
  22. package/dist/cli/doctor-nightly-e2e-guard-io.d.ts.map +1 -0
  23. package/dist/cli/doctor-nightly-e2e-guard-io.js +239 -0
  24. package/dist/cli/doctor-nightly-e2e-guard-io.js.map +1 -0
  25. package/dist/cli/doctor-nightly-e2e-guard-job.d.ts +31 -0
  26. package/dist/cli/doctor-nightly-e2e-guard-job.d.ts.map +1 -0
  27. package/dist/cli/doctor-nightly-e2e-guard-job.js +156 -0
  28. package/dist/cli/doctor-nightly-e2e-guard-job.js.map +1 -0
  29. package/dist/cli/doctor-nightly-e2e-guard-proof.d.ts +42 -0
  30. package/dist/cli/doctor-nightly-e2e-guard-proof.d.ts.map +1 -0
  31. package/dist/cli/doctor-nightly-e2e-guard-proof.js +57 -0
  32. package/dist/cli/doctor-nightly-e2e-guard-proof.js.map +1 -0
  33. package/dist/cli/doctor-nightly-e2e-guard-remediation.d.ts +32 -0
  34. package/dist/cli/doctor-nightly-e2e-guard-remediation.d.ts.map +1 -0
  35. package/dist/cli/doctor-nightly-e2e-guard-remediation.js +55 -0
  36. package/dist/cli/doctor-nightly-e2e-guard-remediation.js.map +1 -0
  37. package/dist/cli/doctor-nightly-e2e-guard-runtime.d.ts +34 -0
  38. package/dist/cli/doctor-nightly-e2e-guard-runtime.d.ts.map +1 -0
  39. package/dist/cli/doctor-nightly-e2e-guard-runtime.js +93 -0
  40. package/dist/cli/doctor-nightly-e2e-guard-runtime.js.map +1 -0
  41. package/dist/cli/doctor-nightly-e2e-guard-scan.d.ts +17 -0
  42. package/dist/cli/doctor-nightly-e2e-guard-scan.d.ts.map +1 -0
  43. package/dist/cli/doctor-nightly-e2e-guard-scan.js +86 -0
  44. package/dist/cli/doctor-nightly-e2e-guard-scan.js.map +1 -0
  45. package/dist/cli/doctor-nightly-e2e-guard-shell-lexer.d.ts +38 -0
  46. package/dist/cli/doctor-nightly-e2e-guard-shell-lexer.d.ts.map +1 -0
  47. package/dist/cli/doctor-nightly-e2e-guard-shell-lexer.js +160 -0
  48. package/dist/cli/doctor-nightly-e2e-guard-shell-lexer.js.map +1 -0
  49. package/dist/cli/doctor-nightly-e2e-guard-shell.d.ts +40 -0
  50. package/dist/cli/doctor-nightly-e2e-guard-shell.d.ts.map +1 -0
  51. package/dist/cli/doctor-nightly-e2e-guard-shell.js +201 -0
  52. package/dist/cli/doctor-nightly-e2e-guard-shell.js.map +1 -0
  53. package/dist/cli/doctor-nightly-e2e-guard.d.ts +36 -0
  54. package/dist/cli/doctor-nightly-e2e-guard.d.ts.map +1 -0
  55. package/dist/cli/doctor-nightly-e2e-guard.js +186 -0
  56. package/dist/cli/doctor-nightly-e2e-guard.js.map +1 -0
  57. package/dist/cli/doctor.d.ts.map +1 -1
  58. package/dist/cli/doctor.js +7 -0
  59. package/dist/cli/doctor.js.map +1 -1
  60. package/dist/core/nightly-e2e-guard-behavior-certificate.d.ts +25 -0
  61. package/dist/core/nightly-e2e-guard-behavior-certificate.d.ts.map +1 -0
  62. package/dist/core/nightly-e2e-guard-behavior-certificate.js +30 -0
  63. package/dist/core/nightly-e2e-guard-behavior-certificate.js.map +1 -0
  64. package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
  65. package/dist/core/upstream-evidence-manifest.js +30 -3
  66. package/dist/core/upstream-evidence-manifest.js.map +1 -1
  67. package/package.json +5 -3
  68. package/plugins/lisa/.claude-plugin/plugin.json +1 -1
  69. package/plugins/lisa/.codex-plugin/plugin.json +1 -1
  70. package/plugins/lisa/.codex-plugin/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +17 -2
  71. package/plugins/lisa/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +17 -2
  72. package/plugins/lisa-agy/plugin.json +1 -1
  73. package/plugins/lisa-agy/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +17 -2
  74. package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
  75. package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
  76. package/plugins/lisa-cdk-agy/plugin.json +1 -1
  77. package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
  78. package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
  79. package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
  80. package/plugins/lisa-copilot/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +17 -2
  81. package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
  82. package/plugins/lisa-cursor/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +17 -2
  83. package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
  84. package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
  85. package/plugins/lisa-expo-agy/plugin.json +1 -1
  86. package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
  87. package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
  88. package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
  89. package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
  90. package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
  91. package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
  92. package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
  93. package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
  94. package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
  95. package/plugins/lisa-nestjs-agy/plugin.json +1 -1
  96. package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
  97. package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
  98. package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
  99. package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
  100. package/plugins/lisa-openclaw-agy/plugin.json +1 -1
  101. package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
  102. package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
  103. package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
  104. package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
  105. package/plugins/lisa-phaser-agy/plugin.json +1 -1
  106. package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
  107. package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
  108. package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
  109. package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
  110. package/plugins/lisa-rails-agy/plugin.json +1 -1
  111. package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
  112. package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
  113. package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
  114. package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
  115. package/plugins/lisa-typescript-agy/plugin.json +1 -1
  116. package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
  117. package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
  118. package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
  119. package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
  120. package/plugins/lisa-wiki-agy/plugin.json +1 -1
  121. package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
  122. package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
  123. package/plugins/src/base/skills/lisa-secrets-access/scripts/publish-aws-bootstrap.mjs +17 -2
  124. package/scripts/check-derived-artifacts.mjs +32 -5
  125. package/scripts/generate-nightly-e2e-guard-certificate.mjs +370 -0
  126. package/scripts/two-channel-couplings.json +16 -4
@@ -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"}
@@ -0,0 +1,55 @@
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 { classifyHostCopy, } from "../core/lisa-owned-provenance.js";
7
+ import { LISA_OWNED_HASH_LEDGER } from "../core/lisa-owned-hash-ledger.js";
8
+ import { NIGHTLY_E2E_GUARD_BEHAVIOR_CERTIFICATES } from "../core/nightly-e2e-guard-behavior-certificate.js";
9
+ import { MAX_NIGHTLY_GUARD_FILE_BYTES, NIGHTLY_GUARD_CANONICAL_TARGET, NIGHTLY_GUARD_SHIPPED_TARGET, } from "./doctor-nightly-e2e-guard-contract.js";
10
+ import { readNightlyGuardFile } from "./doctor-nightly-e2e-guard-io.js";
11
+ import { digestNightlyGuardBytes, } from "./doctor-nightly-e2e-guard-proof.js";
12
+ const exactProbe = (target) => `node ${target} --contract-version`;
13
+ const preserveContext = "preserve the workflow/job names and required-check context unless a coordinated ruleset migration is planned";
14
+ const packageUnavailable = (reason) => `repair or reinstall Lisa first: its packaged guard is unreadable or corrupt (${reason}); then run \`lisa apply .\` and \`${exactProbe(NIGHTLY_GUARD_CANONICAL_TARGET)}\``;
15
+ const packageUncertified = (reason) => `upgrade or reinstall Lisa first: its packaged guard is not behavior-certified (${reason}); then run \`lisa apply .\` and \`${exactProbe(NIGHTLY_GUARD_CANONICAL_TARGET)}\``;
16
+ /**
17
+ * Produce exact repair guidance without collapsing missing, unreadable, stale,
18
+ * and deliberately modified files into the same destructive instruction.
19
+ * @param input - Caller, package, provenance, and deadline context
20
+ * @returns One bounded operator-readable remediation
21
+ */
22
+ export async function nightlyGuardRemediation(input) {
23
+ const shipped = await readNightlyGuardFile(input.lisaRoot, NIGHTLY_GUARD_SHIPPED_TARGET, MAX_NIGHTLY_GUARD_FILE_BYTES, input.deadline);
24
+ if (shipped.state === "missing") {
25
+ return `upgrade first: install Lisa 2.353.0+ on 2.x or, preferably, the current release; then run \`lisa apply .\` and \`${exactProbe(NIGHTLY_GUARD_CANONICAL_TARGET)}\``;
26
+ }
27
+ if (shipped.state === "unavailable") {
28
+ return packageUnavailable(shipped.reason);
29
+ }
30
+ const shippedDigest = digestNightlyGuardBytes(shipped.bytes);
31
+ const certificates = input.certificates ?? NIGHTLY_E2E_GUARD_BEHAVIOR_CERTIFICATES;
32
+ if (certificates[shippedDigest] === undefined) {
33
+ return packageUncertified("its exact bytes are absent from this release's nightly guard behavior certificate; a generic ownership hash is insufficient");
34
+ }
35
+ const ledger = input.ledger ?? LISA_OWNED_HASH_LEDGER;
36
+ if (input.caller.target !== NIGHTLY_GUARD_CANONICAL_TARGET) {
37
+ return `install ${NIGHTLY_GUARD_CANONICAL_TARGET} with \`lisa apply .\`, repoint this job to it, retire ${input.caller.target}, then run \`${exactProbe(NIGHTLY_GUARD_CANONICAL_TARGET)}\`; ${preserveContext}`;
38
+ }
39
+ const host = await readNightlyGuardFile(input.projectRoot, NIGHTLY_GUARD_CANONICAL_TARGET, MAX_NIGHTLY_GUARD_FILE_BYTES, input.deadline);
40
+ if (host.state === "missing") {
41
+ return `run \`lisa apply .\` to install ${NIGHTLY_GUARD_CANONICAL_TARGET}, then run \`${exactProbe(NIGHTLY_GUARD_CANONICAL_TARGET)}\``;
42
+ }
43
+ if (host.state === "unavailable") {
44
+ return `repair the canonical host path before applying: ${host.reason}; no file was replaced`;
45
+ }
46
+ const verdict = classifyHostCopy(NIGHTLY_GUARD_CANONICAL_TARGET, host.bytes, shipped.bytes, ledger);
47
+ if (verdict.kind === "identical") {
48
+ return `the failing target is the byte-identical packaged copy; repair, reinstall, or upgrade Lisa, re-run \`lisa apply .\`, then run \`${exactProbe(NIGHTLY_GUARD_CANONICAL_TARGET)}\``;
49
+ }
50
+ if (verdict.kind === "provably-stale") {
51
+ return `this canonical copy is provably stale; run \`lisa apply .\`, then run \`${exactProbe(NIGHTLY_GUARD_CANONICAL_TARGET)}\``;
52
+ }
53
+ return `review the preserved modified canonical guard, then take Lisa's exact copy with \`lisa apply . --refresh-templates=${NIGHTLY_GUARD_CANONICAL_TARGET}\` and run \`${exactProbe(NIGHTLY_GUARD_CANONICAL_TARGET)}\``;
54
+ }
55
+ //# sourceMappingURL=doctor-nightly-e2e-guard-remediation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-nightly-e2e-guard-remediation.js","sourceRoot":"","sources":["../../src/cli/doctor-nightly-e2e-guard-remediation.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * @file doctor-nightly-e2e-guard-runtime.ts
3
+ * @description Proven shell and environment constraints for static guard calls
4
+ * @module cli/doctor-nightly-e2e-guard-runtime
5
+ */
6
+ /** Metadata whose exact values decide whether POSIX parsing is sound. */
7
+ export interface NightlyGuardRuntimeContext {
8
+ /** Highest-precedence workflow/job/step shell declaration, when present. */
9
+ readonly shell: unknown;
10
+ /** Job runner label used only when no shell is explicitly declared. */
11
+ readonly runsOn: unknown;
12
+ /** Fully merged workflow/job/step environment visible to the command. */
13
+ readonly environment: Readonly<Record<string, unknown>>;
14
+ }
15
+ /**
16
+ * Identify environment controls that can replace or alter Node/shell execution.
17
+ * @param name - Case-sensitive process environment name from YAML or shell
18
+ * @returns Whether the name can change how the certified bytes are executed
19
+ */
20
+ export declare const isExecutionChangingEnvironmentName: (name: string) => boolean;
21
+ /**
22
+ * Refuse an effective environment that can turn exact bytes into false proof.
23
+ * @param environment - Merged environment after YAML precedence is applied
24
+ * @returns A bounded refusal naming the first dangerous control, when present
25
+ */
26
+ export declare const nightlyGuardEnvironmentFailure: (environment: Readonly<Record<string, unknown>>) => string | undefined;
27
+ /**
28
+ * Require either a finite safe shell template or an exact hosted runner label.
29
+ * @param run - YAML-decoded command; empty steps need no shell inference
30
+ * @param context - Effective shell, runner, and merged environment metadata
31
+ * @returns Why static POSIX execution is unproved, or undefined when proved
32
+ */
33
+ export declare const nightlyGuardPosixContextFailure: (run: string, context: NightlyGuardRuntimeContext) => string | undefined;
34
+ //# sourceMappingURL=doctor-nightly-e2e-guard-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-nightly-e2e-guard-runtime.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-nightly-e2e-guard-runtime.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmDH,yEAAyE;AACzE,MAAM,WAAW,0BAA0B;IACzC,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,uEAAuE;IACvE,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB,yEAAyE;IACzE,QAAQ,CAAC,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACzD;AAED;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,GAAI,MAAM,MAAM,KAAG,OAEM,CAAC;AAEzE;;;;GAIG;AACH,eAAO,MAAM,8BAA8B,GACzC,aAAa,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KAC7C,MAAM,GAAG,SAOX,CAAC;AAKF;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,GAC1C,KAAK,MAAM,EACX,SAAS,0BAA0B,KAClC,MAAM,GAAG,SAeX,CAAC"}
@@ -0,0 +1,93 @@
1
+ /**
2
+ * @file doctor-nightly-e2e-guard-runtime.ts
3
+ * @description Proven shell and environment constraints for static guard calls
4
+ * @module cli/doctor-nightly-e2e-guard-runtime
5
+ */
6
+ const EXECUTION_ENVIRONMENT_NAMES = new Set([
7
+ "BASHOPTS",
8
+ "BASH_ENV",
9
+ "CDPATH",
10
+ "ENV",
11
+ "GLOBIGNORE",
12
+ "IFS",
13
+ "PATH",
14
+ "POSIXLY_CORRECT",
15
+ "SHELLOPTS",
16
+ ]);
17
+ const EXECUTION_ENVIRONMENT_PREFIXES = [
18
+ "BASH_FUNC_",
19
+ "DYLD_",
20
+ "LD_",
21
+ "NIX_LD",
22
+ "NODE_",
23
+ ];
24
+ const GITHUB_HOSTED_POSIX_RUNNER = /^(?:ubuntu-(?:latest|24\.04|22\.04|20\.04)|macos-(?:latest|15|14|13))$/u;
25
+ const EXECUTION_PRESERVING_SHELLS = new Set([
26
+ "bash",
27
+ "bash {0}",
28
+ "bash -e {0}",
29
+ "bash -eo pipefail {0}",
30
+ "bash --noprofile --norc -eo pipefail {0}",
31
+ "sh",
32
+ "sh {0}",
33
+ "sh -e {0}",
34
+ "/bin/bash",
35
+ "/bin/bash {0}",
36
+ "/bin/bash -e {0}",
37
+ "/bin/bash -eo pipefail {0}",
38
+ "/bin/bash --noprofile --norc -eo pipefail {0}",
39
+ "/usr/bin/bash",
40
+ "/usr/bin/bash {0}",
41
+ "/usr/bin/bash -e {0}",
42
+ "/usr/bin/bash -eo pipefail {0}",
43
+ "/usr/bin/bash --noprofile --norc -eo pipefail {0}",
44
+ "/bin/sh",
45
+ "/bin/sh {0}",
46
+ "/bin/sh -e {0}",
47
+ "/usr/bin/sh",
48
+ "/usr/bin/sh {0}",
49
+ "/usr/bin/sh -e {0}",
50
+ ]);
51
+ /**
52
+ * Identify environment controls that can replace or alter Node/shell execution.
53
+ * @param name - Case-sensitive process environment name from YAML or shell
54
+ * @returns Whether the name can change how the certified bytes are executed
55
+ */
56
+ export const isExecutionChangingEnvironmentName = (name) => EXECUTION_ENVIRONMENT_NAMES.has(name) ||
57
+ EXECUTION_ENVIRONMENT_PREFIXES.some(prefix => name.startsWith(prefix));
58
+ /**
59
+ * Refuse an effective environment that can turn exact bytes into false proof.
60
+ * @param environment - Merged environment after YAML precedence is applied
61
+ * @returns A bounded refusal naming the first dangerous control, when present
62
+ */
63
+ export const nightlyGuardEnvironmentFailure = (environment) => {
64
+ const unsafe = Object.keys(environment)
65
+ .sort((left, right) => left.localeCompare(right))
66
+ .find(isExecutionChangingEnvironmentName);
67
+ return unsafe
68
+ ? `${unsafe} environment control can change or replace certified guard execution`
69
+ : undefined;
70
+ };
71
+ const normalizedShell = (shell) => shell.trim().split(/\s+/u).join(" ");
72
+ /**
73
+ * Require either a finite safe shell template or an exact hosted runner label.
74
+ * @param run - YAML-decoded command; empty steps need no shell inference
75
+ * @param context - Effective shell, runner, and merged environment metadata
76
+ * @returns Why static POSIX execution is unproved, or undefined when proved
77
+ */
78
+ export const nightlyGuardPosixContextFailure = (run, context) => {
79
+ if (run.trim().length === 0)
80
+ return undefined;
81
+ if (context.shell !== undefined) {
82
+ return typeof context.shell === "string" &&
83
+ EXECUTION_PRESERVING_SHELLS.has(normalizedShell(context.shell))
84
+ ? undefined
85
+ : "step shell is unknown, non-POSIX, or not an execution-preserving bash/sh template";
86
+ }
87
+ if (typeof context.runsOn !== "string" ||
88
+ !GITHUB_HOSTED_POSIX_RUNNER.test(context.runsOn)) {
89
+ return "runner is self-hosted, array-valued, custom, dynamic, or unknown; an explicit supported POSIX shell is required";
90
+ }
91
+ return undefined;
92
+ };
93
+ //# sourceMappingURL=doctor-nightly-e2e-guard-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-nightly-e2e-guard-runtime.js","sourceRoot":"","sources":["../../src/cli/doctor-nightly-e2e-guard-runtime.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,2BAA2B,GAAG,IAAI,GAAG,CAAC;IAC1C,UAAU;IACV,UAAU;IACV,QAAQ;IACR,KAAK;IACL,YAAY;IACZ,KAAK;IACL,MAAM;IACN,iBAAiB;IACjB,WAAW;CACZ,CAAC,CAAC;AACH,MAAM,8BAA8B,GAAG;IACrC,YAAY;IACZ,OAAO;IACP,KAAK;IACL,QAAQ;IACR,OAAO;CACR,CAAC;AAEF,MAAM,0BAA0B,GAC9B,yEAAyE,CAAC;AAE5E,MAAM,2BAA2B,GAAG,IAAI,GAAG,CAAC;IAC1C,MAAM;IACN,UAAU;IACV,aAAa;IACb,uBAAuB;IACvB,0CAA0C;IAC1C,IAAI;IACJ,QAAQ;IACR,WAAW;IACX,WAAW;IACX,eAAe;IACf,kBAAkB;IAClB,4BAA4B;IAC5B,+CAA+C;IAC/C,eAAe;IACf,mBAAmB;IACnB,sBAAsB;IACtB,gCAAgC;IAChC,mDAAmD;IACnD,SAAS;IACT,aAAa;IACb,gBAAgB;IAChB,aAAa;IACb,iBAAiB;IACjB,oBAAoB;CACrB,CAAC,CAAC;AAYH;;;;GAIG;AACH,MAAM,CAAC,MAAM,kCAAkC,GAAG,CAAC,IAAY,EAAW,EAAE,CAC1E,2BAA2B,CAAC,GAAG,CAAC,IAAI,CAAC;IACrC,8BAA8B,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;AAEzE;;;;GAIG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,CAC5C,WAA8C,EAC1B,EAAE;IACtB,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC;SACpC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;SAChD,IAAI,CAAC,kCAAkC,CAAC,CAAC;IAC5C,OAAO,MAAM;QACX,CAAC,CAAC,GAAG,MAAM,sEAAsE;QACjF,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC,CAAC;AAEF,MAAM,eAAe,GAAG,CAAC,KAAa,EAAU,EAAE,CAChD,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAEvC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAC7C,GAAW,EACX,OAAmC,EACf,EAAE;IACtB,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9C,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAChC,OAAO,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ;YACtC,2BAA2B,CAAC,GAAG,CAAC,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;YAC/D,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,mFAAmF,CAAC;IAC1F,CAAC;IACD,IACE,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ;QAClC,CAAC,0BAA0B,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,EAChD,CAAC;QACD,OAAO,iHAAiH,CAAC;IAC3H,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { MAX_NIGHTLY_GUARD_CALLERS, MAX_NIGHTLY_GUARD_FILES, MAX_NIGHTLY_GUARD_TARGETS, type NightlyGuardScanResult } from "./doctor-nightly-e2e-guard-contract.js";
2
+ import { type NightlyGuardDeadline } from "./doctor-nightly-e2e-guard-deadline.js";
3
+ export { MAX_NIGHTLY_GUARD_CALLERS, MAX_NIGHTLY_GUARD_FILES, MAX_NIGHTLY_GUARD_TARGETS, };
4
+ export type { NightlyGuardCaller, NightlyGuardScanFailure, NightlyGuardScanResult, } from "./doctor-nightly-e2e-guard-contract.js";
5
+ /** Optional shared deadline used by the top-level doctor operation. */
6
+ export interface NightlyGuardScanDependencies {
7
+ /** Deadline started before discovery; standalone scans receive their own. */
8
+ readonly deadline?: NightlyGuardDeadline;
9
+ }
10
+ /**
11
+ * Discover every bypass-bearing guard caller reachable from repository events.
12
+ * @param projectRoot - Project root whose workflow tree is inspected
13
+ * @param dependencies - Shared deadline when called by doctor
14
+ * @returns Deterministic callers, or an explicit unavailable refusal
15
+ */
16
+ export declare function scanNightlyE2eGuardCallers(projectRoot: string, dependencies?: NightlyGuardScanDependencies): Promise<NightlyGuardScanResult>;
17
+ //# sourceMappingURL=doctor-nightly-e2e-guard-scan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor-nightly-e2e-guard-scan.d.ts","sourceRoot":"","sources":["../../src/cli/doctor-nightly-e2e-guard-scan.ts"],"names":[],"mappings":"AAMA,OAAO,EACL,yBAAyB,EAEzB,uBAAuB,EACvB,yBAAyB,EAKzB,KAAK,sBAAsB,EAI5B,MAAM,wCAAwC,CAAC;AAChD,OAAO,EAEL,KAAK,oBAAoB,EAC1B,MAAM,wCAAwC,CAAC;AAOhD,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,GAC1B,CAAC;AACF,YAAY,EACV,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,wCAAwC,CAAC;AAEhD,uEAAuE;AACvE,MAAM,WAAW,4BAA4B;IAC3C,6EAA6E;IAC7E,QAAQ,CAAC,QAAQ,CAAC,EAAE,oBAAoB,CAAC;CAC1C;AA6GD;;;;;GAKG;AACH,wBAAsB,0BAA0B,CAC9C,WAAW,EAAE,MAAM,EACnB,YAAY,GAAE,4BAAiC,GAC9C,OAAO,CAAC,sBAAsB,CAAC,CAQjC"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * @file doctor-nightly-e2e-guard-scan.ts
3
+ * @description Bounded executable-YAML discovery for nightly bypass callers
4
+ * @module cli/doctor-nightly-e2e-guard-scan
5
+ */
6
+ import { loadYaml } from "../utils/yaml.js";
7
+ import { MAX_NIGHTLY_GUARD_CALLERS, MAX_NIGHTLY_GUARD_FILE_BYTES, MAX_NIGHTLY_GUARD_FILES, MAX_NIGHTLY_GUARD_TARGETS, MAX_NIGHTLY_GUARD_TOTAL_BYTES, MAX_NIGHTLY_GUARD_WORKFLOW_ID_BYTES, NIGHTLY_GUARD_OPERATION_TIMEOUT_MS, NIGHTLY_GUARD_WORKFLOWS, nightlyGuardObject, orderNightlyGuardStrings, } from "./doctor-nightly-e2e-guard-contract.js";
8
+ import { createNightlyGuardDeadline, } from "./doctor-nightly-e2e-guard-deadline.js";
9
+ import { traceNightlyGuardCallers } from "./doctor-nightly-e2e-guard-graph.js";
10
+ import { readNightlyGuardDirectory, readNightlyGuardFile, } from "./doctor-nightly-e2e-guard-io.js";
11
+ export { MAX_NIGHTLY_GUARD_CALLERS, MAX_NIGHTLY_GUARD_FILES, MAX_NIGHTLY_GUARD_TARGETS, };
12
+ const unavailable = (workflow, reason) => ({
13
+ state: "unavailable",
14
+ failures: [{ workflow, reason }],
15
+ });
16
+ const parseWorkflow = (file, name, source) => {
17
+ try {
18
+ const document = nightlyGuardObject(loadYaml(source.toString("utf8")));
19
+ return document
20
+ ? { file, name, document }
21
+ : unavailable(file, "workflow YAML root is not a mapping");
22
+ }
23
+ catch (error) {
24
+ return unavailable(file, `workflow is unreadable or malformed (${error instanceof Error ? error.message : String(error)})`);
25
+ }
26
+ };
27
+ const isScanResult = (value) => "state" in value;
28
+ const hasControlCharacter = (value) => [...value].some(character => {
29
+ const codePoint = character.codePointAt(0) ?? 0;
30
+ return codePoint <= 31 || codePoint === 127;
31
+ });
32
+ /**
33
+ * Read the bounded workflow inventory without following path components.
34
+ * @param projectRoot - Project containment root
35
+ * @param deadline - Whole-operation deadline already started by doctor
36
+ * @returns Parsed inventory or an explicit availability refusal
37
+ */
38
+ async function readWorkflowRecords(projectRoot, deadline) {
39
+ const directory = await readNightlyGuardDirectory(projectRoot, NIGHTLY_GUARD_WORKFLOWS, deadline);
40
+ if (directory.state === "missing")
41
+ return [];
42
+ if (directory.state === "unavailable") {
43
+ return unavailable(NIGHTLY_GUARD_WORKFLOWS, directory.reason);
44
+ }
45
+ const names = orderNightlyGuardStrings(directory.names.filter(name => /\.ya?ml$/u.test(name)));
46
+ if (names.some(name => Buffer.byteLength(name) > MAX_NIGHTLY_GUARD_WORKFLOW_ID_BYTES ||
47
+ hasControlCharacter(name))) {
48
+ return unavailable(NIGHTLY_GUARD_WORKFLOWS, `workflow identifier exceeds the ${MAX_NIGHTLY_GUARD_WORKFLOW_ID_BYTES}-byte/control-character limit`);
49
+ }
50
+ if (names.length > MAX_NIGHTLY_GUARD_FILES) {
51
+ return unavailable(NIGHTLY_GUARD_WORKFLOWS, `workflow file limit ${MAX_NIGHTLY_GUARD_FILES} exceeded`);
52
+ }
53
+ const readNext = async (index, totalBytes, records) => {
54
+ const name = names[index];
55
+ if (name === undefined)
56
+ return records;
57
+ const file = `${NIGHTLY_GUARD_WORKFLOWS}/${name}`;
58
+ const read = await readNightlyGuardFile(projectRoot, file, MAX_NIGHTLY_GUARD_FILE_BYTES, deadline);
59
+ if (read.state !== "ok")
60
+ return unavailable(file, read.reason);
61
+ const nextTotal = totalBytes + read.bytes.length;
62
+ if (nextTotal > MAX_NIGHTLY_GUARD_TOTAL_BYTES) {
63
+ return unavailable(file, "workflow scan exceeds the 8 MiB total limit");
64
+ }
65
+ const parsed = parseWorkflow(file, name, read.bytes);
66
+ return isScanResult(parsed)
67
+ ? parsed
68
+ : await readNext(index + 1, nextTotal, [...records, parsed]);
69
+ };
70
+ return await readNext(0, 0, []);
71
+ }
72
+ /**
73
+ * Discover every bypass-bearing guard caller reachable from repository events.
74
+ * @param projectRoot - Project root whose workflow tree is inspected
75
+ * @param dependencies - Shared deadline when called by doctor
76
+ * @returns Deterministic callers, or an explicit unavailable refusal
77
+ */
78
+ export async function scanNightlyE2eGuardCallers(projectRoot, dependencies = {}) {
79
+ const deadline = dependencies.deadline ??
80
+ createNightlyGuardDeadline(undefined, NIGHTLY_GUARD_OPERATION_TIMEOUT_MS);
81
+ const records = await readWorkflowRecords(projectRoot, deadline);
82
+ return Array.isArray(records)
83
+ ? traceNightlyGuardCallers(records)
84
+ : records;
85
+ }
86
+ //# sourceMappingURL=doctor-nightly-e2e-guard-scan.js.map