Enforce execution-policy stage handoffs

This commit is contained in:
dotta 2026-04-08 08:05:35 -05:00
parent 9eaf72ab31
commit ec75cabcd8
8 changed files with 949 additions and 138 deletions

View file

@ -696,7 +696,14 @@ export function shouldResetTaskSessionForWake(
if (contextSnapshot?.forceFreshSession === true) return true;
const wakeReason = readNonEmptyString(contextSnapshot?.wakeReason);
if (wakeReason === "issue_assigned") return true;
if (
wakeReason === "issue_assigned" ||
wakeReason === "execution_review_requested" ||
wakeReason === "execution_approval_requested" ||
wakeReason === "execution_changes_requested"
) {
return true;
}
return false;
}
@ -714,6 +721,9 @@ function describeSessionResetReason(
const wakeReason = readNonEmptyString(contextSnapshot?.wakeReason);
if (wakeReason === "issue_assigned") return "wake reason is issue_assigned";
if (wakeReason === "execution_review_requested") return "wake reason is execution_review_requested";
if (wakeReason === "execution_approval_requested") return "wake reason is execution_approval_requested";
if (wakeReason === "execution_changes_requested") return "wake reason is execution_changes_requested";
return null;
}
@ -867,9 +877,8 @@ async function buildPaperclipWakePayload(input: {
}
| null;
}) {
const executionStage = parseObject(input.contextSnapshot.executionStage);
const commentIds = extractWakeCommentIds(input.contextSnapshot);
if (commentIds.length === 0) return null;
const issueId = readNonEmptyString(input.contextSnapshot.issueId);
const issueSummary =
input.issueSummary ??
@ -886,23 +895,27 @@ async function buildPaperclipWakePayload(input: {
.where(and(eq(issues.id, issueId), eq(issues.companyId, input.companyId)))
.then((rows) => rows[0] ?? null)
: null);
if (commentIds.length === 0 && Object.keys(executionStage).length === 0 && !issueSummary) return null;
const commentRows = await input.db
.select({
id: issueComments.id,
issueId: issueComments.issueId,
body: issueComments.body,
authorAgentId: issueComments.authorAgentId,
authorUserId: issueComments.authorUserId,
createdAt: issueComments.createdAt,
})
.from(issueComments)
.where(
and(
eq(issueComments.companyId, input.companyId),
inArray(issueComments.id, commentIds),
),
);
const commentRows =
commentIds.length === 0
? []
: await input.db
.select({
id: issueComments.id,
issueId: issueComments.issueId,
body: issueComments.body,
authorAgentId: issueComments.authorAgentId,
authorUserId: issueComments.authorUserId,
createdAt: issueComments.createdAt,
})
.from(issueComments)
.where(
and(
eq(issueComments.companyId, input.companyId),
inArray(issueComments.id, commentIds),
),
);
const commentsById = new Map(commentRows.map((comment) => [comment.id, comment]));
const comments: Array<Record<string, unknown>> = [];
@ -959,6 +972,7 @@ async function buildPaperclipWakePayload(input: {
priority: issueSummary.priority,
}
: null,
executionStage: Object.keys(executionStage).length > 0 ? executionStage : null,
commentIds,
latestCommentId: commentIds[commentIds.length - 1] ?? null,
comments,