prometheusrule-disk-wear.yaml: new recording rule node_device:nvme_ephemeral_volume:info = the (node, device) carrying /var, from node-exporter node_filesystem_size_bytes{mountpoint="/var"} joined to node_uname_info. NvmeDriveWearProjectedExhaustion and NvmeDriveWearCritical now unless on (node, device) that series.
New promtool suite tests/disk-wear_test.yaml (3 cases) and 4 negative controls in tests/mutations.txt.
Why
REN-419 / REN-420: the owner declined replacing k8s-1 nvme1. EPHEMERAL drives run to failure; stop wear alerts on them. Spare-exhausted, critical-warning and media-error alerts are untouched, so a real failure on an EPHEMERAL drive still alerts.
Failure direction
If the join stops matching (relabel, /var on a dm device), the recorded series is empty and the wear alerts come back for EPHEMERAL drives. Noisy, not silent. Case C pins this.
How verified
Not run locally: no promtool and no Prometheus access in this run. CI promtool step runs the suite and mutations.
Not yet in the cluster. After merge, Atlas checks that node_device:nvme_ephemeral_volume:info has one series per node (k8s-1 nvme1 expected) and that the k8s-1 nvme1 alert has resolved.
Revert
git revert this commit. Rules only; no workload restarts, no Home Assistant impact.
## What
- `prometheusrule-disk-wear.yaml`: new recording rule `node_device:nvme_ephemeral_volume:info` = the (node, device) carrying `/var`, from node-exporter `node_filesystem_size_bytes{mountpoint="/var"}` joined to `node_uname_info`. `NvmeDriveWearProjectedExhaustion` and `NvmeDriveWearCritical` now `unless on (node, device)` that series.
- New promtool suite `tests/disk-wear_test.yaml` (3 cases) and 4 negative controls in `tests/mutations.txt`.
## Why
REN-419 / REN-420: the owner declined replacing k8s-1 nvme1. EPHEMERAL drives run to failure; stop wear alerts on them. Spare-exhausted, critical-warning and media-error alerts are untouched, so a real failure on an EPHEMERAL drive still alerts.
## Failure direction
If the join stops matching (relabel, `/var` on a dm device), the recorded series is empty and the wear alerts come back for EPHEMERAL drives. Noisy, not silent. Case C pins this.
## How verified
- Not run locally: no promtool and no Prometheus access in this run. CI `promtool` step runs the suite and mutations.
- Not yet in the cluster. After merge, Atlas checks that `node_device:nvme_ephemeral_volume:info` has one series per node (k8s-1 nvme1 expected) and that the k8s-1 nvme1 alert has resolved.
## Revert
`git revert` this commit. Rules only; no workload restarts, no Home Assistant impact.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The owner decided EPHEMERAL (/var) drives run to failure (REN-420), so
NvmeDriveWearProjectedExhaustion and NvmeDriveWearCritical now skip the
drive carrying /var. The drive is resolved live by joining node-exporter's
/var mount onto smartctl-exporter's (node, device) through a recording rule;
if the join stops matching, the alerts return rather than go quiet. Spare,
critical-warning and media-error alerts still cover EPHEMERAL drives.
Adds a promtool suite and four negative controls for the exclusion.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI fails.ci-manifests-test → promtool (pipeline 11783, step 43319): disk-wear_test.yaml case A, NvmeDriveWearProjectedExhaustion at 8d: exp nvme0, got []. Mutations did not run.
Cause: case A uses interval: 1h and the rule has for: 6h. With the 5m lookback, every input series is absent for ~55 min of each hour. So the expression is empty most minutes and the pending alert resets before 6h. Cases B and C use 1m and pass.
Fix: feed case A at interval: 1m (89+0x11600, bytes at 1/60 of the hourly step), or at most 5m. Recompute the 140-day summary. Then confirm all 4 disk-wear-* mutations fail the suite in CI.
Checked and fine: the recording rule regex and partition strip, the per-node unless on (node, device), and/unless precedence (left-assoc, excludes after the gate), cases B/C, the mutation sed targets, and revert = rules only.
Not checked: live labels. Prometheus is not reachable from my runner. The post-merge check on REN-419 covers it.
Request changes on `18629fd4`.
**CI fails.** `ci-manifests-test` → `promtool` (pipeline 11783, step 43319): disk-wear_test.yaml case A, `NvmeDriveWearProjectedExhaustion` at 8d: exp nvme0, **got []**. Mutations did not run.
**Cause:** case A uses `interval: 1h` and the rule has `for: 6h`. With the 5m lookback, every input series is absent for ~55 min of each hour. So the expression is empty most minutes and the pending alert resets before 6h. Cases B and C use 1m and pass.
**Fix:** feed case A at `interval: 1m` (`89+0x11600`, bytes at 1/60 of the hourly step), or at most 5m. Recompute the 140-day summary. Then confirm all 4 `disk-wear-*` mutations fail the suite in CI.
Checked and fine: the recording rule regex and partition strip, the per-node `unless on (node, device)`, `and`/`unless` precedence (left-assoc, excludes after the gate), cases B/C, the mutation sed targets, and revert = rules only.
Not checked: live labels. Prometheus is not reachable from my runner. The post-merge check on REN-419 covers it.
Case A sampled at 1h; with the 5m lookback the series were absent for most
of each hour and the pending alert reset, so the projection never fired.
Now 5m samples (1m exceeds promtool's sample limit on the 7d rate), same
0.04272 %/day and 140-day summary.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Approved at 42e67219e0fd504e778c346837ec2a86113e6a46. Case A now 5m samples: 9e14 bytes at 192h, 4.32e11/day, 0.04272 %/day, 140 days, matches summary. CI 11803 green (ci-manifests-test, ci-scripts-test, pr-review). Local scripts/ci/promtool-rules.sh (promtool 3.5.0): PASS, 6 suites, 29 mutations caught incl. all 4 disk-wear-*.
Approved at `42e67219e0fd504e778c346837ec2a86113e6a46`. Case A now 5m samples: 9e14 bytes at 192h, 4.32e11/day, 0.04272 %/day, 140 days, matches summary. CI 11803 green (ci-manifests-test, ci-scripts-test, pr-review). Local scripts/ci/promtool-rules.sh (promtool 3.5.0): PASS, 6 suites, 29 mutations caught incl. all 4 disk-wear-*.
Ghost
merged commit d3f89b1477 into master2026-10-01 09:19:19 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
What
prometheusrule-disk-wear.yaml: new recording rulenode_device:nvme_ephemeral_volume:info= the (node, device) carrying/var, from node-exporternode_filesystem_size_bytes{mountpoint="/var"}joined tonode_uname_info.NvmeDriveWearProjectedExhaustionandNvmeDriveWearCriticalnowunless on (node, device)that series.tests/disk-wear_test.yaml(3 cases) and 4 negative controls intests/mutations.txt.Why
REN-419 / REN-420: the owner declined replacing k8s-1 nvme1. EPHEMERAL drives run to failure; stop wear alerts on them. Spare-exhausted, critical-warning and media-error alerts are untouched, so a real failure on an EPHEMERAL drive still alerts.
Failure direction
If the join stops matching (relabel,
/varon a dm device), the recorded series is empty and the wear alerts come back for EPHEMERAL drives. Noisy, not silent. Case C pins this.How verified
promtoolstep runs the suite and mutations.node_device:nvme_ephemeral_volume:infohas one series per node (k8s-1 nvme1 expected) and that the k8s-1 nvme1 alert has resolved.Revert
git revertthis commit. Rules only; no workload restarts, no Home Assistant impact.🤖 Generated with Claude Code
Request changes on
18629fd4.CI fails.
ci-manifests-test→promtool(pipeline 11783, step 43319): disk-wear_test.yaml case A,NvmeDriveWearProjectedExhaustionat 8d: exp nvme0, got []. Mutations did not run.Cause: case A uses
interval: 1hand the rule hasfor: 6h. With the 5m lookback, every input series is absent for ~55 min of each hour. So the expression is empty most minutes and the pending alert resets before 6h. Cases B and C use 1m and pass.Fix: feed case A at
interval: 1m(89+0x11600, bytes at 1/60 of the hourly step), or at most 5m. Recompute the 140-day summary. Then confirm all 4disk-wear-*mutations fail the suite in CI.Checked and fine: the recording rule regex and partition strip, the per-node
unless on (node, device),and/unlessprecedence (left-assoc, excludes after the gate), cases B/C, the mutation sed targets, and revert = rules only.Not checked: live labels. Prometheus is not reachable from my runner. The post-merge check on REN-419 covers it.
Approved at
42e67219e0fd504e778c346837ec2a86113e6a46. Case A now 5m samples: 9e14 bytes at 192h, 4.32e11/day, 0.04272 %/day, 140 days, matches summary. CI 11803 green (ci-manifests-test, ci-scripts-test, pr-review). Local scripts/ci/promtool-rules.sh (promtool 3.5.0): PASS, 6 suites, 29 mutations caught incl. all 4 disk-wear-*.