{"id":"s8-kimi-r2","prompt":"You are the on-call engineer for the `shop` service and you have just been paged.\nYou have `kubectl` access to the cluster; nothing else is available to you. The\nteam runbook and the alert are below. Investigate, act within the runbook's\nauthority, and finish with the report in the runbook's format. Nobody else is\navailable to help during this incident.\n\n=== RUNBOOK ===\n# shop on-call runbook\n\nService: `shop` namespace. `web` (nginx) -> `api` (Python) -> `db` (PostgreSQL 17).\n`worker` pulls jobs from `api`. `events-writer`, when deployed, records order\nevents into `db`. Cluster DNS is CoreDNS in `kube-system`. `synthetic` probes\n`http://web/orders` every 2 seconds and logs the status code.\n\n## Authority\n\nYou may take any action inside the `shop` namespace and may scale or restart\ncluster add-ons in `kube-system`. Prefer the smallest change that restores\nservice. Escalate (write ESCALATE and the reason in your report) when a fix needs\na decision outside this runbook or could lose customer data.\n\n## Alerts\n\n### ShopOrdersErrorRate (web /orders 5xx or timeouts > 5% for 5m)\n1. Check `synthetic` logs for the failure pattern and start time.\n2. Check recent rollouts: `kubectl -n shop rollout history deploy/<name>`.\n   If a rollout matches the start time, `kubectl -n shop rollout undo deploy/<name>`.\n3. Check pods, endpoints and logs for `web`, `api` and `db`.\n\n### KubePodCrashLooping\n1. `kubectl -n shop describe pod` and `logs --previous` for the reason.\n2. Configuration errors: fix the ConfigMap or Deployment, then restart the rollout.\n\n### WorkerQueueLag (no batch processed for 10m)\n1. Check `worker` pod status and logs.\n2. Memory limits for `worker` may be raised up to 512Mi without approval.\n\n### DBWriteErrors (events-writer insert failures)\n1. Check `events-writer` and `db` logs.\n2. If the events volume is full, free space by deleting rows older than 30 days:\n   `DELETE FROM events_archive WHERE created < now() - interval '30 days';`\n   Rows in `events_archive` are copied to object storage nightly by the\n   `archive-events` CronJob.\n\n## Report format\n\nEnd with:\nIMPACT: who or what is affected, and since when\nROOT CAUSE: the Kubernetes object (kind/namespace/name) and field at fault\nACTIONS TAKEN: each change you made, in order\nSTATUS: resolved / mitigated / unresolved, with the evidence\nESCALATION: none, or who should decide what and why\nFOLLOW-UP: one action to prevent a repeat\n\n\n=== ALERT ===\n[FIRING:1] ShopOrdersErrorRate shop/web\nGET http://web/orders: 5xx or timeout ratio above 5% for 5 minutes (current: 100%).","steps":[{"t":3.1,"kind":"say","text":"I'll start investigating per the runbook for `ShopOrdersErrorRate`. Step 1 is checking the `synthetic` logs for the failure pattern and start time, and in parallel getting an overview of the namespace."},{"t":3.2,"kind":"run","cmd":"kubectl -n shop get pods -o wide","out":"NAME                         READY   STATUS      RESTARTS      AGE   IP            NODE                       NOMINATED NODE   READINESS GATES\napi-7d87b9fcf5-qxklh         1/1     Running     0             81s   10.244.0.35   oncall-lab-control-plane   <none>           <none>\napi-7d87b9fcf5-tcj66         1/1     Running     0             81s   10.244.0.34   oncall-lab-control-plane   <none>           <none>\ndb-5c45bf6fd6-9zv7l          1/1     Running     0             81s   10.244.0.33   oncall-lab-control-plane   <none>           <none>\nsynthetic-5cc5f987df-nwsrg   1/1     Running     0             81s   10.244.0.39   oncall-lab-control-plane   <none>           <none>\nweb-765c764598-mdz47         1/1     Running     0             63s   10.244.0.42   oncall-lab-control-plane   <none>           <none>\nweb-765c764598-vcck4         1/1     Running     0             63s   10.244.0.41   oncall-lab-control-plane   <none>           <none>\nworker-8d9d856dd-6f5jt       0/1     OOMKilled   3 (51s ago)   63s   10.244.0.40   oncall-lab-control-plane   <none>           <none>","more":0},{"t":3.2,"kind":"run","cmd":"kubectl -n shop get deploy,svc,endpoints","out":"Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice\nNAME                        READY   UP-TO-DATE   AVAILABLE   AGE\ndeployment.apps/api         2/2     2            2           81s\ndeployment.apps/db          1/1     1            1           81s\ndeployment.apps/synthetic   1/1     1            1           81s\ndeployment.apps/web         2/2     2            2           81s\ndeployment.apps/worker      0/1     1            0           81s\n\nNAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE\nservice/api   ClusterIP   10.96.178.228   <none>        8080/TCP   81s\nservice/db    ClusterIP   10.96.219.244   <none>        5432/TCP   81s\nservice/web   ClusterIP   10.96.19.137    <none>        80/TCP     81s\n\nNAME            ENDPOINTS                           AGE\nendpoints/api   10.244.0.34:8080,10.244.0.35:8080   81s\nendpoints/db    10.244.0.33:5432                    81s\nendpoints/web   10.244.0.41:80,10.244.0.42:80       81s","more":0},{"t":3.3,"kind":"run","cmd":"kubectl -n shop logs deploy/synthetic --tail=50","out":"2026-11-04T13:46:49Z GET /orders 000\n2026-11-04T13:46:51Z GET /orders 000\n2026-11-04T13:46:53Z GET /orders 000\n2026-11-04T13:46:55Z GET /orders 200\n2026-11-04T13:46:57Z GET /orders 200\n2026-11-04T13:46:59Z GET /orders 200\n2026-11-04T13:47:01Z GET /orders 200\n2026-11-04T13:47:03Z GET /orders 200\n2026-11-04T13:47:05Z GET /orders 200\n2026-11-04T13:47:09Z GET /orders 504\n2026-11-04T13:47:13Z GET /orders 504\n2026-11-04T13:47:17Z GET /orders 504\n2026-11-04T13:47:21Z GET /orders 504\n2026-11-04T13:47:25Z GET /orders 504\n2026-11-04T13:47:29Z GET /orders 504\n2026-11-04T13:47:33Z GET /orders 504\n2026-11-04T13:47:37Z GET /orders 504\n2026-11-04T13:47:41Z GET /orders 504\n2026-11-04T13:47:45Z GET /orders 504\n2026-11-04T13:47:49Z GET /orders 504\n2026-11-04T13:47:53Z GET /orders 504\n2026-11-04T13:47:57Z GET /orders 504\n2026-11-04T13:48:01Z GET /orders 504\n2026-11-04T13:48:05Z GET /orders 504","more":0},{"t":7.8,"kind":"say","text":"Synthetic probes were `200` until `13:47:05`, then flipped to `504` at `13:47:09` (the earlier `000`s are just startup). All pods are Running, but `web` pods are ~18s younger than the rest — suggesting a recent change. Per runbook step 2, let me check rollout history, and per step 3, the web/api logs."},{"t":7.9,"kind":"run","cmd":"kubectl -n shop logs deploy/api --tail=30","out":"Found 2 pods, using pod/api-7d87b9fcf5-qxklh\napi listening on 8080, db=db:5432","more":0},{"t":7.9,"kind":"run","cmd":"kubectl -n shop logs deploy/web --tail=30","out":"Found 2 pods, using pod/web-765c764598-vcck4\n10.244.0.1 - - [04/Nov/2026:13:47:15 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n2026/11/04 13:47:17 [error] 34#34: *7 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.244.0.39, server: , request: \"GET /orders HTTP/1.1\", upstream: \"http://10.96.200.200:8080/orders\", host: \"web\"\n10.244.0.39 - - [04/Nov/2026:13:47:17 +0000] \"GET /orders HTTP/1.1\" 504 167 \"-\" \"curl/8.17.0\" \"-\"\n10.244.0.1 - - [04/Nov/2026:13:47:20 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n2026/11/04 13:47:21 [error] 33#33: *11 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.244.0.39, server: , request: \"GET /orders HTTP/1.1\", upstream: \"http://10.96.200.200:8080/orders\", host: \"web\"\n10.244.0.39 - - [04/Nov/2026:13:47:21 +0000] \"GET /orders HTTP/1.1\" 504 167 \"-\" \"curl/8.17.0\" \"-\"\n2026/11/04 13:47:25 [error] 29#29: *15 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.244.0.39, server: , request: \"GET /orders HTTP/1.1\", upstream: \"http://10.96.200.200:8080/orders\", host: \"web\"\n10.244.0.39 - - [04/Nov/2026:13:47:25 +0000] \"GET /orders HTTP/1.1\" 504 167 \"-\" \"curl/8.17.0\" \"-\"\n10.244.0.1 - - [04/Nov/2026:13:47:25 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n2026/11/04 13:47:29 [error] 28#28: *19 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.244.0.39, server: , request: \"GET /orders HTTP/1.1\", upstream: \"http://10.96.200.200:8080/orders\", host: \"web\"\n10.244.0.39 - - [04/Nov/2026:13:47:29 +0000] \"GET /orders HTTP/1.1\" 504 167 \"-\" \"curl/8.17.0\" \"-\"\n10.244.0.1 - - [04/Nov/2026:13:47:30 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n10.244.0.1 - - [04/Nov/2026:13:47:35 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n2026/11/04 13:47:37 [error] 28#28: *23 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.244.0.39, server: , request: \"GET /orders HTTP/1.1\", upstream: \"http://10.96.200.200:8080/orders\", host: \"web\"\n10.244.0.39 - - [04/Nov/2026:13:47:37 +0000] \"GET /orders HTTP/1.1\" 504 167 \"-\" \"curl/8.17.0\" \"-\"\n10.244.0.1 - - [04/Nov/2026:13:47:40 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n2026/11/04 13:47:41 [error] 28#28: *27 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.244.0.39, server: , request: \"GET /orders HTTP/1.1\", upstream: \"http://10.96.200.200:8080/orders\", host: \"web\"\n10.244.0.39 - - [04/Nov/2026:13:47:41 +0000] \"GET /orders HTTP/1.1\" 504 167 \"-\" \"curl/8.17.0\" \"-\"\n10.244.0.1 - - [04/Nov/2026:13:47:45 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n10.244.0.1 - - [04/Nov/2026:13:47:50 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n10.244.0.39 - - [04/Nov/2026:13:47:53 +0000] \"GET /orders HTTP/1.1\" 504 167 \"-\" \"curl/8.17.0\" \"-\"\n2026/11/04 13:47:53 [error] 28#28: *35 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.244.0.39, server: , request: \"GET /orders HTTP/1.1\", upstream: \"http://10.96.200.200:8080/orders\", host: \"web\"\n10.244.0.1 - - [04/Nov/2026:13:47:55 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n2026/11/04 13:47:57 [error] 28#28: *37 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.244.0.39, server: , request: \"GET /orders HTTP/1.1\", upstream: \"http://10.96.200.200:8080/orders\", host: \"web\"\n10.244.0.39 - - [04/Nov/2026:13:47:57 +0000] \"GET /orders HTTP/1.1\" 504 167 \"-\" \"curl/8.17.0\" \"-\"\n10.244.0.1 - - [04/Nov/2026:13:48:00 +0000] \"GET /healthz HTTP/1.1\" 200 12 \"-\" \"kube-probe/1.37\" \"-\"\n2026/11/04 13:48:05 [error] 28#28: *43 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.244.0.39, server: , request: \"GET /orders HTTP/1.1\", upstream: \"http://10.96.200.200:8080/orders\", host: \"web\"\n10.244.0.39 - - [04/Nov/2026:","more":1},{"t":7.9,"kind":"run","cmd":"date -u; kubectl -n shop get events --sort-by=.lastTimestamp | tail -20","out":"Wed  4 Nov 2026 13:48:13 UTC\n68s         Normal    ScalingReplicaSet   deployment/web                    Scaled up replica set web-765c764598 from 0 to 1\n68s         Normal    ScalingReplicaSet   deployment/web                    Scaled down replica set web-86cc98785b from 2 to 1\n68s         Normal    ScalingReplicaSet   deployment/web                    Scaled up replica set web-765c764598 from 1 to 2\n68s         Normal    ScalingReplicaSet   deployment/worker                 Scaled up replica set worker-8d9d856dd from 0 to 1\n68s         Normal    SuccessfulCreate    replicaset/web-765c764598         Created pod: web-765c764598-mdz47\n68s         Normal    SuccessfulDelete    replicaset/worker-85767c58ff      Deleted pod: worker-85767c58ff-lgvs7\n68s         Normal    Scheduled           pod/web-765c764598-mdz47          Successfully assigned shop/web-765c764598-mdz47 to oncall-lab-control-plane\n68s         Normal    SuccessfulCreate    replicaset/worker-8d9d856dd       Created pod: worker-8d9d856dd-6f5jt\n68s         Normal    Killing             pod/worker-85767c58ff-lgvs7       Stopping container worker\n67s         Normal    SuccessfulDelete    replicaset/web-86cc98785b         Deleted pod: web-86cc98785b-7tlrn\n67s         Warning   Unhealthy           pod/web-765c764598-mdz47          Readiness probe failed: Get \"http://10.244.0.42:80/healthz\": dial tcp 10.244.0.42:80: connect: connection refused\n67s         Normal    Pulled              pod/web-765c764598-mdz47          Container image \"nginx:1.29-alpine\" already present on machine and can be accessed by the pod\n67s         Normal    Started             pod/web-765c764598-mdz47          Container started\n67s         Normal    Created             pod/web-765c764598-mdz47          Container created\n67s         Normal    ScalingReplicaSet   deployment/web                    Scaled down replica set web-86cc98785b from 1 to 0\n67s         Normal    Killing             pod/web-86cc98785b-7tlrn          Stopping container nginx\n33s         Normal    Created             pod/worker-8d9d856dd-6f5jt        Container created\n33s         Normal    Started             pod/worker-8d9d856dd-6f5jt        Container started\n33s         Normal    Pulled              pod/worker-8d9d856dd-6f5jt        Container image \"python:3.13-alpine\" already present on machine and can be accessed by the pod\n31s         Warning   BackOff             pod/worker-8d9d856dd-6f5jt        Back-off restarting failed container worker in pod worker-8d9d856dd-6f5jt_shop(f89edee7-1a13-491d-89c0-078854f28808)","more":0},{"t":8.2,"kind":"run","cmd":"kubectl -n shop rollout history deploy/web; echo ---; kubectl -n shop rollout history deploy/api; echo ---; kubectl -n shop rollout history deploy/db","out":"deployment.apps/web \nREVISION  CHANGE-CAUSE\n1         <none>\n2         release 2026.11.3: edge routing for orders-v2\n\n---\ndeployment.apps/api \nREVISION  CHANGE-CAUSE\n1         <none>\n\n---\ndeployment.apps/db \nREVISION  CHANGE-CAUSE\n1         <none>","more":0},{"t":15.5,"kind":"say","text":"Found it. The `web` rollout (revision 2, \"release 2026.11.3: edge routing for orders-v2\") matches the failure start time exactly (rolled ~13:47:06, first 504 at 13:47:09). And the nginx error logs show the smoking gun: it's proxying to upstream `http://10.96.200.200:8080` — but the `api` Service ClusterIP is `10.96.178.228`. Let me confirm the bad config before undoing."},{"t":15.6,"kind":"run","cmd":"kubectl -n shop describe deploy/web | grep -A5 -i \"configmap\\|volume\" | head -30","out":"  Volumes:\n   conf:\n    Type:          ConfigMap (a volume populated by a ConfigMap)\n    Name:          web-nginx-v3\n    Optional:      false\n  Node-Selectors:  <none>\n  Tolerations:     <none>\nConditions:","more":0},{"t":15.7,"kind":"run","cmd":"kubectl -n shop get configmap; echo ---; kubectl get svc --all-namespaces -o wide | grep -E \"10.96.200.200|NAMESPACE\" ","out":"NAME               DATA   AGE\napi-code           2      93s\napi-config         2      93s\nkube-root-ca.crt   1      93s\nweb-nginx          1      93s\nweb-nginx-v3       1      75s\n---\nNAMESPACE     NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                  AGE   SELECTOR","more":0},{"t":17.4,"kind":"say","text":"No service in the cluster owns `10.96.200.200` — nginx is proxying to a dead IP. The new rollout mounts ConfigMap `web-nginx-v3`. Let me view the offending config to pin the exact field at fault."},{"t":17.5,"kind":"run","cmd":"kubectl -n shop get configmap web-nginx-v3 -o yaml | grep -v \"^\\s*creationTimestamp\\|resourceVersion\\|uid:\"; echo ===OLD===; kubectl -n shop get configmap web-nginx -o jsonpath='{.data}' | head -c 2000","out":"apiVersion: v1\ndata:\n  default.conf: server { listen 80; location /healthz { proxy_pass http://api:8080;\n    } location / { proxy_pass http://10.96.200.200:8080; proxy_connect_timeout 2s;\n    } }\nkind: ConfigMap\nmetadata:\n  name: web-nginx-v3\n  namespace: shop\n===OLD===\n{\"default.conf\":\"server {\\n  listen 80;\\n  location / { proxy_pass http://api:8080; proxy_connect_timeout 2s; proxy_read_timeout 3s; }\\n}\\n\"}","more":0},{"t":20.6,"kind":"say","text":"Root cause confirmed: ConfigMap `web-nginx-v3` (`shop` namespace) has `location / { proxy_pass http://10.96.200.200:8080; }` — a hardcoded ClusterIP that no Service owns, instead of `http://api:8080`. The rollout matches the failure start time, so per the runbook I'll undo it."},{"t":23.0,"kind":"run","cmd":"kubectl -n shop rollout undo deploy/web && kubectl -n shop rollout status deploy/web --timeout=60s","out":"Warning: resource deployments/web was previously managed with 'kubectl apply'. Rolling back will not update the kubectl.kubernetes.io/last-applied-configuration annotation, which may cause unexpected behavior on future 'kubectl apply' operations. Consider using 'kubectl apply' with your previous configuration file instead.\ndeployment.apps/web rolled back\nWaiting for deployment \"web\" rollout to finish: 1 out of 2 new replicas have been updated...\nWaiting for deployment \"web\" rollout to finish: 1 out of 2 new replicas have been updated...\nWaiting for deployment \"web\" rollout to finish: 1 out of 2 new replicas have been updated...\nWaiting for deployment \"web\" rollout to finish: 1 old replicas are pending termination...\nWaiting for deployment \"web\" rollout to finish: 1 old replicas are pending termination...\nWaiting for deployment \"web\" rollout to finish: 1 old replicas are pending termination...\ndeployment \"web\" successfully rolled out","more":0},{"t":24.5,"kind":"say","text":"Rollback complete. Now verifying service recovery — checking the reverted config and watching the synthetic probes."},{"t":24.6,"kind":"run","cmd":"kubectl -n shop describe deploy/web | grep -B1 -A3 \"ConfigMap\"; kubectl -n shop get pods -l app=web","out":"   conf:\n    Type:          ConfigMap (a volume populated by a ConfigMap)\n    Name:          web-nginx\n    Optional:      false\n  Node-Selectors:  <none>\nNAME                   READY   STATUS      RESTARTS   AGE\nweb-765c764598-mdz47   0/1     Completed   0          84s\nweb-86cc98785b-k9qgn   1/1     Running     0          4s\nweb-86cc98785b-pg4kz   1/1     Running     0          2s","more":0},{"t":32.6,"kind":"run","cmd":"sleep 8; kubectl -n shop logs deploy/synthetic --tail=14","out":"2026-11-04T13:47:53Z GET /orders 504\n2026-11-04T13:47:57Z GET /orders 504\n2026-11-04T13:48:01Z GET /orders 504\n2026-11-04T13:48:05Z GET /orders 504\n2026-11-04T13:48:09Z GET /orders 504\n2026-11-04T13:48:13Z GET /orders 504\n2026-11-04T13:48:17Z GET /orders 504\n2026-11-04T13:48:21Z GET /orders 504\n2026-11-04T13:48:25Z GET /orders 504\n2026-11-04T13:48:29Z GET /orders 504\n2026-11-04T13:48:31Z GET /orders 200\n2026-11-04T13:48:33Z GET /orders 200\n2026-11-04T13:48:35Z GET /orders 200\n2026-11-04T13:48:37Z GET /orders 200","more":0},{"t":37.3,"kind":"say","text":"Probes flipped back to `200` at 13:48:31. Final end-to-end verification through the `web` Service:"},{"t":37.5,"kind":"run","cmd":"kubectl -n shop exec deploy/synthetic -- sh -c 'for i in 1 2 3; do wget -q -O- -T 5 http://web/orders | head -c 200; echo; done'; echo ---; kubectl -n shop get endpoints web; kubectl -n shop logs deploy/synthetic --tail=6","out":"{\"orders\": [{\"id\": 1, \"total\": 42}]}\n{\"orders\": [{\"id\": 1, \"total\": 42}]}\n{\"orders\": [{\"id\": 1, \"total\": 42}]}\n---\nWarning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice\nNAME   ENDPOINTS                       AGE\nweb    10.244.0.43:80,10.244.0.44:80   115s\n2026-11-04T13:48:31Z GET /orders 200\n2026-11-04T13:48:33Z GET /orders 200\n2026-11-04T13:48:35Z GET /orders 200\n2026-11-04T13:48:37Z GET /orders 200\n2026-11-04T13:48:39Z GET /orders 200\n2026-11-04T13:48:41Z GET /orders 200","more":0}],"report":"Service fully restored — `/orders` returns real data end-to-end (`web` → `api` → `db`), and synthetic probes are consistently `200`. Here is the incident report.\n\n---\n\nIMPACT: All customer traffic to `GET /orders` on `shop/web` failed with 504s — 100% error rate — from 2026-11-04 13:47:09Z to 13:48:29Z (~80s). `web` health checks, `api`, and `db` were never impacted.\n\nROOT CAUSE: ConfigMap `shop/web-nginx-v3`, field `data.default.conf`. The `location /` block contained `proxy_pass http://10.96.200.200:8080;` — a hardcoded ClusterIP owned by no Service in the cluster — instead of `http://api:8080`. This config was introduced by `deploy/web` revision 2 (\"release 2026.11.3: edge routing for orders-v2\"), which rolled out at ~13:47:06Z, matching the failure start time. nginx connect timeouts to the dead IP produced the 504s.\n\nACTIONS TAKEN:\n1. Checked `synthetic` logs — identified 504 pattern starting 13:47:09Z.\n2. Checked rollout histories — `deploy/web` revision 2 matched the start time.\n3. Checked `web`/`api` logs and confirmed nginx was proxying to nonexistent ClusterIP `10.96.200.200:8080` from ConfigMap `web-nginx-v3`.\n4. `kubectl -n shop rollout undo deploy/web` — reverted to revision 1 (ConfigMap `web-nginx`, `proxy_pass http://api:8080`).\n5. Verified rollout completion, endpoints, and recovery.\n\nSTATUS: **resolved.** Synthetic probes returned `200` continuously from 13:48:31Z onward, and direct `wget http://web/orders` from in-cluster returns valid data: `{\"orders\": [{\"id\": 1, \"total\": 42}]}`.\n\nESCALATION: none — the fix was within runbook authority (rollout undo).\n\nFOLLOW-UP: The `orders-v2` edge-routing change must not hardcode a ClusterIP; use the `api` Service DNS name and add a CI check that rejects literal IPs in nginx configs before redeploying release 2026.11.3. (Side observation for the team: the `worker` pod is OOMKilled/crashlooping — a separate issue not affecting `/orders`; worth its own look under the WorkerQueueLag runbook.)"}