refactor: remove test-only planning and native UI runtime seams

This commit is contained in:
morluto committed 2026-11-10 16:32:53 -05:00
1 parent 3c4be703cd
commit fd584d4495
8 files changed
+38 -34

No files matched your search

@@ -1,6 +1,7 @@
import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import { expect, it } from "vitest";
import { afterEach, expect, it, vi } from "vitest";
import * as filesystemSnapshot from "../../process/capture/FilesystemSnapshot.js";
import { awaitAcknowledgement } from "../../../tests/fixtures/lifecycleAcknowledgement.js";
import { createTestTempDirectory } from "../../../tests/fixtures/temporaryDirectory.js";
@@ -10,6 +11,8 @@ import { err, ok, type Result } from "../../domain/result.js";
import { ProcessCaptureError } from "../../process/capture/ProcessCaptureError.js";
import { prepareProcessScenarioPlan } from "./ProcessScenarioPreparation.js";
afterEach(() => vi.restoreAllMocks());
it("rejects observation roots that capture admission rejects", async () => {
const root = await createTestTempDirectory("rea-process-plan-");
const file = join(root, "selected");
@@ -40,23 +43,24 @@ it("reports cancellation normalized inside admission as planning cancellation",
working_directory: ".",
});
const controller = new AbortController();
vi.spyOn(
filesystemSnapshot,
"admitFilesystemObservationRoots",
).mockImplementationOnce(() => {
controller.abort("caller stopped during admission");
return Promise.resolve(
err(
new ProcessCaptureError("filesystem observation admission failed", {
cause: controller.signal.reason,
}),
),
);
});
const prepared = await prepareProcessScenarioPlan(
scenario,
{},
process.platform,
controller.signal,
{
admitRoots: () => {
controller.abort("caller stopped during admission");
return Promise.resolve(
err(
new ProcessCaptureError("filesystem observation admission failed", {
cause: controller.signal.reason,
}),
),
);
},
},
);
expect(prepared.ok).toBe(false);
@@ -85,18 +89,19 @@ it("reports cancellation after the last awaited admission step", async () => {
);
let admissionCalls = 0;
vi.spyOn(
filesystemSnapshot,
"admitFilesystemObservationRoots",
).mockImplementationOnce(() => {
admissionCalls += 1;
admissionEntered();
return pendingAdmission;
});
const planning = prepareProcessScenarioPlan(
scenario,
{},
process.platform,
controller.signal,
{
admitRoots: () => {
admissionCalls += 1;
admissionEntered();
return pendingAdmission;
},
},
);
// Abort only once admission is actually running. Aborting earlier would be
@@ -14,11 +14,6 @@ import { err, ok, type Result } from "../../domain/result.js";
/** A scenario whose executable and observation paths are resolved for execution. */
export type ResolvedProcessScenario = Omit<ProcessScenario, "dry_run">;
/** Test seam for holding the final admission step while cancellation arrives. */
export interface ProcessScenarioPreparationHost {
readonly admitRoots?: typeof admitFilesystemObservationRoots;
}
/**
* Resolve a scenario for a dry run. This applies the same executable, working
* directory, path and platform admission checks as a capture, then stops
@@ -29,7 +24,6 @@ export const prepareProcessScenarioPlan = async (
environment: Readonly<Record<string, string | undefined>> = process.env,
platform: NodeJS.Platform = process.platform,
signal?: AbortSignal,
host: ProcessScenarioPreparationHost = {},
): Promise<Result<ResolvedProcessScenario, AnalysisError>> => {
if (signal?.aborted === true)
return err(
@@ -60,10 +54,7 @@ export const prepareProcessScenarioPlan = async (
if (aborted()) return cancelled();
const privacy = createProcessSensitiveOutput(scenario);
if (!privacy.ok) return err(privacy.error);
const admitted = await (host.admitRoots ?? admitFilesystemObservationRoots)(
resolved,
signal,
);
const admitted = await admitFilesystemObservationRoots(resolved, signal);
if (!admitted.ok) return aborted() ? cancelled() : admitted;
if (aborted()) return cancelled();
return ok(resolved);
+1 -2
View File
@@ -16,8 +16,7 @@ export interface NativeUiHelperRuntime {
readonly invoke: NativeUiHelper;
readonly cleanupLease: AnalysisCleanupLease;
readonly signal: AbortSignal;
/** Omitted by test doubles; production runtimes always set the selected deadline. */
readonly deadlineMs?: number;
readonly deadlineMs: number;
close(): Promise<void>;
resources(): readonly string[];
}
+6
View File
@@ -374,6 +374,7 @@ describe("native UI deadline execution", () => {
environment: {},
runtime: {
signal: deadline.signal,
deadlineMs: 180_000,
invoke: async () => ({ ok: true, result: snapshot }),
cleanupLease: new AnalysisCleanupLease(async () => undefined),
close: async () => undefined,
@@ -396,6 +397,7 @@ describe("native UI deadline execution", () => {
environment: {},
runtime: {
signal: deadline.signal,
deadlineMs: 180_000,
invoke: async () => ({ ok: true, result: snapshot }),
cleanupLease: new AnalysisCleanupLease(async () => undefined),
close: async () => undefined,
@@ -423,6 +425,7 @@ describe("native UI deadline execution", () => {
environment: {},
runtime: {
signal: deadline.signal,
deadlineMs: 180_000,
invoke: async () => ({ ok: true, result: snapshot }),
cleanupLease: new AnalysisCleanupLease(async () => undefined),
close: async () => undefined,
@@ -493,6 +496,7 @@ describe("native UI interruption provenance", () => {
environment: {},
runtime: {
signal: deadline.signal,
deadlineMs: 180_000,
invoke: async () => ({ ok: true, result: snapshot }),
cleanupLease: new AnalysisCleanupLease(async () => undefined),
close: async () => undefined,
@@ -531,6 +535,7 @@ describe("native UI interruption provenance", () => {
environment: {},
runtime: {
signal: deadline.signal,
deadlineMs: 180_000,
invoke: async () => ({ ok: true, result: snapshot }),
cleanupLease: new AnalysisCleanupLease(async () => undefined),
close: async () => undefined,
@@ -552,6 +557,7 @@ describe("native UI interruption provenance", () => {
environment: {},
runtime: {
signal: deadline.signal,
deadlineMs: 180_000,
invoke: async () => ({ ok: true, result: snapshot }),
cleanupLease: new AnalysisCleanupLease(async () => undefined),
close: async () => undefined,
+1 -1
View File
@@ -82,7 +82,7 @@ export const observeNativeUi = async (
new NativeUiInterruptionControl(
options.signal,
runtime.signal,
runtime.deadlineMs ?? DEFAULT_NATIVE_UI_DEADLINE_MS,
runtime.deadlineMs,
);
const ownsInterruption = options.interruption === undefined;
let result: Result<z.infer<typeof nativeUiResultSchema>, AnalysisError>;
+2 -1
View File
@@ -32,10 +32,11 @@ const connectNativeUi = async () => {
const replies: unknown[] = [];
const factory = vi
.spyOn(runtimes, "createNativeUiHelperRuntime")
.mockImplementation(() => {
.mockImplementation((_environment, deadlineMs = 180_000) => {
const cleanupLease = new AnalysisCleanupLease(async () => {});
return {
signal: new AbortController().signal,
deadlineMs,
cleanupLease,
invoke: async () => {
if (replies.length === 0)
@@ -42,6 +42,7 @@ it.each([false, true])(
});
const runtime = {
signal: deadline.signal,
deadlineMs: 180_000,
cleanupLease,
invoke: async () => ({ ok: true, result: snapshot }),
close: () => cleanupLease.release(),
@@ -39,6 +39,7 @@ const controlledRuntime = (
return {
cleanupLease,
signal,
deadlineMs: 180_000,
invoke: vi.fn(async () => ({ ok: true, result: snapshot })),
close: vi.fn(() => cleanupLease.release()),
resources: () => (cleanupLease.released ? [] : ["controlled-ui-runtime"]),