fix(process): preserve partial evidence and verify detached cleanup (#1011)

* test(ci): allow transport delivery in source identity regression

* fix(process): preserve partial evidence and verify detached cleanup

* fix(process): scope Linux token sweeps by stable process identity

* fix(process): retain environment permission failure codes

* fix(process): wait for signaled processes before verifying cleanup

* fix(process): verify sampled detached groups during cleanup

* fix(electron): preserve prelaunch identities through cleanup

* fix(process): retry growing Darwin process table snapshots

* fix(process): retain compatibility with saved v3 capture evidence

* fix(process): migrate saved v3 captures during reconstruction verification

* fix(process): preserve cancellation during Darwin helper compilation

* fix(process): propagate cancellation through ownership baselines

* perf(javascript): cache canonical export comparison sort keys

* fix(process): cancel provider ownership preparation before spawn

* fix(process): isolate native compiler waiter cancellation
This commit is contained in:
morluto
2026-10-08 04:46:46 +08:00
committed by GitHub
parent 63ba7424c0
commit 63cf28fd8f
51 changed files with 5506 additions and 316 deletions
@@ -1,10 +1,17 @@
import { AnalysisError } from "../../domain/analysisErrorBase.js";
import type {
PartialProcessCaptureObservation,
ProcessCaptureCleanupReport,
} from "../../domain/process/processCapture.js";
interface ProcessCaptureErrorOptions extends ErrorOptions {
readonly userMessage?: string;
readonly userCategory?: "cancelled";
readonly reason?: "capture_failed" | "cleanup_incomplete" | "cancelled";
readonly cleanupResources?: readonly string[];
readonly executionFailure?: string;
readonly partialObservation?: PartialProcessCaptureObservation;
readonly cleanupReport?: ProcessCaptureCleanupReport;
}
/** Typed application failure produced by controlled process capture. */
@@ -16,6 +23,11 @@ export class ProcessCaptureError extends AnalysisError {
readonly reason: NonNullable<ProcessCaptureErrorOptions["reason"]>;
override readonly cleanupIncomplete: boolean;
override readonly cleanupResources: readonly string[];
override readonly executionFailure: string | undefined;
override readonly partialObservation:
| PartialProcessCaptureObservation
| undefined;
override readonly cleanupReport: ProcessCaptureCleanupReport | undefined;
constructor(message: string, options?: ProcessCaptureErrorOptions) {
super(message, options);
@@ -26,9 +38,22 @@ export class ProcessCaptureError extends AnalysisError {
(options?.userCategory === "cancelled" ? "cancelled" : "capture_failed");
this.cleanupIncomplete = this.reason === "cleanup_incomplete";
this.cleanupResources = options?.cleanupResources ?? [];
this.executionFailure = options?.executionFailure;
this.partialObservation = options?.partialObservation;
this.cleanupReport = options?.cleanupReport;
}
}
/** Return one non-recursive, domain-neutral summary of an execution failure. */
export const describeProcessCaptureExecutionFailure = (
failure: unknown,
): string | undefined => {
if (failure instanceof Error) return failure.message || failure.name;
if (typeof failure === "string") return failure;
if (failure === undefined) return undefined;
return "Process capture failed with a non-error rejection.";
};
/** Caller-visible cancellation without exposing capture implementation state. */
export const processCaptureCancelled = (): ProcessCaptureError =>
new ProcessCaptureError("process capture was cancelled", {