diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f1c5c0dbed..f5100f8a5e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -452,6 +452,7 @@ jobs: tests/boundary/filesystem/windowsNpxRegistration.test.ts src/application/ClientRegistrationIdentity.test.ts tests/boundary/filesystem/webScriptManifestPaths.test.ts + tests/boundary/process/ProcessEvidence.host.test.ts tests/acceptance/webModuleCli.test.ts tests/acceptance/webSourceLocationCli.test.ts tests/boundary/cli/referenceSourceImportStatus.test.ts diff --git a/src/application/process/ProcessEvidence.ts b/src/application/process/ProcessEvidence.ts index 516eec4787..b1e50bcc87 100644 --- a/src/application/process/ProcessEvidence.ts +++ b/src/application/process/ProcessEvidence.ts @@ -1,3 +1,5 @@ +import { posix, win32 } from "node:path"; + import type { JsonValue } from "../../domain/jsonValue.js"; import { createEvidence } from "../../domain/evidence.js"; import { PROCESS_PROVIDER } from "../../domain/process/processEvidenceProvider.js"; @@ -12,8 +14,11 @@ export { PROCESS_PROVIDER } from "../../domain/process/processEvidenceProvider.j /** Project one process scenario into secret-free Evidence parameters. */ const processEvidenceParameters = ( scenario: ProcessScenario, + platform: ProcessCapture["manifest"]["platform"], ): Readonly> => ({ - executable_name: scenario.executable.split("/").at(-1) ?? scenario.executable, + executable_name: (platform === "win32" ? win32 : posix).basename( + scenario.executable, + ), argument_count: scenario.arguments.length, event_count: scenario.events.length, filesystem_observation_path_count: @@ -29,7 +34,7 @@ export const createProcessCaptureEvidence = ( return createEvidence(undefined, PROCESS_PROVIDER, { predicateType: "rea.process-capture", operation: "capture_process_scenario", - parameters: processEvidenceParameters(scenario), + parameters: processEvidenceParameters(scenario, capture.manifest.platform), result: jsonValueSchema.parse(capture), confidence: "observed", authority: "controlled-replay", diff --git a/tests/boundary/process/ProcessEvidence.host.test.ts b/tests/boundary/process/ProcessEvidence.host.test.ts index 27300d44ea..9a7e67a2db 100644 --- a/tests/boundary/process/ProcessEvidence.host.test.ts +++ b/tests/boundary/process/ProcessEvidence.host.test.ts @@ -6,6 +6,30 @@ import { parseProcessScenario } from "../../../src/domain/process/processScenari import { createProcessCaptureEvidence } from "../../../src/application/process/ProcessEvidence.js"; import { observeSettlement } from "../../../src/process/capture/ProcessCaptureLifecycle.js"; +it.each([ + ["win32", "program.exe"], + ["linux", "directory\\program.exe"], + ["darwin", "directory\\program.exe"], +] as const)( + "interprets the executable name using the captured %s host", + (platform, expectedName) => { + const scenario = parseProcessScenario({ + executable: "/fixtures/directory\\program.exe", + working_directory: process.cwd(), + events: [], + }); + const base = emptyUnverifiedProcessCapture(); + const capture = parseProcessCapture({ + ...base, + manifest: { ...base.manifest, platform }, + }); + expect( + createProcessCaptureEvidence(scenario, capture).parameters + .executable_name, + ).toBe(expectedName); + }, +); + it("stamps process Evidence from the capture manifest host", () => { const scenario = parseProcessScenario({ executable: process.execPath,