Files
rea/tests/boundary/cli/analysisViewCli.test.ts
T

1217 lines
39 KiB
TypeScript

import {
apiSurfaceHar,
environmentManifestHar,
} from "../../fixtures/historicalHar.js";
import { inspectAnalysisView } from "../../../src/application/analysisView/AnalysisViewService.js";
import { createHash } from "node:crypto";
import { mkdir, readFile, unlink, writeFile } from "node:fs/promises";
import { join, resolve } from "node:path";
import { pathToFileURL } from "node:url";
import {
analysisCliErrorEnvelopeSchema,
analysisErrorProjectionSchema,
} from "../../../src/contracts/errorSchemas.js";
import { expect } from "vitest";
import { TextReader, Uint8ArrayWriter, ZipWriter } from "@zip.js/zip.js";
import { createTestTempDirectory } from "../../fixtures/temporaryDirectory.js";
import { cliTest } from "../../support/cli/cliFixture.js";
import {
analysisViewLayoutEvidence,
analysisViewCaptureFixture,
analysisViewCaptureEvidence,
analysisViewObjectDenseCapture,
analysisViewJavaScriptEvidence,
analysisViewJavaScriptAnalysisWithSource,
analysisViewNativeEvidence,
environmentManifestCaptureFixture,
environmentStateCaptureFixture,
} from "../../fixtures/analysisView.js";
import {
createEvidence,
parseEvidence,
type Evidence,
} from "../../../src/domain/evidence.js";
import { artifactInspectionResultSchema } from "../../../src/domain/artifactInspection.js";
import type { JsonValue } from "../../../src/domain/jsonValue.js";
import { z } from "zod";
import { ghidraFunctionDossier } from "../../../src/domain/ghidraValues.fixture.js";
import {
createEvidenceBundle,
parseEvidenceBundle,
} from "../../../src/domain/evidenceBundle.js";
import { inspectEvidenceBundle } from "../../../src/application/investigation/InspectEvidenceBundle.js";
cliTest(
"authenticates an exact portable parent for non-managed views and rejects ambiguous or altered sources",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-analysis-bundle-cli-");
const path = join(root, "bundle.json");
const parent = analysisViewLayoutEvidence();
const view = {
kind: "item",
collection: "sections",
selector: { name: ".data" },
};
const request = {
source: { kind: "retained-evidence", evidence_id: parent.evidence_id },
view,
};
const bundle = createEvidenceBundle([
analysisViewJavaScriptEvidence(),
parent,
]);
const original = JSON.stringify(bundle);
await writeFile(path, original);
const result = await cli.run({
arguments: [
"inspect-analysis-view",
JSON.stringify(request),
"--evidence-bundle",
path,
"--json",
],
});
expect(result.exitCode).toBe(0);
const expected = await inspectAnalysisView({
source: { kind: "inline", evidence: parent },
view,
});
if (!expected.ok) throw expected.error;
const evidence = parseEvidence(result.json);
expect(evidence.evidence_id).toBe(expected.value.evidence_id);
expect(evidence.normalized_result).toEqual(
expected.value.normalized_result,
);
expect(evidence.evidence_links).toEqual([parent.evidence_id]);
expect(await readFile(path, "utf8")).toBe(original);
for (const [source, expectedCode] of [
[{ kind: "inline", evidence: parent }, "invalid_request"],
[
{ kind: "retained-evidence", evidence_id: `ev_${"f".repeat(64)}` },
"evidence_integrity_mismatch",
],
] as const) {
const rejected = await cli.run({
arguments: [
"inspect-analysis-view",
JSON.stringify({ source, view }),
"--evidence-bundle",
path,
"--json",
],
});
expect(rejected.exitCode).toBe(1);
expect(rejected.json).toMatchObject({ code: expectedCode });
expect(rejected.json).not.toHaveProperty("evidence_id");
}
for (const [contents, expectedCode] of [
[JSON.stringify(parent), "invalid_request"],
["{invalid JSON", "evidence_integrity_mismatch"],
[
JSON.stringify({
...bundle,
records: bundle.records.map((record) => ({
...record,
normalized_result: "altered",
})),
}),
"evidence_integrity_mismatch",
],
] as const) {
await writeFile(path, contents);
const rejected = await cli.run({
arguments: [
"inspect-analysis-view",
JSON.stringify(request),
"--evidence-bundle",
path,
"--json",
],
});
expect(rejected.exitCode).toBe(1);
expect(rejected.json).toMatchObject({ code: expectedCode });
expect(rejected.json).not.toHaveProperty("evidence_id");
}
},
);
cliTest(
"preserves native relationship coverage independently of exhausted CLI pages",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-native-coverage-cli-");
const parent = analysisViewNativeEvidence({
status: "partial",
limited_directions: ["callees"],
limitations: ["Callees: fixture read limit"],
diagnostics: ["Fixture relationship diagnostic"],
});
const parentBefore = JSON.stringify(parent);
const request = join(root, "request.json");
await writeFile(
request,
JSON.stringify({
source: { kind: "inline", evidence: parent },
view: { kind: "native", facet: "callees", offset: 0, limit: 1 },
}),
);
const response = await cli.run({
arguments: ["inspect-analysis-view", request, "--json"],
});
expect(response.exitCode).toBe(0);
const evidence = parseEvidence(response.json);
expect(evidence.relationship_coverage).toEqual(
parent.relationship_coverage,
);
expect(evidence.normalized_result).toMatchObject({
item: [],
coverage: { total: 0, exhausted: true },
limitations: expect.arrayContaining(["Fixture dossier caveat"]),
});
expect(evidence.evidence_links).toEqual([parent.evidence_id]);
expect(JSON.stringify(parent)).toBe(parentBefore);
},
);
cliTest(
"reads typed module references through the public CLI with canonical Evidence",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-module-reference-cli-");
const request = join(root, "request.json");
const parent = analysisViewJavaScriptEvidence(
analysisViewJavaScriptAnalysisWithSource(),
);
const input = {
source: { kind: "inline", evidence: parent },
view: {
kind: "javascript",
collection: "modules",
projection: "references",
where: { path: "renderer.js" },
limit: 1,
},
};
const expected = await inspectAnalysisView(input);
if (!expected.ok) throw expected.error;
await writeFile(request, JSON.stringify(input));
const response = await cli.run({
arguments: ["inspect-analysis-view", request, "--json"],
});
expect(response.exitCode).toBe(0);
const evidence = parseEvidence(response.json);
expect(evidence.normalized_result).toEqual(
expected.value.normalized_result,
);
expect(evidence.evidence_id).toBe(expected.value.evidence_id);
expect(evidence.evidence_links).toEqual([parent.evidence_id]);
},
);
cliTest(
"projects opted-in query names through compiled CLI without query values",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-query-names-cli-");
const path = join(root, "view.json");
const capture = analysisViewCaptureFixture();
capture.records = capture.records.slice(0, 2);
capture.total_records = 2;
capture.records.forEach((record, index) => {
record.reported = {
request: {
method: "GET",
url:
index === 0
? "https://api.test/products?category=books&page=1&category=repeat"
: "https://api.test/products?category=games&sort=price#ignored",
},
};
});
await writeFile(
path,
JSON.stringify({
source: {
kind: "inline",
evidence: analysisViewCaptureEvidence(capture),
},
view: { kind: "api-surface", include_query_parameter_names: true },
}),
);
const result = await cli.run({
arguments: ["inspect-analysis-view", path, "--json"],
});
expect(result.exitCode).toBe(0);
const evidence = parseEvidence(result.json);
expect(evidence.normalized_result).toMatchObject({
groups: [
{
query_parameter_names: [
{ name: "category", record_ordinals: [0, 1] },
{ name: "page", record_ordinals: [0] },
{ name: "sort", record_ordinals: [1] },
],
},
],
});
for (const value of ["books", "games", "repeat", "price", "ignored"])
expect(result.stdout).not.toContain(value);
},
);
cliTest(
"projects portable artifact inventory after the original ZIP is removed",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-inventory-view-cli-");
const archive = join(root, "fixture.zip");
const writer = new ZipWriter(new Uint8ArrayWriter());
await writer.add("main.js", new TextReader("console.log('portable');\n"));
await writeFile(archive, await writer.close());
const bundlePath = join(root, "inspection-bundle.json");
const inspected = await cli.run({
arguments: [
"inspect-artifact",
archive,
"--detail",
"summary",
"--evidence_output",
bundlePath,
"--json",
],
});
expect(inspected.exitCode).toBe(0);
const savedBundle = parseEvidenceBundle(
JSON.parse(await readFile(bundlePath, "utf8")),
);
const parent = savedBundle.records.find(
(record) => record.operation === "inspect_artifact",
)!;
const atomicId = artifactInspectionResultSchema.parse(
parent.normalized_result,
).substeps[0]!.evidence_id;
expect(savedBundle.records.map((record) => record.evidence_id)).toContain(
atomicId,
);
const call = await cli.sharedMcpCall?.();
if (call === undefined) throw new Error("Expected shared MCP session");
expect(
(await call("import_evidence_bundle", { path: bundlePath })).isError,
).not.toBe(true);
const atomicView = await call("inspect_analysis_view", {
source: { kind: "retained-evidence", evidence_id: atomicId },
view: {
kind: "inventory",
collection: "occurrences",
logical_paths: ["main.js"],
},
});
expect(atomicView.isError).not.toBe(true);
expect(
parseEvidence(atomicView.structuredContent).normalized_result,
).toMatchObject({
parent_evidence_id: atomicId,
items: [expect.objectContaining({ logical_path: "main.js" })],
});
const unsupportedRequest = join(root, "unsupported-view.json");
const unsupportedInput = {
source: { kind: "inline", evidence: parent },
view: { kind: "page", collection: "sections", offset: 0, limit: 20 },
};
await writeFile(unsupportedRequest, JSON.stringify(unsupportedInput));
const unsupported = await cli.run({
arguments: ["inspect-analysis-view", unsupportedRequest, "--json"],
});
expect(unsupported.exitCode).toBe(1);
expect(unsupported.json).toMatchObject({
code: "invalid_request",
details: {
issues: [
{
path: ["view"],
message: "Artifact Evidence supports summary and inventory views.",
},
],
},
});
await unlink(archive);
const request = join(root, "view.json");
await writeFile(
request,
JSON.stringify({
source: { kind: "inline", evidence: parent },
view: {
kind: "inventory",
collection: "occurrences",
logical_paths: ["main.js"],
},
}),
);
const projected = await cli.run({
arguments: ["inspect-analysis-view", request, "--json"],
});
expect(projected.exitCode).toBe(0);
expect(projected.json).toMatchObject({
operation: "inspect_analysis_view",
evidence_links: [parent.evidence_id],
normalized_result: {
parent_evidence_id: parent.evidence_id,
kind: "inventory",
source_complete: true,
artifact: { path: archive, sha256: parent.subject?.digest.sha256 },
items: [expect.objectContaining({ logical_path: "main.js" })],
coverage: { total: 1, exhausted: true, next_offset: null },
},
});
},
);
cliTest(
"preserves artifact parent schema diagnostics through the application and CLI",
async ({ cli }) => {
const root = await createTestTempDirectory(
"rea-inventory-diagnostics-cli-",
);
const archive = join(root, "fixture.zip");
const writer = new ZipWriter(new Uint8ArrayWriter());
await writer.add("main.js", new TextReader("console.log(1);\n"));
await writeFile(archive, await writer.close());
const inspected = await cli.run({
arguments: ["inspect-artifact", archive, "--json"],
});
expect(inspected.exitCode).toBe(0);
const inspection = parseEvidence(inspected.json);
const inventory = artifactInspectionResultSchema.parse(
inspection.normalized_result,
).substeps[0]!.evidence;
const path = join(root, "view.json");
const reseal = (carrier: Evidence, result: JsonValue) => {
const subject = carrier.subject!;
return createEvidence(
{
path: subject.local_path,
sha256: subject.digest.sha256,
format: subject.format,
},
carrier.provider,
{ operation: carrier.operation, parameters: {}, result },
);
};
for (const [carrier, group, field] of [
[inventory, "manifest", "node_count"],
[inspection, "coverage", "substeps_completed"],
] as const) {
for (const variant of ["valid", "type", "missing"] as const) {
const payload = structuredClone(carrier.normalized_result) as Record<
string,
Record<string, JsonValue>
>;
if (variant === "type") payload[group]![field] = "bad";
if (variant === "missing") delete payload[group]![field];
const evidence = reseal(carrier, payload);
const request = {
source: { kind: "inline" as const, evidence },
view: { kind: "summary" as const },
};
const application = await inspectAnalysisView(request);
await writeFile(path, JSON.stringify(request));
const reply = await cli.run({
arguments: ["inspect-analysis-view", path, "--json"],
});
expect(reply.stderr).toBe("");
if (variant === "valid") {
expect(application.ok).toBe(true);
expect(reply.exitCode).toBe(0);
expect(parseEvidence(reply.json).normalized_result).toMatchObject({
kind: "summary",
});
continue;
}
expect(application.ok).toBe(false);
if (application.ok) throw new Error("Expected an invalid parent");
expect(application.error.cause).toBeInstanceOf(z.ZodError);
expect(reply.exitCode).toBe(1);
expect(reply.json).toMatchObject({
code: "invalid_request",
category: "invalid_input",
retryable: false,
recovery: {
kind: "inspect_input_contract",
operation: "inspect_analysis_view",
},
details: {
issues: [
{
path: ["source", "normalized_result", group, field],
reason:
variant === "type" ? "invalid_type" : "missing_argument",
expected: "number",
},
],
},
});
}
}
const nested = artifactInspectionResultSchema.parse(
inspection.normalized_result,
);
nested.substeps.push(structuredClone(nested.substeps[0]!));
nested.coverage.substeps_completed = nested.substeps.length;
nested.substeps[1]!.evidence.evidence_id = `ev_${"f".repeat(64)}`;
const request = {
source: { kind: "inline" as const, evidence: reseal(inspection, nested) },
view: { kind: "summary" as const },
};
const application = await inspectAnalysisView(request);
expect(application.ok).toBe(false);
if (application.ok) throw new Error("Expected invalid nested Evidence");
expect(application.error.cause).toMatchObject({
cause: expect.any(z.ZodError),
issues: [
expect.objectContaining({
path: ["substeps", 1, "evidence", "evidence_id"],
}),
],
});
await writeFile(path, JSON.stringify(request));
const refused = await cli.run({
arguments: ["inspect-analysis-view", path, "--json"],
});
expect(refused.exitCode).toBe(1);
expect(refused.stderr).toBe("");
expect(refused.json).toMatchObject({
code: "invalid_request",
details: {
issues: [
{
path: [
"source",
"normalized_result",
"substeps",
1,
"evidence",
"evidence_id",
],
reason: "invalid_value",
message: "Evidence semantic identifier does not match its record",
},
],
},
});
},
);
cliTest(
"admits portable captures before parsing and preserves capture caveats",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-inline-capture-cli-");
const path = join(root, "view.json");
const environment = {
HOME: root,
XDG_CONFIG_HOME: root,
XDG_CACHE_HOME: root,
};
await writeFile(
path,
JSON.stringify({
source: {
kind: "inline",
evidence: analysisViewCaptureEvidence(
analysisViewObjectDenseCapture(),
),
},
view: { kind: "api-surface" },
}),
);
const refused = await cli.run({
arguments: ["inspect-analysis-view", path, "--json"],
environment,
});
expect(refused.exitCode).toBe(1);
expect(refused.json).toMatchObject({
code: "resource_constraint",
details: { resource: "memory" },
});
const capture = analysisViewCaptureFixture();
capture.records = capture.records.slice(0, 1);
capture.total_records = 1;
const caveat = "Producer omitted exchanges before capture startup.";
capture.limitations = [caveat, caveat];
capture.records[0]!.reported = {
request: { method: "GET", url: "https://api.test/a" },
response: {
status: 200,
content: { mimeType: "\u000btext/plain\u000b" },
},
};
const parent = analysisViewCaptureEvidence(capture);
expect(parent.limitations).not.toContain(caveat);
await writeFile(
path,
JSON.stringify({
source: { kind: "inline", evidence: parent },
view: { kind: "api-surface" },
}),
);
const response = await cli.run({
arguments: ["inspect-analysis-view", path, "--json"],
environment,
});
expect(response.exitCode, response.stdout).toBe(0);
const result = parseEvidence(response.json);
expect(result.limitations.filter((value) => value === caveat)).toEqual([
caveat,
]);
expect(result.normalized_result).toMatchObject({
groups: [{ content_types: [], flags: ["single-sample"] }],
limitations: expect.arrayContaining([caveat]),
unknowns: [
"Some retained records have unavailable status or content type values.",
],
});
},
);
cliTest(
"discovers native records from a complete portable bundle using the shared workflow",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-evidence-discovery-cli-");
const parent = createEvidence(
{ path: "/fixtures/native.exe", format: "pe", sha256: "a".repeat(64) },
{ id: "ghidra", name: "Ghidra", version: "12.1.4" },
{
operation: "analyze_function",
parameters: {},
result: ghidraFunctionDossier(),
},
);
const bundle = createEvidenceBundle([parent]);
const path = join(root, "evidence.json");
await writeFile(path, JSON.stringify(bundle));
const options = {
detail: "summary" as const,
filters: { evidence_id: parent.evidence_id },
};
const result = await cli.run({
arguments: [
"inspect-evidence-bundle",
JSON.stringify({ path, ...options }),
"--json",
],
environment: { HOME: root, XDG_CONFIG_HOME: root, XDG_CACHE_HOME: root },
});
expect(result.exitCode).toBe(0);
const expected = inspectEvidenceBundle(bundle, options);
if (!expected.ok) throw expected.error;
expect(result.json).toEqual(expected.value);
const complete = await cli.run({
arguments: [
"inspect-evidence-bundle",
JSON.stringify({ path }),
"--json",
],
environment: { HOME: root, XDG_CONFIG_HOME: root, XDG_CACHE_HOME: root },
});
expect(complete.exitCode).toBe(0);
expect(complete.json).toEqual(bundle);
},
);
cliTest(
"formats the full caller-admitted native inventory page as Markdown and JSON",
async ({ cli }) => {
const root = await createTestTempDirectory(
"rea-native-inventory-markdown-",
);
const input = join(root, "view.json");
const rowCount = 150_000;
{
const parent = createEvidence(
{
path: "/fixtures/native.exe",
format: "pe",
sha256: "a".repeat(64),
},
{ id: "fixture", name: "Fixture", version: "1" },
{
operation: "list_names",
parameters: {},
result: Array.from({ length: rowCount }, (_, index) => ({
address: `0x${index.toString(16)}`,
value: `item${index}`,
})),
},
);
const request = {
source: { kind: "inline", evidence: parent },
view: {
kind: "native-inventory",
limit: rowCount,
fields: ["value"],
},
};
await writeFile(input, JSON.stringify(request));
}
const environment = {
HOME: root,
XDG_CONFIG_HOME: root,
XDG_CACHE_HOME: root,
REA_LOG_LEVEL: "silent",
};
{
const json = await cli.run({
arguments: [
"inspect-analysis-view",
input,
"--format",
"json",
"--filter-output",
"normalized_result.rows",
],
environment,
timeoutMs: 60_000,
});
expect(json.exitCode).toBe(0);
expect(
(json.json as { normalized_result: { rows: unknown[] } })
.normalized_result.rows,
).toHaveLength(rowCount);
}
const markdown = await cli.run({
arguments: [
"inspect-analysis-view",
input,
"--format",
"md",
"--filter-output",
"normalized_result.rows",
],
environment,
timeoutMs: 60_000,
});
expect(markdown.exitCode).toBe(0);
expect(markdown.stdout).toContain("## normalized_result.rows");
expect(markdown.stdout).toContain("| source_index");
let lineBreaks = 0;
for (const character of markdown.stdout)
if (character === "\n") lineBreaks += 1;
expect(lineBreaks).toBeGreaterThan(rowCount);
expect(markdown.stdout).toContain("149999");
},
);
cliTest(
"projects one section from a JSON file of inline layout Evidence",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-analysis-view-cli-");
const parent = analysisViewLayoutEvidence();
const request = {
source: { kind: "inline", evidence: parent },
view: {
kind: "item",
collection: "sections",
selector: { name: ".data" },
},
};
const input = join(root, "view.json");
await mkdir(root, { recursive: true });
await writeFile(input, JSON.stringify(request));
const result = await cli.run({
arguments: ["inspect-analysis-view", input, "--json"],
environment: {
HOME: root,
XDG_CONFIG_HOME: root,
XDG_CACHE_HOME: root,
},
});
expect(result.exitCode).toBe(0);
expect(result.json).toMatchObject({
operation: "inspect_analysis_view",
normalized_result: {
kind: "item",
parent_evidence_id: parent.evidence_id,
item: { name: { display: ".data" } },
},
});
},
);
cliTest(
"projects native function pseudocode without requiring Ghidra",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-native-view-cli-");
const parent = createEvidence(
{ path: "/fixtures/native.exe", format: "pe", sha256: "a".repeat(64) },
{ id: "ghidra", name: "Ghidra", version: "12.1.4" },
{
operation: "analyze_function",
parameters: { address: "0x401000" },
result: ghidraFunctionDossier(),
},
);
const input = join(root, "native-view.json");
await writeFile(
input,
JSON.stringify({
source: { kind: "inline", evidence: parent },
view: { kind: "native", facet: "pseudocode", offset: 0, limit: 12 },
}),
);
const result = await cli.run({
arguments: ["inspect-analysis-view", input, "--json"],
environment: { HOME: root, XDG_CONFIG_HOME: root, XDG_CACHE_HOME: root },
});
expect(result.exitCode).toBe(0);
expect(result.json).toMatchObject({
operation: "inspect_analysis_view",
normalized_result: {
kind: "native",
parent_evidence_id: parent.evidence_id,
procedure_address: "0x401000",
item: { text: "int fixture_", unit: "utf16-code-units" },
},
locations: [
{ kind: "artifact-path", path: "/fixtures/native.exe" },
{ kind: "address", address: "0x401000" },
],
});
},
);
cliTest("rejects malformed JSON before projection", async ({ cli }) => {
const root = await createTestTempDirectory("rea-analysis-view-cli-bad-");
const result = await cli.run({
arguments: ["inspect-analysis-view", "{", "--json"],
environment: {
HOME: root,
XDG_CONFIG_HOME: root,
XDG_CACHE_HOME: root,
},
});
expect(result.exitCode).toBe(1);
expect(result.json).toMatchObject({
code: "invalid_request",
category: "invalid_input",
details: { operation: "inspect-analysis-view" },
});
});
cliTest("rejects a request that omits source", async ({ cli }) => {
const root = await createTestTempDirectory("rea-analysis-view-cli-missing-");
const input = join(root, "missing-source.json");
await writeFile(input, JSON.stringify({ view: { kind: "summary" } }));
const result = await cli.run({
arguments: ["inspect-analysis-view", input, "--json"],
environment: {
HOME: root,
XDG_CONFIG_HOME: root,
XDG_CACHE_HOME: root,
},
});
expect(result.exitCode).toBe(1);
expect(result.json).toMatchObject({
code: "invalid_request",
category: "invalid_input",
details: { operation: "inspect_analysis_view" },
});
});
for (const [view, reason] of [
[{ kind: "unknown-view" }, "invalid_value"],
[{}, "missing_argument"],
] as const) {
cliTest(
`reports correction details for ${reason} view kind`,
async ({ cli }) => {
const root = await createTestTempDirectory("rea-view-variant-");
const input = join(root, "view.json");
await writeFile(
input,
JSON.stringify({
source: {
kind: "inline",
evidence: analysisViewLayoutEvidence(),
},
view,
}),
);
const result = await cli.run({
arguments: ["inspect-analysis-view", input, "--json"],
environment: {
HOME: root,
XDG_CONFIG_HOME: root,
XDG_CACHE_HOME: root,
},
});
expect(result.exitCode).toBe(1);
expect(result.json).toMatchObject({
code: "invalid_request",
details: {
issues: [
{
path: ["view", "kind"],
reason,
expected: expect.arrayContaining(["summary", "page"]),
},
],
},
});
expect(JSON.stringify(result.json)).not.toContain("unknown-view");
},
);
}
cliTest(
"decodes HAR credentials and projects recorded API paths through the compiled workflows",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-surface-cli-");
const fixture = apiSurfaceHar();
const entry = fixture.log.entries[0]!;
const urls = [
"https://user:password@api.example.test/a/%2e%2e/admin?token=ordinary#fragment",
"https://api.example.test/admin",
"https:user:password@api.example.test/path",
"https:///user:password@api.example.test/path",
];
fixture.log.entries.push(
...urls.map((url) => ({
...entry,
request: { ...entry.request, url },
})),
);
const bytes = JSON.stringify(fixture);
const capturePath = join(root, "capture.har");
const input = join(root, "view.json");
const environment = {
HOME: root,
XDG_CONFIG_HOME: root,
XDG_CACHE_HOME: root,
};
await writeFile(capturePath, bytes);
const capture = await cli.run({
arguments: ["inspect-web-network-capture", capturePath, "har", "--json"],
environment,
});
expect(capture.exitCode, capture.stdout).toBe(0);
const parent = parseEvidence(capture.json);
expect(parent.subject?.digest.sha256).toBe(
createHash("sha256").update(bytes).digest("hex"),
);
expect(JSON.stringify(parent)).not.toContain("password");
await writeFile(
input,
JSON.stringify({
source: { kind: "inline", evidence: parent },
view: { kind: "api-surface" },
}),
);
const result = await cli.run({
arguments: ["inspect-analysis-view", input, "--json"],
environment,
});
expect(result.exitCode, result.stdout).toBe(0);
expect(result.json).toMatchObject({
confidence: "inferred",
evidence_links: [parent.evidence_id],
normalized_result: {
kind: "api-surface",
records: { examined: 17, total: 17, excluded: 2 },
coverage: { total: 14, exhausted: true },
groups: expect.arrayContaining([
expect.objectContaining({
path_template: "/a/%2e%2e/admin",
record_ordinals: [13],
}),
expect.objectContaining({
path_template: "/admin",
record_ordinals: [14],
}),
]),
excluded_records: [
{ ordinal: 15, reason: "url-redacted" },
{ ordinal: 16, reason: "url-redacted" },
],
},
});
expect(JSON.stringify(result.json)).not.toContain("password");
expect(JSON.stringify(result.json)).not.toContain("ordinary");
},
);
cliTest(
"projects an environment manifest from an Evidence file through the compiled CLI",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-evidence-file-cli-");
const capturePath = join(root, "capture.json");
const parent = analysisViewCaptureEvidence(
environmentManifestCaptureFixture(),
);
await writeFile(capturePath, JSON.stringify(parent));
const requestPath = join(root, "view.json");
const view = {
kind: "environment-manifest",
template_rules: ["opaque-token", "sibling-pair-variance"],
} as const;
await writeFile(
requestPath,
JSON.stringify({
source: { kind: "evidence-file", path: capturePath },
view,
}),
);
const result = await cli.run({
arguments: ["inspect-analysis-view", requestPath, "--json"],
});
expect(result.exitCode, result.stdout).toBe(0);
const evidence = parseEvidence(result.json);
expect(evidence.parameters).toMatchObject({
parent_evidence_id: parent.evidence_id,
});
// The file source projects exactly what the same Evidence projects inline.
const inline = await inspectAnalysisView({
source: { kind: "inline", evidence: parent },
view,
});
if (!inline.ok) throw inline.error;
expect(evidence.normalized_result).toEqual(inline.value.normalized_result);
expect(evidence.normalized_result).toMatchObject({
kind: "environment-manifest",
origin: "http://grafana.example",
});
},
);
cliTest(
"projects an environment manifest through the compiled CLI without recorded values",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-environment-manifest-cli-");
const path = join(root, "view.json");
await writeFile(
path,
JSON.stringify({
source: {
kind: "inline",
evidence: analysisViewCaptureEvidence(
environmentManifestCaptureFixture(),
),
},
view: {
kind: "environment-manifest",
template_rules: [
"after-uid-literal",
"opaque-token",
"sibling-variance",
],
},
}),
);
const result = await cli.run({
arguments: ["inspect-analysis-view", path, "--json"],
});
expect(result.exitCode, result.stdout).toBe(0);
const evidence = parseEvidence(result.json);
expect(evidence.confidence).toBe("inferred");
expect(evidence.normalized_result).toMatchObject({
kind: "environment-manifest",
origin: "http://grafana.example",
name: "grafana-example",
coverage: { total: 19, exhausted: true },
excluded: expect.arrayContaining([
expect.objectContaining({ reason: "other-origin" }),
]),
});
for (const template of [
"/api/dashboards/uid/{uid}",
"/api/folders/{uid}",
"/api/plugins/{plugin_id}/settings",
"/api/datasources/uid/{uid}/health",
])
expect(result.stdout).toContain(JSON.stringify(template));
for (const value of ["probe folder", "Main Org", "JFIF", "console.log"])
expect(result.stdout).not.toContain(value);
await writeFile(
path,
JSON.stringify({
source: {
kind: "inline",
evidence: analysisViewCaptureEvidence(
analysisViewObjectDenseCapture(),
),
},
view: { kind: "environment-manifest" },
}),
);
const refused = await cli.run({
arguments: ["inspect-analysis-view", path, "--json"],
});
expect(refused.exitCode).toBe(1);
expect(refused.json).toMatchObject({
code: "resource_constraint",
details: { resource: "memory" },
});
},
);
cliTest(
"extracts an environment state through the compiled CLI with recorded values",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-environment-state-cli-");
const path = join(root, "view.json");
await writeFile(
path,
JSON.stringify({
source: {
kind: "inline",
evidence: analysisViewCaptureEvidence(
environmentStateCaptureFixture(),
),
},
view: {
kind: "environment-state",
template_rules: [
"after-uid-literal",
"opaque-token",
"sibling-variance",
],
},
}),
);
const result = await cli.run({
arguments: ["inspect-analysis-view", path, "--json"],
});
expect(result.exitCode, result.stdout).toBe(0);
const evidence = parseEvidence(result.json);
expect(evidence.confidence).toBe("inferred");
expect(evidence.normalized_result).toMatchObject({
kind: "environment-state",
origin: "http://grafana.example",
timeline: "recorded-start-time",
types: expect.arrayContaining([
expect.objectContaining({
collection_template: "/api/folders",
id_field: "uid",
}),
]),
});
for (const value of ["probe folder", "probe@example.test"])
expect(result.stdout).toContain(value);
},
);
cliTest(
"decodes a Grafana-shaped HAR and projects its environment manifest through the compiled workflows",
async ({ cli }) => {
const root = await createTestTempDirectory("rea-manifest-chain-cli-");
const capturePath = join(root, "capture.har");
await writeFile(capturePath, JSON.stringify(environmentManifestHar()));
const capture = await cli.run({
arguments: ["inspect-web-network-capture", capturePath, "har", "--json"],
});
expect(capture.exitCode, capture.stdout).toBe(0);
const parent = parseEvidence(capture.json);
const input = join(root, "manifest.json");
await writeFile(
input,
JSON.stringify({
source: { kind: "inline", evidence: parent },
view: { kind: "environment-manifest" },
}),
);
const result = await cli.run({
arguments: ["inspect-analysis-view", input, "--json"],
});
expect(result.exitCode, result.stdout).toBe(0);
expect(result.json).toMatchObject({
confidence: "inferred",
evidence_links: [parent.evidence_id],
normalized_result: {
kind: "environment-manifest",
name: "grafana-example",
templated_groups: 6,
coverage: { total: 22, exhausted: true },
artifact: { path: capturePath, sha256: parent.subject?.digest.sha256 },
records: expect.arrayContaining([
{
ordinal: 3,
method: "GET",
path: "/api/org",
status: 200,
content_type: "application/json",
},
]),
unknowns: [
expect.objectContaining({ kind: "authorization-model" }),
expect.objectContaining({ kind: "response-semantics" }),
expect.objectContaining({ kind: "state-transition" }),
],
},
});
expect(JSON.stringify(result.json)).not.toContain("probe folder");
},
);
cliTest.for(
(process.platform === "win32"
? (["event"] as const)
: (["event", "os"] as const)
).flatMap((delivery) => [
{ signal: "SIGINT" as const, status: 130, delivery },
{ signal: "SIGTERM" as const, status: 143, delivery },
]),
)(
"retains inline projection when $signal ($delivery) is queued during final sealing",
async ({ signal, status, delivery }, { cli }) => {
const root = await createTestTempDirectory("rea-inline-view-signal-");
const parent = analysisViewLayoutEvidence(),
marker = join(root, "signal.json");
const preload = resolve(
"tests/fixtures/evidenceCompletionSignalPreload.mjs",
);
const reply = await cli.run({
arguments: [
"inspect-analysis-view",
JSON.stringify({
source: { kind: "inline", evidence: parent },
view: { kind: "summary" },
}),
"--json",
],
environment: {
HOME: root,
REA_LOG_LEVEL: "silent",
REA_TEST_EVIDENCE_COMPLETION: JSON.stringify({
operation: "inspect_analysis_view",
parent_evidence_id: parent.evidence_id,
marker,
signal,
delivery,
}),
NODE_OPTIONS: `--max-old-space-size=2048 --import=${pathToFileURL(preload).href}`,
},
});
expect(reply.exitCode).toBe(status);
const { error: label, ...projection } =
analysisCliErrorEnvelopeSchema.parse(reply.json);
expect(label).toBe("Application workflow failed");
const error = analysisErrorProjectionSchema.parse(projection);
expect(error.code).toBe("cancelled");
expect(error.details?.operation).toBe("inspect_analysis_view");
const partial = parseEvidence(error.details?.partial_observation);
expect(partial.operation).toBe("inspect_analysis_view");
expect(partial.evidence_links).toEqual([parent.evidence_id]);
expect(partial.normalized_result).toMatchObject({
parent_evidence_id: parent.evidence_id,
kind: "summary",
});
const proof = JSON.parse(await readFile(marker, "utf8"));
expect(proof).toMatchObject({
evidence_id: partial.evidence_id,
signal,
delivery,
});
expect(proof.listeners).toBeGreaterThan(0);
},
);