@@ -8303,6 +8303,12 @@ async function maybePublishPrPublicSurface(
83038303 let autoReviewSkipReasonForPublish: string | null = null;
83048304 const publishedOutputs: PublicSurfaceOutput[] = [];
83058305 const failedOutputs: PublicSurfaceOutputFailure[] = [];
8306+ // #6724 (review-burst): true until a comment/label publish proves itself a no-op (byte-identical body / label
8307+ // already present) -- read by finishPublicSurfacePublication's final call below to avoid double-counting a
8308+ // republish that changed nothing on GitHub. Stay true (the safe default) for any output this pass doesn't
8309+ // attempt, and for output kinds with no cheap no-op signal (gate_check_run, check_run).
8310+ let commentContentChanged = true;
8311+ let labelContentChanged = true;
83068312 const reviewedHeadSha = reviewedPullRequestHeadSha(pr.headSha, advisory.headSha);
83078313 const freshnessForReviewOutput = (phase: string): Promise<PullRequestFreshness> =>
83088314 reviewTargetFreshness(env, {
@@ -8352,7 +8358,10 @@ async function maybePublishPrPublicSurface(
83528358 });
83538359 return reviewFiles;
83548360 };
8355- const finishPublicSurfacePublication = async (): Promise<
8361+ // #6724 (review-burst): contentChanged defaults true so every existing caller (the three early-return call
8362+ // sites below, none of which reach the comment/label publish steps) keeps recording pr_public_surface_published
8363+ // exactly as before -- only the final "full" call site computes and passes the real value.
8364+ const finishPublicSurfacePublication = async (contentChanged = true): Promise<
83568365 ReturnType<typeof evaluateGateCheck> | undefined
83578366 > => {
83588367 const gateSurfaceIncomplete = gateEnabled && !gateFinalized;
@@ -8467,41 +8476,61 @@ async function maybePublishPrPublicSurface(
84678476 .then((startedAt) => reviewDurationMsSince(startedAt, Date.now()))
84688477 .catch(() => undefined)
84698478 : undefined;
8470- await recordAuditEvent(env, {
8471- eventType: "github_app.pr_public_surface_published",
8472- actor: author,
8473- targetKey: `${repoFullName}#${pr.number}`,
8474- outcome: "completed",
8475- metadata: {
8476- deliveryId: webhook.deliveryId,
8477- publicSurface: settings.publicSurface,
8478- label: decision.willLabel ? settings.gittensorLabel : null,
8479- checkRunMode: settings.checkRunMode,
8480- reviewCheckMode: settings.reviewCheckMode,
8481- publicAudienceMode: settings.publicAudienceMode,
8482- publishedOutputs,
8483- failedOutputs,
8484- gateCheckFinalized: gateFinalized,
8485- ...(reviewEffortMinutesForStats !== undefined ? { reviewEffortMinutes: reviewEffortMinutesForStats } : {}),
8486- ...(reviewDurationMsForStats !== undefined ? { reviewDurationMs: reviewDurationMsForStats } : {}),
8487- },
8488- });
8489- await recordGithubProductUsage(env, "pr_public_surface_published", {
8490- actor: author,
8491- repoFullName,
8492- targetKey: `${repoFullName}#${pr.number}`,
8493- outcome: "completed",
8494- metadata: {
8495- publicSurface: settings.publicSurface,
8496- labelApplied: decision.willLabel,
8497- checkRunMode: settings.checkRunMode,
8498- reviewCheckMode: settings.reviewCheckMode,
8499- publicAudienceMode: settings.publicAudienceMode,
8500- publishedOutputs,
8501- failedOutputs,
8502- gateCheckFinalized: gateFinalized,
8503- },
8504- });
8479+ // #6724 (review-burst): a proven no-op republish (comment byte-identical, label already present) still
8480+ // completes every side effect below (surface-published stamp, AI-review-published stamp) -- those ARE
8481+ // accurate on a no-op, since the head genuinely is current -- but skips the two DURABLE "a review was
8482+ // published" records (this event feeds public-stats.ts/services/public-review-volume-trend.ts and is
8483+ // exempt from retention pruning, db/retention.ts), so a CI-flap/retry-storm that keeps re-rendering the
8484+ // same content stops inflating both the public "reviews completed" count and the review-burst anomaly
8485+ // counter (findHottestReviewTargetForRepo, db/repositories.ts) that reads this exact event type. A narrower
8486+ // event records the no-op instead, mirroring the existing github_app.public_surface_publish_skipped_current
8487+ // precedent (#6685) for the same "provably nothing changed" shape.
8488+ if (contentChanged) {
8489+ await recordAuditEvent(env, {
8490+ eventType: "github_app.pr_public_surface_published",
8491+ actor: author,
8492+ targetKey: `${repoFullName}#${pr.number}`,
8493+ outcome: "completed",
8494+ metadata: {
8495+ deliveryId: webhook.deliveryId,
8496+ publicSurface: settings.publicSurface,
8497+ label: decision.willLabel ? settings.gittensorLabel : null,
8498+ checkRunMode: settings.checkRunMode,
8499+ reviewCheckMode: settings.reviewCheckMode,
8500+ publicAudienceMode: settings.publicAudienceMode,
8501+ publishedOutputs,
8502+ failedOutputs,
8503+ gateCheckFinalized: gateFinalized,
8504+ ...(reviewEffortMinutesForStats !== undefined ? { reviewEffortMinutes: reviewEffortMinutesForStats } : {}),
8505+ ...(reviewDurationMsForStats !== undefined ? { reviewDurationMs: reviewDurationMsForStats } : {}),
8506+ },
8507+ });
8508+ await recordGithubProductUsage(env, "pr_public_surface_published", {
8509+ actor: author,
8510+ repoFullName,
8511+ targetKey: `${repoFullName}#${pr.number}`,
8512+ outcome: "completed",
8513+ metadata: {
8514+ publicSurface: settings.publicSurface,
8515+ labelApplied: decision.willLabel,
8516+ checkRunMode: settings.checkRunMode,
8517+ reviewCheckMode: settings.reviewCheckMode,
8518+ publicAudienceMode: settings.publicAudienceMode,
8519+ publishedOutputs,
8520+ failedOutputs,
8521+ gateCheckFinalized: gateFinalized,
8522+ },
8523+ });
8524+ } else {
8525+ await recordAuditEvent(env, {
8526+ eventType: "github_app.pr_public_surface_republish_noop",
8527+ actor: author,
8528+ targetKey: `${repoFullName}#${pr.number}`,
8529+ outcome: "completed",
8530+ detail: "republish produced no visible change (comment byte-identical / label already present)",
8531+ metadata: { deliveryId: webhook.deliveryId, repoFullName, publishedOutputs },
8532+ }).catch(() => undefined);
8533+ }
85058534 // Stamp the head SHA only after every required public surface for this repo completed. For gate-enabled repos,
85068535 // a comment/label without a finalized Orb gate check is incomplete and must stay repair-visible to the sweep.
85078536 await markPullRequestSurfacePublished(env, repoFullName, pr.number, advisory.headSha).catch((error) => {
@@ -10551,7 +10580,7 @@ async function maybePublishPrPublicSurface(
1055110580 });
1055210581 }
1055310582 try {
10554- await withReviewPipelineSpan(
10583+ const commentResult = await withReviewPipelineSpan(
1055510584 "selfhost.review.publish.comment",
1055610585 {
1055710586 installationId,
@@ -10570,6 +10599,10 @@ async function maybePublishPrPublicSurface(
1057010599 { mode },
1057110600 ),
1057210601 );
10602+ // #6724 (review-burst): only a proven byte-identical no-op (createOrUpdatePrIntelligenceComment's own
10603+ // idempotency check) sets this false -- a real create/update, or the createIfMissing:false null case
10604+ // (not reachable on this call site, which never sets that option), both default true.
10605+ commentContentChanged = commentResult?.changed ?? true;
1057310606 publishedOutputs.push("comment");
1057410607 incr("loopover_reviews_published_total", { repo: repoFullName });
1057510608 // Real end-to-end review latency (#review-latency-metric): pr.headShaObservedAt is the moment THIS
@@ -10616,7 +10649,7 @@ async function maybePublishPrPublicSurface(
1061610649 }
1061710650 if (decision.willLabel) {
1061810651 try {
10619- await withReviewPipelineSpan(
10652+ const labelResult = await withReviewPipelineSpan(
1062010653 "selfhost.review.publish.label",
1062110654 {
1062210655 installationId,
@@ -10638,6 +10671,9 @@ async function maybePublishPrPublicSurface(
1063810671 },
1063910672 ),
1064010673 );
10674+ // #6724 (review-burst): applied:false means the label was already present -- a proven no-op, same idea
10675+ // as commentContentChanged above.
10676+ labelContentChanged = labelResult.applied;
1064110677 publishedOutputs.push("label");
1064210678 } catch (error) {
1064310679 const message = errorMessage(error);
@@ -10654,7 +10690,15 @@ async function maybePublishPrPublicSurface(
1065410690 if (isGitHubRateLimitedError(error)) throw error;
1065510691 }
1065610692 }
10657- return finishPublicSurfacePublication();
10693+ // #6724 (review-burst): only a PUBLISHED-OUTPUTS SET of exactly comment/label (both proven no-ops, or absent
10694+ // entirely) counts as a no-op pass. Any other output kind in this pass (gate_check_run, check_run) has no
10695+ // cheap no-op signal, so its mere presence keeps this true -- conservative by design, this can only ever
10696+ // suppress a pr_public_surface_published record for a pass PROVEN to have changed nothing, never the reverse.
10697+ const surfaceContentChanged =
10698+ publishedOutputs.some((output) => output !== "comment" && output !== "label") ||
10699+ (publishedOutputs.includes("comment") && commentContentChanged) ||
10700+ (publishedOutputs.includes("label") && labelContentChanged);
10701+ return finishPublicSurfacePublication(surfaceContentChanged);
1065810702}
1065910703
1066010704async function recordPublicSurfaceOutputFailure(
0 commit comments