From 92f07c7854fea9c8b4993eb674030b899616c7d8 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Fri, 1 May 2026 04:10:36 +0000
Subject: [PATCH] fix: safe_output_summary shows final posted body including
 footer for add_comment

When an agent submits an add_comment via the safe outputs MCP tool,
the body preview in the job step summary was showing only what the
agent submitted (message.body), without the footer that is appended
during processing. This caused a mismatch between the "Body Preview"
shown in the step summary and the actually posted comment (which
includes the footer attribution).

Fix:
- Return `processedBody` (the final body with footer) from
  add_comment.cjs in the result object as `body`
- Update safe_output_summary.cjs to prefer `result.body` (final
  posted body) over `message.body` (submitted body) for the Body
  Preview, falling back to message.body when result.body is absent
- Add two tests verifying the result.body preference and fallback

Agent-Logs-Url: https://github.com/github/gh-aw/sessions/8069bd2d-dd4c-403e-96f3-9e2d9532f4a2

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
---
 actions/setup/js/add_comment.cjs              |  2 +-
 actions/setup/js/safe_output_summary.cjs      |  6 ++-
 actions/setup/js/safe_output_summary.test.cjs | 40 +++++++++++++++++++
 3 files changed, 45 insertions(+), 3 deletions(-)

diff --git a/actions/setup/js/add_comment.cjs b/actions/setup/js/add_comment.cjs
index cbda27c49dc..bbb62304d4b 100644
--- a/actions/setup/js/add_comment.cjs
+++ b/actions/setup/js/add_comment.cjs
@@ -657,7 +657,7 @@ async function main(config = {}) {
     // Records a created comment in createdComments and returns the success result.
     const recordComment = (/** @type {{ id: string | number, html_url: string }} */ comment, /** @type {boolean} */ isDiscussionFlag) => {
       createdComments.push({ id: comment.id, html_url: comment.html_url, _tracking: { commentId: comment.id, itemNumber, repo: itemRepo, isDiscussion: isDiscussionFlag } });
-      return { success: true, commentId: comment.id, url: comment.html_url, itemNumber, repo: itemRepo, isDiscussion: isDiscussionFlag };
+      return { success: true, commentId: comment.id, url: comment.html_url, body: processedBody, itemNumber, repo: itemRepo, isDiscussion: isDiscussionFlag };
     };
 
     // Normalize reply_to_id once so both the main discussion path and the
diff --git a/actions/setup/js/safe_output_summary.cjs b/actions/setup/js/safe_output_summary.cjs
index 1e17ed89b29..43cd9f9c6ea 100644
--- a/actions/setup/js/safe_output_summary.cjs
+++ b/actions/setup/js/safe_output_summary.cjs
@@ -101,10 +101,12 @@ function generateSafeOutputSummary(options) {
       if (message.title) {
         summary += `**Title:** ${message.title}\n\n`;
       }
-      if (message.body && typeof message.body === "string") {
+      // Prefer result.body (final posted body including footer) over message.body (submitted body)
+      const bodyToShow = result && typeof result.body === "string" ? result.body : message.body;
+      if (bodyToShow && typeof bodyToShow === "string") {
         // Truncate body if too long
         const maxBodyLength = 500;
-        const bodyPreview = message.body.length > maxBodyLength ? message.body.substring(0, maxBodyLength) + "..." : message.body;
+        const bodyPreview = bodyToShow.length > maxBodyLength ? bodyToShow.substring(0, maxBodyLength) + "..." : bodyToShow;
         summary += `**Body Preview:**\n\`\`\`\`\`\`\n${bodyPreview}\n\`\`\`\`\`\`\n\n`;
       }
       if (message.labels && Array.isArray(message.labels)) {
diff --git a/actions/setup/js/safe_output_summary.test.cjs b/actions/setup/js/safe_output_summary.test.cjs
index e37f78cdf08..758dba5e575 100644
--- a/actions/setup/js/safe_output_summary.test.cjs
+++ b/actions/setup/js/safe_output_summary.test.cjs
@@ -238,6 +238,46 @@ describe("safe_output_summary", () => {
       expect(summary).toContain("medium");
     });
 
+    it("should use result.body (final posted body) over message.body for body preview", () => {
+      const options = {
+        type: "add_comment",
+        messageIndex: 1,
+        success: true,
+        result: {
+          url: "https://github.com/owner/repo/issues/1#issuecomment-123",
+          body: "Submitted body\n\n> *Footer added by workflow*",
+        },
+        message: {
+          body: "Submitted body",
+        },
+      };
+
+      const summary = generateSafeOutputSummary(options);
+
+      // Should show the final posted body (from result.body) not the raw submitted body
+      expect(summary).toContain("Footer added by workflow");
+      expect(summary).toContain("Body Preview");
+    });
+
+    it("should fall back to message.body when result.body is absent", () => {
+      const options = {
+        type: "add_comment",
+        messageIndex: 1,
+        success: true,
+        result: {
+          url: "https://github.com/owner/repo/issues/1#issuecomment-123",
+        },
+        message: {
+          body: "Submitted body only",
+        },
+      };
+
+      const summary = generateSafeOutputSummary(options);
+
+      expect(summary).toContain("Submitted body only");
+      expect(summary).toContain("Body Preview");
+    });
+
     it("should not display secrecy or integrity when absent from message", () => {
       const options = {
         type: "create_issue",
