fix(pi): strengthen final release proof

This commit is contained in:
2026-08-24 15:47:57 +08:00
parent c7e777246e
commit df1151b5eb
19 changed files with 1120 additions and 149 deletions

View File

@@ -0,0 +1,593 @@
import { spawn, type ChildProcess } from 'node:child_process';
import { mkdtemp, rm } from 'node:fs/promises';
import { tmpdir } from 'node:os';
import path from 'node:path';
import { pathToFileURL } from 'node:url';
import { createCodingConversationStore } from '../../coding-projects/conversation-store';
import { createCodingProjectAgent } from '../../coding-projects/project-config';
import {
createCodingProjectStore,
createLocalCodingProject,
createMemoryCodingProjectStorage,
} from '../../coding-projects/project-store';
import type { ProviderAccount } from '../../shared/providers/types';
import type { PrepareConversationInput } from '../contracts';
import type { PiProcessError } from './process-errors';
import { PiManagedExtensionHost } from './extension-host';
import type {
PiRpcCommand,
PiRpcEvent,
PiRpcResponse,
} from './rpc-client';
import {
PiSubagentScheduler,
type PiSubagentChild,
} from './subagent';
import {
PiProcessBudget,
PiWorkerPool,
type PiConversationWorker,
} from './worker-pool';
import { PiProjectWriteLeaseCoordinator, type PiProjectWriteLease } from './write-lease';
import { createPiManagedWorkerOpener } from './runtime';
import { PiSessionRegistry } from './session-registry';
import type { PiRuntimeTelemetryEvent } from './telemetry';
type ExtensionHandler = (...arguments_: unknown[]) => Promise<unknown> | unknown;
type ExtensionTool = {
name: string;
execute?: (...arguments_: unknown[]) => Promise<unknown>;
};
type PressureProcess = {
label: string;
child: ChildProcess;
pid: number;
stop(): Promise<void>;
};
type Deferred = {
promise: Promise<void>;
resolve(): void;
};
type PressureRun = {
active: PiReleasePressureSnapshot;
finish(): Promise<PiReleasePressureSnapshot>;
};
export interface PiReleasePressureSnapshot {
parentWorkers: number;
childWorkers: number;
liveProcessIds: number[];
processBudget: { active: number; waiting: number };
childPermits: { active: number; waiting: number };
dispatches: { active: number; parents: number };
writeLeases: { active: number; waiting: number };
}
export interface PiReleaseExtensionProof {
parentToolNames: string[];
childToolNames: string[];
subagentStatus: string;
subagentSummary: string;
materializedExtension: string;
managedWorkerMilestones: PiRuntimeTelemetryEvent[];
released: {
processBudget: { active: number; waiting: number };
childPermits: { active: number; waiting: number };
dispatches: { active: number; parents: number };
};
}
let pressureRun: PressureRun | null = null;
function deferred(): Deferred {
let resolve!: () => void;
const promise = new Promise<void>((done) => { resolve = done; });
return { promise, resolve };
}
async function waitFor(predicate: () => boolean, message: string): Promise<void> {
const deadline = Date.now() + 10_000;
while (Date.now() < deadline) {
if (predicate()) return;
await new Promise((resolveWait) => setTimeout(resolveWait, 20));
}
throw new Error(message);
}
async function spawnPressureProcess(label: string): Promise<PressureProcess> {
const child = spawn(process.execPath, [
'-e',
`process.title=${JSON.stringify(`makelore-pi-proof-${label}`)};setInterval(()=>{},1000)`,
], {
env: { ...process.env, ELECTRON_RUN_AS_NODE: '1' },
stdio: 'ignore',
windowsHide: true,
});
await new Promise<void>((resolveSpawn, rejectSpawn) => {
child.once('spawn', resolveSpawn);
child.once('error', rejectSpawn);
});
if (!child.pid) throw new Error(`Pressure process ${label} has no pid`);
let stopFlight: Promise<void> | null = null;
return {
label,
child,
pid: child.pid,
stop: () => {
if (stopFlight) return stopFlight;
stopFlight = (async () => {
if (child.exitCode !== null || child.signalCode !== null) return;
const exited = new Promise<void>((resolveExit) => child.once('exit', () => resolveExit()));
child.kill('SIGTERM');
const graceful = await Promise.race([
exited.then(() => true),
new Promise<boolean>((resolveTimeout) => setTimeout(() => resolveTimeout(false), 2_000)),
]);
if (!graceful && child.exitCode === null && child.signalCode === null) {
child.kill('SIGKILL');
await exited;
}
})();
return stopFlight;
},
};
}
class PressureConversationWorker implements PiConversationWorker {
readonly id: string;
private readonly eventListeners = new Set<(event: PiRpcEvent) => void>();
constructor(
readonly generation: number,
readonly process: PressureProcess,
) {
this.id = process.label;
}
async request<T = unknown>(command: PiRpcCommand): Promise<PiRpcResponse<T>> {
return {
type: 'response',
id: `${this.id}-${command.type}`,
command: command.type,
success: true,
};
}
async send(_command: PiRpcCommand): Promise<void> {}
subscribe(listener: (event: PiRpcEvent) => void): () => void {
this.eventListeners.add(listener);
return () => this.eventListeners.delete(listener);
}
subscribeInvalidation(_listener: (error: PiProcessError) => void): () => void {
return () => undefined;
}
emitSettled(): void {
for (const listener of this.eventListeners) listener({ type: 'agent_settled' });
}
async stop() {
await this.process.stop();
return { mode: 'forced-tree-kill' as const, code: 0, signal: null };
}
}
function conversation(index: number): PrepareConversationInput {
return {
conversationId: `release-proof-conversation-${index}`,
projectId: `release-proof-project-${index}`,
agentId: 'release-proof-agent',
title: `Release proof ${index}`,
model: {
model: {
accountId: 'release-proof-account',
modelId: 'release-proof-model',
thinkingLevel: 'medium',
},
modelResolution: 'resolved',
},
};
}
function pressureSnapshot(
pool: PiWorkerPool,
processBudget: PiProcessBudget,
scheduler: PiSubagentScheduler,
leases: PiProjectWriteLeaseCoordinator,
processes: PressureProcess[],
): PiReleasePressureSnapshot {
const subagents = scheduler.getDiagnostics();
return {
parentWorkers: pool.getDiagnostics().workers.filter(({ state }) => state === 'running').length,
childWorkers: subagents.activeChildPermits,
liveProcessIds: processes
.filter(({ child }) => child.exitCode === null && child.signalCode === null)
.map(({ pid }) => pid)
.sort((left, right) => left - right),
processBudget: { active: processBudget.activeCount, waiting: processBudget.waitingCount },
childPermits: {
active: subagents.activeChildPermits,
waiting: subagents.waitingChildPermits,
},
dispatches: {
active: subagents.activeDispatches,
parents: subagents.activeParents,
},
writeLeases: { active: leases.activeCount, waiting: leases.waitingCount() },
};
}
async function startPressureRun(): Promise<PressureRun> {
const processBudget = new PiProcessBudget(8);
const processes: PressureProcess[] = [];
const parentWorkers = new Map<string, PressureConversationWorker>();
const childGate = deferred();
const pool = new PiWorkerPool({
maxRunning: 4,
maxIdle: 4,
processBudget,
openWorker: async ({ conversation: input, generation }) => {
const pressureProcess = await spawnPressureProcess(`parent-${generation}-${input.conversationId}`);
processes.push(pressureProcess);
const worker = new PressureConversationWorker(generation, pressureProcess);
parentWorkers.set(input.conversationId, worker);
return {
worker,
session: {
piSessionId: `release-proof-session-${input.conversationId}`,
sessionKey: `release-proof-session-${input.conversationId}`,
},
};
},
});
let childIndex = 0;
const scheduler = new PiSubagentScheduler({
processBudget,
createId: (kind) => `release-proof-${kind}-${++childIndex}`,
openChild: async (input): Promise<PiSubagentChild> => {
const pressureProcess = await spawnPressureProcess(`child-${input.taskId}`);
processes.push(pressureProcess);
return {
id: input.taskId,
async run(_prompt, signal) {
await Promise.race([
childGate.promise,
new Promise<void>((_resolve, reject) => {
signal.addEventListener('abort', () => reject(new Error('Pressure child aborted')), {
once: true,
});
}),
]);
return { summary: `completed ${input.agentId}` };
},
async stop() { await pressureProcess.stop(); },
};
},
});
const writeLeases = new PiProjectWriteLeaseCoordinator();
const heldWriteLeases: PiProjectWriteLease[] = [];
const dispatches: Array<Promise<unknown>> = [];
try {
const inputs = Array.from({ length: 4 }, (_, index) => conversation(index + 1));
await Promise.all(inputs.map(async (input) => await pool.prepare(input)));
await Promise.all(inputs.map(async (input, index) => {
const ticket = pool.startTopLevel({
conversationId: input.conversationId,
runId: `release-proof-parent-run-${index + 1}`,
command: { type: 'prompt', message: 'release qualification pressure' },
});
await ticket.accepted;
}));
for (let index = 0; index < 4; index += 1) {
heldWriteLeases.push(await writeLeases.acquire(
`release-proof-write-project-${index + 1}`,
`release-proof-holder-${index + 1}`,
));
dispatches.push(scheduler.dispatch({
conversationId: inputs[index]?.conversationId ?? `release-proof-conversation-${index + 1}`,
workerGeneration: 1,
runId: `release-proof-parent-run-${index + 1}`,
projectId: inputs[index]?.projectId ?? `release-proof-project-${index + 1}`,
request: {
mode: 'single',
tasks: [{
agentId: `release-proof-child-agent-${index + 1}`,
task: 'hold one child during UI interaction',
toolProfile: 'read-only',
}],
},
}));
}
await waitFor(
() => processBudget.activeCount === 8
&& scheduler.getDiagnostics().activeChildPermits === 4
&& processes.length === 8,
'4 parent + 4 child pressure did not become active',
);
const active = pressureSnapshot(pool, processBudget, scheduler, writeLeases, processes);
if (active.liveProcessIds.length !== 8) {
throw new Error(`Expected 8 live pressure processes, got ${active.liveProcessIds.length}`);
}
return {
active,
finish: async () => {
childGate.resolve();
await Promise.all(dispatches);
for (const worker of parentWorkers.values()) worker.emitSettled();
await scheduler.close();
await pool.shutdown();
for (const lease of heldWriteLeases.splice(0)) lease.release();
await Promise.all(processes.map(async (entry) => await entry.stop()));
return pressureSnapshot(pool, processBudget, scheduler, writeLeases, processes);
},
};
} catch (error) {
childGate.resolve();
await scheduler.close().catch(() => undefined);
await pool.shutdown().catch(() => undefined);
for (const lease of heldWriteLeases.splice(0)) lease.release();
await Promise.allSettled(processes.map(async (entry) => await entry.stop()));
throw error;
}
}
async function withWorkerEnvironment<T>(
environment: NodeJS.ProcessEnv,
operation: () => Promise<T>,
): Promise<T> {
const previous = {
bridge: process.env.MAKELORE_PI_BRIDGE_URL,
token: process.env.MAKELORE_PI_WORKER_TOKEN,
context: process.env.MAKELORE_PI_CONTEXT_FILE,
role: process.env.MAKELORE_PI_WORKER_ROLE,
};
Object.assign(process.env, environment);
try {
return await operation();
} finally {
const values: Array<[keyof typeof previous, string]> = [
['bridge', 'MAKELORE_PI_BRIDGE_URL'],
['token', 'MAKELORE_PI_WORKER_TOKEN'],
['context', 'MAKELORE_PI_CONTEXT_FILE'],
['role', 'MAKELORE_PI_WORKER_ROLE'],
];
for (const [key, environmentKey] of values) {
const value = previous[key];
if (value === undefined) delete process.env[environmentKey];
else process.env[environmentKey] = value;
}
}
}
async function loadExtension(extensionPath: string, environment: NodeJS.ProcessEnv): Promise<{
tools: Map<string, ExtensionTool>;
handlers: Map<string, ExtensionHandler>;
}> {
return await withWorkerEnvironment(environment, async () => {
const module = await import(
/* @vite-ignore */ `${pathToFileURL(extensionPath).href}?release-proof=${Date.now()}-${Math.random()}`
) as {
default(factory: {
registerTool(tool: ExtensionTool): void;
on(event: string, handler: ExtensionHandler): void;
}): void;
};
const tools = new Map<string, ExtensionTool>();
const handlers = new Map<string, ExtensionHandler>();
module.default({
registerTool: (tool) => tools.set(tool.name, tool),
on: (event, handler) => handlers.set(event, handler),
});
return { tools, handlers };
});
}
async function runManagedWorkerMilestoneProof(
root: string,
extensionHost: PiManagedExtensionHost,
): Promise<PiRuntimeTelemetryEvent[]> {
const now = new Date().toISOString();
const projectPath = path.join(root, 'managed-project');
const userDataDir = path.join(root, 'managed-user-data');
const projectStore = createCodingProjectStore(createMemoryCodingProjectStorage(), {
createId: () => 'release-proof-managed-project',
now: () => now,
});
await createLocalCodingProject({ projectPath, now }, projectStore);
await createCodingProjectAgent(projectPath, {
id: 'release-proof-agent',
avatarId: 'avatar-01',
roleName: 'Release proof',
name: 'Release proof agent',
model: {
accountId: 'release-proof-account',
modelId: 'release-proof-model',
thinkingLevel: 'medium',
},
modelResolution: 'resolved',
responsibility: {
mission: 'Exercise final packaged managed worker composition',
owns: [],
boundaries: [],
collaborators: [],
principles: [],
},
prompt: 'Release qualification only.',
skillIds: [],
}, { now });
const conversationStore = createCodingConversationStore(projectPath, {
createId: () => 'f47ac10b-58cc-4372-a567-0e02b2c3d479',
now: () => now,
});
const created = await conversationStore.create({
agentId: 'release-proof-agent',
title: 'Release proof managed conversation',
model: {
accountId: 'release-proof-account',
modelId: 'release-proof-model',
thinkingLevel: 'medium',
},
modelResolution: 'resolved',
});
const input: PrepareConversationInput = {
conversationId: created.id,
projectId: 'release-proof-managed-project',
agentId: 'release-proof-agent',
title: created.title,
model: { model: created.model, modelResolution: created.modelResolution },
};
const account: ProviderAccount = {
id: 'release-proof-account',
vendorId: 'custom',
label: 'Release proof account',
authMode: 'api_key',
apiProtocol: 'openai-completions',
baseUrl: 'http://127.0.0.1:1/v1',
model: 'release-proof-model',
enabled: true,
isDefault: true,
createdAt: now,
updatedAt: now,
};
const telemetry: PiRuntimeTelemetryEvent[] = [];
const opener = createPiManagedWorkerOpener({
registry: new PiSessionRegistry({ projectStore }),
executablePath: process.execPath,
cliPath: path.join(process.resourcesPath, 'pi-runtime', 'dist', 'cli.js'),
userDataDir,
bundledSkillsDir: path.join(process.resourcesPath, 'resources', 'coding-skills'),
extensionHost,
loadProviderInput: async () => ({ accounts: [account], modelSummaries: [] }),
resolveCredential: async () => 'release-proof-local-only',
createSessionKey: () => '8b1a9953-c461-4d88-9c3e-7e1f8f3f2c11',
onTelemetry: (event) => telemetry.push(event),
});
const first = await opener({
conversation: input,
generation: 1,
revision: { provider: 1, resources: 1 },
});
try {
await first.worker.stop();
const reopened = await opener({
conversation: input,
generation: 2,
revision: { provider: 1, resources: 1 },
existingSession: first.session,
});
await reopened.worker.stop();
} finally {
await first.worker.stop().catch(() => undefined);
}
const expected = ['resources.ready', 'worker.spawn', 'rpc.ready', 'session.open'];
for (const cold of [true, false]) {
const milestones = telemetry.filter((event) => event.cold === cold).map(({ milestone }) => milestone);
if (JSON.stringify(milestones) !== JSON.stringify(expected)) {
throw new Error(`Managed worker ${cold ? 'cold' : 'warm'} milestones are incomplete: ${milestones}`);
}
}
return telemetry;
}
export async function runFinalAsarExtensionProof(): Promise<PiReleaseExtensionProof> {
const root = await mkdtemp(path.join(tmpdir(), 'makelore-pi-final-asar-extension-'));
const processBudget = new PiProcessBudget(8);
const scheduler = new PiSubagentScheduler({
processBudget,
openChild: async (input) => ({
id: input.taskId,
async run() { return { summary: `done ${input.agentId}` }; },
async stop() {},
}),
});
const host = new PiManagedExtensionHost();
host.configureSubagents({ scheduler });
try {
const managedWorkerMilestones = await runManagedWorkerMilestoneProof(root, host);
const parent = await host.registerWorker({
conversationId: 'release-proof-extension-parent',
generation: 1,
projectId: 'release-proof-project',
extensionsDir: root,
});
await host.bindRun('release-proof-extension-parent', 1, 'release-proof-run');
const parentExtension = await loadExtension(parent.extensionPath, parent.env);
const updates: unknown[] = [];
const result = await withWorkerEnvironment(parent.env, async () => (
await parentExtension.tools.get('subagent')?.execute?.(
'release-proof-subagent',
{
mode: 'single',
tasks: [{
agentId: 'release-proof-agent',
task: 'execute the final materialized extension',
toolProfile: 'read-only',
}],
},
new AbortController().signal,
(update: unknown) => updates.push(update),
)
)) as { details?: { tasks?: Array<{ status?: string; summary?: string }> } } | undefined;
const child = await host.registerWorker({
conversationId: 'release-proof-extension-child',
generation: 1,
projectId: 'release-proof-project',
extensionsDir: root,
role: 'child',
runId: 'release-proof-run',
});
const childExtension = await loadExtension(child.extensionPath, child.env);
const task = result?.details?.tasks?.[0];
if (task?.status !== 'complete' || updates.length === 0) {
throw new Error('Final materialized extension did not execute its subagent bridge');
}
if (childExtension.tools.size !== 0) {
throw new Error('Final child extension exposed parent-only product tools');
}
await scheduler.close();
const diagnostics = scheduler.getDiagnostics();
return {
parentToolNames: [...parentExtension.tools.keys()].sort(),
childToolNames: [...childExtension.tools.keys()].sort(),
subagentStatus: task.status,
subagentSummary: task.summary ?? '',
materializedExtension: path.basename(parent.extensionPath),
managedWorkerMilestones,
released: {
processBudget: { active: processBudget.activeCount, waiting: processBudget.waitingCount },
childPermits: {
active: diagnostics.activeChildPermits,
waiting: diagnostics.waitingChildPermits,
},
dispatches: {
active: diagnostics.activeDispatches,
parents: diagnostics.activeParents,
},
},
};
} finally {
await scheduler.close().catch(() => undefined);
await host.close().catch(() => undefined);
await rm(root, { recursive: true, force: true, maxRetries: 5, retryDelay: 100 });
}
}
export async function startFinalAsarPressureProof(): Promise<PiReleasePressureSnapshot> {
if (pressureRun) throw new Error('PI release pressure proof is already running');
pressureRun = await startPressureRun();
return pressureRun.active;
}
export async function finishFinalAsarPressureProof(): Promise<PiReleasePressureSnapshot> {
const current = pressureRun;
if (!current) throw new Error('PI release pressure proof is not running');
pressureRun = null;
return await current.finish();
}

View File

@@ -361,7 +361,7 @@ function recordManagedMilestone(
milestone,
conversationId: input.conversation.conversationId,
workerGeneration: input.generation,
cold: true,
cold: !input.existingSession,
durationMs,
at,
}));

View File

@@ -98,6 +98,9 @@ class FifoSemaphore {
}
}
get activeCount(): number { return this.active; }
get waitingCount(): number { return this.waiters.length; }
acquire(signal: AbortSignal): Promise<() => void> {
if (signal.aborted) return Promise.reject(new PiSubagentChildError('SUBAGENT_ABORTED'));
if (this.active < this.maximum) return Promise.resolve(this.issuePermit());
@@ -292,6 +295,20 @@ export class PiSubagentScheduler {
}
}
getDiagnostics(): {
activeChildPermits: number;
waitingChildPermits: number;
activeDispatches: number;
activeParents: number;
} {
return {
activeChildPermits: this.childPermits.activeCount,
waitingChildPermits: this.childPermits.waitingCount,
activeDispatches: this.dispatches.size,
activeParents: this.parentDispatches.size,
};
}
async close(): Promise<void> {
if (this.closing) {
await Promise.allSettled([...this.dispatches.values()].map((record) => record.flight));

View File

@@ -5,6 +5,7 @@ export const PI_RUNTIME_MILESTONES = [
'session.open',
'resources.ready',
'prompt.accepted',
'agent.settled',
] as const;
export type PiRuntimeMilestone = (typeof PI_RUNTIME_MILESTONES)[number];

View File

@@ -230,7 +230,12 @@ export class PiWorkerPool {
private readonly prepareFlights = new Map<string, Promise<PiWorkerPoolState>>();
private readonly rebuildFlights = new Set<Promise<WorkerRecord>>();
private readonly waitingRuns: PendingTopLevelRun[] = [];
private readonly activeRuns = new Map<string, { runId: string; generation: number }>();
private readonly activeRuns = new Map<string, {
runId: string;
generation: number;
cold: boolean;
acceptedAt?: number;
}>();
private readonly generations = new Map<string, number>();
private readonly listeners = new Set<(event: PiWorkerPoolEvent) => void>();
private readonly reclaimWaiters = new Set<() => void>();
@@ -614,6 +619,7 @@ export class PiWorkerPool {
this.activeRuns.set(run.conversationId, {
runId: run.runId,
generation: record.generation,
cold: record.acceptedPromptCount === 0,
});
void this.acceptTopLevel(record, run);
}
@@ -635,7 +641,15 @@ export class PiWorkerPool {
const acceptedAt = this.now();
const response = await current.worker.request(run.command);
if (run.command.type === 'prompt') {
this.recordMilestone(current, run, 'prompt.accepted', this.now() - acceptedAt);
const acceptedFinishedAt = this.now();
active.acceptedAt = acceptedFinishedAt;
this.recordMilestone(
current,
run,
'prompt.accepted',
acceptedFinishedAt - acceptedAt,
active.cold,
);
current.acceptedPromptCount += 1;
}
run.resolve(response);
@@ -661,6 +675,15 @@ export class PiWorkerPool {
const conversationId = record.conversation.conversationId;
const active = this.activeRuns.get(conversationId);
if (!active || active.generation !== record.generation) return;
if (active.acceptedAt !== undefined) {
this.recordMilestone(
record,
{ runId: active.runId },
'agent.settled',
this.now() - active.acceptedAt,
active.cold,
);
}
this.activeRuns.delete(conversationId);
this.runningCount -= 1;
record.state = 'idle';
@@ -1032,9 +1055,10 @@ export class PiWorkerPool {
private recordMilestone(
record: WorkerRecord,
run: PendingTopLevelRun,
milestone: 'worker.queue_wait' | 'prompt.accepted',
run: Pick<PendingTopLevelRun, 'runId'>,
milestone: 'worker.queue_wait' | 'prompt.accepted' | 'agent.settled',
durationMs: number,
cold = record.acceptedPromptCount === 0,
): void {
if (!this.onTelemetry) return;
this.onTelemetry(createPiRuntimeTelemetryEvent({
@@ -1042,7 +1066,7 @@ export class PiWorkerPool {
conversationId: record.conversation.conversationId,
workerGeneration: record.generation,
runId: run.runId,
cold: record.acceptedPromptCount === 0,
cold,
durationMs,
at: this.now(),
}));