
effectIt.effect("review: nonzero PowerShell exits retain the last snapshot and back off", () => {
  let runs = 0;
  const layer = makeWindowsScannerLayer({
    windowsListeners: Effect.fail(new NativeTelemetryClient.NativeTelemetryUnavailable({ reason: "review fixture" })),
    run: () => {
      runs++;
      return Effect.succeed({ stdout: runs === 1 ? `127.0.0.1|${LSOF_TEST_PORT}|4242|node\n` : "", stderr: runs === 1 ? "" : "CIM query failed", code: (runs === 1 ? 0 : 1) as never, timedOut: false, stdoutTruncated: false, stderrTruncated: false, stdoutInvalidUtf8: false, stderrInvalidUtf8: false });
    },
    fetch: (() => Promise.resolve(new Response("app", { headers: { "content-type": "text/html" } }))) as typeof globalThis.fetch,
  });
  return Effect.gen(function* () {
    const scanner = yield* PortScanner.PortDiscovery;
    expect(yield* scanner.scan()).toHaveLength(1);
    yield* TestClock.adjust(Duration.seconds(3));
    const afterFailure = yield* scanner.scan();
    const duringCooldown = yield* scanner.scan();
    expect({ afterFailure: afterFailure.length, duringCooldown: duringCooldown.length, runs }).toEqual({ afterFailure: 1, duringCooldown: 1, runs: 2 });
  }).pipe(Effect.provide(layer));
});

effectIt.effect("review: truncated PowerShell tables retain the last snapshot and back off", () => {
  let runs = 0;
  const layer = makeWindowsScannerLayer({
    windowsListeners: Effect.fail(new NativeTelemetryClient.NativeTelemetryUnavailable({ reason: "review fixture" })),
    run: () => {
      runs++;
      return Effect.succeed({ stdout: runs === 1 ? `127.0.0.1|${LSOF_TEST_PORT}|4242|node\n` : "127.0.0.1|", stderr: "", code: 0 as never, timedOut: false, stdoutTruncated: runs > 1, stderrTruncated: false, stdoutInvalidUtf8: false, stderrInvalidUtf8: false });
    },
    fetch: (() => Promise.resolve(new Response("app", { headers: { "content-type": "text/html" } }))) as typeof globalThis.fetch,
  });
  return Effect.gen(function* () {
    const scanner = yield* PortScanner.PortDiscovery;
    expect(yield* scanner.scan()).toHaveLength(1);
    yield* TestClock.adjust(Duration.seconds(3));
    const afterFailure = yield* scanner.scan();
    yield* scanner.scan();
    expect({ afterFailure: afterFailure.length, runs }).toEqual({ afterFailure: 1, runs: 2 });
  }).pipe(Effect.provide(layer));
});