fix(pi): harden release proof lifecycle

This commit is contained in:
2026-08-24 17:59:49 +08:00
parent ead9d1dbaf
commit 09841c8dbd
7 changed files with 286 additions and 36 deletions

View File

@@ -133,6 +133,7 @@ async function runProductProofSamples(artifact, projectRoot, samples) {
runtimeRoot: artifact.artifact.runtimeRoot,
electronExecutable: artifact.artifact.executable,
reportPath: undefined,
verifyCleanupFailure: false,
}));
}
return reports;

View File

@@ -16,6 +16,7 @@ function parseArgs(argv, projectRoot = process.cwd()) {
runtimeRoot: undefined,
electronExecutable: undefined,
reportPath: undefined,
verifyCleanupFailure: true,
};
for (let index = 0; index < argv.length; index += 1) {
const argument = argv[index];
@@ -107,6 +108,27 @@ function assertReleasedPressure(pressure) {
}
}
function assertManagedTurns(extension) {
const expectedMilestones = 'worker.queue_wait,resources.ready,worker.spawn,rpc.ready,session.open,prompt.accepted,agent.start,provider.first_event,agent.settled';
const expectedDelayMs = extension?.providerFirstEventDelayMs;
if (!Number.isFinite(expectedDelayMs) || expectedDelayMs < 1) {
throw new Error(`PI proof did not expose a controlled Provider first-event delay: ${expectedDelayMs}`);
}
for (const turn of extension?.managedTurns ?? []) {
if (turn.milestones.map(({ milestone }) => milestone).join(',') !== expectedMilestones) {
throw new Error(`PI managed turn timeline is incomplete: ${JSON.stringify(turn)}`);
}
const agentStart = turn.milestones.find(({ milestone }) => milestone === 'agent.start');
const providerFirstEvent = turn.milestones.find(({ milestone }) => milestone === 'provider.first_event');
if (agentStart?.source !== 'pi.agent_start'
|| providerFirstEvent?.source !== 'pi.assistant_message_start'
|| providerFirstEvent.at <= agentStart.at
|| providerFirstEvent.durationMs < Math.floor(expectedDelayMs * 0.75)) {
throw new Error(`PI Provider first-event milestone is not Provider-response-backed: ${JSON.stringify(turn)}`);
}
}
}
async function evaluateProof(electronApplication, action) {
return await electronApplication.evaluate(async (_electron, requestedAction) => {
const proof = globalThis.__niancodeRunPiReleaseProofE2E;
@@ -158,17 +180,14 @@ export async function runPackagedProductProof(options) {
const extension = await evaluateProof(electronApplication, 'extension');
assertPackagedMain(extension);
assertManagedTurns(extension.extension);
if (extension.extension?.subagentStatus !== 'complete'
|| extension.extension?.childToolNames?.join(',') !== 'find,grep,ls,read'
|| !extension.extension?.parentToolNames?.includes('subagent')
|| extension.extension?.parentProcessIds?.length < 2
|| extension.extension?.childProcessIds?.length !== 1
|| extension.extension?.providerRequests?.child !== 1
|| extension.extension?.managedTurns?.length !== 2
|| extension.extension.managedTurns.some(({ milestones }) => (
milestones.map(({ milestone }) => milestone).join(',')
!== 'worker.queue_wait,resources.ready,worker.spawn,rpc.ready,session.open,prompt.accepted,agent.start,provider.first_event,agent.settled'
))) {
|| extension.extension?.managedTurns?.length !== 2) {
throw new Error(`Final ASAR extension/subagent proof failed: ${JSON.stringify(extension.extension)}`);
}
@@ -187,6 +206,34 @@ export async function runPackagedProductProof(options) {
assertPackagedMain(pressureFinish);
assertReleasedPressure(pressureFinish.pressure);
let failureCleanup;
if (options.verifyCleanupFailure === true) {
const failureStart = await evaluateProof(electronApplication, 'pressure.start');
pressureActive = true;
assertPackagedMain(failureStart);
assertActivePressure(failureStart.pressure);
let injectedFailure;
try {
await evaluateProof(electronApplication, 'pressure.finish.inject-failure');
} catch (error) {
injectedFailure = error;
}
if (!injectedFailure
|| !String(injectedFailure).includes('PI release pressure cleanup failed: parents.settle')) {
throw new Error(`PI pressure cleanup failure injection did not fail as expected: ${String(injectedFailure)}`);
}
const retryFinish = await evaluateProof(electronApplication, 'pressure.finish');
pressureActive = false;
assertPackagedMain(retryFinish);
assertReleasedPressure(retryFinish.pressure);
failureCleanup = {
injectedAt: 'parents.settle',
firstFinish: 'failed-as-injected',
retry: 'pass',
released: retryFinish.pressure,
};
}
const report = {
schemaVersion: 1,
generatedAt: new Date().toISOString(),
@@ -203,6 +250,7 @@ export async function runPackagedProductProof(options) {
durationMs: uiInteractiveMs,
},
released: pressureFinish.pressure,
...(failureCleanup ? { failureCleanup } : {}),
},
result: 'pass',
};

View File

@@ -35,6 +35,7 @@ async function runExtensionSmoke(projectRoot, artifact) {
runtimeRoot: artifact.artifact.runtimeRoot,
electronExecutable: artifact.artifact.executable,
reportPath: undefined,
verifyCleanupFailure: true,
});
}