Make workflow alerts conditional with severity-graded rules - #1264
Merged
Paul Lizer (paullizer) merged 3 commits intoAug 18, 2026
Merged
Conversation
Workflow alerts fired on every run because a workflow carried a single alert_priority field, so the notification only meant 'the workflow ran'. Replace that switch with a rule engine. A workflow now declares why it should notify and how loudly, and a run matching nothing stays silent. - New functions_workflow_alerts.py holds the rule schema, validation, deterministic evaluators, the batched model evaluation helper and the legacy migration. It imports neither the runner nor the workflow CRUD modules, and takes the model client as an injected callable, so every caller can share it without an import cycle. - Conditions cover run status, task status, output text (contains, not-contains, regex), File Sync outcome, empty output, agent signals and a plain-English condition judged by a model. Each rule can be scoped to the final output, any task, or one specific task. - Model-judged rules are batched into one call per run and skipped entirely when a deterministic rule already matched at or above their severity, so deterministic-only workflows add no model calls. - Severity grew to info/low/medium/high/critical. Info and low land in the notification bell; medium and above open the pop-up, overridable per rule. A separate failure category restyles run errors independently of severity. - Highest matching severity wins and the alert lists every matched rule under a Triggered by section. One notification per run. - Agents can raise alerts mid-run via a new gated raise_workflow_alert plugin function. It refuses outside an active run, is opt-in per action, and its severity can escalate a rule but never quiet it. - Each run records why it did or did not alert, surfaced in workflow activity. - Legacy workflows migrate on read into two editable rules that reproduce the previous behavior exactly, so no data migration runs and cancelled runs stay silent as before. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
The v0.250.209 notes covered the alert engine but not the builder UI that replaces the single Pop-up Alert Priority dropdown. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Development moved to 0.250.212 and reordered the workspace templates. Conflicts were both additive-at-top rather than semantic: - config.py: took Development's 0.250.212 and bumped to 0.250.213 for this feature. - release_notes.md: kept both sections, renumbered the alert rules entry to 0.250.213 and placed it above 0.250.212. Restated the alert rules implementation version as 0.250.213 across the feature doc, module docstring and test headers so the shipping version is accurate. Verified the auto-merged files kept both sides: the alert rules block survives intact in the review step of both workspace templates, and the raise_workflow_alert capability plus its opt-in default survive in both stepper modules alongside the new Yamcs plugin UI. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A workflow carried a single
alert_priorityfield (none | low | medium | high). Infunctions_workflow_runner.py,_create_workflow_priority_alert()was called unconditionally on both the success and failure return paths, so if the priority was anything other thannonea notification fired on every run.The result: the alert only ever meant "the workflow ran," not "something worth your attention happened." Owners either drowned in notifications or turned alerts off entirely.
Approach
Replace the single switch with a rule engine. A workflow now declares why it should notify and how loudly, and a run that matches nothing produces no notification at all.
Conditions
run_status,task_status,text_match(contains any / contains all / does not contain / regex),file_syncoutcome,no_output,agent_signal, andmodel_evaluation— a plain-English condition such as "any certificate expires within 14 days" judged by a model.Each rule scopes to the final output, any task output, or one specific task.
Severity, category and delivery
Severity grew from low/medium/high to
info / low / medium / high / critical. Info and low land quietly in the notification bell; medium and above open the pop-up, overridable per rule.Separately from severity, every alert carries a category. Run errors, task failures, File Sync failures and empty runs are categorized
failure, which swaps the icon, forces the danger accent, and changes the badge fromHIGH PRIORITYtoHIGH FAILURE. This keeps "the workflow broke" visually distinct from "the workflow found something," at whatever severity the owner chose.When several rules match, the highest severity wins and the alert opens with a
Triggered bysection listing every matched rule and its reason. One notification per run, always.Agent-raised alerts
Agent-runner workflows can raise a signal mid-run through a new gated
raise_workflow_alertplugin function, backed by a run-scopedcontextvarthat the runner opens around the run and resets in afinallyblock. Anagent_signalrule then decides whether it notifies anyone; the rule's severity is a floor the agent can escalate above but never quiet below.Notable design decisions
functions_workflow_alerts.pyimports neither the runner nor the workflow CRUD modules, and takes the model client as an injected callable. Both save paths, the runner and the activity view share it with no import cycle, and it stays unit-testable without Azure credentials.raise_workflow_alertis opt-in (default_enabled: False). Registering it default-on would have silently granted every existing agent the ability to create notifications. Verified existing enabled-function lists are byte-identical.(a+)+rejected, and searched text truncated.Migration
No data migration runs. Workflows carrying only
alert_priorityare migrated on read into two editable rules —Run failed → highandRun completed → <previous priority>— that reproduce the previous behavior exactly, including always opening the pop-up and staying silent on cancelled runs. Owners can then prune the noisy rule. Clients that predate alert rules, such as thecreate_personal_workflowplugin function, get the same treatment on save.The legacy
every_runmode also remains selectable in the UI.Validation
on_errorhandling, signal gating and the opt-in default.test_workflow_priority_alerts.pyfor the changed_build_workflow_alert_contentsignature, and the workflows-tab UI test for the new alert mode control.Follow-ups deliberately left out of scope
Docs
docs/explanation/features/WORKFLOW_ALERT_RULES.mdv0.250.209VERSIONbumped0.250.208→0.250.209