Review: Bug: platform-validation OOMKilled at 64Mi + stale alert rule (v2)
Verdict: NEEDS_REFINEMENT
Second review pass (post scope-correction comment on issue #171). First review identified 3 issues; scope correction resolved 2 of 3 but introduced a new PromQL semantics issue.
Template Completeness
Checked against
template-issue. Original issue body + scope correction comment combined:- [x] Type (bug)
- [x] Lineage (standalone — discovered during AlertManager triage 2026-03-26)
- [x] Repo (corrected in comment: pal-e-deployments + pal-e-platform)
- [ ] User Story — MISSING
- [x] What Broke (serves as Context for a bug)
- [x] File Targets (added in scope correction, verified — see below)
- [x] Acceptance Criteria (updated in scope correction)
- [ ] Test Expectations — MISSING (no test commands beyond manual kubectl; should specify tofu plan and ArgoCD sync verification commands)
- [ ] Constraints — MISSING (should note:
tofu plan -lock=false; ArgoCD auto-syncs pal-e-deployments; two separate PRs needed) - [ ] Checklist — MISSING
- [x] Related
File Targets
- [x]
pal-e-deployments/overlays/platform-validation/prod/deployment-patch.yamllines 22-27 — VERIFIED:resourcesblock present,limits.memory: 64Miconfirmed at line 27. Scope correction says lines 22-27, actual is lines 22-27. Exact match. - [x]
pal-e-platform/terraform/main.tflines 230-242 — VERIFIED: OOMKilled alert rule at lines 230-241, expressionkube_pod_container_status_last_terminated_reason{reason="OOMKilled"} > 0withfor = "0m"confirmed at lines 232-233. Scope correction says lines 230-242, actual block ends at line 241 (closing brace). Close enough.
Repo Placement
The scope correction correctly identifies two repos. Improvement over v1 review — repos and file paths are now explicit:
- Memory limit:
forgejo_admin/pal-e-deployments(kustomize overlay, ArgoCD-synced) - Alert rule:
forgejo_admin/pal-e-platform(terraform PrometheusRule, applied viatofu apply)
However, the issue body on Forgejo has NOT been updated — the corrections only exist in a comment. The Forgejo issue is filed only on
pal-e-platform. An agent reading just the issue body would not know about the pal-e-deployments change. The cross-repo scope needs to be either in the issue body or a second issue must be created on pal-e-deployments.Dependencies
No blockers found on
board-pal-e-platform. Item #388 is in todo column. No items currently in in_progress. Three sibling alert-triage bugs also in todo (#385, #386, #387) — independent, no blocking relationship. The pal-e-deployments memory bump and the pal-e-platform alert rule fix are independent of each other and can be merged in either order.Acceptance Criteria
Assessment of the updated acceptance criteria from the scope correction comment:
- [x] "Memory limit bumped to 128Mi in pal-e-deployments" — testable via
kubectl get pod -n platform-validation -o jsonpath='{.items[0].spec.containers[0].resources.limits.memory}' - [x] "OOMKilled alert rule updated with for: 15m in pal-e-platform" — testable via
tofu plan -lock=false - [x] "ArgoCD syncs platform-validation successfully" — testable via
kubectl get app platform-validation -n argocd - [x] "tofu plan shows only the for: duration change" — testable
- [ ] "Current OOMKilled alert clears within 15 minutes" — ISSUE: Misleading criterion. The metric
kube_pod_container_status_last_terminated_reason{reason="OOMKilled"}persists in kube-state-metrics as long as the pod's last termination was OOMKilled. It does NOT clear when the pod recovers and runs successfully. Addingfor: 15mmeans the alert transitions from pending to firing after 15 minutes of the condition being true — but since the condition is permanently true after an OOMKill (until pod deletion or restart for a different reason), the alert will still fire 15 minutes after the OOMKill and remain firing indefinitely. The alert clears in this specific case only because bumping the memory limit triggers a deployment rollout, which creates a new pod with no OOM termination history. The acceptance criterion should state: "After deployment rollout from the memory bump, the OOMKilled alert clears because the new pod has no OOM termination history." This distinction matters for future OOMKills —for: 15malone does not prevent staleness.
Blast Radius
- Other 64Mi services:
playground(main + asset-upload sidecar) andsvelte-playgroundalso have 64Mi memory limits in pal-e-deployments. These are nginx static file servers where 64Mi is appropriate. No action needed. - Other
for: 0mrules:PodRestartStorm(line 220-221) also usesfor: 0m, but its expression usesincrease(...[15m])which naturally resets when restarts stop. Not stale in the same way. No blast radius issue. - Cluster-wide alert scope: The OOMKilled alert has no namespace filter — changing
for:to 15m affects all OOMKill alerts cluster-wide. This is correct behavior (brief OOMKills that self-resolve should not be critical alerts), but agents should be aware.
PromQL Correction Assessment
The scope correction correctly identifies that the originally proposed
increase(kube_pod_container_status_restarts_total{reason="OOMKilled"}[15m]) > 0 is invalid — kube_pod_container_status_restarts_total does NOT carry a reason label in kube-state-metrics. This was confirmed by examining the existing PodRestartStorm rule at line 220 which uses the same metric without a reason label.The corrected approach (keep existing expression, add
for: 15m) is a pragmatic improvement but does not fully solve staleness. See Acceptance Criteria section above for details.Recommendation
Three items must be addressed before this ticket is READY:
- Cross-repo scope must be explicit and agent-readable — The scope correction lives only in a comment. Either update the issue body to include both repos with file paths and note "two PRs required," or create a companion issue on
pal-e-deploymentsfor the memory bump. An agent reading just the issue body would miss the pal-e-deployments change entirely. - Correct the "alert clears within 15 minutes" acceptance criterion — Replace with: "After deployment rollout (triggered by memory limit bump), the OOMKilled alert clears because the new pod has no OOM termination history." The current wording implies
for: 15malone resolves staleness, which is incorrect. - Add missing template sections — Test Expectations (verification commands for both repos), Constraints (
tofu plan -lock=false, ArgoCD auto-sync, two separate PRs), and Checklist.