test(pi): arm delayed prompt proof explicitly

This commit is contained in:
2026-08-26 00:10:22 +08:00
parent 019cbb115a
commit 4b75d201b8
5 changed files with 32 additions and 1 deletions

View File

@@ -197,6 +197,13 @@ Follow-up plan from cumulative HEAD `621ebb17810394f6f7b97154cb01217bc9112857`:
Authenticode, and zero-residual-process results are completed after the task
documentation/registry commit so the returned artifact binds to a clean
cumulative HEAD.
- The first candidate packaged proof intentionally required
`CODING_REQUEST_UNCERTAIN` but the controlled Provider's message-shape
matcher did not arm the delay; diagnostics showed both runs, both Main
leases, both Pi processes, and both Provider requests still active with no
runtime failure. The proof was corrected to arm prompt and compact delay
explicitly through E2E-only Main seams, removing message-shape dependence;
this was a proof-wiring failure, not a product fallback or relaxed gate.
- `pnpm install --frozen-lockfile` — passed with package-manager-pinned pnpm
`10.33.4` and locked Pi `0.84.2`.

View File

@@ -74,6 +74,7 @@ type LocalProofProvider = {
releaseChildren(): void;
releaseParents(): void;
releaseAll(): void;
armDelayedPrompt(): void;
armDelayedCompaction(): void;
close(): Promise<void>;
};
@@ -486,6 +487,7 @@ async function startLocalProofProvider(mode: ProofProviderMode): Promise<LocalPr
const held = new Set<HeldProviderResponse>();
let closed = false;
let closeFlight: Promise<void> | null = null;
let delayedPromptArmed = false;
let delayedCompactionArmed = false;
const server: Server = createServer(async (request, response) => {
response.once('error', () => undefined);
@@ -560,7 +562,8 @@ async function startLocalProofProvider(mode: ProofProviderMode): Promise<LocalPr
respondWithText(response, model, 'RESILIENCE_COMPACTION_SUMMARY');
return;
}
if (role === 'parent' && latestUserMessageContains(body, 'BACKGROUND_ACTIVE')) {
if (role === 'parent' && delayedPromptArmed) {
delayedPromptArmed = false;
const entry = { role, response } satisfies HeldProviderResponse;
held.add(entry);
response.once('close', () => held.delete(entry));
@@ -659,6 +662,7 @@ async function startLocalProofProvider(mode: ProofProviderMode): Promise<LocalPr
releaseChildren: () => release('child'),
releaseParents: () => release('parent'),
releaseAll: () => release(),
armDelayedPrompt: () => { delayedPromptArmed = true; },
armDelayedCompaction: () => { delayedCompactionArmed = true; },
close: async () => {
if (closed) return;
@@ -1897,6 +1901,13 @@ export function armFinalAsarResilienceCompactDelay(): { delayMs: number } {
return { delayMs: PROOF_MUTATION_CONFIRMATION_DELAY_MS };
}
export function armFinalAsarResiliencePromptDelay(): { delayMs: number } {
const run = resilienceCompositionRun;
if (!run) throw new Error('PI resilience proof is not running');
run.provider.armDelayedPrompt();
return { delayMs: PROOF_MUTATION_CONFIRMATION_DELAY_MS };
}
export async function restartFinalAsarResilienceOther(): Promise<PiReleaseResilienceStatus> {
const run = resilienceCompositionRun;
if (!run) throw new Error('PI resilience proof is not running');

View File

@@ -90,6 +90,7 @@ import {
} from '../api/coding-composition';
import {
armFinalAsarResilienceCompactDelay,
armFinalAsarResiliencePromptDelay,
abortFinalAsarResilienceTarget,
disposeFinalAsarResilienceTarget,
finishFinalAsarProxyCompositionProof,
@@ -905,6 +906,7 @@ type PiReleaseProofAction =
| 'resilience.start'
| 'resilience.status'
| 'resilience.arm-compact-delay'
| 'resilience.arm-prompt-delay'
| 'resilience.idle-status'
| 'resilience.restart-other'
| 'resilience.dispose-target'
@@ -974,6 +976,9 @@ export async function runPiReleaseProofE2E(action: PiReleaseProofAction) {
if (action === 'resilience.arm-compact-delay') {
return { action, packagedMain, resilience: armFinalAsarResilienceCompactDelay() };
}
if (action === 'resilience.arm-prompt-delay') {
return { action, packagedMain, resilience: armFinalAsarResiliencePromptDelay() };
}
if (action === 'resilience.idle-status') {
return { action, packagedMain, resilience: await getFinalAsarResilienceIdleStatus() };
}

View File

@@ -548,6 +548,11 @@ export async function runPackagedProductProof(options) {
|| resilienceStart?.resilience?.realTurnVerified !== false) {
throw new Error(`Packaged resilience setup failed: ${JSON.stringify(resilienceStart?.resilience)}`);
}
const promptDelay = await evaluateProof(electronApplication, 'resilience.arm-prompt-delay');
assertPackagedMain(promptDelay);
if (!(promptDelay?.resilience?.delayMs > 10_000)) {
throw new Error(`Packaged prompt proof did not exceed the former 10s threshold: ${JSON.stringify(promptDelay?.resilience)}`);
}
await page.reload();
await page.waitForLoadState('domcontentloaded');
if (await page.getByTestId('ai-module-selection-page').count()) {
@@ -894,6 +899,7 @@ export async function runPackagedProductProof(options) {
resilience: {
setup: resilienceStart.resilience,
backgroundLifecycle: {
configured: promptDelay.resilience,
active: backgroundActive.resilience,
hiddenPastGrace: backgroundHidden.resilience,
idleEvicted: backgroundIdle.resilience,

View File

@@ -41,7 +41,9 @@ describe('Pi packaged release proof wiring', () => {
expect(scriptSource).toContain("evaluateProof(electronApplication, 'resilience.dispose-target')");
expect(proofSource).toContain('const PROOF_MUTATION_CONFIRMATION_DELAY_MS = 12_000;');
expect(mainSource).toContain("'resilience.arm-compact-delay'");
expect(mainSource).toContain("'resilience.arm-prompt-delay'");
expect(scriptSource).toContain("evaluateProof(electronApplication, 'resilience.arm-compact-delay')");
expect(scriptSource).toContain("evaluateProof(electronApplication, 'resilience.arm-prompt-delay')");
expect(scriptSource).toContain("status?.target?.errorCode === 'CODING_REQUEST_UNCERTAIN'");
expect(scriptSource).toContain('status?.target?.completedCompactions >= 1');
});