diff --git a/src/infra/restart-sentinel.test.ts b/src/infra/restart-sentinel.test.ts index ec97c8c5c..76b9e53b5 100644 --- a/src/infra/restart-sentinel.test.ts +++ b/src/infra/restart-sentinel.test.ts @@ -116,3 +116,33 @@ describe("restart sentinel", () => { expect(textA).not.toContain('"ts"'); }); }); + +describe("restart sentinel message dedup", () => { + it("omits duplicate Reason: line when stats.reason matches message", () => { + const payload = { + kind: "restart" as const, + status: "ok" as const, + ts: Date.now(), + message: "Applying config changes", + stats: { mode: "gateway.restart", reason: "Applying config changes" }, + }; + const result = formatRestartSentinelMessage(payload); + // The message text should appear exactly once, not duplicated as "Reason: ..." + const occurrences = result.split("Applying config changes").length - 1; + expect(occurrences).toBe(1); + expect(result).not.toContain("Reason:"); + }); + + it("keeps Reason: line when stats.reason differs from message", () => { + const payload = { + kind: "restart" as const, + status: "ok" as const, + ts: Date.now(), + message: "Restart requested by /restart", + stats: { mode: "gateway.restart", reason: "/restart" }, + }; + const result = formatRestartSentinelMessage(payload); + expect(result).toContain("Restart requested by /restart"); + expect(result).toContain("Reason: /restart"); + }); +}); diff --git a/src/infra/restart-sentinel.ts b/src/infra/restart-sentinel.ts index 919fb56a3..baf816804 100644 --- a/src/infra/restart-sentinel.ts +++ b/src/infra/restart-sentinel.ts @@ -118,7 +118,7 @@ export function formatRestartSentinelMessage(payload: RestartSentinelPayload): s lines.push(message); } const reason = payload.stats?.reason?.trim(); - if (reason) { + if (reason && reason !== message) { lines.push(`Reason: ${reason}`); } if (payload.doctorHint?.trim()) {