Merge pull request #2065 from edimuj/fix/heartbeat-session-reuse

fix: preserve session continuity for timer/heartbeat wakes
This commit is contained in:
Dotta 2026-03-31 08:29:45 -05:00 committed by GitHub
commit 9f1bb350fe
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 61 additions and 2 deletions

View file

@ -6,6 +6,7 @@ import {
applyPersistedExecutionWorkspaceConfig,
buildRealizedExecutionWorkspaceFromPersisted,
buildExplicitResumeSessionOverride,
deriveTaskKeyWithHeartbeatFallback,
formatRuntimeWorkspaceWarningLog,
prioritizeProjectWorkspaceCandidatesForRun,
parseSessionCompactionPolicy,
@ -328,6 +329,34 @@ describe("shouldResetTaskSessionForWake", () => {
});
});
describe("deriveTaskKeyWithHeartbeatFallback", () => {
it("returns explicit taskKey when present", () => {
expect(deriveTaskKeyWithHeartbeatFallback({ taskKey: "issue-123" }, null)).toBe("issue-123");
});
it("returns explicit issueId when no taskKey", () => {
expect(deriveTaskKeyWithHeartbeatFallback({ issueId: "issue-456" }, null)).toBe("issue-456");
});
it("returns __heartbeat__ for timer wakes with no explicit key", () => {
expect(deriveTaskKeyWithHeartbeatFallback({ wakeSource: "timer" }, null)).toBe("__heartbeat__");
});
it("prefers explicit key over heartbeat fallback even on timer wakes", () => {
expect(
deriveTaskKeyWithHeartbeatFallback({ wakeSource: "timer", taskKey: "issue-789" }, null),
).toBe("issue-789");
});
it("returns null for non-timer wakes with no explicit key", () => {
expect(deriveTaskKeyWithHeartbeatFallback({ wakeSource: "on_demand" }, null)).toBeNull();
});
it("returns null for empty context", () => {
expect(deriveTaskKeyWithHeartbeatFallback({}, null)).toBeNull();
});
});
describe("buildExplicitResumeSessionOverride", () => {
it("reuses saved task session params when they belong to the selected failed run", () => {
const result = buildExplicitResumeSessionOverride({