Skip to content

Commit d5fdfdc

Browse files
Adamulek123juliusmarmingeclaude
authored
fix(server): automatically settle empty inactive threads (#15783)
Co-authored-by: Julius Marminge <[email protected]> Co-authored-by: Claude Fable 5.1 <[email protected]>
1 parent 462810f commit d5fdfdc

3 files changed

Lines changed: 32 additions & 10 deletions

File tree

‎apps/server/src/orchestration-v2/ThreadSettlementService.test.ts‎

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,28 @@ describe("resolveAutoSettlementAt", () => {
297297
expect(
298298
ThreadSettlementService.resolveAutoSettlementAt({ ...input, autoSettleAfterDays: null }),
299299
).toBeNull();
300+
});
301+
302+
it("anchors an empty thread's inactivity at its creation time", () => {
303+
const input = {
304+
thread: shell({ createdAt: at(-3 * DAY_MS) }),
305+
pullRequest: null,
306+
nowMs: NOW_MS,
307+
autoSettleAfterDays: 2,
308+
autoSettleOnMerge: false,
309+
};
310+
expect(ThreadSettlementService.resolveAutoSettlementAt(input)).toEqual(at(-3 * DAY_MS));
300311
expect(
301-
ThreadSettlementService.resolveAutoSettlementAt({ ...input, thread: shell() }),
312+
ThreadSettlementService.resolveAutoSettlementAt({
313+
...input,
314+
thread: shell({ createdAt: at(-DAY_MS) }),
315+
}),
316+
).toBeNull();
317+
expect(
318+
ThreadSettlementService.resolveAutoSettlementAt({
319+
...input,
320+
thread: { ...input.thread, lastSnoozeWakeAt: at(-DAY_MS) },
321+
}),
302322
).toBeNull();
303323
});
304324

‎apps/server/src/orchestration-v2/ThreadSettlementService.ts‎

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -231,19 +231,20 @@ export function resolveAutoSettlementAt(input: {
231231
};
232232
}
233233
if (!isAutoSettlementCandidate(thread, input.nowMs)) return null;
234-
const activityAtMs = latestMillis([
235-
toMillis(thread.latestUserMessageAt),
236-
toMillis(thread.latestRunRequestedAt),
237-
toMillis(thread.latestRunStartedAt),
238-
toMillis(thread.latestRunCompletedAt),
239-
]);
234+
const activityAtMs =
235+
latestMillis([
236+
toMillis(thread.latestUserMessageAt),
237+
toMillis(thread.latestRunRequestedAt),
238+
toMillis(thread.latestRunStartedAt),
239+
toMillis(thread.latestRunCompletedAt),
240+
]) ?? DateTime.toEpochMillis(thread.createdAt);
240241
if (pullRequest !== null && pullRequestSettles(thread, pullRequest, input.autoSettleOnMerge)) {
241-
return activityAtMs === null ? thread.createdAt : DateTime.makeUnsafe(activityAtMs);
242+
return DateTime.makeUnsafe(activityAtMs);
242243
}
243244
const hasPullRequest =
244245
pullRequest !== null || thread.linkedPullRequest != null || thread.branchPullRequest != null;
245246
if (input.autoSettleKeepPullRequests === true && hasPullRequest) return null;
246-
if (input.autoSettleAfterDays === null || activityAtMs === null) return null;
247+
if (input.autoSettleAfterDays === null) return null;
247248
const snoozedUntilMs = toMillis(thread.snoozedUntil);
248249
const timerWakeAtMs =
249250
snoozedUntilMs !== null && snoozedUntilMs <= input.nowMs ? snoozedUntilMs : null;

‎docs/user/thread-sidebar.md‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@ Press `Escape` while dragging to cancel.
148148

149149
By default, environments settle inactive threads after three days and settle
150150
threads whose pull request merged. A closed pull request can also settle an idle
151-
thread. Work in progress, pending questions or approvals, and live background work
151+
thread. An empty thread's inactivity counts from when it was created.
152+
Work in progress, pending questions or approvals, and live background work
152153
prevent automatic settlement. An open pull request does not prevent inactivity
153154
settlement unless you turn on **Keep threads with a PR** in **Settings → General**,
154155
but an old closed or merged pull request does not settle work you

0 commit comments

Comments
 (0)