fix(native): scope governed waits to one run

Clear settled wait authority when rebinding a provider session to a new run. Reject duplicate approval requests that reference a resolved action through an unknown completion criterion.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-10-07 10:38:12 -05:00
1 parent 7ad54e8305
commit ba9b0b4610
5 files changed
+19 -2

No files matched your search

@@ -77,6 +77,11 @@ describe("native final-response feedback", () => {
completionClaim: { ...report.completionClaim, criteria: [{ criterionId: "objective", status: "not_satisfied", evidenceRefs: [`approval:${actionRequestId}`] }] },
};
await expect(nativeCompletionFeedback(db, value.runId, criterionOnly)).rejects.toThrow("already resolved");
// A provider can mark the approval criterion unknown while citing the exact
// declined interaction; that still is not a new review target.
await expect(nativeCompletionFeedback(db, value.runId, {
...criterionOnly, completionClaim: { ...criterionOnly.completionClaim, criteria: [{ criterionId: "objective", status: "unknown", evidenceRefs: [`interaction:${interactionId}`] }] },
})).rejects.toThrow("already resolved");
// Satisfied historical evidence does not bind the independent review target.
if (disposition !== "yielded") await expect(nativeCompletionFeedback(db, value.runId, {
...criterionOnly, completionClaim: { ...criterionOnly.completionClaim, criteria: [{ criterionId: "past-action", status: "satisfied", evidenceRefs: [`approval:${actionRequestId}`] }] },
@@ -186,7 +186,7 @@ export async function nativeCompletionFeedback(
blocker: result.blocker,
// An unmet criterion can name the action still being requested. Completed
// evidence elsewhere in the report is not authority to suppress a review.
unmetCriteria: result.completionClaim.criteria.filter(criterion => criterion.status === "not_satisfied"),
unmetCriteria: result.completionClaim.criteria.filter(criterion => criterion.status !== "satisfied"),
continuation: result.continuation,
// The existing response-wake contract also names its card through evidence.
evidence: result.reportedWorkDisposition === "yielded" && result.continuation?.kind === "response_wake" ? result.evidence : [],
@@ -2125,10 +2125,17 @@ describe("rebindNativeSessionCheckpoint", () => {
});
it("retains provider identity but clears prior turn and event state", () => {
const prior = previousRun();
const profile = prior.runnerProfileJson as Record<string, unknown>;
const checkpoint = profile.sessionCheckpoint as Record<string, unknown>;
checkpoint.governedWait = { sourceEvent: { runId: previousRunId, turnId: "old-turn" }, result: { reportedWorkDisposition: "yielded" } };
const before = structuredClone(prior);
const rebound = rebindNativeSessionCheckpoint({
previousRun: previousRun(),
previousRun: prior,
currentExecution: execution(currentRunId),
});
expect(rebound?.governedWait).toBeUndefined();
expect(prior).toEqual(before);
expect(rebound).toMatchObject({
sessionId: "provider-thread-123",
providerSessionId: "provider-thread-123",
@@ -568,6 +568,9 @@ export function rebindNativeSessionCheckpoint(input: {
activeTurnId: null,
terminalTurns: [],
pendingRuntimeRequests: [],
// Settlement evidence belongs to the prior heartbeat run, even when the
// provider session is reused for the user's response.
governedWait: undefined,
providerRecoveryPolicy,
};
}