Skip to content

fix(agents): skip Telegram notify on no-op Succeeded runs - #530

Merged
mashkovd merged 2 commits into
mainfrom
fix/agents-notify-noop-noise
Jul 6, 2026
Merged

mashkovd merged 2 commits into
mainfrom
fix/agents-notify-noop-noise

Conversation

@mashkovd

@mashkovd mashkovd commented Jul 6, 2026

Copy link
Copy Markdown
Member

Summary

  • implement (/5), issue-poll (/15), and shepherd (hourly) CronWorkflows send an unconditional ✅ Telegram message even on steady-state ticks that did nothing (empty proposal queue / no labelled issues / no proposal transitions) — this is the noise visible in the Telegram screenshot (implement firing every 5 min).
  • commit-and-push in each CWFT already distinguishes "nothing to commit" from an actual push. Surface that as a workflow output (activity: none|yes) and gate notify-telegram's Telegram leg: skip only when WORKFLOW_STATUS=Succeeded AND activity=none. Failed/Error always notify, regardless of activity.
  • No change to cron cadence, incident-leg logic, or the mctl_list_incidents path — purely filters the no-op success spam.

Test plan

  • python3 -c "import yaml; yaml.safe_load_all(open(f))" on all 3 modified templates — valid YAML
  • After merge + ArgoCD sync (~3 min), trigger a one-shot implement run with an empty queue and confirm no Telegram message, then trigger issue-poll/shepherd similarly
  • Confirm a real proposal transition (or injected failure) still sends a Telegram message

implement (*/5), issue-poll (*/15), and shepherd (hourly) sent an
unconditional Telegram Succeeded message even on steady-state ticks
that found nothing to do (empty proposal queue / no labelled issues /
no proposal transitions) — drowning out the runs that did real work.

commit-and-push already distinguished "nothing to commit" from a real
push; surface that as a workflow output (activity=none|yes) and have
notify-telegram skip the Telegram leg only when Succeeded AND no
activity. Failed/Error always notify regardless.
@claude

claude Bot commented Jul 6, 2026 •

Copy link
Copy Markdown

Claude encountered an error after 0s —— View job


I'll analyze this and get back to you.

@claude

claude Bot commented Jul 6, 2026 •

Copy link
Copy Markdown

Claude finished @mashkovd's task in 1m 44s —— View job


Code Review: fix/agents-notify-noop-noise

Analysis

Reviewed PR diff across three CronWorkflow templates to reduce Telegram notification spam on steady-state no-op runs. The solution adds an activity output parameter (none|yes) to track whether meaningful changes were committed, then gates the Telegram leg accordingly.

Findings

✅ Correctness

  • Workflow-level outputs.parameters.activity properly declared with sensible defaults to satisfy Argo's static validator (required for onExit parameter access)
  • Parameter propagation chain correct: commit-and-push step output → template output → workflow output → accessible in onExit
  • File writes (/tmp/activity) occur at all required exit paths:
    • "none" when no STATUS_CHANGES found
    • "none" when git diff is empty post-staging
    • "yes" when git push succeeds
  • Default "unknown" safely falls through to notification if activity can't be determined (robust failure mode)

✅ Logic & Edge Cases

  • Conditional pattern consistent across all three templates: skip when WORKFLOW_STATUS=Succeeded AND activity=none, otherwise notify
  • Failed/Error/Unknown statuses always trigger notification regardless of activity (safe behavior—no silent failures)
  • Push failure scenario: step fails → workflow status becomes Failed → notification sent (correct)
  • Clone/earlier-step failure: /tmp/activity never written → uses default "unknown" → notification sent (correct)
  • All three templates follow identical pattern (consistency)

✅ Shell Safety

  • String comparisons, no injection vectors
  • echo -n correctly avoids trailing newlines
  • set -e ensures file is either successfully written or step fails

✅ YAML & Conventions

  • Proper 2-space indentation throughout
  • Comments explain non-obvious configuration (why skip no-ops, what cadence drives steady-state)
  • Parameter references valid Argo syntax: {{steps.commit.outputs.parameters.activity}}, {{workflow.outputs.parameters.activity}}
  • No new secrets, permissions, or breaking changes

✅ Operational Impact

  • Reduces notification spam from steady-state runs (~5 min implement, ~15 min issue-poll, ~1 hr shepherd)
  • Real activity and failures still notify immediately
  • No DAG or step dependency changes
  • Backwards compatible

Verdict

No P1/P2 findings — good to merge. Clean, well-documented implementation that solves the stated problem. Runtime testing can proceed post-merge per the test plan.


…check

Same reason shepherd was already excluded: the community CRD schema
catalog doesn't recognize .spec.outputs on a ClusterWorkflowTemplate,
even though it's required for the onExit handler's
workflow.outputs.parameters.activity reference to pass Argo's own
static validator.
@claude

claude Bot commented Jul 6, 2026 •

Copy link
Copy Markdown

Claude encountered an error after 0s —— View job


I'll analyze this and get back to you.

@claude

claude Bot commented Jul 6, 2026 •

Copy link
Copy Markdown

Claude finished @mashkovd's task in 1m 28s —— View job


PR Review: fix(agents) — skip Telegram notify on no-op runs

Summary

This PR reduces Telegram notification spam by gating the notification leg of three CronWorkflows (implement, issue-poll, shepherd) to skip on successful runs that found nothing to do.

Changes reviewed:

  • ✓ 3 CronWorkflow templates updated with activity tracking
  • ✓ Validation workflow updated to exclude the modified templates
  • ✓ YAML syntax valid; 2-space indentation correct
  • ✓ Argo Workflows parameter references properly structured

Analysis

Correctness

  • Parameter flow is properly wired: commit-and-push template outputs activity from /tmp/activity → commit step captures it → workflow-level outputs.parameters.activity exposes it → notify-telegram receives via WORKFLOW_ACTIVITY env var
  • Git logic correctly distinguishes "nothing to commit" (writes "none") from "pushed successfully" (writes "yes")
  • Notification condition is explicit: skip only when WORKFLOW_STATUS=Succeeded AND activity=none
  • Failed/Error/Unknown statuses always notify regardless of activity — correct behavior
  • Default fallback to "unknown" ensures safe-open behavior if the parameter is ever absent

Argo Workflows Specifics

  • Valid use of valueFrom.path to read file output from scripts
  • Valid step reference {{steps.commit.outputs.parameters.activity}} in workflow-level outputs (commit is a step in the entrypoint template)
  • Mutual consistency across all 3 templates — all follow the same pattern

Operational Safety

  • No hardcoded secrets or unsafe string interpolation
  • Git push logic already has 5-attempt retry loop with rebase — unchanged
  • Commit-and-push always runs (even on implement failure via continueOn: {failed: true, error: true}) so activity status is always available
  • Validation workflow correctly excludes all 3 modified templates from kubeconform's strict schema check (due to .spec.outputs on ClusterWorkflowTemplate, which the community CRD schema doesn't yet recognize)

Conventions

  • YAML indentation 2-space throughout (per CLAUDE.md)
  • Comments explain the non-obvious: why activity is needed, when it's set, why skipping is safe for steady-state runs
  • Commit messages and PR language follow the codebase style

Verdict

No P1/P2 findings, good to merge. This is a well-implemented noise reduction that correctly gates notifications without sacrificing safety. The parameter passing is correct, the logic is sound, and the validation update properly reflects the schema exceptions.


@mashkovd
mashkovd merged commit 428c595 into main Jul 6, 2026
6 checks passed
@mashkovd
mashkovd deleted the fix/agents-notify-noop-noise branch July 6, 2026 21:24

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f0dd87d8a2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

# at the */15 cadence that's the steady-state outcome. JSON-encode
# the body via jq so a quote / newline / backslash cannot malform
# the payload and silently drop it.
if [ "$WORKFLOW_STATUS" = "Succeeded" ] && [ "$WORKFLOW_ACTIVITY" = "none" ]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Do not skip poller failures with no diff

In the issue-poll workflow, poll uses continueOn: failed/error and there is no later assertion step, so WORKFLOW_STATUS can still be Succeeded when run-poller exits before writing proposal files (for example when GITHUB_TOKEN is missing). In that case commit-and-push records activity=none, and this new branch suppresses the only Telegram/incident signal for a broken poller; include the poll step status in the gate or assert it before treating activity=none as a harmless no-op.

Useful? React with 👍 / 👎.

# unconditional ✅ every hour drowned out real merges/rejections.
# Failed/Error/Unknown (incl. a post-deploy-verify degraded-apps
# failure) always notify regardless of activity.
if [ "$WORKFLOW_STATUS" = "Succeeded" ] && [ "$WORKFLOW_ACTIVITY" = "none" ]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Do not skip shepherd failures with no diff

The shepherd step is also marked continueOn: failed/error, and this workflow has no equivalent of the implementer assert-produced step. If run-shepherd crashes before producing any .status.yaml change, commit-and-push emits activity=none, post-deploy-verify can still pass, and this condition suppresses the only Telegram alert even though the shepherd run failed internally; gate the skip on the shepherd step status as well as the workflow status/activity.

Useful? React with 👍 / 👎.

# Telegram leg on a no-op Succeeded run.
outputs:
parameters:
- name: activity

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Export activity as a global output

The exit handlers read {{workflow.outputs.parameters.activity}}, but parameters only become available under workflow.outputs when the producing output is exported globally (the existing degraded_apps output in this file does that with globalName). As written, /tmp/activity is only a local steps.commit... output, so no-op Succeeded implement/issue-poll/shepherd runs will not see WORKFLOW_ACTIVITY=none and the Telegram spam this change is meant to suppress will continue; add globalName: activity or pass the entrypoint output through a supported mechanism.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant