fix(server): dedupe recovery liveness findings

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
DottaandPaperclip committed 2026-07-15 20:47:29 +00:00
1 parent ce301686a6
commit 9b4976b532
4 files changed
+27 -4

No files matched your search

@@ -1389,7 +1389,7 @@ describeEmbeddedPostgres("heartbeat orphaned process recovery", () => {
});
await db
.update(issues)
.set({ monitorNextCheckAt: new Date("2026-03-19T00:00:00.000Z") })
.set({ monitorNextCheckAt: new Date("2099-03-19T00:00:00.000Z") })
.where(and(eq(issues.id, issueId), eq(issues.companyId, companyId)));
const heartbeat = heartbeatService(db);
@@ -297,6 +297,26 @@ describe("issue graph liveness classifier", () => {
});
});
it("prefers the blocker finding for an in-review source with a cancelled blocker", () => {
const findings = classifyIssueGraphLiveness({
issues: [
issue({ status: "in_review" }),
issue({
id: blockerId,
identifier: "PAP-1704",
title: "Cancelled unblock work",
status: "cancelled",
assigneeAgentId: "blocker-agent",
}),
],
relations: blocks,
agents: [agent(), manager, agent({ id: "blocker-agent", name: "Cancelled owner" })],
});
expect(findings).toHaveLength(1);
expect(findings[0]?.state).toBe("blocked_by_cancelled_issue");
});
it("detects blocker assignees under terminated org ancestors as uninvokable", () => {
const findings = classifyIssueGraphLiveness({
issues: [
+5 -2
View File
@@ -10993,10 +10993,13 @@ export function heartbeatService(db: Db, options: HeartbeatServiceOptions = {})
const runContext = parseObject(run.contextSnapshot);
const monitorIssueId = readNonEmptyString(runContext.issueId);
const monitorNextCheckAt = monitorIssueId
? monitorNextCheckAtByIssue.get(`${run.companyId}:${monitorIssueId}`)
: undefined;
const monitorDispatchLostWithoutFutureWake =
readNonEmptyString(runContext.wakeReason) === "issue_monitor_due" &&
Boolean(monitorIssueId) &&
monitorNextCheckAtByIssue.get(`${run.companyId}:${monitorIssueId}`) === null;
monitorNextCheckAt !== undefined &&
(!monitorNextCheckAt || monitorNextCheckAt.getTime() <= now.getTime());
const shouldRetry = (run.processLossRetryCount ?? 0) < 1 && (
(tracksLocalChild && (!!run.processPid || !!run.processGroupId)) ||
monitorDispatchLostWithoutFutureWake
@@ -608,7 +608,7 @@ export function classifyIssueGraphLiveness(input: IssueGraphLivenessInput): Issu
if (chainFinding) findings.push(chainFinding);
}
if (issue.status === "in_review" && !unresolvedBlockers.has(issue.id)) {
if (issue.status === "in_review" && !shouldInspectBlockedChain && !unresolvedBlockers.has(issue.id)) {
const review = reviewFinding(issue, issue, [issue]);
if (review) findings.push(review);
}