Skip to content

[9.4] [Alerting] Preserve rule type payload across delayed-to-active graduation (#266012)#268402

Merged
kibanamachine merged 1 commit into
elastic:9.4from
kibanamachine:backport/9.4/pr-266012
May 8, 2026
Merged

[9.4] [Alerting] Preserve rule type payload across delayed-to-active graduation (#266012)#268402
kibanamachine merged 1 commit into
elastic:9.4from
kibanamachine:backport/9.4/pr-266012

Conversation

@kibanamachine
Copy link
Copy Markdown
Contributor

Backport

This will backport the following commits from main to 9.4:

Questions ?

Please refer to the Backport tool documentation

…tion (elastic#266012)

## Summary

Resolves elastic#259886. Architectural alternative to elastic#265588.

When a delayed alert is reactivated by `delayRecoveredFlappingAlerts`
(flap-hold) and crosses `alertDelay` on a run where the executor does
**not** report it, the alert builder used to dispatch to `buildNewAlert`
with an empty payload — producing an active AAD doc with blank rule type
fields (e.g. `kibana.alert.reason`).

Rather than skip the graduation in that case, this PR makes the
framework own the `delayed -> active` transition explicitly so the
resulting active doc is always complete.

### Fix (code)

- **`buildDelayedAlert`** now stores the full executor payload on the
delayed AAD doc. Previously the delayed doc only carried framework
fields. Persisting the rule type payload turns each delayed doc into a
usable predecessor.
- **`buildGraduatedAlert`** is a new builder dedicated to `delayed ->
active` transitions. It deep-merges the predecessor delayed doc with the
current run's payload (per-field precedence: current wins, predecessor
fills gaps), sets `event.action: 'open'` and `kibana.alert.status:
active`, and treats the alert as user-visible for the first time
(`severity_improving: false`, no `previous_action_group`).
- **`AlertBuilder.buildActiveAlerts`** now branches on `trackedActive`
vs `trackedDelayed` to dispatch to ongoing / graduated / new
respectively, instead of the previous status check on a single tracked
alert.

The per-field merge means:

| Run shape on graduation | `cleanedPayload[K]` | Resulting field |
| --- | --- | --- |
| Executor reports `K` | present | fresh value (predecessor shadowed) |
| Flap-hold reactivation, no executor report | absent | predecessor's
value preserved |
| Partial report (some `K` reported) | present for some | executor where
present, predecessor where absent |

This matches the long-standing semantics of `buildOngoingAlert`, just
sourced from the delayed predecessor instead of an active one.

How to reproduce the issue (on the 6th execution we see an alert without
context):

Run | pattern | flappingHistory | active | recovered | activeCount |
pending recovered | flapping | AAD status
-- | -- | -- | -- | -- | -- | -- | -- | --
1 | a | T | x |   | 1 | 0 | FALSE | delayed
2 | a | T,F | x |   | 2 | 0 | FALSE | active
3 | - | T,F,T |   | x | 0 | - | FALSE | recovered
4 | - | T,F,T,F |   | x | 0 | - | FALSE | recovered
5 | a | T,F,T,F,T | x |   | 1 | 0 | FALSE | delayed
6 | - | T,F,T,F,T,T | x |   | 2 | 1 | TRUE | active

(cherry picked from commit 5a5a2d0)
@kibanamachine
Copy link
Copy Markdown
Contributor Author

💛 Build succeeded, but was flaky

Failed CI Steps

Test Failures

  • [job] [logs] Scout Lane #6 - stateful-classic / default / local-stateful-classic - Infrastructure Inventory - Onboarding - Renders no data page and redirects to onboarding page when no data is present

Metrics [docs]

✅ unchanged

cc @ersin-erdal

@kibanamachine kibanamachine merged commit 460a7f1 into elastic:9.4 May 8, 2026
34 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport This PR is a backport of another PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants