fix(windows): preserve unresolved readiness and cleanup ownership

Do not report a retryable failed capture admission as available. A fresh capability declaration must observe actual admission success. Report combined window resources when closing a session, preserving helper and executable cleanup observations without assigning the wrong owner.

Both regressions fail before the change. Focused provider, loader, helper and lazy-client checks pass after the fixes.
This commit is contained in:
N0zoM1z0 committed 2026-10-15 23:38:41 +08:00
1 parent dcccb4fca7
commit 283292edda
4 files changed
+61 -7

No files matched your search

@@ -9,6 +9,7 @@ import type { BinaryTarget } from "../domain/binaryTargetTypes.js";
import { MAX_WINDOWS_WINDOW_PNG_BYTES } from "../domain/native/windowsWindowScreenshot.js";
import { OwnedFileHandle } from "../filesystem/OwnedFileHandle.js";
import { RegularFileAdmissionFailure } from "../filesystem/RegularFile.js";
import * as execution from "./WindowsWindowCaptureExecution.js";
import {
captureWindowsWindowScreenshot,
hashWindowsCaptureExecutable,
@@ -56,6 +57,33 @@ const host = (
...overrides,
});
it("attributes a helper-only close failure to selected-window resources", async () => {
const observation = {
reason: "Owned capture Job cleanup remains pending",
resources: ["capture-run:42"],
};
const cleanup = vi
.spyOn(execution, "retryWindowsCaptureCleanup")
.mockResolvedValue(observation);
try {
const client = new NativeWindowsUiProvider(
{},
host(),
"linux",
).createClient(TARGET);
expect(await client.close()).toMatchObject({
ok: false,
error: {
_tag: "AnalysisOutputError",
reason: "Selected-window capture resource cleanup remains incomplete.",
cleanup: observation,
},
});
} finally {
cleanup.mockRestore();
}
});
it("captures only an HWND whose live executable identity matches the active PE target", async () => {
const captured = await captureWindowsWindowScreenshot(
TARGET,
+14 -4
View File
@@ -238,10 +238,20 @@ export class NativeWindowsUiProvider implements AnalysisProvider {
return incomplete.length === 0
? ok(null)
: err(
incompleteExecutableIdentityCleanupError({
reason: incomplete.map((cleanup) => cleanup.reason).join("; "),
resources: incomplete.flatMap((cleanup) => cleanup.resources),
}),
new AnalysisOutputError(
OPERATION,
"Selected-window capture resource cleanup remains incomplete.",
{
cleanup: {
reason: incomplete
.map((cleanup) => cleanup.reason)
.join("; "),
resources: incomplete.flatMap(
(cleanup) => cleanup.resources,
),
},
},
),
);
},
};
@@ -24,3 +24,21 @@ it("requires affirmative inspected capture support on the shipped Windows archit
}))[0],
).toMatchObject({ available: false, reason: "artifact unavailable" });
});
it("keeps retryable admission unavailable until a fresh successful snapshot", () => {
let readiness: WindowsWindowCaptureLoadResult = {
available: false,
reason: "Private runtime admission is still unresolved",
retryable: true,
};
const first = nativeWindowsUiCapabilities("win32", "x64", () => readiness);
expect(first[0]).toMatchObject({
available: false,
reason: readiness.reason,
});
readiness = loaded();
expect(
nativeWindowsUiCapabilities("win32", "x64", () => readiness)[0],
).toMatchObject({ available: true });
expect(first[0]).toMatchObject({ available: false });
});
@@ -23,9 +23,7 @@ export const nativeWindowsUiCapabilities = (
): readonly CapabilityDescriptor[] => {
const loaded =
platform === "win32" && architecture === "x64" ? load() : undefined;
const captureReady =
loaded?.available === true ||
(loaded?.available === false && loaded.retryable === true);
const captureReady = loaded?.available === true;
const availability =
platform === "win32" && architecture === "x64"
? captureReady