flakelab 0.1.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 (245) hide show
  1. package/README.md +341 -0
  2. package/bin/flakelab.mjs +3 -0
  3. package/dist/artifacts/ndjson.d.ts +3 -0
  4. package/dist/artifacts/ndjson.js +16 -0
  5. package/dist/artifacts/ndjson.js.map +1 -0
  6. package/dist/bisect/archive.d.ts +1 -0
  7. package/dist/bisect/archive.js +14 -0
  8. package/dist/bisect/archive.js.map +1 -0
  9. package/dist/bisect/confidence.d.ts +7 -0
  10. package/dist/bisect/confidence.js +27 -0
  11. package/dist/bisect/confidence.js.map +1 -0
  12. package/dist/bisect/engine.d.ts +10 -0
  13. package/dist/bisect/engine.js +110 -0
  14. package/dist/bisect/engine.js.map +1 -0
  15. package/dist/bisect/git.d.ts +7 -0
  16. package/dist/bisect/git.js +56 -0
  17. package/dist/bisect/git.js.map +1 -0
  18. package/dist/bisect/schema.d.ts +82 -0
  19. package/dist/bisect/schema.js +33 -0
  20. package/dist/bisect/schema.js.map +1 -0
  21. package/dist/bisect/solari-command.d.ts +7 -0
  22. package/dist/bisect/solari-command.js +95 -0
  23. package/dist/bisect/solari-command.js.map +1 -0
  24. package/dist/bisect/solari-evaluator.d.ts +20 -0
  25. package/dist/bisect/solari-evaluator.js +310 -0
  26. package/dist/bisect/solari-evaluator.js.map +1 -0
  27. package/dist/ci/changed-tests.d.ts +7 -0
  28. package/dist/ci/changed-tests.js +104 -0
  29. package/dist/ci/changed-tests.js.map +1 -0
  30. package/dist/ci/job-summary.d.ts +11 -0
  31. package/dist/ci/job-summary.js +45 -0
  32. package/dist/ci/job-summary.js.map +1 -0
  33. package/dist/ci/select-command.d.ts +1 -0
  34. package/dist/ci/select-command.js +49 -0
  35. package/dist/ci/select-command.js.map +1 -0
  36. package/dist/ci/summary-command.d.ts +1 -0
  37. package/dist/ci/summary-command.js +46 -0
  38. package/dist/ci/summary-command.js.map +1 -0
  39. package/dist/cli-help.d.ts +2 -0
  40. package/dist/cli-help.js +47 -0
  41. package/dist/cli-help.js.map +1 -0
  42. package/dist/cli.d.ts +1 -0
  43. package/dist/cli.js +121 -0
  44. package/dist/cli.js.map +1 -0
  45. package/dist/commands/bisect.d.ts +2 -0
  46. package/dist/commands/bisect.js +63 -0
  47. package/dist/commands/bisect.js.map +1 -0
  48. package/dist/commands/diagnose.d.ts +2 -0
  49. package/dist/commands/diagnose.js +27 -0
  50. package/dist/commands/diagnose.js.map +1 -0
  51. package/dist/commands/discover.d.ts +2 -0
  52. package/dist/commands/discover.js +46 -0
  53. package/dist/commands/discover.js.map +1 -0
  54. package/dist/commands/doctor.d.ts +8 -0
  55. package/dist/commands/doctor.js +78 -0
  56. package/dist/commands/doctor.js.map +1 -0
  57. package/dist/commands/investigate.d.ts +2 -0
  58. package/dist/commands/investigate.js +43 -0
  59. package/dist/commands/investigate.js.map +1 -0
  60. package/dist/commands/options.d.ts +38 -0
  61. package/dist/commands/options.js +35 -0
  62. package/dist/commands/options.js.map +1 -0
  63. package/dist/commands/prove.d.ts +2 -0
  64. package/dist/commands/prove.js +21 -0
  65. package/dist/commands/prove.js.map +1 -0
  66. package/dist/commands/repair.d.ts +2 -0
  67. package/dist/commands/repair.js +55 -0
  68. package/dist/commands/repair.js.map +1 -0
  69. package/dist/commands/replay.d.ts +2 -0
  70. package/dist/commands/replay.js +26 -0
  71. package/dist/commands/replay.js.map +1 -0
  72. package/dist/commands/report.d.ts +2 -0
  73. package/dist/commands/report.js +79 -0
  74. package/dist/commands/report.js.map +1 -0
  75. package/dist/commands/scan.d.ts +12 -0
  76. package/dist/commands/scan.js +86 -0
  77. package/dist/commands/scan.js.map +1 -0
  78. package/dist/core/plan.d.ts +3 -0
  79. package/dist/core/plan.js +17 -0
  80. package/dist/core/plan.js.map +1 -0
  81. package/dist/discovery/evaluate.d.ts +22 -0
  82. package/dist/discovery/evaluate.js +81 -0
  83. package/dist/discovery/evaluate.js.map +1 -0
  84. package/dist/discovery/minimize.d.ts +24 -0
  85. package/dist/discovery/minimize.js +73 -0
  86. package/dist/discovery/minimize.js.map +1 -0
  87. package/dist/domain/schema.d.ts +155 -0
  88. package/dist/domain/schema.js +67 -0
  89. package/dist/domain/schema.js.map +1 -0
  90. package/dist/faults/install.d.ts +4 -0
  91. package/dist/faults/install.js +9 -0
  92. package/dist/faults/install.js.map +1 -0
  93. package/dist/faults/network-delay.d.ts +5 -0
  94. package/dist/faults/network-delay.js +34 -0
  95. package/dist/faults/network-delay.js.map +1 -0
  96. package/dist/faults/request-failure.d.ts +5 -0
  97. package/dist/faults/request-failure.js +24 -0
  98. package/dist/faults/request-failure.js.map +1 -0
  99. package/dist/investigator/agent.d.ts +26 -0
  100. package/dist/investigator/agent.js +197 -0
  101. package/dist/investigator/agent.js.map +1 -0
  102. package/dist/investigator/budget.d.ts +14 -0
  103. package/dist/investigator/budget.js +39 -0
  104. package/dist/investigator/budget.js.map +1 -0
  105. package/dist/investigator/file.d.ts +2 -0
  106. package/dist/investigator/file.js +7 -0
  107. package/dist/investigator/file.js.map +1 -0
  108. package/dist/investigator/groq.d.ts +5 -0
  109. package/dist/investigator/groq.js +26 -0
  110. package/dist/investigator/groq.js.map +1 -0
  111. package/dist/investigator/ledger.d.ts +17 -0
  112. package/dist/investigator/ledger.js +121 -0
  113. package/dist/investigator/ledger.js.map +1 -0
  114. package/dist/investigator/safe-source.d.ts +6 -0
  115. package/dist/investigator/safe-source.js +79 -0
  116. package/dist/investigator/safe-source.js.map +1 -0
  117. package/dist/investigator/schema.d.ts +110 -0
  118. package/dist/investigator/schema.js +53 -0
  119. package/dist/investigator/schema.js.map +1 -0
  120. package/dist/playwright.d.ts +3 -0
  121. package/dist/playwright.js +21 -0
  122. package/dist/playwright.js.map +1 -0
  123. package/dist/providers/errors.d.ts +21 -0
  124. package/dist/providers/errors.js +159 -0
  125. package/dist/providers/errors.js.map +1 -0
  126. package/dist/repair/file.d.ts +2 -0
  127. package/dist/repair/file.js +6 -0
  128. package/dist/repair/file.js.map +1 -0
  129. package/dist/repair/generator.d.ts +12 -0
  130. package/dist/repair/generator.js +74 -0
  131. package/dist/repair/generator.js.map +1 -0
  132. package/dist/repair/policy.d.ts +2 -0
  133. package/dist/repair/policy.js +70 -0
  134. package/dist/repair/policy.js.map +1 -0
  135. package/dist/repair/remote-proof-runner.d.ts +1 -0
  136. package/dist/repair/remote-proof-runner.js +53 -0
  137. package/dist/repair/remote-proof-runner.js.map +1 -0
  138. package/dist/repair/schema.d.ts +78 -0
  139. package/dist/repair/schema.js +44 -0
  140. package/dist/repair/schema.js.map +1 -0
  141. package/dist/repair/solari-validator.d.ts +25 -0
  142. package/dist/repair/solari-validator.js +231 -0
  143. package/dist/repair/solari-validator.js.map +1 -0
  144. package/dist/repair/validator.d.ts +16 -0
  145. package/dist/repair/validator.js +81 -0
  146. package/dist/repair/validator.js.map +1 -0
  147. package/dist/repair/workspace.d.ts +7 -0
  148. package/dist/repair/workspace.js +40 -0
  149. package/dist/repair/workspace.js.map +1 -0
  150. package/dist/report/browser-entry.d.ts +2 -0
  151. package/dist/report/browser-entry.js +15 -0
  152. package/dist/report/browser-entry.js.map +1 -0
  153. package/dist/report/bundle.d.ts +2 -0
  154. package/dist/report/bundle.js +77 -0
  155. package/dist/report/bundle.js.map +1 -0
  156. package/dist/report/classification.d.ts +9 -0
  157. package/dist/report/classification.js +55 -0
  158. package/dist/report/classification.js.map +1 -0
  159. package/dist/report/components/artifacts.d.ts +4 -0
  160. package/dist/report/components/artifacts.js +6 -0
  161. package/dist/report/components/artifacts.js.map +1 -0
  162. package/dist/report/components/experiments.d.ts +4 -0
  163. package/dist/report/components/experiments.js +7 -0
  164. package/dist/report/components/experiments.js.map +1 -0
  165. package/dist/report/components/hypotheses.d.ts +4 -0
  166. package/dist/report/components/hypotheses.js +26 -0
  167. package/dist/report/components/hypotheses.js.map +1 -0
  168. package/dist/report/components/indicators.d.ts +32 -0
  169. package/dist/report/components/indicators.js +42 -0
  170. package/dist/report/components/indicators.js.map +1 -0
  171. package/dist/report/components/layout.d.ts +29 -0
  172. package/dist/report/components/layout.js +20 -0
  173. package/dist/report/components/layout.js.map +1 -0
  174. package/dist/report/components/proof.d.ts +4 -0
  175. package/dist/report/components/proof.js +34 -0
  176. package/dist/report/components/proof.js.map +1 -0
  177. package/dist/report/components/reproduction.d.ts +4 -0
  178. package/dist/report/components/reproduction.js +19 -0
  179. package/dist/report/components/reproduction.js.map +1 -0
  180. package/dist/report/components/summary.d.ts +4 -0
  181. package/dist/report/components/summary.js +12 -0
  182. package/dist/report/components/summary.js.map +1 -0
  183. package/dist/report/components/verdict.d.ts +4 -0
  184. package/dist/report/components/verdict.js +27 -0
  185. package/dist/report/components/verdict.js.map +1 -0
  186. package/dist/report/model.d.ts +19 -0
  187. package/dist/report/model.js +82 -0
  188. package/dist/report/model.js.map +1 -0
  189. package/dist/report/open.d.ts +1 -0
  190. package/dist/report/open.js +24 -0
  191. package/dist/report/open.js.map +1 -0
  192. package/dist/report/publish.d.ts +12 -0
  193. package/dist/report/publish.js +67 -0
  194. package/dist/report/publish.js.map +1 -0
  195. package/dist/report/redaction.d.ts +1 -0
  196. package/dist/report/redaction.js +58 -0
  197. package/dist/report/redaction.js.map +1 -0
  198. package/dist/report/report-app.d.ts +6 -0
  199. package/dist/report/report-app.js +16 -0
  200. package/dist/report/report-app.js.map +1 -0
  201. package/dist/report/report-details.css +182 -0
  202. package/dist/report/report.css +404 -0
  203. package/dist/report/schema.d.ts +101 -0
  204. package/dist/report/schema.js +71 -0
  205. package/dist/report/schema.js.map +1 -0
  206. package/dist/reproducer/file.d.ts +3 -0
  207. package/dist/reproducer/file.js +14 -0
  208. package/dist/reproducer/file.js.map +1 -0
  209. package/dist/reproducer/schema.d.ts +17 -0
  210. package/dist/reproducer/schema.js +14 -0
  211. package/dist/reproducer/schema.js.map +1 -0
  212. package/dist/runner/local.d.ts +12 -0
  213. package/dist/runner/local.js +72 -0
  214. package/dist/runner/local.js.map +1 -0
  215. package/dist/runner/playwright-executor.d.ts +10 -0
  216. package/dist/runner/playwright-executor.js +148 -0
  217. package/dist/runner/playwright-executor.js.map +1 -0
  218. package/dist/security/credentials.d.ts +23 -0
  219. package/dist/security/credentials.js +105 -0
  220. package/dist/security/credentials.js.map +1 -0
  221. package/dist/solari/checkout-fixture.d.ts +3 -0
  222. package/dist/solari/checkout-fixture.js +54 -0
  223. package/dist/solari/checkout-fixture.js.map +1 -0
  224. package/dist/solari/executor.d.ts +17 -0
  225. package/dist/solari/executor.js +280 -0
  226. package/dist/solari/executor.js.map +1 -0
  227. package/dist/solari/retry.d.ts +7 -0
  228. package/dist/solari/retry.js +50 -0
  229. package/dist/solari/retry.js.map +1 -0
  230. package/dist/solari/run-demo.d.ts +21 -0
  231. package/dist/solari/run-demo.js +64 -0
  232. package/dist/solari/run-demo.js.map +1 -0
  233. package/dist/solari/transport.d.ts +1 -0
  234. package/dist/solari/transport.js +21 -0
  235. package/dist/solari/transport.js.map +1 -0
  236. package/dist/solari/usage.d.ts +23 -0
  237. package/dist/solari/usage.js +53 -0
  238. package/dist/solari/usage.js.map +1 -0
  239. package/dist/solari/websocket-proxy.d.ts +7 -0
  240. package/dist/solari/websocket-proxy.js +131 -0
  241. package/dist/solari/websocket-proxy.js.map +1 -0
  242. package/dist/ui/progress.d.ts +5 -0
  243. package/dist/ui/progress.js +16 -0
  244. package/dist/ui/progress.js.map +1 -0
  245. package/package.json +79 -0
@@ -0,0 +1,82 @@
1
+ import { z } from "zod";
2
+ export declare const revisionSchema: z.ZodObject<{
3
+ hash: z.ZodString;
4
+ shortHash: z.ZodString;
5
+ subject: z.ZodString;
6
+ }, z.core.$strip>;
7
+ export declare const revisionEvidenceSchema: z.ZodObject<{
8
+ revision: z.ZodObject<{
9
+ hash: z.ZodString;
10
+ shortHash: z.ZodString;
11
+ subject: z.ZodString;
12
+ }, z.core.$strip>;
13
+ classification: z.ZodEnum<{
14
+ good: "good";
15
+ bad: "bad";
16
+ incompatible: "incompatible";
17
+ inconclusive: "inconclusive";
18
+ }>;
19
+ reason: z.ZodString;
20
+ trials: z.ZodNumber;
21
+ passed: z.ZodNumber;
22
+ failed: z.ZodNumber;
23
+ errors: z.ZodNumber;
24
+ failureRate: z.ZodNumber;
25
+ lowerBound80: z.ZodNumber;
26
+ upperBound80: z.ZodNumber;
27
+ snapshotReuseCount: z.ZodNumber;
28
+ durationMs: z.ZodNumber;
29
+ }, z.core.$strip>;
30
+ export declare const bisectReportSchema: z.ZodObject<{
31
+ version: z.ZodLiteral<1>;
32
+ goodRevision: z.ZodObject<{
33
+ hash: z.ZodString;
34
+ shortHash: z.ZodString;
35
+ subject: z.ZodString;
36
+ }, z.core.$strip>;
37
+ badRevision: z.ZodObject<{
38
+ hash: z.ZodString;
39
+ shortHash: z.ZodString;
40
+ subject: z.ZodString;
41
+ }, z.core.$strip>;
42
+ firstFailingCommit: z.ZodNullable<z.ZodObject<{
43
+ hash: z.ZodString;
44
+ shortHash: z.ZodString;
45
+ subject: z.ZodString;
46
+ }, z.core.$strip>>;
47
+ earliestKnownBadCommit: z.ZodObject<{
48
+ hash: z.ZodString;
49
+ shortHash: z.ZodString;
50
+ subject: z.ZodString;
51
+ }, z.core.$strip>;
52
+ exact: z.ZodBoolean;
53
+ minimumFailureRate: z.ZodNumber;
54
+ evaluatedRevisionCount: z.ZodNumber;
55
+ totalRevisionCount: z.ZodNumber;
56
+ evidence: z.ZodArray<z.ZodObject<{
57
+ revision: z.ZodObject<{
58
+ hash: z.ZodString;
59
+ shortHash: z.ZodString;
60
+ subject: z.ZodString;
61
+ }, z.core.$strip>;
62
+ classification: z.ZodEnum<{
63
+ good: "good";
64
+ bad: "bad";
65
+ incompatible: "incompatible";
66
+ inconclusive: "inconclusive";
67
+ }>;
68
+ reason: z.ZodString;
69
+ trials: z.ZodNumber;
70
+ passed: z.ZodNumber;
71
+ failed: z.ZodNumber;
72
+ errors: z.ZodNumber;
73
+ failureRate: z.ZodNumber;
74
+ lowerBound80: z.ZodNumber;
75
+ upperBound80: z.ZodNumber;
76
+ snapshotReuseCount: z.ZodNumber;
77
+ durationMs: z.ZodNumber;
78
+ }, z.core.$strip>>;
79
+ }, z.core.$strip>;
80
+ export type BisectReport = z.infer<typeof bisectReportSchema>;
81
+ export type Revision = z.infer<typeof revisionSchema>;
82
+ export type RevisionEvidence = z.infer<typeof revisionEvidenceSchema>;
@@ -0,0 +1,33 @@
1
+ import { z } from "zod";
2
+ export const revisionSchema = z.object({
3
+ hash: z.string().regex(/^[0-9a-f]{40}$/u),
4
+ shortHash: z.string().regex(/^[0-9a-f]{7,12}$/u),
5
+ subject: z.string().min(1).max(500),
6
+ });
7
+ export const revisionEvidenceSchema = z.object({
8
+ revision: revisionSchema,
9
+ classification: z.enum(["good", "bad", "incompatible", "inconclusive"]),
10
+ reason: z.string().min(1).max(500),
11
+ trials: z.number().int().nonnegative(),
12
+ passed: z.number().int().nonnegative(),
13
+ failed: z.number().int().nonnegative(),
14
+ errors: z.number().int().nonnegative(),
15
+ failureRate: z.number().min(0).max(1),
16
+ lowerBound80: z.number().min(0).max(1),
17
+ upperBound80: z.number().min(0).max(1),
18
+ snapshotReuseCount: z.number().int().nonnegative(),
19
+ durationMs: z.number().int().nonnegative(),
20
+ });
21
+ export const bisectReportSchema = z.object({
22
+ version: z.literal(1),
23
+ goodRevision: revisionSchema,
24
+ badRevision: revisionSchema,
25
+ firstFailingCommit: revisionSchema.nullable(),
26
+ earliestKnownBadCommit: revisionSchema,
27
+ exact: z.boolean(),
28
+ minimumFailureRate: z.number().gt(0).max(1),
29
+ evaluatedRevisionCount: z.number().int().min(2),
30
+ totalRevisionCount: z.number().int().min(2),
31
+ evidence: z.array(revisionEvidenceSchema).min(2),
32
+ });
33
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/bisect/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,MAAM,CAAC;IACrC,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC;IACzC,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,mBAAmB,CAAC;IAChD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;CACpC,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,QAAQ,EAAE,cAAc;IACxB,cAAc,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,cAAc,CAAC,CAAC;IACvE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC;IAClC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IACtC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IACtC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IACtC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IACtC,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACrC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACtC,YAAY,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACtC,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;IAClD,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,WAAW,EAAE;CAC3C,CAAC,CAAA;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;IACrB,YAAY,EAAE,cAAc;IAC5B,WAAW,EAAE,cAAc;IAC3B,kBAAkB,EAAE,cAAc,CAAC,QAAQ,EAAE;IAC7C,sBAAsB,EAAE,cAAc;IACtC,KAAK,EAAE,CAAC,CAAC,OAAO,EAAE;IAClB,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3C,sBAAsB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/C,kBAAkB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3C,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;CACjD,CAAC,CAAA"}
@@ -0,0 +1,7 @@
1
+ import type { Sandbox } from "@solarisdk/sandbox";
2
+ export declare const REMOTE_SETUP_ROOT = "/work/flakelab-setup";
3
+ export declare class HistoricalIncompatibility extends Error {
4
+ }
5
+ export declare function requireCommand(sandbox: Sandbox, cwd: string, label: string, command: string, args: string[]): Promise<void>;
6
+ export declare function runDetachedSetup(sandbox: Sandbox, script: string, signal?: AbortSignal): Promise<void>;
7
+ export declare function runDetachedTrial(sandbox: Sandbox, cwd: string, selector: string, environment: Record<string, string>, signal?: AbortSignal): Promise<number>;
@@ -0,0 +1,95 @@
1
+ import { setTimeout as delay } from "node:timers/promises";
2
+ export const REMOTE_SETUP_ROOT = "/work/flakelab-setup";
3
+ const REMOTE_COMMAND_ROOT = "/work/flakelab-command";
4
+ const PREPARATION_COMMAND_TIMEOUT_MS = 2 * 60_000;
5
+ const TRIAL_COMMAND_TIMEOUT_MS = 90_000;
6
+ const SETUP_POLL_ATTEMPTS = 600;
7
+ export class HistoricalIncompatibility extends Error {
8
+ }
9
+ function labelForCommand(value) {
10
+ return value.toLowerCase().replaceAll(/[^a-z0-9]+/gu, "-").replaceAll(/(^-|-$)/gu, "");
11
+ }
12
+ async function pollExitStatus(sandbox, statusPath, label, attempts, signal) {
13
+ for (let attempt = 1; attempt <= attempts; attempt += 1) {
14
+ signal?.throwIfAborted();
15
+ try {
16
+ const status = await sandbox.files.readText(statusPath);
17
+ return Number(status.trim());
18
+ }
19
+ catch (error) {
20
+ const message = error instanceof Error ? error.message : "";
21
+ if (/control channel closed|connection/iu.test(message)) {
22
+ await sandbox.reconnect();
23
+ }
24
+ else if (!/enoent|not found|no such file/iu.test(message)) {
25
+ throw error;
26
+ }
27
+ }
28
+ await delay(1_000, undefined, { signal });
29
+ }
30
+ throw new Error(`${label} exceeded its timeout`);
31
+ }
32
+ async function runCommand(sandbox, cwd, label, command, args, timeoutMs = PREPARATION_COMMAND_TIMEOUT_MS, signal) {
33
+ const statusPath = `${REMOTE_COMMAND_ROOT}/${labelForCommand(label)}.exit`;
34
+ const started = await sandbox.commands.run("sh", {
35
+ args: [
36
+ "-c",
37
+ "status_path=$1; shift; mkdir -p \"$(dirname \"$status_path\")\"; "
38
+ + "\"$@\" >\"${status_path%.exit}.log\" 2>&1; exit_code=$?; "
39
+ + "printf '%s' \"$exit_code\" >\"$status_path\"",
40
+ "flakelab-command",
41
+ statusPath,
42
+ command,
43
+ ...args,
44
+ ],
45
+ background: true,
46
+ cwd,
47
+ });
48
+ if (started.exitCode !== 0) {
49
+ throw new Error(`Solari could not start ${command}`);
50
+ }
51
+ return pollExitStatus(sandbox, statusPath, `Solari ${command}`, Math.ceil(timeoutMs / 1_000), signal);
52
+ }
53
+ export async function requireCommand(sandbox, cwd, label, command, args) {
54
+ const exitCode = await runCommand(sandbox, cwd, label, command, args);
55
+ if (exitCode !== 0) {
56
+ throw new HistoricalIncompatibility(`${label} failed with exit code ${exitCode}`);
57
+ }
58
+ }
59
+ async function requireInfrastructureCommand(sandbox, label, command, args) {
60
+ const exitCode = await runCommand(sandbox, "/", label, command, args);
61
+ if (exitCode !== 0) {
62
+ throw new Error(`Solari ${label} failed with exit code ${exitCode}`);
63
+ }
64
+ }
65
+ export async function runDetachedSetup(sandbox, script, signal) {
66
+ await requireInfrastructureCommand(sandbox, "workspace preparation", "mkdir", [
67
+ "-p",
68
+ REMOTE_SETUP_ROOT,
69
+ ]);
70
+ const statusPath = `${REMOTE_SETUP_ROOT}/bootstrap.exit`;
71
+ const started = await sandbox.commands.run("sh", {
72
+ args: ["-c", script],
73
+ background: true,
74
+ cwd: "/",
75
+ });
76
+ if (started.exitCode !== 0) {
77
+ throw new Error("Solari could not start the detached bisect bootstrap");
78
+ }
79
+ const exitCode = await pollExitStatus(sandbox, statusPath, "Solari bisect bootstrap", SETUP_POLL_ATTEMPTS, signal);
80
+ if (exitCode !== 0) {
81
+ throw new Error(`Solari bisect bootstrap failed with exit code ${exitCode}`);
82
+ }
83
+ }
84
+ export async function runDetachedTrial(sandbox, cwd, selector, environment, signal) {
85
+ await sandbox.env(environment);
86
+ return runCommand(sandbox, cwd, "bisect trial", "pnpm", [
87
+ "exec",
88
+ "playwright",
89
+ "test",
90
+ `./${selector}`,
91
+ "--workers=1",
92
+ "--reporter=line",
93
+ ], TRIAL_COMMAND_TIMEOUT_MS, signal);
94
+ }
95
+ //# sourceMappingURL=solari-command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solari-command.js","sourceRoot":"","sources":["../../src/bisect/solari-command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { Reproducer } from "../reproducer/schema.js";
2
+ import type { Revision, RevisionEvidence } from "./schema.js";
3
+ interface SolariEvaluatorOptions {
4
+ apiKey: string;
5
+ baseUrl: string;
6
+ concurrency: number;
7
+ maxTrials: number;
8
+ minimumFailureRate: number;
9
+ projectPath: string;
10
+ repositoryRoot: string;
11
+ reproducer: Reproducer;
12
+ signal?: AbortSignal;
13
+ }
14
+ export declare class SolariRevisionEvaluator {
15
+ #private;
16
+ constructor(options: SolariEvaluatorOptions);
17
+ evaluate: (revision: Revision) => Promise<RevisionEvidence>;
18
+ dispose(): Promise<void>;
19
+ }
20
+ export {};
@@ -0,0 +1,310 @@
1
+ import { SandboxClient } from "@solarisdk/sandbox";
2
+ import { posix } from "node:path";
3
+ import { setTimeout as delay } from "node:timers/promises";
4
+ import { deriveTrialSeed } from "../core/plan.js";
5
+ import { createRevisionArchive } from "./archive.js";
6
+ import { classifyFailureProbability, wilsonInterval80 } from "./confidence.js";
7
+ import { HistoricalIncompatibility, REMOTE_SETUP_ROOT, requireCommand, runDetachedSetup, runDetachedTrial, } from "./solari-command.js";
8
+ const REMOTE_REPOSITORY = "/work/repository";
9
+ const REMOTE_ARCHIVE = "/work/flakelab-revision.tar";
10
+ const CLIENT_CALL_TIMEOUT_MS = 2 * 60_000;
11
+ const SANDBOX_TIMEOUT_MS = 15 * 60_000;
12
+ const PLAYWRIGHT_VERSION = "1.62.1";
13
+ const SANDBOX_CREATE_ATTEMPTS = 8;
14
+ const MAX_INFRASTRUCTURE_ERRORS = 4;
15
+ function inconclusiveReason(errors) {
16
+ if (errors >= MAX_INFRASTRUCTURE_ERRORS) {
17
+ return `stopped after ${errors} infrastructure errors`;
18
+ }
19
+ return "failure probability remained inconclusive within the trial budget";
20
+ }
21
+ function remoteProjectRoot(projectPath) {
22
+ if (projectPath === "") {
23
+ return REMOTE_REPOSITORY;
24
+ }
25
+ const segments = projectPath.replaceAll("\\", "/").split("/");
26
+ if (segments.some((segment) => segment === ".." || segment === "")) {
27
+ throw new Error("project path must remain inside the Git repository");
28
+ }
29
+ return posix.join(REMOTE_REPOSITORY, ...segments);
30
+ }
31
+ function validateSelector(selector) {
32
+ const normalized = selector.replaceAll("\\", "/");
33
+ if (normalized.startsWith("/") || normalized.split("/").includes("..")) {
34
+ throw new Error("reproducer test must be a relative path inside the project");
35
+ }
36
+ }
37
+ function faultEnvironment(reproducer, trialIndex) {
38
+ const fault = reproducer.faults[0];
39
+ return {
40
+ FLAKELAB_FAULT_KIND: "network-delay",
41
+ FLAKELAB_TRIAL_SEED: String(deriveTrialSeed(reproducer.seed, trialIndex)),
42
+ FLAKELAB_NETWORK_DELAY_MS: String(fault.delayMs),
43
+ FLAKELAB_NETWORK_PATTERN: fault.pattern,
44
+ FLAKELAB_REQUEST_FAILURE_STATUS: "0",
45
+ };
46
+ }
47
+ async function killSandbox(sandbox) {
48
+ sandbox.close();
49
+ await sandbox.kill();
50
+ }
51
+ export class SolariRevisionEvaluator {
52
+ #client;
53
+ #options;
54
+ #ownedSnapshotIds = new Set();
55
+ #prepared = new Map();
56
+ #preparing = new Map();
57
+ #basePreparation;
58
+ constructor(options) {
59
+ validateSelector(options.reproducer.test);
60
+ if (options.maxTrials < options.reproducer.trials || options.maxTrials > 100) {
61
+ throw new Error("max trials must be at least the reproducer trials and at most 100");
62
+ }
63
+ this.#options = options;
64
+ this.#client = new SandboxClient({
65
+ apiKey: options.apiKey,
66
+ baseUrl: options.baseUrl,
67
+ callTimeoutMs: CLIENT_CALL_TIMEOUT_MS,
68
+ });
69
+ }
70
+ async #createSandbox(role, fromSnapshot, revision) {
71
+ for (let attempt = 1; attempt <= SANDBOX_CREATE_ATTEMPTS; attempt += 1) {
72
+ try {
73
+ return await this.#client.create({
74
+ template: "base",
75
+ ...(fromSnapshot ? { fromSnapshot } : {}),
76
+ cpu: 4,
77
+ memMb: 8_192,
78
+ timeoutMs: SANDBOX_TIMEOUT_MS,
79
+ lifecycle: { onTimeout: "kill" },
80
+ metadata: {
81
+ product: "flakelab",
82
+ role,
83
+ ...(revision ? { revision } : {}),
84
+ },
85
+ });
86
+ }
87
+ catch (error) {
88
+ const message = error instanceof Error ? error.message : "Solari sandbox creation failed";
89
+ const transient = /fetch|connection|timeout|503|429|capacity|too many concurrent/iu
90
+ .test(message);
91
+ if (attempt === SANDBOX_CREATE_ATTEMPTS || !transient) {
92
+ throw error;
93
+ }
94
+ await delay(attempt * 500, undefined, { signal: this.#options.signal });
95
+ }
96
+ }
97
+ throw new Error("Solari sandbox creation retry budget exhausted");
98
+ }
99
+ async #prepareRevision(revision) {
100
+ const cached = this.#prepared.get(revision.hash);
101
+ if (cached) {
102
+ return cached;
103
+ }
104
+ const pending = this.#preparing.get(revision.hash);
105
+ if (pending) {
106
+ return pending;
107
+ }
108
+ const preparation = this.#createPreparedRevision(revision);
109
+ this.#preparing.set(revision.hash, preparation);
110
+ try {
111
+ const prepared = await preparation;
112
+ this.#prepared.set(revision.hash, prepared);
113
+ return prepared;
114
+ }
115
+ finally {
116
+ this.#preparing.delete(revision.hash);
117
+ }
118
+ }
119
+ async #createPreparedRevision(revision) {
120
+ this.#options.signal?.throwIfAborted();
121
+ const archive = await createRevisionArchive(this.#options.repositoryRoot, revision.hash);
122
+ const base = await this.#prepareBase();
123
+ const sandbox = await this.#createSandbox("bisect-preparation", base.snapshotId, revision.shortHash);
124
+ try {
125
+ await sandbox.connect();
126
+ await sandbox.files.write(REMOTE_ARCHIVE, archive);
127
+ await requireCommand(sandbox, "/work", "repository extraction", "mkdir", [
128
+ "-p",
129
+ REMOTE_REPOSITORY,
130
+ ]);
131
+ await requireCommand(sandbox, "/work", "repository extraction", "tar", [
132
+ "-xf",
133
+ REMOTE_ARCHIVE,
134
+ "-C",
135
+ REMOTE_REPOSITORY,
136
+ ]);
137
+ const projectRoot = remoteProjectRoot(this.#options.projectPath);
138
+ await requireCommand(sandbox, projectRoot, "historical package manifest", "test", ["-f", "package.json"]);
139
+ await requireCommand(sandbox, projectRoot, "historical dependency installation", "pnpm", [
140
+ "install",
141
+ "--frozen-lockfile",
142
+ ]);
143
+ await requireCommand(sandbox, projectRoot, "Chromium installation", "pnpm", [
144
+ "exec",
145
+ "playwright",
146
+ "install",
147
+ "chromium",
148
+ ]);
149
+ await requireCommand(sandbox, projectRoot, "historical test discovery", "pnpm", [
150
+ "exec",
151
+ "playwright",
152
+ "test",
153
+ this.#options.reproducer.test,
154
+ "--list",
155
+ ]);
156
+ const snapshotId = await sandbox.snapshot(`flakelab-bisect-${revision.shortHash}`);
157
+ this.#ownedSnapshotIds.add(snapshotId);
158
+ return { snapshotId };
159
+ }
160
+ finally {
161
+ await killSandbox(sandbox);
162
+ }
163
+ }
164
+ async #prepareBase() {
165
+ this.#basePreparation ??= this.#createBaseSnapshot();
166
+ return this.#basePreparation;
167
+ }
168
+ async #createBaseSnapshot() {
169
+ const sandbox = await this.#createSandbox("bisect-base");
170
+ try {
171
+ await sandbox.connect();
172
+ await runDetachedSetup(sandbox, `npm install --global node@22.14.0 >${REMOTE_SETUP_ROOT}/bootstrap.log 2>&1`
173
+ + ` && npm install --global pnpm@11.6.0 >>${REMOTE_SETUP_ROOT}/bootstrap.log 2>&1`
174
+ + ` && npx --yes playwright@${PLAYWRIGHT_VERSION} install-deps chromium >>${REMOTE_SETUP_ROOT}/bootstrap.log 2>&1`
175
+ + ` && npx --yes playwright@${PLAYWRIGHT_VERSION} install chromium >>${REMOTE_SETUP_ROOT}/bootstrap.log 2>&1`
176
+ + `; printf '%s' $? >${REMOTE_SETUP_ROOT}/bootstrap.exit`, this.#options.signal);
177
+ const snapshotId = await sandbox.snapshot("flakelab-bisect-base");
178
+ this.#ownedSnapshotIds.add(snapshotId);
179
+ return { snapshotId };
180
+ }
181
+ finally {
182
+ await killSandbox(sandbox);
183
+ }
184
+ }
185
+ async #runTrial(snapshotId, trialIndex) {
186
+ this.#options.signal?.throwIfAborted();
187
+ const sandbox = await this.#createSandbox("bisect-trial", snapshotId);
188
+ try {
189
+ await sandbox.connect();
190
+ const exitCode = await runDetachedTrial(sandbox, remoteProjectRoot(this.#options.projectPath), this.#options.reproducer.test, faultEnvironment(this.#options.reproducer, trialIndex), this.#options.signal);
191
+ return exitCode === 0 ? "passed" : "failed";
192
+ }
193
+ catch {
194
+ return "errors";
195
+ }
196
+ finally {
197
+ await killSandbox(sandbox);
198
+ }
199
+ }
200
+ async #runBatch(snapshotId, startIndex, count) {
201
+ const outcomes = new Map();
202
+ let nextIndex = 0;
203
+ const worker = async () => {
204
+ while (nextIndex < count) {
205
+ const offset = nextIndex;
206
+ nextIndex += 1;
207
+ outcomes.set(offset, await this.#runTrial(snapshotId, startIndex + offset));
208
+ }
209
+ };
210
+ await Promise.all(Array.from({ length: Math.min(this.#options.concurrency, count) }, worker));
211
+ const counts = { errors: 0, failed: 0, passed: 0 };
212
+ for (const outcome of outcomes.values()) {
213
+ counts[outcome] += 1;
214
+ }
215
+ return counts;
216
+ }
217
+ evaluate = async (revision) => {
218
+ const startedAt = Date.now();
219
+ let prepared;
220
+ try {
221
+ prepared = await this.#prepareRevision(revision);
222
+ }
223
+ catch (error) {
224
+ if (!(error instanceof HistoricalIncompatibility)) {
225
+ throw error;
226
+ }
227
+ return {
228
+ revision,
229
+ classification: "incompatible",
230
+ reason: error.message,
231
+ trials: 0,
232
+ passed: 0,
233
+ failed: 0,
234
+ errors: 0,
235
+ failureRate: 0,
236
+ lowerBound80: 0,
237
+ upperBound80: 1,
238
+ snapshotReuseCount: 0,
239
+ durationMs: Date.now() - startedAt,
240
+ };
241
+ }
242
+ const counts = { errors: 0, failed: 0, passed: 0 };
243
+ let classification = classifyFailureProbability(0, 0, 0, this.#options.minimumFailureRate);
244
+ while (counts.passed + counts.failed + counts.errors < this.#options.maxTrials) {
245
+ const completed = counts.passed + counts.failed + counts.errors;
246
+ const batchSize = Math.min(this.#options.reproducer.trials, this.#options.maxTrials - completed);
247
+ const batch = await this.#runBatch(prepared.snapshotId, completed, batchSize);
248
+ counts.passed += batch.passed;
249
+ counts.failed += batch.failed;
250
+ counts.errors += batch.errors;
251
+ if (counts.errors >= MAX_INFRASTRUCTURE_ERRORS) {
252
+ break;
253
+ }
254
+ const completedTrials = counts.passed + counts.failed + counts.errors;
255
+ classification = classifyFailureProbability(counts.failed, completedTrials, counts.errors, this.#options.minimumFailureRate);
256
+ if (classification !== "inconclusive") {
257
+ break;
258
+ }
259
+ }
260
+ const trials = counts.passed + counts.failed + counts.errors;
261
+ const validTrials = counts.passed + counts.failed;
262
+ const interval = wilsonInterval80(counts.failed, validTrials);
263
+ return {
264
+ revision,
265
+ classification,
266
+ reason: classification === "inconclusive"
267
+ ? inconclusiveReason(counts.errors)
268
+ : `80% confidence interval is ${interval.lower.toFixed(3)}–${interval.upper.toFixed(3)}`,
269
+ trials,
270
+ passed: counts.passed,
271
+ failed: counts.failed,
272
+ errors: counts.errors,
273
+ failureRate: validTrials === 0 ? 0 : counts.failed / validTrials,
274
+ lowerBound80: interval.lower,
275
+ upperBound80: interval.upper,
276
+ snapshotReuseCount: Math.max(0, trials - 1),
277
+ durationMs: Date.now() - startedAt,
278
+ };
279
+ };
280
+ async #deleteSnapshot(snapshotId) {
281
+ for (let attempt = 1; attempt <= 3; attempt += 1) {
282
+ try {
283
+ await this.#client.deleteSnapshot(snapshotId);
284
+ return undefined;
285
+ }
286
+ catch (error) {
287
+ const message = error instanceof Error ? error.message : "snapshot cleanup failed";
288
+ if (attempt < 3 && /live children|has children|conflict/iu.test(message)) {
289
+ await delay(attempt * 500);
290
+ }
291
+ else {
292
+ return error instanceof Error ? error : new Error(message);
293
+ }
294
+ }
295
+ }
296
+ return new Error("snapshot cleanup retry budget exhausted");
297
+ }
298
+ async dispose() {
299
+ let cleanupError;
300
+ for (const snapshotId of [...this.#ownedSnapshotIds].reverse()) {
301
+ cleanupError ??= await this.#deleteSnapshot(snapshotId);
302
+ }
303
+ this.#prepared.clear();
304
+ this.#ownedSnapshotIds.clear();
305
+ if (cleanupError) {
306
+ throw cleanupError;
307
+ }
308
+ }
309
+ }
310
+ //# sourceMappingURL=solari-evaluator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"solari-evaluator.js","sourceRoot":"","sources":["../../src/bisect/solari-evaluator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface ChangedTestSelection {
2
+ changedFiles: string[];
3
+ mode: "affected-suite" | "direct" | "none";
4
+ tests: string[];
5
+ truncated: boolean;
6
+ }
7
+ export declare function selectChangedTests(projectRoot: string, baseRevision: string, headRevision: string): Promise<ChangedTestSelection>;