Review checklist
This is the checklist to run down — by eye, on any diff, yours or an AI’s — after the tools in Verification Tools have run and come back clean. It fits on one printed page on purpose: a checklist nobody actually opens during a review is worthless. Every line links the lesson that explains why, so this page stays a list, not a re-run of the course. The groups follow the same order as How to read Kubernetes YAML you did not write, plus a final Tooling group covering how each of the other seven actually gets verified.
flowchart LR A["API versions & shape"] --> T["dry-run=server catches most<br/>(discovery errors, strict decoding)"] W["Workloads"] --> P["Partial: immutable-field errors caught,<br/>headless-Service/concurrency gaps are not"] S["Scheduling"] --> P N["Networking"] --> M["Mostly human review<br/>(selector/policyTypes are unvalidated matchers)"] ST["Storage & config"] --> M Sec["Security"] --> P2["Partial: PSA/VAP catch known fields,<br/>RBAC over-grant needs auth can-i"] O["Observability"] --> M
API versions & shape
Section titled “API versions & shape”- Does
apiVersionstill resolve on the cluster you’re deploying to (kubectl api-resources,kubectl explain <kind>)?extensions/v1beta1,batch/v1beta1, andnetworking.k8s.io/v1beta1are all removed. See the AI Bug Catalog, entries 1–3. - Does anything still reference
kind: PodSecurityPolicy? Removed in Kubernetes 1.25 — the replacement is a Namespace label plus Pod Security Admission. See entry 4. - Does an
Ingressuse the currentbackend.service.name/port.numbershape (withpathTypeset), not the removedbackend.serviceName/servicePort? See entry 3. - Does a
HorizontalPodAutoscalermixautoscaling/v1fields (targetCPUUtilizationPercentage) withautoscaling/v2-only fields (metrics,behavior) in the same object? A real, current server-sideBadRequest. See entry 5.
Workloads
Section titled “Workloads”- Is anyone attempting to change an existing Deployment’s
spec.selector? A real, currentfield is immutablerejection. See the AI Bug Catalog, entry 6, and Deployments and ReplicaSets. - Does a Job’s Pod template ever set
restartPolicy: Always? OnlyOnFailure/Neverare valid — see entry 7 for the real, current rejection. - Does a Deployment’s
strategy.rollingUpdateset bothmaxUnavailable: 0andmaxSurge: 0? A real, current invalid-value rejection, not a stuck rollout discovered later. See entry 8. - Does every StatefulSet’s
serviceNamepoint at a Service that actually exists and is headless (clusterIP: None)? Not validated at creation time — see entry 9, proven with a realNXDOMAIN. - Is
concurrencyPolicyset deliberately on every CronJob, rather than left at its silentAllowdefault? See entry 10, proven with real overlapping Job runs. - Does every Service’s
selectorgenuinely match the Pod template’s reallabels— checked directly, not assumed? See entry 11, proven with a real, emptyEndpointSlice.
Scheduling
Section titled “Scheduling”- If an HPA targets a workload by CPU/memory utilization, does that workload’s containers set
resources.requests? See the AI Bug Catalog, entry 12, proven with a realFailedGetResourceMetric, and Horizontal Pod Autoscaling. - Does every PodDisruptionBudget’s
minAvailable(ormaxUnavailable) leave real room strictly below the full replica count? See entry 13, proven with a real, permanently-blocked drain, and Pod Disruption & Cluster Autoscaling.
Networking
Section titled “Networking”- Does a NetworkPolicy’s
policyTypeslist every direction its name or comment claims to restrict? OmittingEgressleaves that direction completely unrestricted, not “covered by default.” See the AI Bug Catalog, entry 14, proven with a real, unblocked curl. - If a NetworkPolicy is a genuine default-deny (
policyTypes: [Ingress, Egress], no rules), does it still explicitly allow egress to the cluster’s DNS provider (kube-system, UDP/TCP 53)? Otherwise every hostname lookup — including Kubernetes Service names — fails too. See entry 15, proven with a real, timed-outnslookup.
Storage & configuration
Section titled “Storage & configuration”- Does a
hostPathvolume carry data meant to survive the Pod being rescheduled onto a different node? Proven to silently leave data behind — see the AI Bug Catalog, entry 16. - Does anything — a comment, a variable name, a runbook — call a
Secret’s contents “encrypted”? Itsdatafields are base64-encoded only, trivially reversible by anyone with ordinaryget secretaccess. See entry 17.
Security
Section titled “Security”- Does
securityContext.privileged: true(orhostNetwork/hostPID/hostIPC) appear as the apparent fix for an in-container permission error, rather than the one specific capability or field actually needed? See the AI Bug Catalog, entry 18, and Pod & Cluster Security for the real Pod Security Admission rejection this produces. - Are Linux capabilities ever dropped (
capabilities.drop: ["ALL"]), with only what’s genuinely needed added back viacapabilities.add? See entry 19. - Is
automountServiceAccountToken: falseset on any workload that never calls the Kubernetes API server? See entry 20. - Is a workload’s ServiceAccount ever bound to
cluster-admin, rather than a narrowly-scopedRole/ClusterRole? See entry 21, proven with a realkubectl auth can-ishowing cluster-wide reach, and RBAC & Service Accounts.
Observability
Section titled “Observability”- Does every Deployment sitting behind a Service have a
readinessProbethat checks the real application endpoint, not just “process is running”? See the AI Bug Catalog, entry 22, proven with a realConnection refusedduring startup, and Probes: Liveness, Readiness, Startup. - Are
livenessProbeandreadinessProbeever pointed at the identical endpoint with nostartupProbecushioning a slow warm-up? See entry 23, proven with a real, self-inflicted restart loop. - Does a debugging instruction assume
kubectl exec -it <pod> -- shalways works, even against a minimal or distroless image with no shell at all?kubectl debug --target(ephemeral containers, GA since 1.25) is the real fix. See entry 24, and Logging & Metrics.
Tooling
Section titled “Tooling”- Is
kubectl apply --dry-run=server(not just--dry-run=client) run against a real API server before anything in this checklist is trusted as “probably fine”?--dry-run=clientnever contacts the server at all and misses every discovery/admission/strict-decoding error this checklist relies on. See Verification Tools. - Does CI run a real schema validator (
kubeconform,kube-linter,polaris, or this course’s owntools/verify-manifests.mjs) against every manifest, not just a human skim? See Verification Tools. - Is Pod Security Admission’s
warnmode (not justenforce) treated as a live linter — checked on every apply, even in namespaces not yet ready to enforcerestricted? See Pod & Cluster Security.