Verify native Stop callback and terminal settlement

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-08 12:28:13 -05:00
1 parent b7ea45ae9c
commit d4eee95165
2 files changed
+54 -3

No files matched your search

@@ -1396,3 +1396,23 @@ local build is not qualification evidence. The completed build left no live
compiler; its 850,932,819 bytes of disposable target output were removed and
the staged runner restored to the verified cloud-built binary. Subsequent
checks invoke TypeScript directly and perform no local Rust or Docker build.
At `1bda794003f98bf6e2879cd474c7f84c3e4145a9`, both cloud targets pass nine
native fixtures and 38 pinned Python checks. The verified Mac artifact retains
binary SHA-256 `fef7167af720db91537bbc066e3b8129a15d59bb6425dd95efa2b8a1a00b4980`.
Fresh Greptile reports 5/5; 53 checks pass with two skips. The broader browser
shard fails during an unrelated agent-chat cleanup with a database lock timeout,
then leaves its instance setting enabled for the following test. Its original
failure remains recorded; PR checks are not fully green.
The native Stop fixture now consumes events through the cancelled terminal
instead of closing immediately after the interrupt acknowledgement. It requires
one same-scope cancelled native input, one ordered cancelled terminal, no fallback
or invented completion, retained final prompt usage, and rejection of a late
answer after terminal settlement. The strengthened fixture passes locally in
16.526 seconds against the verified cloud-built Mac daemon, using an empty home
and a deterministic loopback model, with no credentials or paid calls. Earlier
fixture attempts remain separate: one checked the late answer prematurely and
failed during shutdown; another placed the workspace inside its isolated host
home and was rejected before launch. Neither is live-provider proof. A fresh
paid browser Stop campaign and the remaining release gates are still required.
@@ -144,6 +144,7 @@ for (const { interactionKind, nativeQuestionAction } of cases) test(nativeQuesti
await session.startTurn({ message: { role: 'user', text: input.task.prompt, attachments: input.attachments } });
const events = [];
let cancellationOutcome;
let stoppedQuestionRequest;
let questionResolutions = 0;
for await (const event of session.events()) {
events.push(event);
@@ -165,10 +166,9 @@ for (const { interactionKind, nativeQuestionAction } of cases) test(nativeQuesti
const resolution = { requestId: request.requestId, turnId: request.turnId,
resolution: nativeQuestionAction === 'submit' ? { action: 'submit', response: nativeResponse } : { action: 'cancel' } };
if (nativeQuestionAction === 'stop') {
stoppedQuestionRequest = structuredClone(request);
await session.cancel({ reason: 'stop during native clarification', signal: new AbortController().signal }).cleanup;
await session.close({ reason: 'native clarification stopped' });
await assert.rejects(session.resolveRuntimeRequest(resolution), /no longer pending/);
break;
continue;
}
await session.resolveRuntimeRequest(resolution);
await assert.rejects(session.resolveRuntimeRequest(resolution), /no longer pending/);
@@ -185,6 +185,37 @@ for (const { interactionKind, nativeQuestionAction } of cases) test(nativeQuesti
assert.equal(events.filter(event => event.eventType === 'runtime_request.created').length, 1);
if (nativeQuestionAction === 'stop') {
assert.equal(requests.length, 1, 'Stopped clarification started another model request');
const outcomes = events.filter(event => ['runtime_request.resolved', 'runtime_request.cancelled', 'runtime_request.expired'].includes(event.eventType));
assert.equal(outcomes.length, 1, 'Stopped clarification must close exactly once');
const outcome = outcomes[0];
assert.equal(outcome.eventType, 'runtime_request.cancelled', 'Stop revived the native input as a durable fallback');
assert.equal(outcome.runId, identity.runId);
assert.equal(outcome.normalizedSessionId, identity.sessionId);
assert.equal(outcome.turnId, stoppedQuestionRequest.turnId);
assert.equal(outcome.itemId, stoppedQuestionRequest.itemId);
assert.equal(outcome.payload.requestId, stoppedQuestionRequest.requestId);
assert.equal(outcome.payload.requestKind, 'runtime');
assert.equal(outcome.payload.requestType, 'input');
assert.equal(outcome.payload.action, 'cancel');
assert.ok(outcome.payload.reason);
assert.equal(outcome.payload.response, undefined);
assert.equal(outcome.payload.request, undefined);
assert.equal(outcome.payload.replayAllowed, undefined);
const terminals = events.filter(event => ['turn.completed', 'turn.failed', 'turn.cancelled', 'turn.interrupted'].includes(event.eventType));
assert.equal(terminals.length, 1, 'Stopped clarification must retain one native terminal');
assert.equal(terminals[0].eventType, 'turn.cancelled');
assert.equal(terminals[0].turnId, outcome.turnId);
assert.equal(terminals[0].payload.status, 'cancelled');
assert.equal(terminals[0].payload.error, null);
assert.ok(terminals[0].sourceSeq > outcome.sourceSeq);
await assert.rejects(session.resolveRuntimeRequest({ requestId: stoppedQuestionRequest.requestId,
turnId: stoppedQuestionRequest.turnId, resolution: { action: 'cancel' } }), /no longer pending/);
const usage = await session.accountingUsageEvent?.();
assert.deepEqual(usage?.payload.usage.runDelta && {
input: usage.payload.usage.runDelta.inputTokens, output: usage.payload.usage.runDelta.outputTokens,
complete: usage.payload.usage.runDeltaComplete,
}, { input: 10, output: 5, complete: true }, 'Stopped clarification lost final native prompt usage');
await session.close({ reason: 'native clarification stopped' });
assert.equal((await session.snapshot()).semanticResult, null, 'Stop invented task completion');
return;
}