01 · Why clicked silences rot
"Ok", ending in 2137.
A real audit of one estate found silences created years earlier with
an end date more than a century away, a two-word comment, and
matchers for alert rules that no longer existed anywhere. They muted
nothing useful and hid whatever came next under the same name.
The fix is not a better UI. It is making every silence a reviewed
change with a reason and an end.
02 · Declare the window
One file per silence, with an end time that is mandatory.
Silences live in your alerting-config repo under
silences/<tenant>/<id>.yaml: matchers, a
start, an end at most 30 days later, a comment and a link to
the change that justifies it.
The rare genuinely long-lived silence has a loud escape hatch,
permanent:, which requires a reason, an approver and a
review_by date.
03 · Checked before merge
A lint that needs no credentials at all.
The merge request pipeline runs a small, self-contained validator:
unknown keys, duplicate keys and multi-document files are refused,
the tenant must match its directory, the id must match the file
name, the window must be bounded, every regex must compile.
It runs with no network and no secrets, because in many Alertmanager
setups a "read-only" certificate can also write. The same validator
is the loader the assistant uses, so review and runtime never
disagree about the schema.
04 · Applied on merge, by your CI
The assistant never holds an Alertmanager write key.
After merge, a job on the default branch prints a plan, then creates
the silence. Each silence carries a sentinel comment with its id and
generation, so a past window is never re-created and an edited end
time is reconciled on the next pass.
The lint ships with the assistant; the applier is a small, tested
script that runs in your pipeline. If a tenant cannot be read, the job fails
instead of guessing.
05 · PagerDuty follows the silence
An incident opened before the window stops paging too.
An Alertmanager silence does nothing for a PagerDuty incident that
was already open: the escalation policy keeps re-notifying. So every
15 minutes the same pipeline snoozes open incidents that a
live declared silence covers, until the silence ends.
It also resolves incidents whose alert group has stopped
firing, which a silenced alert would otherwise never do on its own.
06 · During the window
The alert fires, nobody is woken, the context is kept.
The migration trips PostgresReplicationLag at 06:40.
Alertmanager matches it to the silence and sends nothing.
The assistant's alert triage still sees it, with the silence
attached as context: silenced alerts are annotated, not
dropped, so if something outside the planned change breaks, the
triage knows which alerts were expected.
07 · Before and at the end
A warning if it is still firing. Then alerting comes back.
Two hours and again thirty minutes before the end, if alerts covered
by the silence are still firing, a Slack message says so.
That is the moment to extend it deliberately (edit
ends_at in a new MR) or accept the page.
At ends_at the silence expires. Nothing has to be
remembered or cleaned up.
08 · Audited afterwards
Every live silence, checked against the rules that exist.
A read-only audit walks every tenant's live silences and the loaded
rule set. Deterministic rules flag an unbounded or over-30-day
expiry, a silence that matches no loaded rule, an empty or broken
matcher, and a permanent grant whose review date has passed.
A second report inventories the other ways an alert can be
muted (inhibit rules, mute intervals, severity demotions) and their
expiry debt. If a source cannot be read, the answer is "unknown",
never "clean".
09 · Proposed with the change Roadmap
Planned: the silence arrives next to the upgrade MR.
Planned: when the assistant proposes a risky upgrade hop, it also
drafts the matching silence file as a companion MR, sized to the
window the hop needs. Recurring maintenance windows (a weekly
patch slot, as a route-level mute interval) are also planned.
Today your team writes the silence file. The rest of this page
runs in production.