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.
- package/README.md +341 -0
- package/bin/flakelab.mjs +3 -0
- package/dist/artifacts/ndjson.d.ts +3 -0
- package/dist/artifacts/ndjson.js +16 -0
- package/dist/artifacts/ndjson.js.map +1 -0
- package/dist/bisect/archive.d.ts +1 -0
- package/dist/bisect/archive.js +14 -0
- package/dist/bisect/archive.js.map +1 -0
- package/dist/bisect/confidence.d.ts +7 -0
- package/dist/bisect/confidence.js +27 -0
- package/dist/bisect/confidence.js.map +1 -0
- package/dist/bisect/engine.d.ts +10 -0
- package/dist/bisect/engine.js +110 -0
- package/dist/bisect/engine.js.map +1 -0
- package/dist/bisect/git.d.ts +7 -0
- package/dist/bisect/git.js +56 -0
- package/dist/bisect/git.js.map +1 -0
- package/dist/bisect/schema.d.ts +82 -0
- package/dist/bisect/schema.js +33 -0
- package/dist/bisect/schema.js.map +1 -0
- package/dist/bisect/solari-command.d.ts +7 -0
- package/dist/bisect/solari-command.js +95 -0
- package/dist/bisect/solari-command.js.map +1 -0
- package/dist/bisect/solari-evaluator.d.ts +20 -0
- package/dist/bisect/solari-evaluator.js +310 -0
- package/dist/bisect/solari-evaluator.js.map +1 -0
- package/dist/ci/changed-tests.d.ts +7 -0
- package/dist/ci/changed-tests.js +104 -0
- package/dist/ci/changed-tests.js.map +1 -0
- package/dist/ci/job-summary.d.ts +11 -0
- package/dist/ci/job-summary.js +45 -0
- package/dist/ci/job-summary.js.map +1 -0
- package/dist/ci/select-command.d.ts +1 -0
- package/dist/ci/select-command.js +49 -0
- package/dist/ci/select-command.js.map +1 -0
- package/dist/ci/summary-command.d.ts +1 -0
- package/dist/ci/summary-command.js +46 -0
- package/dist/ci/summary-command.js.map +1 -0
- package/dist/cli-help.d.ts +2 -0
- package/dist/cli-help.js +47 -0
- package/dist/cli-help.js.map +1 -0
- package/dist/cli.d.ts +1 -0
- package/dist/cli.js +121 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/bisect.d.ts +2 -0
- package/dist/commands/bisect.js +63 -0
- package/dist/commands/bisect.js.map +1 -0
- package/dist/commands/diagnose.d.ts +2 -0
- package/dist/commands/diagnose.js +27 -0
- package/dist/commands/diagnose.js.map +1 -0
- package/dist/commands/discover.d.ts +2 -0
- package/dist/commands/discover.js +46 -0
- package/dist/commands/discover.js.map +1 -0
- package/dist/commands/doctor.d.ts +8 -0
- package/dist/commands/doctor.js +78 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/investigate.d.ts +2 -0
- package/dist/commands/investigate.js +43 -0
- package/dist/commands/investigate.js.map +1 -0
- package/dist/commands/options.d.ts +38 -0
- package/dist/commands/options.js +35 -0
- package/dist/commands/options.js.map +1 -0
- package/dist/commands/prove.d.ts +2 -0
- package/dist/commands/prove.js +21 -0
- package/dist/commands/prove.js.map +1 -0
- package/dist/commands/repair.d.ts +2 -0
- package/dist/commands/repair.js +55 -0
- package/dist/commands/repair.js.map +1 -0
- package/dist/commands/replay.d.ts +2 -0
- package/dist/commands/replay.js +26 -0
- package/dist/commands/replay.js.map +1 -0
- package/dist/commands/report.d.ts +2 -0
- package/dist/commands/report.js +79 -0
- package/dist/commands/report.js.map +1 -0
- package/dist/commands/scan.d.ts +12 -0
- package/dist/commands/scan.js +86 -0
- package/dist/commands/scan.js.map +1 -0
- package/dist/core/plan.d.ts +3 -0
- package/dist/core/plan.js +17 -0
- package/dist/core/plan.js.map +1 -0
- package/dist/discovery/evaluate.d.ts +22 -0
- package/dist/discovery/evaluate.js +81 -0
- package/dist/discovery/evaluate.js.map +1 -0
- package/dist/discovery/minimize.d.ts +24 -0
- package/dist/discovery/minimize.js +73 -0
- package/dist/discovery/minimize.js.map +1 -0
- package/dist/domain/schema.d.ts +155 -0
- package/dist/domain/schema.js +67 -0
- package/dist/domain/schema.js.map +1 -0
- package/dist/faults/install.d.ts +4 -0
- package/dist/faults/install.js +9 -0
- package/dist/faults/install.js.map +1 -0
- package/dist/faults/network-delay.d.ts +5 -0
- package/dist/faults/network-delay.js +34 -0
- package/dist/faults/network-delay.js.map +1 -0
- package/dist/faults/request-failure.d.ts +5 -0
- package/dist/faults/request-failure.js +24 -0
- package/dist/faults/request-failure.js.map +1 -0
- package/dist/investigator/agent.d.ts +26 -0
- package/dist/investigator/agent.js +197 -0
- package/dist/investigator/agent.js.map +1 -0
- package/dist/investigator/budget.d.ts +14 -0
- package/dist/investigator/budget.js +39 -0
- package/dist/investigator/budget.js.map +1 -0
- package/dist/investigator/file.d.ts +2 -0
- package/dist/investigator/file.js +7 -0
- package/dist/investigator/file.js.map +1 -0
- package/dist/investigator/groq.d.ts +5 -0
- package/dist/investigator/groq.js +26 -0
- package/dist/investigator/groq.js.map +1 -0
- package/dist/investigator/ledger.d.ts +17 -0
- package/dist/investigator/ledger.js +121 -0
- package/dist/investigator/ledger.js.map +1 -0
- package/dist/investigator/safe-source.d.ts +6 -0
- package/dist/investigator/safe-source.js +79 -0
- package/dist/investigator/safe-source.js.map +1 -0
- package/dist/investigator/schema.d.ts +110 -0
- package/dist/investigator/schema.js +53 -0
- package/dist/investigator/schema.js.map +1 -0
- package/dist/playwright.d.ts +3 -0
- package/dist/playwright.js +21 -0
- package/dist/playwright.js.map +1 -0
- package/dist/providers/errors.d.ts +21 -0
- package/dist/providers/errors.js +159 -0
- package/dist/providers/errors.js.map +1 -0
- package/dist/repair/file.d.ts +2 -0
- package/dist/repair/file.js +6 -0
- package/dist/repair/file.js.map +1 -0
- package/dist/repair/generator.d.ts +12 -0
- package/dist/repair/generator.js +74 -0
- package/dist/repair/generator.js.map +1 -0
- package/dist/repair/policy.d.ts +2 -0
- package/dist/repair/policy.js +70 -0
- package/dist/repair/policy.js.map +1 -0
- package/dist/repair/remote-proof-runner.d.ts +1 -0
- package/dist/repair/remote-proof-runner.js +53 -0
- package/dist/repair/remote-proof-runner.js.map +1 -0
- package/dist/repair/schema.d.ts +78 -0
- package/dist/repair/schema.js +44 -0
- package/dist/repair/schema.js.map +1 -0
- package/dist/repair/solari-validator.d.ts +25 -0
- package/dist/repair/solari-validator.js +231 -0
- package/dist/repair/solari-validator.js.map +1 -0
- package/dist/repair/validator.d.ts +16 -0
- package/dist/repair/validator.js +81 -0
- package/dist/repair/validator.js.map +1 -0
- package/dist/repair/workspace.d.ts +7 -0
- package/dist/repair/workspace.js +40 -0
- package/dist/repair/workspace.js.map +1 -0
- package/dist/report/browser-entry.d.ts +2 -0
- package/dist/report/browser-entry.js +15 -0
- package/dist/report/browser-entry.js.map +1 -0
- package/dist/report/bundle.d.ts +2 -0
- package/dist/report/bundle.js +77 -0
- package/dist/report/bundle.js.map +1 -0
- package/dist/report/classification.d.ts +9 -0
- package/dist/report/classification.js +55 -0
- package/dist/report/classification.js.map +1 -0
- package/dist/report/components/artifacts.d.ts +4 -0
- package/dist/report/components/artifacts.js +6 -0
- package/dist/report/components/artifacts.js.map +1 -0
- package/dist/report/components/experiments.d.ts +4 -0
- package/dist/report/components/experiments.js +7 -0
- package/dist/report/components/experiments.js.map +1 -0
- package/dist/report/components/hypotheses.d.ts +4 -0
- package/dist/report/components/hypotheses.js +26 -0
- package/dist/report/components/hypotheses.js.map +1 -0
- package/dist/report/components/indicators.d.ts +32 -0
- package/dist/report/components/indicators.js +42 -0
- package/dist/report/components/indicators.js.map +1 -0
- package/dist/report/components/layout.d.ts +29 -0
- package/dist/report/components/layout.js +20 -0
- package/dist/report/components/layout.js.map +1 -0
- package/dist/report/components/proof.d.ts +4 -0
- package/dist/report/components/proof.js +34 -0
- package/dist/report/components/proof.js.map +1 -0
- package/dist/report/components/reproduction.d.ts +4 -0
- package/dist/report/components/reproduction.js +19 -0
- package/dist/report/components/reproduction.js.map +1 -0
- package/dist/report/components/summary.d.ts +4 -0
- package/dist/report/components/summary.js +12 -0
- package/dist/report/components/summary.js.map +1 -0
- package/dist/report/components/verdict.d.ts +4 -0
- package/dist/report/components/verdict.js +27 -0
- package/dist/report/components/verdict.js.map +1 -0
- package/dist/report/model.d.ts +19 -0
- package/dist/report/model.js +82 -0
- package/dist/report/model.js.map +1 -0
- package/dist/report/open.d.ts +1 -0
- package/dist/report/open.js +24 -0
- package/dist/report/open.js.map +1 -0
- package/dist/report/publish.d.ts +12 -0
- package/dist/report/publish.js +67 -0
- package/dist/report/publish.js.map +1 -0
- package/dist/report/redaction.d.ts +1 -0
- package/dist/report/redaction.js +58 -0
- package/dist/report/redaction.js.map +1 -0
- package/dist/report/report-app.d.ts +6 -0
- package/dist/report/report-app.js +16 -0
- package/dist/report/report-app.js.map +1 -0
- package/dist/report/report-details.css +182 -0
- package/dist/report/report.css +404 -0
- package/dist/report/schema.d.ts +101 -0
- package/dist/report/schema.js +71 -0
- package/dist/report/schema.js.map +1 -0
- package/dist/reproducer/file.d.ts +3 -0
- package/dist/reproducer/file.js +14 -0
- package/dist/reproducer/file.js.map +1 -0
- package/dist/reproducer/schema.d.ts +17 -0
- package/dist/reproducer/schema.js +14 -0
- package/dist/reproducer/schema.js.map +1 -0
- package/dist/runner/local.d.ts +12 -0
- package/dist/runner/local.js +72 -0
- package/dist/runner/local.js.map +1 -0
- package/dist/runner/playwright-executor.d.ts +10 -0
- package/dist/runner/playwright-executor.js +148 -0
- package/dist/runner/playwright-executor.js.map +1 -0
- package/dist/security/credentials.d.ts +23 -0
- package/dist/security/credentials.js +105 -0
- package/dist/security/credentials.js.map +1 -0
- package/dist/solari/checkout-fixture.d.ts +3 -0
- package/dist/solari/checkout-fixture.js +54 -0
- package/dist/solari/checkout-fixture.js.map +1 -0
- package/dist/solari/executor.d.ts +17 -0
- package/dist/solari/executor.js +280 -0
- package/dist/solari/executor.js.map +1 -0
- package/dist/solari/retry.d.ts +7 -0
- package/dist/solari/retry.js +50 -0
- package/dist/solari/retry.js.map +1 -0
- package/dist/solari/run-demo.d.ts +21 -0
- package/dist/solari/run-demo.js +64 -0
- package/dist/solari/run-demo.js.map +1 -0
- package/dist/solari/transport.d.ts +1 -0
- package/dist/solari/transport.js +21 -0
- package/dist/solari/transport.js.map +1 -0
- package/dist/solari/usage.d.ts +23 -0
- package/dist/solari/usage.js +53 -0
- package/dist/solari/usage.js.map +1 -0
- package/dist/solari/websocket-proxy.d.ts +7 -0
- package/dist/solari/websocket-proxy.js +131 -0
- package/dist/solari/websocket-proxy.js.map +1 -0
- package/dist/ui/progress.d.ts +5 -0
- package/dist/ui/progress.js +16 -0
- package/dist/ui/progress.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { build } from "vite";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { mkdir, writeFile } from "node:fs/promises";
|
|
4
|
+
import { dirname } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
/** Large enough that no report asset is ever emitted as a separate, breakable file. */
|
|
7
|
+
const MAX_INLINE_ASSET_BYTES = 16 * 1_024 * 1_024;
|
|
8
|
+
function escapeEmbeddedJson(value) {
|
|
9
|
+
return JSON.stringify(value)
|
|
10
|
+
.replaceAll("<", String.raw `\u003c`)
|
|
11
|
+
.replaceAll(">", String.raw `\u003e`)
|
|
12
|
+
.replaceAll("&", String.raw `\u0026`)
|
|
13
|
+
.replaceAll("\u2028", String.raw `\u2028`)
|
|
14
|
+
.replaceAll("\u2029", String.raw `\u2029`);
|
|
15
|
+
}
|
|
16
|
+
function escapeHtml(value) {
|
|
17
|
+
return value
|
|
18
|
+
.replaceAll("&", "&")
|
|
19
|
+
.replaceAll("<", "<")
|
|
20
|
+
.replaceAll(">", ">")
|
|
21
|
+
.replaceAll('"', """);
|
|
22
|
+
}
|
|
23
|
+
function htmlDocument(report, script, styles) {
|
|
24
|
+
return `<!doctype html>
|
|
25
|
+
<html lang="en">
|
|
26
|
+
<head>
|
|
27
|
+
<meta charset="utf-8">
|
|
28
|
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
29
|
+
<meta name="color-scheme" content="light dark">
|
|
30
|
+
<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src data:; font-src data:; style-src 'unsafe-inline'; script-src 'unsafe-inline'">
|
|
31
|
+
<title>FlakeLab · ${escapeHtml(report.test)}</title>
|
|
32
|
+
<style>${styles}</style>
|
|
33
|
+
</head>
|
|
34
|
+
<body>
|
|
35
|
+
<div id="root"></div>
|
|
36
|
+
<script id="flakelab-report" type="application/json">${escapeEmbeddedJson(report)}</script>
|
|
37
|
+
<script type="module">${script.replaceAll("</script", String.raw `<\/script`)}</script>
|
|
38
|
+
</body>
|
|
39
|
+
</html>
|
|
40
|
+
`;
|
|
41
|
+
}
|
|
42
|
+
export async function writePortableReport(projectRoot, outputPath, report) {
|
|
43
|
+
const sourceEntry = fileURLToPath(new URL("./browser-entry.tsx", import.meta.url));
|
|
44
|
+
const compiledEntry = fileURLToPath(new URL("./browser-entry.js", import.meta.url));
|
|
45
|
+
const result = await build({
|
|
46
|
+
configFile: false,
|
|
47
|
+
logLevel: "silent",
|
|
48
|
+
root: projectRoot,
|
|
49
|
+
build: {
|
|
50
|
+
// Everything the report references — the Geist Mono woff2 above all — has to become a
|
|
51
|
+
// data URI, or the generated file stops working the moment it is moved.
|
|
52
|
+
assetsInlineLimit: MAX_INLINE_ASSET_BYTES,
|
|
53
|
+
cssCodeSplit: false,
|
|
54
|
+
minify: true,
|
|
55
|
+
write: false,
|
|
56
|
+
rollupOptions: {
|
|
57
|
+
input: existsSync(sourceEntry) ? sourceEntry : compiledEntry,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
});
|
|
61
|
+
const outputs = Array.isArray(result) ? result : [result];
|
|
62
|
+
const entries = outputs.flatMap((output) => "output" in output ? output.output : []);
|
|
63
|
+
const script = entries.find((entry) => entry.type === "chunk" && entry.isEntry);
|
|
64
|
+
const stylesheet = entries.find((entry) => entry.type === "asset" && entry.fileName.endsWith(".css"));
|
|
65
|
+
if (script?.type !== "chunk") {
|
|
66
|
+
throw new Error("Vite did not produce the FlakeLab report script");
|
|
67
|
+
}
|
|
68
|
+
const detached = entries.filter((entry) => entry.type === "asset" && !entry.fileName.endsWith(".css"));
|
|
69
|
+
if (detached.length > 0) {
|
|
70
|
+
const names = detached.map((entry) => entry.fileName).join(", ");
|
|
71
|
+
throw new Error(`Report assets must be inlined to stay portable: ${names}`);
|
|
72
|
+
}
|
|
73
|
+
const styles = stylesheet?.type === "asset" ? stylesheet.source.toString() : "";
|
|
74
|
+
await mkdir(dirname(outputPath), { recursive: true });
|
|
75
|
+
await writeFile(outputPath, htmlDocument(report, script.code, styles), "utf8");
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=bundle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/report/bundle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { InvestigationReport } from "../investigator/schema.js";
|
|
2
|
+
import type { FailureOwnership } from "./schema.js";
|
|
3
|
+
interface Classification {
|
|
4
|
+
classification: FailureOwnership;
|
|
5
|
+
confidence: "high" | "medium" | "low";
|
|
6
|
+
rationale: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function classifyFailure(investigation: InvestigationReport): Classification;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
const RULES = [
|
|
2
|
+
{
|
|
3
|
+
category: "PRODUCT_RACE",
|
|
4
|
+
terms: ["deadline", "race", "hydration", "ordering", "before the"],
|
|
5
|
+
rationale: "A controlled timing intervention changed product behavior at an application boundary.",
|
|
6
|
+
},
|
|
7
|
+
{
|
|
8
|
+
category: "TEST_SELECTOR",
|
|
9
|
+
terms: ["locator", "selector", "detached element", "stale element"],
|
|
10
|
+
rationale: "The evidence points to how the test identifies or retains an element.",
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
category: "TEST_STATE_LEAK",
|
|
14
|
+
terms: ["shared state", "state leak", "test order"],
|
|
15
|
+
rationale: "The failure depends on mutable state shared across otherwise independent tests.",
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
category: "AUTH_EXPIRATION",
|
|
19
|
+
terms: ["authentication", "expired session", "access token"],
|
|
20
|
+
rationale: "The observed failure is associated with authentication lifetime or session state.",
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
category: "BACKEND_NONDETERMINISM",
|
|
24
|
+
terms: ["non-2xx", "backend", "server response", "status code"],
|
|
25
|
+
rationale: "The evidence attributes varying behavior to backend responses or server state.",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
category: "EXTERNAL_DEPENDENCY",
|
|
29
|
+
terms: ["third-party", "external dependency", "upstream"],
|
|
30
|
+
rationale: "The causal intervention isolates a service outside the application boundary.",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
category: "INFRASTRUCTURE_PRESSURE",
|
|
34
|
+
terms: ["cpu", "memory pressure", "ci load", "worker pressure"],
|
|
35
|
+
rationale: "The failure correlates with constrained execution resources or worker pressure.",
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
export function classifyFailure(investigation) {
|
|
39
|
+
const confirmed = investigation.hypotheses.find((hypothesis) => hypothesis.id === investigation.conclusionHypothesisId && hypothesis.status === "confirmed");
|
|
40
|
+
const evidence = `${investigation.conclusion} ${confirmed?.explanation ?? ""}`.toLowerCase();
|
|
41
|
+
const rule = RULES.find((candidate) => candidate.terms.some((term) => evidence.includes(term)));
|
|
42
|
+
if (!rule) {
|
|
43
|
+
return {
|
|
44
|
+
classification: "UNKNOWN",
|
|
45
|
+
confidence: "low",
|
|
46
|
+
rationale: "The current evidence does not map cleanly to a supported ownership category.",
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
classification: rule.category,
|
|
51
|
+
confidence: confirmed ? "high" : "medium",
|
|
52
|
+
rationale: rule.rationale,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=classification.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classification.js","sourceRoot":"","sources":["../../src/report/classification.ts"],"names":[],"mappings":"AASA,MAAM,KAAK,GAAyE;IAClF;QACE,QAAQ,EAAE,cAAc;QACxB,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,CAAC;QAClE,SAAS,EAAE,uFAAuF;KACnG;IACD;QACE,QAAQ,EAAE,eAAe;QACzB,KAAK,EAAE,CAAC,SAAS,EAAE,UAAU,EAAE,kBAAkB,EAAE,eAAe,CAAC;QACnE,SAAS,EAAE,uEAAuE;KACnF;IACD;QACE,QAAQ,EAAE,iBAAiB;QAC3B,KAAK,EAAE,CAAC,cAAc,EAAE,YAAY,EAAE,YAAY,CAAC;QACnD,SAAS,EAAE,iFAAiF;KAC7F;IACD;QACE,QAAQ,EAAE,iBAAiB;QAC3B,KAAK,EAAE,CAAC,gBAAgB,EAAE,iBAAiB,EAAE,cAAc,CAAC;QAC5D,SAAS,EAAE,mFAAmF;KAC/F;IACD;QACE,QAAQ,EAAE,wBAAwB;QAClC,KAAK,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,iBAAiB,EAAE,aAAa,CAAC;QAC/D,SAAS,EAAE,gFAAgF;KAC5F;IACD;QACE,QAAQ,EAAE,qBAAqB;QAC/B,KAAK,EAAE,CAAC,aAAa,EAAE,qBAAqB,EAAE,UAAU,CAAC;QACzD,SAAS,EAAE,8EAA8E;KAC1F;IACD;QACE,QAAQ,EAAE,yBAAyB;QACnC,KAAK,EAAE,CAAC,KAAK,EAAE,iBAAiB,EAAE,SAAS,EAAE,iBAAiB,CAAC;QAC/D,SAAS,EAAE,iFAAiF;KAC7F;CACF,CAAA;AAED,MAAM,UAAU,eAAe,CAAC,aAAkC;IAChE,MAAM,SAAS,GAAG,aAAa,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAC7D,UAAU,CAAC,EAAE,KAAK,aAAa,CAAC,sBAAsB,IAAI,UAAU,CAAC,MAAM,KAAK,WAAW,CAAC,CAAA;IAC9F,MAAM,QAAQ,GAAG,GAAG,aAAa,CAAC,UAAU,IAAI,SAAS,EAAE,WAAW,IAAI,EAAE,EAAE,CAAC,WAAW,EAAE,CAAA;IAC5F,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CACpC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAC1D,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO;YACL,cAAc,EAAE,SAAS;YACzB,UAAU,EAAE,KAAK;YACjB,SAAS,EAAE,8EAA8E;SAC1F,CAAA;IACH,CAAC;IACD,OAAO;QACL,cAAc,EAAE,IAAI,CAAC,QAAQ;QAC7B,UAAU,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ;QACzC,SAAS,EAAE,IAAI,CAAC,SAAS;KAC1B,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Section } from "./layout.js";
|
|
3
|
+
export function ArtifactSection({ report }) {
|
|
4
|
+
return _jsxs(Section, { id: "artifacts", meta: `${report.artifacts.length} files`, ordinal: "07", title: "Reproducible artifacts", children: [_jsx("p", { className: "lede", children: "Paths are relative to the project root. They open only when this report is read alongside the run that produced it; nothing here is fetched over the network." }), _jsx("ul", { className: "artifacts", children: report.artifacts.map((artifact) => _jsx("li", { children: _jsxs("a", { className: "artifact", href: artifact.path, children: [_jsx("span", { className: "artifact-label", children: artifact.label }), _jsx("span", { className: "artifact-path", children: artifact.path })] }) }, artifact.label)) })] });
|
|
5
|
+
}
|
|
6
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../../../src/report/components/artifacts.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAErC,MAAM,UAAU,eAAe,CAAC,EAAE,MAAM,EAEtC;IACA,OAAO,MAAC,OAAO,IACb,EAAE,EAAC,WAAW,EACd,IAAI,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,QAAQ,EACxC,OAAO,EAAC,IAAI,EACZ,KAAK,EAAC,wBAAwB,aAE9B,YAAG,SAAS,EAAC,MAAM,8KAGf,EACJ,aAAI,SAAS,EAAC,WAAW,YACtB,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,uBAClC,aAAG,SAAS,EAAC,UAAU,EAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,aACzC,eAAM,SAAS,EAAC,gBAAgB,YAAE,QAAQ,CAAC,KAAK,GAAQ,EACxD,eAAM,SAAS,EAAC,eAAe,YAAE,QAAQ,CAAC,IAAI,GAAQ,IACpD,IAJuC,QAAQ,CAAC,KAAK,CAKtD,CAAC,GACH,IACG,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { percent, RateCell, TrialCounts } from "./indicators.js";
|
|
3
|
+
import { Section, TableScroll } from "./layout.js";
|
|
4
|
+
export function ExperimentSection({ report }) {
|
|
5
|
+
return _jsxs(Section, { id: "experiments", meta: `${report.experiments.length} interventions`, ordinal: "04", title: "Experiment record", children: [_jsx("p", { className: "table-note", children: "Controlled interventions in execution order. Floor is the 80% lower confidence bound on the observed failure rate." }), _jsx(TableScroll, { label: "Experiment record", children: _jsxs("table", { className: "grid", children: [_jsx("caption", { className: "sr-only", children: "Experiment record" }), _jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: "ID" }), _jsx("th", { scope: "col", children: "Tests" }), _jsx("th", { scope: "col", children: "Condition" }), _jsx("th", { className: "num", scope: "col", children: "Trials" }), _jsx("th", { className: "num", scope: "col", children: "Failure rate" }), _jsx("th", { className: "num", scope: "col", children: "Floor" })] }) }), _jsx("tbody", { children: report.experiments.map((experiment) => _jsxs("tr", { id: `exp-${experiment.id}`, children: [_jsx("th", { className: "mono id-cell", scope: "row", children: experiment.id }), _jsx("td", { className: "mono", children: experiment.hypothesisId }), _jsx("td", { children: experiment.condition }), _jsx("td", { className: "num", children: _jsx(TrialCounts, { result: experiment.result }) }), _jsx("td", { className: "num", children: _jsx(RateCell, { rate: experiment.result.failureRate }) }), _jsx("td", { className: "num mono", children: percent(experiment.result.lowerBound80) })] }, experiment.id)) })] }) })] });
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=experiments.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"experiments.js","sourceRoot":"","sources":["../../../src/report/components/experiments.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAChE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAElD,MAAM,UAAU,iBAAiB,CAAC,EAAE,MAAM,EAExC;IACA,OAAO,MAAC,OAAO,IACb,EAAE,EAAC,aAAa,EAChB,IAAI,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,gBAAgB,EAClD,OAAO,EAAC,IAAI,EACZ,KAAK,EAAC,mBAAmB,aAEzB,YAAG,SAAS,EAAC,YAAY,mIAGrB,EACJ,KAAC,WAAW,IAAC,KAAK,EAAC,mBAAmB,YACpC,iBAAO,SAAS,EAAC,MAAM,aACrB,kBAAS,SAAS,EAAC,SAAS,kCAA4B,EACxD,0BACE,yBACE,aAAI,KAAK,EAAC,KAAK,mBAAQ,EACvB,aAAI,KAAK,EAAC,KAAK,sBAAW,EAC1B,aAAI,KAAK,EAAC,KAAK,0BAAe,EAC9B,aAAI,SAAS,EAAC,KAAK,EAAC,KAAK,EAAC,KAAK,uBAAY,EAC3C,aAAI,SAAS,EAAC,KAAK,EAAC,KAAK,EAAC,KAAK,6BAAkB,EACjD,aAAI,SAAS,EAAC,KAAK,EAAC,KAAK,EAAC,KAAK,sBAAW,IACvC,GACC,EACR,0BACG,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,cAAI,EAAE,EAAE,OAAO,UAAU,CAAC,EAAE,EAAE,aACpE,aAAI,SAAS,EAAC,cAAc,EAAC,KAAK,EAAC,KAAK,YAAE,UAAU,CAAC,EAAE,GAAM,EAC7D,aAAI,SAAS,EAAC,MAAM,YAAE,UAAU,CAAC,YAAY,GAAM,EACnD,uBAAK,UAAU,CAAC,SAAS,GAAM,EAC/B,aAAI,SAAS,EAAC,KAAK,YAAC,KAAC,WAAW,IAAC,MAAM,EAAE,UAAU,CAAC,MAAM,GAAI,GAAK,EACnE,aAAI,SAAS,EAAC,KAAK,YAAC,KAAC,QAAQ,IAAC,IAAI,EAAE,UAAU,CAAC,MAAM,CAAC,WAAW,GAAI,GAAK,EAC1E,aAAI,SAAS,EAAC,UAAU,YAAE,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,YAAY,CAAC,GAAM,KANI,UAAU,CAAC,EAAE,CAOrF,CAAC,GACA,IACF,GACI,IACN,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Section } from "./layout.js";
|
|
3
|
+
const GROUPS = [
|
|
4
|
+
{ heading: "Confirmed", status: "confirmed" },
|
|
5
|
+
{ heading: "Still proposed", status: "proposed" },
|
|
6
|
+
{ heading: "Rejected", status: "rejected" },
|
|
7
|
+
];
|
|
8
|
+
function EvidenceRefs({ hypothesis, known }) {
|
|
9
|
+
return _jsxs("p", { className: "evidence-refs", children: [_jsx("span", { className: "evidence-label", children: "Evidence" }), hypothesis.evidenceExperimentIds.map((id) => known.has(id)
|
|
10
|
+
? _jsx("a", { className: "ref", href: `#exp-${encodeURIComponent(id)}`, children: id }, id)
|
|
11
|
+
: _jsx("span", { className: "ref ref-missing", children: id }, id))] });
|
|
12
|
+
}
|
|
13
|
+
function HypothesisEntry({ hypothesis, known }) {
|
|
14
|
+
return _jsxs("article", { className: `hypothesis hypothesis-${hypothesis.status}`, children: [_jsxs("h4", { className: "hypothesis-head", children: [_jsx("span", { className: "hypothesis-id", children: hypothesis.id }), _jsx("span", { className: "hypothesis-statement", children: hypothesis.statement })] }), _jsx("p", { className: "hypothesis-explanation", children: hypothesis.explanation }), _jsx(EvidenceRefs, { hypothesis: hypothesis, known: known })] });
|
|
15
|
+
}
|
|
16
|
+
export function HypothesisSection({ report }) {
|
|
17
|
+
const known = new Set(report.experiments.map((experiment) => experiment.id));
|
|
18
|
+
const groups = GROUPS
|
|
19
|
+
.map((group) => ({
|
|
20
|
+
...group,
|
|
21
|
+
members: report.hypotheses.filter((entry) => entry.status === group.status),
|
|
22
|
+
}))
|
|
23
|
+
.filter((group) => group.members.length > 0);
|
|
24
|
+
return _jsx(Section, { id: "hypotheses", meta: `${report.hypotheses.length} explanations`, ordinal: "05", title: "Competing hypotheses", children: groups.map((group) => _jsxs("div", { className: `group group-${group.status}`, children: [_jsxs("h3", { className: "group-title", children: [group.heading, _jsx("span", { className: "group-count", children: group.members.length })] }), group.members.map((hypothesis) => _jsx(HypothesisEntry, { hypothesis: hypothesis, known: known }, hypothesis.id))] }, group.status)) });
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=hypotheses.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hypotheses.js","sourceRoot":"","sources":["../../../src/report/components/hypotheses.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAErC,MAAM,MAAM,GAAG;IACb,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE;IAC7C,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,UAAU,EAAE;IACjD,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE;CACnC,CAAA;AAEV,SAAS,YAAY,CAAC,EAAE,UAAU,EAAE,KAAK,EAGvC;IACA,OAAO,aAAG,SAAS,EAAC,eAAe,aACjC,eAAM,SAAS,EAAC,gBAAgB,yBAAgB,EAC/C,UAAU,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzD,CAAC,CAAC,YAAG,SAAS,EAAC,KAAK,EAAC,IAAI,EAAE,QAAQ,kBAAkB,CAAC,EAAE,CAAC,EAAE,YAAY,EAAE,IAAP,EAAE,CAAU;gBAC9E,CAAC,CAAC,eAAM,SAAS,EAAC,iBAAiB,YAAW,EAAE,IAAP,EAAE,CAAa,CAAC,IACzD,CAAA;AACN,CAAC;AAED,SAAS,eAAe,CAAC,EAAE,UAAU,EAAE,KAAK,EAG1C;IACA,OAAO,mBAAS,SAAS,EAAE,yBAAyB,UAAU,CAAC,MAAM,EAAE,aACrE,cAAI,SAAS,EAAC,iBAAiB,aAC7B,eAAM,SAAS,EAAC,eAAe,YAAE,UAAU,CAAC,EAAE,GAAQ,EACtD,eAAM,SAAS,EAAC,sBAAsB,YAAE,UAAU,CAAC,SAAS,GAAQ,IACjE,EACL,YAAG,SAAS,EAAC,wBAAwB,YAAE,UAAU,CAAC,WAAW,GAAK,EAClE,KAAC,YAAY,IAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,KAAK,GAAI,IAC9C,CAAA;AACZ,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,EAAE,MAAM,EAExC;IACA,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,CAAA;IAC5E,MAAM,MAAM,GAAG,MAAM;SAClB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACf,GAAG,KAAK;QACR,OAAO,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,KAAK,CAAC,MAAM,CAAC;KAC5E,CAAC,CAAC;SACF,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAA;IAC9C,OAAO,KAAC,OAAO,IACb,EAAE,EAAC,YAAY,EACf,IAAI,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,eAAe,EAChD,OAAO,EAAC,IAAI,EACZ,KAAK,EAAC,sBAAsB,YAE3B,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,eAAK,SAAS,EAAE,eAAe,KAAK,CAAC,MAAM,EAAE,aAClE,cAAI,SAAS,EAAC,aAAa,aACxB,KAAK,CAAC,OAAO,EACd,eAAM,SAAS,EAAC,aAAa,YAAE,KAAK,CAAC,OAAO,CAAC,MAAM,GAAQ,IACxD,EACJ,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,KAAC,eAAe,IACjD,UAAU,EAAE,UAAU,EAEtB,KAAK,EAAE,KAAK,IADP,UAAU,CAAC,EAAE,CAElB,CAAC,KATsE,KAAK,CAAC,MAAM,CAUjF,CAAC,GACC,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { EvidenceReport } from "../schema.js";
|
|
2
|
+
export type TrialResult = EvidenceReport["experiments"][number]["result"];
|
|
3
|
+
export type Hypothesis = EvidenceReport["hypotheses"][number];
|
|
4
|
+
export type Experiment = EvidenceReport["experiments"][number];
|
|
5
|
+
export type MatrixEntry = EvidenceReport["proof"]["matrix"][number];
|
|
6
|
+
export type Artifact = EvidenceReport["artifacts"][number];
|
|
7
|
+
/** Semantic tone. Every tone is also carried by a word and a border style, never colour alone. */
|
|
8
|
+
export type Tone = "pass" | "fail" | "open";
|
|
9
|
+
export declare function percent(value: number): string;
|
|
10
|
+
export declare function formatMoney(value: number): string;
|
|
11
|
+
/** Renders the ISO timestamp as a stable UTC stamp so two readers never see different times. */
|
|
12
|
+
export declare function formatTimestamp(iso: string): string;
|
|
13
|
+
export declare function resultTone(result: TrialResult): Tone;
|
|
14
|
+
export declare function Tag({ label, tone }: Readonly<{
|
|
15
|
+
label: string;
|
|
16
|
+
tone: Tone;
|
|
17
|
+
}>): React.JSX.Element;
|
|
18
|
+
export declare function CheckTag({ label, passed }: Readonly<{
|
|
19
|
+
label: string;
|
|
20
|
+
passed: boolean;
|
|
21
|
+
}>): React.JSX.Element;
|
|
22
|
+
/**
|
|
23
|
+
* A failure rate as a right-aligned number plus a proportional bar. The bar is decorative;
|
|
24
|
+
* the exact percentage is always present as text.
|
|
25
|
+
*/
|
|
26
|
+
export declare function RateCell({ rate }: Readonly<{
|
|
27
|
+
rate: number;
|
|
28
|
+
}>): React.JSX.Element;
|
|
29
|
+
/** Pass/trial counts, with failures and errors spelled out rather than implied. */
|
|
30
|
+
export declare function TrialCounts({ result }: Readonly<{
|
|
31
|
+
result: TrialResult;
|
|
32
|
+
}>): React.JSX.Element;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function percent(value) {
|
|
3
|
+
return `${Math.round(value * 100)}%`;
|
|
4
|
+
}
|
|
5
|
+
export function formatMoney(value) {
|
|
6
|
+
return new Intl.NumberFormat("en-US", {
|
|
7
|
+
currency: "USD",
|
|
8
|
+
maximumFractionDigits: 4,
|
|
9
|
+
style: "currency",
|
|
10
|
+
}).format(value);
|
|
11
|
+
}
|
|
12
|
+
function pad(value) {
|
|
13
|
+
return String(value).padStart(2, "0");
|
|
14
|
+
}
|
|
15
|
+
/** Renders the ISO timestamp as a stable UTC stamp so two readers never see different times. */
|
|
16
|
+
export function formatTimestamp(iso) {
|
|
17
|
+
const at = new Date(iso);
|
|
18
|
+
const date = `${at.getUTCFullYear()}-${pad(at.getUTCMonth() + 1)}-${pad(at.getUTCDate())}`;
|
|
19
|
+
return `${date} ${pad(at.getUTCHours())}:${pad(at.getUTCMinutes())} UTC`;
|
|
20
|
+
}
|
|
21
|
+
export function resultTone(result) {
|
|
22
|
+
return result.failed === 0 && result.errors === 0 ? "pass" : "fail";
|
|
23
|
+
}
|
|
24
|
+
export function Tag({ label, tone }) {
|
|
25
|
+
return _jsx("span", { className: `tag tag-${tone}`, children: label });
|
|
26
|
+
}
|
|
27
|
+
export function CheckTag({ label, passed }) {
|
|
28
|
+
return _jsxs("span", { className: "check", "data-testid": `check-${label}`, children: [_jsx("span", { className: "check-label", children: label }), _jsx(Tag, { label: passed ? "PASS" : "FAIL", tone: passed ? "pass" : "fail" })] });
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A failure rate as a right-aligned number plus a proportional bar. The bar is decorative;
|
|
32
|
+
* the exact percentage is always present as text.
|
|
33
|
+
*/
|
|
34
|
+
export function RateCell({ rate }) {
|
|
35
|
+
const tone = rate > 0 ? "fail" : "pass";
|
|
36
|
+
return _jsxs("span", { className: "rate", children: [_jsx("span", { className: "rate-value", children: percent(rate) }), _jsx("span", { "aria-hidden": "true", className: "rate-track", children: _jsx("span", { className: `rate-fill rate-${tone}`, style: { width: `${rate * 100}%` } }) })] });
|
|
37
|
+
}
|
|
38
|
+
/** Pass/trial counts, with failures and errors spelled out rather than implied. */
|
|
39
|
+
export function TrialCounts({ result }) {
|
|
40
|
+
return _jsxs("span", { className: "counts", children: [_jsxs("span", { className: "counts-main", children: [result.passed, "/", result.trials] }), _jsxs("span", { className: "counts-detail", children: [result.failed, " failed", result.errors > 0 ? ` · ${result.errors} errors` : ""] })] });
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=indicators.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indicators.js","sourceRoot":"","sources":["../../../src/report/components/indicators.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface SpecEntry {
|
|
2
|
+
readonly label: string;
|
|
3
|
+
readonly value: React.ReactNode;
|
|
4
|
+
/** Renders the value as wrapping monospace, for paths, patterns and signatures. */
|
|
5
|
+
readonly mono?: boolean;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A numbered report section. The ordinal is decorative so the accessible heading stays
|
|
9
|
+
* "Verdict" rather than "01 Verdict".
|
|
10
|
+
*/
|
|
11
|
+
export declare function Section({ children, id, ordinal, title, meta }: Readonly<{
|
|
12
|
+
children: React.ReactNode;
|
|
13
|
+
id: string;
|
|
14
|
+
ordinal: string;
|
|
15
|
+
title: string;
|
|
16
|
+
meta?: React.ReactNode;
|
|
17
|
+
}>): React.JSX.Element;
|
|
18
|
+
/** Label/value evidence rows. A description list, because that is what these rows are. */
|
|
19
|
+
export declare function SpecList({ entries }: Readonly<{
|
|
20
|
+
entries: readonly SpecEntry[];
|
|
21
|
+
}>): React.JSX.Element;
|
|
22
|
+
/**
|
|
23
|
+
* Keeps wide evidence tables scrollable inside their own region instead of overflowing the
|
|
24
|
+
* page, and keeps that region reachable from the keyboard.
|
|
25
|
+
*/
|
|
26
|
+
export declare function TableScroll({ children, label }: Readonly<{
|
|
27
|
+
children: React.ReactNode;
|
|
28
|
+
label: string;
|
|
29
|
+
}>): React.JSX.Element;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* A numbered report section. The ordinal is decorative so the accessible heading stays
|
|
4
|
+
* "Verdict" rather than "01 Verdict".
|
|
5
|
+
*/
|
|
6
|
+
export function Section({ children, id, ordinal, title, meta }) {
|
|
7
|
+
return _jsxs("section", { "aria-label": title, className: "section", id: id, children: [_jsxs("div", { className: "section-head", children: [_jsxs("h2", { className: "section-title", id: `${id}-title`, children: [_jsx("span", { "aria-hidden": "true", className: "section-ordinal", children: ordinal }), title] }), _jsx("span", { "aria-hidden": "true", className: "section-rule" }), meta ? _jsx("span", { className: "section-meta", children: meta }) : undefined] }), children] });
|
|
8
|
+
}
|
|
9
|
+
/** Label/value evidence rows. A description list, because that is what these rows are. */
|
|
10
|
+
export function SpecList({ entries }) {
|
|
11
|
+
return _jsx("dl", { className: "spec", children: entries.map((entry) => _jsxs("div", { className: "spec-row", children: [_jsx("dt", { children: entry.label }), _jsx("dd", { className: entry.mono ? "spec-mono" : undefined, children: entry.value })] }, entry.label)) });
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Keeps wide evidence tables scrollable inside their own region instead of overflowing the
|
|
15
|
+
* page, and keeps that region reachable from the keyboard.
|
|
16
|
+
*/
|
|
17
|
+
export function TableScroll({ children, label }) {
|
|
18
|
+
return _jsx("div", { "aria-label": label, className: "table-scroll", role: "region", tabIndex: 0, children: children });
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layout.js","sourceRoot":"","sources":["../../../src/report/components/layout.tsx"],"names":[],"mappings":";AAOA;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAM1D;IACA,OAAO,iCAAqB,KAAK,EAAE,SAAS,EAAC,SAAS,EAAC,EAAE,EAAE,EAAE,aAC3D,eAAK,SAAS,EAAC,cAAc,aAC3B,cAAI,SAAS,EAAC,eAAe,EAAC,EAAE,EAAE,GAAG,EAAE,QAAQ,aAC7C,8BAAkB,MAAM,EAAC,SAAS,EAAC,iBAAiB,YAAE,OAAO,GAAQ,EACpE,KAAK,IACH,EACL,8BAAkB,MAAM,EAAC,SAAS,EAAC,cAAc,GAAG,EACnD,IAAI,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,cAAc,YAAE,IAAI,GAAQ,CAAC,CAAC,CAAC,SAAS,IAC5D,EACL,QAAQ,IACD,CAAA;AACZ,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,QAAQ,CAAC,EAAE,OAAO,EAEhC;IACA,OAAO,aAAI,SAAS,EAAC,MAAM,YACxB,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,eAAK,SAAS,EAAC,UAAU,aAC/C,uBAAK,KAAK,CAAC,KAAK,GAAM,EACtB,aAAI,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,YAAG,KAAK,CAAC,KAAK,GAAM,KAFlB,KAAK,CAAC,KAAK,CAG5D,CAAC,GACJ,CAAA;AACP,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,EAAE,QAAQ,EAAE,KAAK,EAG3C;IACA,OAAO,4BAAiB,KAAK,EAAE,SAAS,EAAC,cAAc,EAAC,IAAI,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC,YAC9E,QAAQ,GACL,CAAA;AACR,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { CheckTag, percent, RateCell, resultTone, Tag, TrialCounts } from "./indicators.js";
|
|
3
|
+
import { Section, TableScroll } from "./layout.js";
|
|
4
|
+
const BEFORE_HOSTILE = "Before · hostile";
|
|
5
|
+
const AFTER_HOSTILE = "After · hostile";
|
|
6
|
+
function find(matrix, label) {
|
|
7
|
+
return matrix.find((entry) => entry.label === label);
|
|
8
|
+
}
|
|
9
|
+
function DeltaRow({ entry, term }) {
|
|
10
|
+
return _jsxs("div", { className: "delta-row", children: [_jsx("dt", { children: term }), _jsxs("dd", { children: [_jsx(RateCell, { rate: entry.result.failureRate }), _jsxs("span", { className: "delta-counts", children: [entry.result.passed, "/", entry.result.trials, " passed"] })] })] });
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The headline comparison: the same hostile trigger, before and after the patch. Two aligned
|
|
14
|
+
* bars sharing one scale, so the change is legible before any table is read.
|
|
15
|
+
*/
|
|
16
|
+
function HostileDelta({ matrix }) {
|
|
17
|
+
const before = find(matrix, BEFORE_HOSTILE);
|
|
18
|
+
const after = find(matrix, AFTER_HOSTILE);
|
|
19
|
+
if (!before || !after) {
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
return _jsxs("figure", { "aria-labelledby": "delta-caption", className: "delta", children: [_jsx("figcaption", { id: "delta-caption", children: "Failure rate under the hostile trigger, before and after the candidate patch" }), _jsxs("dl", { className: "delta-bars", children: [_jsx(DeltaRow, { entry: before, term: "Before" }), _jsx(DeltaRow, { entry: after, term: "After" })] })] });
|
|
23
|
+
}
|
|
24
|
+
function MatrixTable({ matrix }) {
|
|
25
|
+
return _jsxs(_Fragment, { children: [_jsx("p", { className: "table-note", children: "Every condition re-executed against the patched workspace, including the clean control and regression checks." }), _jsx(TableScroll, { label: "Proof matrix", children: _jsxs("table", { className: "grid", children: [_jsx("caption", { className: "sr-only", children: "Proof matrix" }), _jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: "Condition" }), _jsx("th", { className: "num", scope: "col", children: "Trials" }), _jsx("th", { className: "num", scope: "col", children: "Failure rate" }), _jsx("th", { className: "num", scope: "col", children: "Floor" }), _jsx("th", { scope: "col", children: "Outcome" })] }) }), _jsx("tbody", { children: matrix.map((entry) => {
|
|
26
|
+
const tone = resultTone(entry.result);
|
|
27
|
+
return _jsxs("tr", { children: [_jsx("th", { className: "mono", scope: "row", children: entry.label }), _jsx("td", { className: "num", children: _jsx(TrialCounts, { result: entry.result }) }), _jsx("td", { className: "num", children: _jsx(RateCell, { rate: entry.result.failureRate }) }), _jsx("td", { className: "num mono", children: percent(entry.result.lowerBound80) }), _jsx("td", { children: _jsx(Tag, { label: tone === "pass" ? "PASS" : "FAIL", tone: tone }) })] }, entry.label);
|
|
28
|
+
}) })] }) })] });
|
|
29
|
+
}
|
|
30
|
+
export function ProofSection({ report }) {
|
|
31
|
+
const { proof } = report;
|
|
32
|
+
return _jsxs(Section, { id: "proof", meta: proof.execution, ordinal: "06", title: "Proof of repair", children: [_jsx(HostileDelta, { matrix: proof.matrix }), _jsxs("div", { className: "static-checks", children: [_jsx("span", { className: "static-checks-label", children: "Static checks" }), _jsx(CheckTag, { label: "typecheck", passed: proof.staticChecks.typecheck }), _jsx(CheckTag, { label: "eslint", passed: proof.staticChecks.lint })] }), _jsx(MatrixTable, { matrix: proof.matrix })] });
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=proof.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"proof.js","sourceRoot":"","sources":["../../../src/report/components/proof.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { percent } from "./indicators.js";
|
|
3
|
+
import { Section, SpecList } from "./layout.js";
|
|
4
|
+
function triggerEntries(trigger) {
|
|
5
|
+
const entries = [
|
|
6
|
+
{ label: "Fault", mono: true, value: trigger.kind },
|
|
7
|
+
{ label: "Route pattern", mono: true, value: trigger.pattern },
|
|
8
|
+
{ label: "Delay", mono: true, value: `${trigger.delayMs} ms` },
|
|
9
|
+
{ label: "Required failure rate", mono: true, value: `>= ${percent(trigger.minimumFailureRate)}` },
|
|
10
|
+
];
|
|
11
|
+
if (trigger.signature) {
|
|
12
|
+
entries.push({ label: "Failure signature", mono: true, value: trigger.signature });
|
|
13
|
+
}
|
|
14
|
+
return entries;
|
|
15
|
+
}
|
|
16
|
+
export function ReproductionSection({ report }) {
|
|
17
|
+
return _jsxs(Section, { id: "reproduction", ordinal: "02", title: "Reproduction", children: [_jsxs("p", { className: "lede", children: ["The minimal hostile trigger. Applying it reproduces the failure in at least", " ", percent(report.trigger.minimumFailureRate), " of trials."] }), _jsx(SpecList, { entries: triggerEntries(report.trigger) })] });
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=reproduction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reproduction.js","sourceRoot":"","sources":["../../../src/report/components/reproduction.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAEzC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE/C,SAAS,cAAc,CAAC,OAAkC;IACxD,MAAM,OAAO,GAAgB;QAC3B,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,IAAI,EAAE;QACnD,EAAE,KAAK,EAAE,eAAe,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,EAAE;QAC9D,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,OAAO,KAAK,EAAE;QAC9D,EAAE,KAAK,EAAE,uBAAuB,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,EAAE,EAAE;KACnG,CAAA;IACD,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,OAAO,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,mBAAmB,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE,CAAC,CAAA;IACpF,CAAC;IACD,OAAO,OAAO,CAAA;AAChB,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,EAAE,MAAM,EAE1C;IACA,OAAO,MAAC,OAAO,IAAC,EAAE,EAAC,cAAc,EAAC,OAAO,EAAC,IAAI,EAAC,KAAK,EAAC,cAAc,aACjE,aAAG,SAAS,EAAC,MAAM,4FAC2D,GAAG,EAC9E,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,mBACzC,EACJ,KAAC,QAAQ,IAAC,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,GAAI,IAC7C,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { CheckTag, formatMoney } from "./indicators.js";
|
|
3
|
+
import { Section } from "./layout.js";
|
|
4
|
+
function Metric({ label, value, detail }) {
|
|
5
|
+
return _jsxs("div", { className: "metric", children: [_jsx("dt", { children: label }), _jsxs("dd", { children: [_jsx("span", { className: "metric-value", children: value }), detail ? _jsx("span", { className: "metric-detail", children: detail }) : undefined] })] });
|
|
6
|
+
}
|
|
7
|
+
export function EvidenceSummarySection({ report }) {
|
|
8
|
+
const confirmed = report.hypotheses.filter((entry) => entry.status === "confirmed").length;
|
|
9
|
+
const tokens = report.usage.inputTokens + report.usage.outputTokens;
|
|
10
|
+
return _jsxs(Section, { id: "summary", ordinal: "03", title: "Evidence summary", children: [_jsxs("dl", { className: "metrics", children: [_jsx(Metric, { detail: `${report.hypotheses.length} hypotheses`, label: "Experiments", value: String(report.experiments.length) }), _jsx(Metric, { detail: "of the hypotheses", label: "Confirmed causes", value: String(confirmed) }), _jsx(Metric, { detail: `${tokens.toLocaleString("en-US")} tokens`, label: "Model cost", value: formatMoney(report.usage.estimatedCostUsd) }), _jsx(Metric, { detail: "proof environment", label: "Execution", value: report.proof.execution })] }), _jsxs("div", { className: "static-checks", children: [_jsx("span", { className: "static-checks-label", children: "Static checks" }), _jsx(CheckTag, { label: "typecheck", passed: report.proof.staticChecks.typecheck }), _jsx(CheckTag, { label: "eslint", passed: report.proof.staticChecks.lint })] })] });
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"summary.js","sourceRoot":"","sources":["../../../src/report/components/summary.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAErC,SAAS,MAAM,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAIpC;IACA,OAAO,eAAK,SAAS,EAAC,QAAQ,aAC5B,uBAAK,KAAK,GAAM,EAChB,yBACE,eAAM,SAAS,EAAC,cAAc,YAAE,KAAK,GAAQ,EAC5C,MAAM,CAAC,CAAC,CAAC,eAAM,SAAS,EAAC,eAAe,YAAE,MAAM,GAAQ,CAAC,CAAC,CAAC,SAAS,IAClE,IACD,CAAA;AACR,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,EAAE,MAAM,EAE7C;IACA,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC,MAAM,CAAA;IAC1F,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,YAAY,CAAA;IACnE,OAAO,MAAC,OAAO,IAAC,EAAE,EAAC,SAAS,EAAC,OAAO,EAAC,IAAI,EAAC,KAAK,EAAC,kBAAkB,aAChE,cAAI,SAAS,EAAC,SAAS,aACrB,KAAC,MAAM,IACL,MAAM,EAAE,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,aAAa,EAChD,KAAK,EAAC,aAAa,EACnB,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,GACxC,EACF,KAAC,MAAM,IAAC,MAAM,EAAC,mBAAmB,EAAC,KAAK,EAAC,kBAAkB,EAAC,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,GAAI,EACxF,KAAC,MAAM,IACL,MAAM,EAAE,GAAG,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,SAAS,EAClD,KAAK,EAAC,YAAY,EAClB,KAAK,EAAE,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAgB,CAAC,GACjD,EACF,KAAC,MAAM,IAAC,MAAM,EAAC,mBAAmB,EAAC,KAAK,EAAC,WAAW,EAAC,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,GAAI,IACnF,EACL,eAAK,SAAS,EAAC,eAAe,aAC5B,eAAM,SAAS,EAAC,qBAAqB,8BAAqB,EAC1D,KAAC,QAAQ,IAAC,KAAK,EAAC,WAAW,EAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,SAAS,GAAI,EAC3E,KAAC,QAAQ,IAAC,KAAK,EAAC,QAAQ,EAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,GAAI,IAC/D,IACE,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Tag } from "./indicators.js";
|
|
3
|
+
import { Section, SpecList } from "./layout.js";
|
|
4
|
+
const VERDICT_COPY = {
|
|
5
|
+
FIX_PROVEN: {
|
|
6
|
+
headline: "FIX PROVEN",
|
|
7
|
+
summary: "The candidate patch was accepted by an independent proof run.",
|
|
8
|
+
},
|
|
9
|
+
PATCH_REJECTED: {
|
|
10
|
+
headline: "PATCH REJECTED",
|
|
11
|
+
summary: "The candidate patch was not accepted by the proof run.",
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export function VerdictSection({ report }) {
|
|
15
|
+
const proven = report.status === "FIX_PROVEN";
|
|
16
|
+
const copy = VERDICT_COPY[report.status];
|
|
17
|
+
return _jsxs(Section, { id: "verdict", ordinal: "01", title: "Verdict", children: [_jsxs("div", { className: proven ? "verdict verdict-pass" : "verdict verdict-fail", children: [_jsxs("p", { className: "verdict-headline", children: [copy.headline, _jsx(Tag, { label: proven ? "PASS" : "FAIL", tone: proven ? "pass" : "fail" })] }), _jsx("p", { className: "verdict-summary", children: copy.summary })] }), _jsx(SpecList, { entries: [
|
|
18
|
+
{ label: "Test", mono: true, value: report.test },
|
|
19
|
+
{ label: "Ownership", mono: true, value: report.ownership.classification },
|
|
20
|
+
{
|
|
21
|
+
label: "Confidence",
|
|
22
|
+
mono: true,
|
|
23
|
+
value: report.ownership.confidence.toUpperCase(),
|
|
24
|
+
},
|
|
25
|
+
] }), _jsxs("div", { className: "prose", children: [_jsx("h3", { className: "sub-title", children: "Root cause" }), _jsx("p", { children: report.conclusion }), _jsxs("p", { className: "note", children: [_jsx("span", { className: "note-label", children: "Classification basis" }), report.ownership.rationale] })] })] });
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=verdict.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verdict.js","sourceRoot":"","sources":["../../../src/report/components/verdict.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAA;AACrC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAE/C,MAAM,YAAY,GAAG;IACnB,UAAU,EAAE;QACV,QAAQ,EAAE,YAAY;QACtB,OAAO,EAAE,+DAA+D;KACzE;IACD,cAAc,EAAE;QACd,QAAQ,EAAE,gBAAgB;QAC1B,OAAO,EAAE,wDAAwD;KAClE;CACO,CAAA;AAEV,MAAM,UAAU,cAAc,CAAC,EAAE,MAAM,EAErC;IACA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,KAAK,YAAY,CAAA;IAC7C,MAAM,IAAI,GAAG,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;IACxC,OAAO,MAAC,OAAO,IAAC,EAAE,EAAC,SAAS,EAAC,OAAO,EAAC,IAAI,EAAC,KAAK,EAAC,SAAS,aACvD,eAAK,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,sBAAsB,aACtE,aAAG,SAAS,EAAC,kBAAkB,aAC5B,IAAI,CAAC,QAAQ,EACd,KAAC,GAAG,IAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,GAAI,IACtE,EACJ,YAAG,SAAS,EAAC,iBAAiB,YAAE,IAAI,CAAC,OAAO,GAAK,IAC7C,EAEN,KAAC,QAAQ,IAAC,OAAO,EAAE;oBACjB,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE;oBACjD,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,cAAc,EAAE;oBAC1E;wBACE,KAAK,EAAE,YAAY;wBACnB,IAAI,EAAE,IAAI;wBACV,KAAK,EAAE,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,WAAW,EAAE;qBACjD;iBACF,GAAI,EAEL,eAAK,SAAS,EAAC,OAAO,aACpB,aAAI,SAAS,EAAC,WAAW,2BAAgB,EACzC,sBAAI,MAAM,CAAC,UAAU,GAAK,EAC1B,aAAG,SAAS,EAAC,MAAM,aACjB,eAAM,SAAS,EAAC,YAAY,qCAA4B,EACvD,MAAM,CAAC,SAAS,CAAC,SAAS,IACzB,IACA,IACE,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { InvestigationReport } from "../investigator/schema.js";
|
|
2
|
+
import type { ProofOfFix } from "../repair/schema.js";
|
|
3
|
+
import type { Reproducer } from "../reproducer/schema.js";
|
|
4
|
+
import type { EvidenceReport } from "./schema.js";
|
|
5
|
+
interface ReportPaths {
|
|
6
|
+
investigation: string;
|
|
7
|
+
patch: string;
|
|
8
|
+
proof: string;
|
|
9
|
+
reproducer: string;
|
|
10
|
+
}
|
|
11
|
+
interface BuildReportOptions {
|
|
12
|
+
generatedAt?: Date;
|
|
13
|
+
investigation: InvestigationReport;
|
|
14
|
+
paths: ReportPaths;
|
|
15
|
+
proof: ProofOfFix;
|
|
16
|
+
reproducer: Reproducer;
|
|
17
|
+
}
|
|
18
|
+
export declare function buildEvidenceReport(options: BuildReportOptions): EvidenceReport;
|
|
19
|
+
export {};
|