fix(mantis): publish proof comments on auto-triggered runs (#127787)

## What Problem This Solves

Auto-triggered Mantis proof runs (label/`clawsweeper_label` and other non-comment request sources) end with no PR comment at all. The durable evidence publisher runs with `--create-missing false` and only edits an existing marker comment, but the inline status comment carrying that marker was only created when `request_source == 'issue_comment'`. Label-triggered runs therefore published nothing and logged the misleading "Skipped stale Mantis QA evidence comment because its status is no longer active" — observed on PR #127735. This is the silent-failure class: a Mantis run completes and the PR shows no visible outcome.

## Why This Change Was Made

- `.github/workflows/mantis-telegram-desktop-proof.yml`: the status ack comment (👀 + active-job link + run-scoped marker) is now created for every request source that resolves to a PR (`pr_number != ''`), not only `issue_comment`. The 👀 *reaction* stays `issue_comment`-only (it lives in `mantis-resolve-request.yml`, untouched — there is no triggering comment to react to on label runs).
- The start-failure fallback comment and the existing-artifact republish path now use the same run-scoped marker `<!-- mantis-telegram-desktop-proof:${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT} -->` as the status comment and the main publisher, so every publisher edits the single run-owned comment (ack → progress → final proof; no comment spam). The republish path gets an explicit `--create-missing false` to match. The design invariant that makes `false` safe: the fallback status-comment step is not `continue-on-error`, so a run in which no marker comment could be created fails `resolve_request` and never reaches publish.
- `scripts/mantis/publish-pr-evidence.mjs`: the two skip cases now log honestly — "no existing comment found" vs "could not update existing comment" — instead of one misleading stale-status message.

## User Impact

Operators triggering Mantis via labels (ClawSweeper flows) now get the same single evolving PR comment as comment-triggered runs: an immediate 👀 ack with the running job link, edited in place into the final proof evidence. No more runs that finish invisibly.

## Evidence

- Focused suite: `node scripts/run-vitest.mjs test/scripts/mantis-telegram-desktop-proof-workflow.test.ts` — 28/28, including new assertions that the status/failure comment gates use `pr_number != ''` (and not `request_source`) and that both publishers pass the run-scoped marker with `--create-missing false`.
- `node scripts/check-changed.mjs -- <touched files>` green; `git diff --check` clean.
- Marker alignment verified across all five sites in the workflow (status comment, prior-attempt cleanup regex, fallback comment, failure report, both publisher invocations): all use `mantis-telegram-desktop-proof:${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}`.
- Live-run proof of the label-triggered path requires a merged workflow (GitHub runs the workflow from the default branch for these triggers), so the first post-merge label-triggered Mantis run is the live verification; stated here as the known evidence gap.

Production LOC delta: −4 (workflow/tooling); tests +13.
This commit is contained in:
Ayaan Zaidi
2026-08-22 11:10:11 +05:30
committed by GitHub
parent 10e0e690df
commit 0933263f76
3 changed files with 26 additions and 17 deletions
@@ -181,7 +181,7 @@ jobs:
setOutput("request_source", requestSource);
- name: Create Mantis status token
id: mantis_status_token
if: ${{ steps.resolve.outputs.request_source == 'issue_comment' }}
if: ${{ steps.resolve.outputs.pr_number != '' }}
continue-on-error: true
uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3
with:
@@ -201,12 +201,9 @@ jobs:
with:
github-token: ${{ steps.mantis_status_token.outputs.token }}
script: |
const markerRoot = "<!-- mantis-telegram-desktop-proof:";
const runId = Number(process.env.GITHUB_RUN_ID);
const runAttempt = Number(process.env.GITHUB_RUN_ATTEMPT);
const marker = `${markerRoot}${runId}-${runAttempt} -->`;
const marker = `<!-- mantis-telegram-desktop-proof:${process.env.GITHUB_RUN_ID}-${process.env.GITHUB_RUN_ATTEMPT} -->`;
const runUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`;
const body = `${marker}\nMantis started this proof. [Follow the active job](${runUrl}).`;
const body = `${marker}\n👀 Mantis started this proof. [Follow the active job](${runUrl}).`;
const { owner, repo } = context.repo;
const issueNumber = Number(process.env.TARGET_PR);
await github.rest.issues.createComment({
@@ -248,7 +245,7 @@ jobs:
if: >-
${{
always() &&
steps.resolve.outputs.request_source == 'issue_comment' &&
steps.resolve.outputs.pr_number != '' &&
(
steps.mantis_status_token.outcome != 'success' ||
steps.mantis_status_comment.outcome != 'success'
@@ -260,7 +257,7 @@ jobs:
with:
github-token: ${{ github.token }}
script: |
const marker = "<!-- mantis-telegram-desktop-proof -->";
const marker = `<!-- mantis-telegram-desktop-proof:${process.env.GITHUB_RUN_ID}-${process.env.GITHUB_RUN_ATTEMPT} -->`;
const runUrl = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`;
const { owner, repo } = context.repo;
await github.rest.issues.createComment({
@@ -1238,7 +1235,7 @@ jobs:
--request-source "$REQUEST_SOURCE"
- name: Report failed Mantis proof
if: ${{ always() && needs.resolve_request.outputs.request_source == 'issue_comment' && steps.publish_evidence.outcome != 'success' }}
if: ${{ always() && needs.resolve_request.outputs.pr_number != '' && steps.publish_evidence.outcome != 'success' }}
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9
env:
TARGET_PR: ${{ needs.resolve_request.outputs.pr_number }}
@@ -1367,7 +1364,8 @@ jobs:
--manifest "$root/mantis-evidence.json" \
--target-pr "$TARGET_PR" \
--artifact-root "mantis/telegram-desktop/pr-${TARGET_PR}/published-${PUBLISH_RUN_ID}-${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}" \
--marker "<!-- mantis-telegram-desktop-proof -->" \
--marker "<!-- mantis-telegram-desktop-proof:${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT} -->" \
--create-missing false \
--artifact-url "$PUBLISH_ARTIFACT_URL" \
--run-url "https://github.com/${GITHUB_REPOSITORY}/actions/runs/${PUBLISH_RUN_ID}" \
--request-source "$REQUEST_SOURCE"
+2 -4
View File
@@ -631,7 +631,7 @@ function upsertPrComment({ body, createMissing, marker, prNumber, repo }) {
} catch {
if (!createMissing) {
console.log(
"Skipped stale Mantis QA evidence comment because its status is no longer active.",
`Could not update existing Mantis QA evidence comment ${commentId}; create-missing is false.`,
);
return;
}
@@ -641,9 +641,7 @@ function upsertPrComment({ body, createMissing, marker, prNumber, repo }) {
}
}
if (!createMissing) {
console.log(
"Skipped stale Mantis QA evidence comment because its status is no longer active.",
);
console.log("No existing Mantis QA evidence comment found and create-missing is false.");
return;
}
run("gh", ["pr", "comment", prNumber, "--body-file", bodyFile], { stdio: "inherit" });
@@ -382,10 +382,11 @@ describe("Mantis Telegram Desktop proof workflow", () => {
const fallbackComment = resolver?.steps?.find(
(step) => step.name === "Report Mantis start failure with workflow token",
);
expect(startedToken?.if).toContain("request_source == 'issue_comment'");
expect(startedToken?.if).toBe("${{ steps.resolve.outputs.pr_number != '' }}");
expect(startedToken?.if).not.toContain("request_source");
expect(startedToken?.with?.["permission-pull-requests"]).toBe("write");
expect(startedComment?.["continue-on-error"]).toBe(true);
expect(startedComment?.with?.script).toContain("Mantis started this proof.");
expect(startedComment?.with?.script).toContain("👀 Mantis started this proof.");
expect(startedComment?.with?.script).toContain("actions/runs/${process.env.GITHUB_RUN_ID}");
expect(startedComment?.with?.script).toContain("mantis-telegram-desktop-proof:");
expect(startedComment?.with?.script).toContain("GITHUB_RUN_ATTEMPT");
@@ -393,6 +394,8 @@ describe("Mantis Telegram Desktop proof workflow", () => {
expect(startedComment?.with?.script).toContain("issues.deleteComment");
expect(fallbackComment?.if).toContain("steps.mantis_status_token.outcome != 'success'");
expect(fallbackComment?.if).toContain("steps.mantis_status_comment.outcome != 'success'");
expect(fallbackComment?.if).toContain("steps.resolve.outputs.pr_number != ''");
expect(fallbackComment?.if).not.toContain("request_source");
expect(fallbackComment?.with?.["github-token"]).toBe("${{ github.token }}");
expect(fallbackComment?.["continue-on-error"]).toBeUndefined();
expect(fallbackComment?.with?.script).toContain("mantis-telegram-desktop-proof");
@@ -406,7 +409,8 @@ describe("Mantis Telegram Desktop proof workflow", () => {
const failureComment = proofSteps.find((step) => step.name === "Report failed Mantis proof");
expect(evidenceComment?.id).toBe("publish_evidence");
expect(failureComment?.if).toContain("always()");
expect(failureComment?.if).toContain("request_source == 'issue_comment'");
expect(failureComment?.if).toContain("needs.resolve_request.outputs.pr_number != ''");
expect(failureComment?.if).not.toContain("request_source");
expect(failureComment?.if).toContain("steps.publish_evidence.outcome != 'success'");
expect(failureComment?.with?.script).toContain("Mantis could not complete this proof.");
expect(failureComment?.with?.script).toContain("issues.updateComment");
@@ -454,6 +458,15 @@ describe("Mantis Telegram Desktop proof workflow", () => {
expect(workflowText).toContain(
"PUBLISH_ARTIFACT_URL=https://github.com/${GITHUB_REPOSITORY}/actions/runs/",
);
const evidenceComment = jobStep(
WORKFLOW,
"publish_existing_telegram_desktop_proof",
"Comment PR with inline QA evidence",
);
expect(evidenceComment.run).toContain(
"mantis-telegram-desktop-proof:${GITHUB_RUN_ID}-${GITHUB_RUN_ATTEMPT}",
);
expect(evidenceComment.run).toContain("--create-missing false");
});
it("limits evidence publishers to comment and PR-read permissions", () => {