fix(process): integrate main and confirm native exit transitions

This commit is contained in:
gensokyo-dev committed 2026-10-19 17:30:45 +00:00
commit 8ea965261e
71 files changed
+6651 -475

No files matched your search

+23 -12
View File
@@ -5,15 +5,22 @@ import { dirname, join, resolve } from "node:path";
import { fileURLToPath } from "node:url";
// Route production MCP before importing Incur. Incur owns registration helpers
// such as `mcp add`, while the MCP runtime serves the stdio tool catalog.
// such as `mcp add`, while the MCP runtime serves the tool catalog over stdio
// or, with `--http`, over streamable HTTP.
const args = process.argv.slice(2);
const { default: packageJson } = await import("../package.json", {
with: { type: "json" },
});
process.env.REA_PACKAGE_VERSION = packageJson.version;
const isMcpMode =
args.length === 1 && (args[0] === "--mcp" || args[0] === "mcp");
const isMcpEntry = args[0] === "--mcp" || args[0] === "mcp";
const isMcpMode = isMcpEntry && args.length === 1;
const isMcpDoctorMode = args[0] === "mcp" && args[1] === "doctor";
// Only flags may follow the entry: `mcp add --http` stays Incur's `mcp add`,
// while `mcp -h --http` reaches the HTTP entry's own help.
const isMcpHttpMode =
isMcpEntry &&
(args[1]?.startsWith("-") ?? false) &&
args.slice(1).includes("--http");
/** Exit status of a writer terminated by SIGPIPE (128 + 13). */
const SIGPIPE_EXIT_STATUS = 141;
// Set once the reader of CLI output has closed the pipe.
@@ -40,15 +47,16 @@ if (
process.env.PLAYWRIGHT_BROWSERS_PATH = join(cacheRoot, "ms-playwright");
}
const runtimeFiles = isMcpMode
? ["dist/mcp/main.js"]
: isMcpDoctorMode
? ["dist/mcp/main.js", "dist/cli-runtime/mcpDoctor.js"]
: [
"dist/cli-runtime/cli.js",
"dist/cli-runtime/cliOutput.js",
"dist/cli-runtime/cliResultOutput.js",
];
const runtimeFiles =
isMcpMode || isMcpHttpMode
? ["dist/mcp/main.js"]
: isMcpDoctorMode
? ["dist/mcp/main.js", "dist/cli-runtime/mcpDoctor.js"]
: [
"dist/cli-runtime/cli.js",
"dist/cli-runtime/cliOutput.js",
"dist/cli-runtime/cliResultOutput.js",
];
if (!(await compiledRuntimeExists(runtimeFiles))) {
process.stderr.write(
@@ -58,6 +66,9 @@ if (!(await compiledRuntimeExists(runtimeFiles))) {
} else if (isMcpMode) {
const { runEntrypoint } = await import("../dist/mcp/main.js");
await runEntrypoint();
} else if (isMcpHttpMode) {
const { runMcpHttpEntrypoint } = await import("../dist/mcp/main.js");
await runMcpHttpEntrypoint(args.slice(1));
} else if (isMcpDoctorMode) {
guardClosedStdout();
const { runProductionMcpDoctorCli } =
+8
View File
@@ -0,0 +1,8 @@
/** Preserve an unexpected JSON result while describing the failed plan check. */
export function setupPlanFailureMessage(options: {
readonly planned: unknown;
readonly plannedExecution: { readonly status: number | null };
readonly plannedClaudeConfig: string;
readonly plannedCodexConfig: string;
readonly plannedCursorConfig: string;
}): string;
+23
View File
@@ -0,0 +1,23 @@
/** Describe a failed package setup-plan check without masking its result shape. */
export const setupPlanFailureMessage = ({
planned,
plannedExecution,
plannedClaudeConfig,
plannedCodexConfig,
plannedCursorConfig,
}) => {
const actionKinds = (actions) =>
Array.isArray(actions)
? actions.map((action) => action?.kind ?? action)
: actions;
return `packaged setup plan was not read-only: ${JSON.stringify({
status: planned?.status,
exitCode: plannedExecution.status,
plannedKinds: actionKinds(planned?.plannedActions),
appliedKinds: actionKinds(planned?.appliedActions),
result: planned,
claudeConfig: plannedClaudeConfig,
codexConfig: plannedCodexConfig,
cursorConfig: plannedCursorConfig,
})}`;
};
+20 -5
View File
@@ -21,6 +21,7 @@ import {
} from "./lib/verify-package-core.mjs";
import { parse as parseJsonc } from "jsonc-parser";
import { skillReferenceIssues } from "./lib/docs-facts.mjs";
import { setupPlanFailureMessage } from "./verify-package-setup-plan.mjs";
export const terminalModesRestored = (termios) => {
if (typeof termios !== "string") return false;
@@ -250,23 +251,37 @@ const verifySetupPlan = async ({
);
const planned = json(plannedExecution.stdout);
if (supportedSetupHost) {
const plannedActions = Array.isArray(planned?.plannedActions)
? planned.plannedActions
: undefined;
const appliedActions = Array.isArray(planned?.appliedActions)
? planned.appliedActions
: undefined;
const plannedClaudeConfig = await readFile(claudeConfig, "utf8");
const plannedCodexConfig = await readFile(codexTarget, "utf8");
const plannedCursorConfig = await readFile(cursorConfig, "utf8");
const plannedOpenCodeConfig = await readFile(opencodeConfig, "utf8");
if (
planned.status !== "planned" ||
planned?.status !== "planned" ||
plannedExecution.status !== 0 ||
planned.appliedActions.length !== 0 ||
!planned.plannedActions.some(({ kind }) => kind === "configure_client") ||
!planned.plannedActions.some(({ kind }) => kind === "install_skill") ||
plannedActions === undefined ||
appliedActions === undefined ||
appliedActions.length !== 0 ||
!plannedActions.some((action) => action?.kind === "configure_client") ||
!plannedActions.some((action) => action?.kind === "install_skill") ||
plannedClaudeConfig !== '{"existing":true}\n' ||
plannedCodexConfig !== CODEX_ORIGINAL ||
plannedCursorConfig !== '{"existing":true}\n' ||
plannedOpenCodeConfig !== opencodeOriginal
)
throw new Error(
`packaged setup plan was not read-only: ${JSON.stringify({ status: planned.status, exitCode: plannedExecution.status, plannedKinds: planned.plannedActions.map(({ kind }) => kind), appliedKinds: planned.appliedActions.map(({ kind }) => kind), claudeConfig: plannedClaudeConfig, codexConfig: plannedCodexConfig, cursorConfig: plannedCursorConfig })}`,
setupPlanFailureMessage({
planned,
plannedExecution,
plannedClaudeConfig,
plannedCodexConfig,
plannedCursorConfig,
}),
);
}
return { planned };
@@ -0,0 +1,17 @@
export interface OwnershipTraceExecution {
readonly pid: number;
readonly path: string;
readonly line: string;
readonly succeeded: boolean;
readonly ownershipInventory: boolean;
}
/** Parsed topology and execution facts for one complete strace observation. */
export function collectOwnershipTraceFacts(options: {
readonly traces: readonly { readonly pid: number; readonly text: string }[];
readonly nodeExecutable: string;
readonly psExecutables: ReadonlySet<string>;
}): {
readonly ownershipThreads: ReadonlySet<number>;
readonly psProcesses: ReadonlySet<number>;
readonly executions: readonly OwnershipTraceExecution[];
};
@@ -0,0 +1,127 @@
import assert from "node:assert/strict";
const ownershipPsArguments =
'["ps", "-axo", "pid=,ppid=,pgid=,uid=,stat=,command="]';
/** Parse execution/thread facts once; only an observed Node ps caller owns inventory reads. */
export const collectOwnershipTraceFacts = ({
traces,
nodeExecutable,
psExecutables,
}) => {
const processGroups = new Map();
const findGroup = (pid) => {
const parent = processGroups.get(pid);
if (parent === undefined) {
processGroups.set(pid, pid);
return pid;
}
if (parent === pid) return pid;
const root = findGroup(parent);
processGroups.set(pid, root);
return root;
};
const joinThreadGroup = (left, right) => {
const leftRoot = findGroup(left);
const rightRoot = findGroup(right);
if (leftRoot !== rightRoot) processGroups.set(rightRoot, leftRoot);
};
const cloneEvents = [];
for (const trace of traces) {
let unfinished;
for (const rawLine of trace.text.split("\n")) {
const line = rawLine.trimStart();
const start = /^(clone3?|fork|vfork)\((.*)<unfinished \.\.\.>$/u.exec(
line,
);
if (start !== null) {
unfinished = { name: start[1], text: start[2] };
continue;
}
const resumed = /^<\.\.\. (clone3?|fork|vfork) resumed>(.*)$/u.exec(line);
if (resumed !== null && resumed[1] === unfinished?.name) {
cloneEvents.push({
parentPid: trace.pid,
text: `${unfinished.text}${resumed[2]}`,
});
unfinished = undefined;
continue;
}
const complete =
/^(clone3?|fork|vfork)\((.*\)) = (\d+)(?:<[^>]*>)?$/u.exec(line);
if (complete !== null)
cloneEvents.push({
parentPid: trace.pid,
childPid: Number(complete[3]),
text: complete[2],
});
}
}
for (const event of cloneEvents) {
const childPid =
event.childPid ?? /\) = (\d+)(?:<[^>]*>)?$/u.exec(event.text)?.[1];
if (childPid === undefined) continue;
const observedChild = Number(childPid);
// A child-side clone return of zero is not a parent-to-child edge.
if (!Number.isSafeInteger(observedChild) || observedChild <= 0) continue;
event.childPid = observedChild;
if (/\bCLONE_THREAD\b/u.test(event.text))
joinThreadGroup(event.parentPid, event.childPid);
}
const executions = [];
for (const trace of traces) {
for (const line of trace.text.split("\n")) {
if (!/execve(?:at)?\(/u.test(line)) continue;
const match = /^execve\("([^"]+)"/u.exec(line);
assert.notEqual(match, null, `Unresolved executable identity: ${line}`);
assert.ok(
/ = (?:0|-1 [A-Z]+)/u.test(line),
`Incomplete execution observation: ${line}`,
);
executions.push({
pid: trace.pid,
path: match[1],
line,
succeeded: line.endsWith(" = 0"),
ownershipInventory:
psExecutables.has(match[1]) && line.includes(ownershipPsArguments),
});
}
}
const psProcesses = new Set(
executions
.filter(
({ succeeded, ownershipInventory }) => succeeded && ownershipInventory,
)
.map(({ pid }) => pid),
);
const psParentGroups = new Set(
cloneEvents
.filter(({ childPid }) => psProcesses.has(childPid))
.map(({ parentPid }) => findGroup(parentPid)),
);
const nodeGroups = new Set(
executions
.filter(({ path, succeeded }) => succeeded && path === nodeExecutable)
.map(({ pid }) => findGroup(pid)),
);
const replaced = new Set(
executions
.filter(({ path, succeeded }) => succeeded && path !== nodeExecutable)
.map(({ pid }) => pid),
);
const ownershipThreads = new Set(
traces
.filter(
({ pid }) =>
nodeGroups.has(findGroup(pid)) &&
psParentGroups.has(findGroup(pid)) &&
!replaced.has(pid),
)
.map(({ pid }) => pid),
);
return { ownershipThreads, psProcesses, executions };
};
@@ -7,14 +7,10 @@ export const historicalPidTraceContract: {
readonly pid_syscalls: readonly string[];
readonly unverified: readonly string[];
};
export function nodeInventoryThreads(
traces: readonly SyscallTrace[],
executable: string,
): ReadonlySet<number>;
export function assertHistoricalPidAccess(input: {
readonly trace: SyscallTrace;
readonly historicalPid: number;
readonly nodeThreads: ReadonlySet<number>;
readonly ownershipThreads: ReadonlySet<number>;
readonly liveCollision: boolean;
readonly psInventory: boolean;
}): readonly string[];
+5 -50
View File
@@ -1,52 +1,6 @@
import assert from "node:assert/strict";
import { posix } from "node:path";
/** Identify REA's Node processes and their observed CLONE_THREAD children. */
export function nodeInventoryThreads(traces, executable) {
const executesForeign = (text) =>
text
.split("\n")
.some(
(line) =>
/^execve\(/u.test(line) &&
line.endsWith(" = 0") &&
!line.startsWith(`execve(${JSON.stringify(executable)},`),
);
const byPid = new Map(traces.map((trace) => [trace.pid, trace]));
const nodes = new Set(
traces
.filter(
({ text }) =>
!executesForeign(text) &&
text
.split("\n")
.some(
(line) =>
line.startsWith(`execve(${JSON.stringify(executable)},`) &&
line.endsWith(" = 0"),
),
)
.map(({ pid }) => pid),
);
for (const pid of nodes) {
let pendingThreadClone = false;
for (const line of byPid.get(pid)?.text.split("\n") ?? []) {
if (!/^(?:clone3?\(|<\.\.\. clone3? resumed>)/u.test(line)) continue;
if (/^clone3?\(/u.test(line))
pendingThreadClone = /\bCLONE_THREAD\b/u.test(line);
const child = / = (\d+)$/u.exec(line);
if (pendingThreadClone && child !== null) {
const childPid = Number(child[1]);
const trace = byPid.get(childPid);
if (trace !== undefined && !executesForeign(trace.text))
nodes.add(childPid);
}
if (!line.endsWith("<unfinished ...>")) pendingThreadClone = false;
}
}
return nodes;
}
// This owner supplies both tracer selection and target interpretation. Kinds
// describe syscall argument semantics, never catalog positions or output PIDs.
const pidTargetKinds = new Map([
@@ -176,7 +130,7 @@ const readsMetadata = (line, root, names) => {
export function assertHistoricalPidAccess({
trace,
historicalPid,
nodeThreads,
ownershipThreads,
liveCollision,
psInventory,
}) {
@@ -216,8 +170,9 @@ export function assertHistoricalPidAccess({
!referencesHistoricalPath(line)
)
continue;
const nodeStat =
nodeThreads.has(trace.pid) && readsMetadata(line, root, ["stat"]);
const ownershipMetadata =
ownershipThreads.has(trace.pid) &&
readsMetadata(line, root, ["stat", "status"]);
const psMetadata =
psInventory &&
(readsMetadata(line, root, [
@@ -236,7 +191,7 @@ export function assertHistoricalPidAccess({
liveCollision &&
target !== "historical" &&
target !== "unresolved" &&
(nodeStat || psMetadata),
(ownershipMetadata || psMetadata),
`${target === "unresolved" ? "Unresolved process target in" : "Historical PID caused a"} non-inventory lookup in trace ${trace.pid}: ${line}`,
);
accesses.push(line);
+46 -56
View File
@@ -7,8 +7,8 @@ import { parseEvidence } from "../../../dist/domain/evidence.js";
import {
assertHistoricalPidAccess,
historicalPidTraceContract,
nodeInventoryThreads,
} from "./trace-policy.mjs";
import { collectOwnershipTraceFacts } from "./trace-ownership.mjs";
/** Check attempted syscalls, including failed attempts, on a recorded PID that collides with an owned live sentinel. */
export async function verifyCoreInspectionTrace({
@@ -100,11 +100,19 @@ export async function verifyCoreInspectionTrace({
// Retain only execution/thread evidence across files, not all raw traces.
const inventory = text
.split("\n")
.filter((line) => /^(?:execve|clone|<\.\.\. clone)/u.test(line))
.filter((line) =>
/^(?:execve|clone|fork|vfork|<\.\.\. (?:clone|fork|vfork))/u.test(
line,
),
)
.join("\n");
traces.push({ pid, text: inventory, file });
}
const nodeThreads = nodeInventoryThreads(traces, process.execPath);
const ownershipFacts = collectOwnershipTraceFacts({
traces,
nodeExecutable: process.execPath,
psExecutables: psPaths,
});
for (const trace of traces) {
const { file } = trace;
const text = await readFile(join(root, file), "utf8");
@@ -115,23 +123,13 @@ export async function verifyCoreInspectionTrace({
!text.split("\n").some((line) => line.includes(recordedExecutable)),
`Inspection attempted access to the recorded executable: ${file}`,
);
const ownershipTrace = text
.split("\n")
.some(
(line) =>
/^execve\("\/(?:usr\/)?bin\/ps",/u.test(line) &&
line.includes(
'["ps", "-axo", "pid=,ppid=,pgid=,uid=,stat=,command="]',
) &&
line.endsWith(" = 0"),
);
ownershipReads.push(
...assertHistoricalPidAccess({
trace: { pid: trace.pid, text },
historicalPid,
nodeThreads,
ownershipThreads: ownershipFacts.ownershipThreads,
liveCollision: historicalPid === sentinel.pid,
psInventory: ownershipTrace,
psInventory: ownershipFacts.psProcesses.has(trace.pid),
}),
);
assert.ok(
@@ -148,48 +146,40 @@ export async function verifyCoreInspectionTrace({
),
`Inspection attempted an Internet socket: ${file}`,
);
for (const line of text.split("\n")) {
if (!/execve(?:at)?\(/u.test(line)) continue;
const match = /^execve\("([^"]+)"/u.exec(line);
assert.notEqual(match, null, `Unresolved executable identity: ${line}`);
assert.ok(
/ = (?:0|-1 [A-Z]+)/u.test(line),
`Incomplete execution observation: ${line}`,
}
for (const execution of ownershipFacts.executions) {
const { line } = execution;
const executable = await realpath(execution.path).catch(
() => execution.path,
);
const ownership = execution.ownershipInventory;
const iconv =
iconvPaths.has(execution.path) && line.includes('["iconv", "-l"]');
const version =
gitPaths.has(execution.path) &&
line.includes(
"[" +
[
"git",
"--git-dir",
join(plugin, ".git"),
"rev-parse",
"--short",
"HEAD",
]
.map((argument) => JSON.stringify(argument))
.join(", ") +
"]",
);
const executable = await realpath(match[1]).catch(() => match[1]);
const ownership =
psPaths.has(match[1]) &&
line.includes(
'["ps", "-axo", "pid=,ppid=,pgid=,uid=,stat=,command="]',
);
const iconv =
iconvPaths.has(match[1]) && line.includes('["iconv", "-l"]');
const version =
gitPaths.has(match[1]) &&
line.includes(
"[" +
[
"git",
"--git-dir",
join(plugin, ".git"),
"rev-parse",
"--short",
"HEAD",
]
.map((argument) => JSON.stringify(argument))
.join(", ") +
"]",
);
assert.ok(
[process.execPath, python, gdb].includes(executable) ||
ownership ||
iconv ||
version,
`Unexpected attempted host execution: ${line}`,
);
if (executable === gdb) gdbObserved = true;
executions.push(executable);
}
assert.ok(
[process.execPath, python, gdb].includes(executable) ||
ownership ||
iconv ||
version,
`Unexpected attempted host execution: ${line}`,
);
if (executable === gdb) gdbObserved = true;
executions.push(executable);
}
assert.ok(gdbObserved, "Trace must include the actual core-only GDB stage");
assert.ok(executions.includes(python));