mirror of
https://github.com/morluto/rea
synced 2026-10-26 06:16:17 -04:00
fix(kuna): own version-probe processes through output and cleanup
Use the shared command supervisor for installation probes and retain exact process cleanup owners through doctor, profile resolution, and session health. Preserve exit status, bounded captured output, cancellation reasons, and live cleanup facts. Block subsequent inspection until retained cleanup is retried. Generalize the existing inspection resource scope and migrate its consumers, including verifier scripts; remove the verifier's duplicate raw version probe. Validation: 116 distinct focused tests passed, including built CLI doctor with inherited output, cancellation/finalization, cleanup retry, and fake-provider verifier workflows. Build, check:fast, and test discovery passed. No real Kuna distribution or analysis target was executed. Synthetic Darwin inspection timing: first-call median 707ms versus 5.79ms; same-process repeat 37.9ms versus 3.08ms. First use includes ownership-helper preparation. Family CPU and actual peak family memory remain unmeasured. Fixes #5557
This commit is contained in:
@@ -14,14 +14,14 @@ export const nativeKunaIncomingSites = async ({
|
||||
binary,
|
||||
address,
|
||||
retain,
|
||||
fileCloseResources,
|
||||
resourceScope,
|
||||
}) => {
|
||||
const installed = await inspectKunaInstallation(
|
||||
{
|
||||
REA_KUNA_COMMAND: executable,
|
||||
REA_KUNA_CACHE_DIR: cacheRoot,
|
||||
},
|
||||
{ fileCloseResources },
|
||||
{ resourceScope },
|
||||
);
|
||||
assert.ok(installed.ok, "Native reference oracle could not inspect Kuna");
|
||||
const input = await realpath(binary);
|
||||
@@ -37,7 +37,7 @@ export const nativeKunaIncomingSites = async ({
|
||||
outputBytes: KUNA_XREF_OUTPUT_BYTES,
|
||||
signal: new AbortController().signal,
|
||||
retainFailedFileClose: (owner, resource) =>
|
||||
fileCloseResources.retain(owner, resource),
|
||||
resourceScope.retain(owner, resource),
|
||||
});
|
||||
if (outcome.kind === "retained") retain(outcome);
|
||||
if (outcome.kind !== "ok") throw outcome.error;
|
||||
|
||||
@@ -19,14 +19,14 @@ export const nativeKunaStrings = async ({
|
||||
workspace,
|
||||
binary,
|
||||
retain,
|
||||
fileCloseResources,
|
||||
resourceScope,
|
||||
}) => {
|
||||
const installed = await inspectKunaInstallation(
|
||||
{
|
||||
REA_KUNA_COMMAND: executable,
|
||||
REA_KUNA_CACHE_DIR: cacheRoot,
|
||||
},
|
||||
{ fileCloseResources },
|
||||
{ resourceScope },
|
||||
);
|
||||
assert.ok(installed.ok, "Native string oracle could not inspect Kuna");
|
||||
const input = await realpath(binary);
|
||||
@@ -51,7 +51,7 @@ export const nativeKunaStrings = async ({
|
||||
outputBytes: 16 * 1024 * 1024,
|
||||
signal: new AbortController().signal,
|
||||
retainFailedFileClose: (owner, resource) =>
|
||||
fileCloseResources.retain(owner, resource),
|
||||
resourceScope.retain(owner, resource),
|
||||
});
|
||||
if (outcome.kind === "retained") retain(outcome);
|
||||
if (outcome.kind !== "ok") throw outcome.error;
|
||||
@@ -87,7 +87,6 @@ export const verifyKunaStrings = async ({
|
||||
cacheRoot,
|
||||
nativeStrings,
|
||||
expectedStrings = [],
|
||||
fileCloseResources,
|
||||
}) => {
|
||||
const expected = await nativeStrings();
|
||||
if (expectedStrings.length > 0)
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { ArtifactResourceScope } from "../../src/artifacts/ArtifactResourceScope.js";
|
||||
import type { FileCloseResourceOwner } from "../../src/application/AnalysisProvider.js";
|
||||
import type { RetainedResourceScope } from "../../src/application/AnalysisProvider.js";
|
||||
|
||||
/** Complete a prerequisite operation, including retained cleanup on failure. */
|
||||
export function withVerifierResourceOwner<T>(
|
||||
operation: (owner: FileCloseResourceOwner) => Promise<T>,
|
||||
operation: (owner: RetainedResourceScope) => Promise<T>,
|
||||
): Promise<T>;
|
||||
|
||||
/** Hash one verifier input and transfer failed-close ownership to its scope. */
|
||||
|
||||
@@ -25,8 +25,9 @@ import { fileURLToPath } from "node:url";
|
||||
import { parseArgs, promisify } from "node:util";
|
||||
import { Client } from "@modelcontextprotocol/client";
|
||||
import { StdioClientTransport } from "@modelcontextprotocol/client/stdio";
|
||||
import { execFileOutput } from "../dist/process/ExecFileOutput.js";
|
||||
import { inspectKunaInstallation } from "../dist/kuna/KunaInstallation.js";
|
||||
import { ArtifactResourceScope } from "../dist/artifacts/ArtifactResourceScope.js";
|
||||
import { AnalysisCleanupLease } from "../dist/artifacts/AnalysisCleanupLease.js";
|
||||
import { requireMcpOperationResult } from "./lib/mcp-verifier-results.mjs";
|
||||
import { verifyKunaReferences } from "./lib/kuna-reference-verifier.mjs";
|
||||
import {
|
||||
@@ -71,11 +72,15 @@ if (values["compare-ghidra"]) {
|
||||
);
|
||||
}
|
||||
const run = createVerifierRun();
|
||||
const fileCloseScope = new ArtifactResourceScope();
|
||||
const fileCloseResources = {
|
||||
const inspectionResources = new ArtifactResourceScope();
|
||||
const resourceScope = {
|
||||
retain: (owner, resource) =>
|
||||
fileCloseScope.retain({ kind: "file-handle", resource, handle: owner }),
|
||||
run: (operation) => fileCloseScope.run(operation),
|
||||
inspectionResources.retain({
|
||||
kind: "lease",
|
||||
resource,
|
||||
lease: AnalysisCleanupLease.forCloseOwner(owner, resource),
|
||||
}),
|
||||
run: (operation) => inspectionResources.run(operation),
|
||||
};
|
||||
const workspace = await mkdtemp(join(tmpdir(), "rea-kuna-lane-"));
|
||||
const cacheRoot = join(workspace, "cache");
|
||||
@@ -292,7 +297,6 @@ const verifyKuna = async (
|
||||
call: cold.call,
|
||||
cacheRoot,
|
||||
expectedStrings,
|
||||
fileCloseResources,
|
||||
nativeStrings: () =>
|
||||
nativeKunaStrings({
|
||||
executable: kuna,
|
||||
@@ -300,7 +304,7 @@ const verifyKuna = async (
|
||||
workspace,
|
||||
binary: path,
|
||||
retain: (owner) => retainedNative.add(owner),
|
||||
fileCloseResources,
|
||||
resourceScope,
|
||||
}),
|
||||
}),
|
||||
});
|
||||
@@ -324,7 +328,7 @@ const verifyKuna = async (
|
||||
binary: path,
|
||||
address: targetAddress,
|
||||
retain: (outcome) => retainedNative.add(outcome),
|
||||
fileCloseResources,
|
||||
resourceScope,
|
||||
}),
|
||||
});
|
||||
const pseudocode = await cold.call("procedure_pseudo_code", {
|
||||
@@ -492,15 +496,17 @@ const verifyVariant = async ({ flavor, directory, symbols }, variant) => {
|
||||
|
||||
const results = [];
|
||||
const failures = [];
|
||||
let fileResourcesClean = true;
|
||||
let inspectionResourcesClean = true;
|
||||
try {
|
||||
kunaVersion = (
|
||||
await execFileOutput(kuna, ["--version"], {
|
||||
timeout: 10_000,
|
||||
maxBuffer: 64 * 1024,
|
||||
stopSignal: "SIGTERM",
|
||||
})
|
||||
).stdout.trim();
|
||||
const installation = await inspectKunaInstallation(
|
||||
{ REA_KUNA_COMMAND: kuna, REA_KUNA_CACHE_DIR: cacheRoot },
|
||||
{ resourceScope },
|
||||
);
|
||||
assert.ok(
|
||||
installation.ok,
|
||||
installation.ok ? undefined : installation.error.reason,
|
||||
);
|
||||
kunaVersion = `kuna ${installation.value.version}`;
|
||||
let callerPairs = [];
|
||||
if (values.targets !== undefined) {
|
||||
const names = (values.functions ?? "").split(",").filter(Boolean);
|
||||
@@ -566,14 +572,16 @@ for (const retained of [...retainedNative]) {
|
||||
}
|
||||
}
|
||||
try {
|
||||
await fileCloseScope.close();
|
||||
await inspectionResources.close();
|
||||
} catch (cause) {
|
||||
fileResourcesClean = false;
|
||||
inspectionResourcesClean = false;
|
||||
failures.push(cause);
|
||||
}
|
||||
const lifecycle = await completeVerifierRun(run);
|
||||
let cleanupComplete =
|
||||
pendingServers.size === 0 && retainedNative.size === 0 && fileResourcesClean;
|
||||
pendingServers.size === 0 &&
|
||||
retainedNative.size === 0 &&
|
||||
inspectionResourcesClean;
|
||||
try {
|
||||
assertVerifierCleanupComplete(lifecycle.process_lineage);
|
||||
} catch (cause) {
|
||||
|
||||
Reference in New Issue
Block a user