mirror of
https://github.com/morluto/rea.git
synced 2026-11-14 18:52:48 +00:00
* fix(verifiers): release fixture roots only after their owners finish Several real-tool verifiers released a fixture root even when a cleanup that still used it had failed, so a surviving MCP server, session or descendant kept running against a deleted directory and the failure looked like ordinary cleanup. - scripts/lib/verifier-cleanup.mjs: new releaseAfter(dependents, release, retained) task. It attempts every dependent cleanup and releases the resource only if all succeed; otherwise it keeps the resource and reports it with the dependent failures. - verify-signal-recording: the root is released after the MCP client and transport close, and the host-limits read moves before the root is acquired so its failure cannot leak the root. - verify-recorded-crash: sessions, the sentinel and the process-lineage check must all succeed before the root is released. A transport close failure after a failed connect keeps the connect failure. - verify-wasm-artifact: both roots are released after the MCP client and transport close; the residue check and the two directories stay independent after that. - verify-native-ui: `open -W` exits only after the app exits, so the root is removed only once that exit is observed; otherwise it is retained and reported. Fixes #8561 Fixes #8562 Fixes #8564 Refs #8559 Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(verifiers): treat a signaled open as unproven fixture exit A terminated `open` launcher does not prove the LaunchServices app it started has exited, so only an `open -W` that exits on its own counts. Also clear the grace timer so a prompt exit does not hold the process for the rest of the grace period. Refs #8559 Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * test(verifiers): model open -W exiting after the fixture is signaled The native UI verifier now removes its root only after `open -W` exits on its own. The authored recording's `open` never exited when the fixture was signaled and had no signalCode, so the complete case waited out the grace period and kept the root. The double now behaves like `open -W`: it exits once the fixture process is signaled. Refs #8559 Co-Authored-By: gensokyo-dev <gensokyo-dev@users.noreply.github.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: gensokyo-dev <gensokyo-dev@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
59 lines
1.6 KiB
JavaScript
59 lines
1.6 KiB
JavaScript
async function collectCleanupFailures(tasks) {
|
|
const failures = [];
|
|
for (const task of tasks) {
|
|
try {
|
|
await task();
|
|
} catch (cause) {
|
|
failures.push(cause);
|
|
}
|
|
}
|
|
|
|
return failures;
|
|
}
|
|
|
|
/**
|
|
* A cleanup task that releases one resource only after every cleanup that may
|
|
* still use it has succeeded. When a dependent fails, the resource is retained
|
|
* and reported with that failure instead of being released underneath it.
|
|
*/
|
|
export function releaseAfter(dependents, release, retained) {
|
|
return async () => {
|
|
const failures = await collectCleanupFailures(dependents);
|
|
if (failures.length > 0)
|
|
throw new AggregateError(
|
|
[
|
|
...failures,
|
|
new Error(`Retained ${retained} because a dependent cleanup failed.`),
|
|
],
|
|
"Verifier cleanup failed",
|
|
);
|
|
await release();
|
|
};
|
|
}
|
|
|
|
/** Attempt every independent cleanup and preserve each failure. */
|
|
export async function closeVerifierResources(tasks) {
|
|
const failures = await collectCleanupFailures(tasks);
|
|
if (failures.length > 0)
|
|
throw new AggregateError(failures, "Verifier cleanup failed");
|
|
}
|
|
|
|
/** Finish one operation and its cleanup without losing either failure. */
|
|
export async function withVerifierCleanup(operation, cleanupTasks) {
|
|
let value;
|
|
try {
|
|
value = await operation();
|
|
} catch (cause) {
|
|
const failures = await collectCleanupFailures(cleanupTasks);
|
|
if (failures.length > 0)
|
|
throw new AggregateError(
|
|
[cause, ...failures],
|
|
"Verifier cleanup failed",
|
|
{ cause },
|
|
);
|
|
throw cause;
|
|
}
|
|
await closeVerifierResources(cleanupTasks);
|
|
return value;
|
|
}
|