Checking Production Readiness
Overview
This skill walks through a 40-item checklist against a service's source tree and
generated artifacts (Dockerfile, k8s manifests, CI config). It does not run the
service or connect to cloud providers. It produces a punch-list graded by
severity so the team knows exactly what to fix before the deploy.
Quick reference
| Area |
Example checks |
| Health |
GET /healthz, GET /readyz, distinct and correct |
| Shutdown |
SIGTERM handler, drain timeout, in-flight request handling |
| Config |
All config via env vars; schema-validated at boot; no commits with real values |
| Logging |
Structured JSON, correlation id, no PII/secret leakage |
| Metrics |
At least RED (Rate / Errors / Duration) exposed; /metrics for Prometheus |
| Tracing |
OpenTelemetry SDK initialized; traceparent propagated through outbound calls |
| Errors |
Error envelope consistent; stack traces never in response body |
| Dependencies |
Pinned versions; lockfile present; npm audit / pip-audit clean |
| Container |
Non-root user, minimal base, pinned digest, HEALTHCHECK or readiness probe |
| Rollout |
Declared strategy (rolling, blue/green, canary); rollback documented |
| Docs |
Runbook, SLOs, on-call rotation, dashboards linked from README |
Workflow
Readiness check:
- [ ] Step 1: Confirm target project root
- [ ] Step 2: Detect stack (Node / Python / Go / Java) and framework
- [ ] Step 3: Run the 40-item checklist via scripts/check.py
- [ ] Step 4: Group findings by severity (Blocker / High / Medium / Info)
- [ ] Step 5: For each Blocker, propose a concrete fix
- [ ] Step 6: Emit punch-list to stdout; offer to write PRODUCTION-READINESS.md
- [ ] Step 7: Print the decision: Ship / Fix first / Needs deeper review
Step 1 — Scope
Operate on the current directory. Refuse paths outside the project. Confirm the
directory contains at minimum one of: package.json, pyproject.toml,
go.mod, pom.xml, build.gradle, or Cargo.toml.
Step 2 — Stack detection
Read the manifest file(s). Pick one primary stack. Emit a warning if multiple
services appear to live in the same root — suggest the user run the skill per
service.
Step 3 — Checklist execution
python scripts/check.py
The script runs each item against the project tree. Each item returns one of:
pass, fail, warn, skip with a short reason string.
Step 4 — Severity buckets
- Blocker — will cause an incident on day 1 (no
/healthz, no shutdown
handler, secret committed, no logging).
- High — will cause an incident within weeks (no error envelope, no rate
limiting, no metrics, no tracing).
- Medium — will bite on-call within a quarter (no structured logs, no SLOs
defined, docs missing).
- Info — nice-to-have.
Step 5 — Per-blocker fix suggestions
For each blocker, include:
- Exact file and line (when applicable).
- The concrete fix (code snippet or config change).
- Rationale: what incident it prevents.
Step 6 — Output format
Print the punch-list to stdout first. Then ask:
"¿Querés que guarde esto como ./PRODUCTION-READINESS.md? (y/N)"
Only write on explicit confirmation. Use this template:
# Production readiness — <service> — <ISO date>
## Decision: <Ship | Fix first | Needs deeper review>
## Blockers (N)
- [ ] <file>:<line> — <check id> — <short reason>
Fix: <concrete fix>
## High (N)
...
## Medium (N)
...
## Info (N)
...
Step 7 — Decision rule
- 0 Blockers and ≤2 High → Ship.
- 0 Blockers and >2 High → Fix first (the Highs together usually add up to an
incident).
- ≥1 Blocker → Fix first.
- Tricky ambiguous cases → Needs deeper review, list unresolved questions.
The 40-item checklist (summary)
1–5: Health endpoints present, distinct, correct status codes, readiness pings deps, liveness is trivial.
6–10: Graceful shutdown — SIGTERM handler, drain timeout, in-flight requests, connection pools, queue workers.
11–15: Config — env-only, schema-validated, no defaults for secrets, fail-fast on missing, .env.example up to date.
16–20: Logging — structured, level-configurable, correlation id, no PII/secret leakage, sensible redaction list.
21–25: Metrics — RED exposed, /metrics endpoint, cardinality safe, business metrics identified, no per-user labels.
26–30: Tracing — OTel SDK, sampled, propagation, DB spans, outbound HTTP instrumented.
31–33: Errors — consistent envelope, no stack leakage, 4xx vs 5xx correctly mapped.
34–36: Dependencies — lockfile, pinned, audit tool run, no unapproved licenses.
37–40: Container — non-root, pinned base digest, HEALTHCHECK, rollout strategy + rollback runbook linked.
Full implementation in scripts/check.py.
Examples
Example 1 — Greenfield Fastify service before first deploy
Input: "is this Fastify service ready to ship to prod?"
Behavior: Detects Node + Fastify, runs 40 checks, reports 2 Blockers (no graceful
shutdown, no /readyz pinging DB), 3 High, 1 Medium. Outputs decision: Fix first.
Concrete fixes referenced by file:line.
Example 2 — Python worker that looks fine but has no tracing
Input: "pre-deploy audit of my celery worker"
Behavior: 0 Blockers, 1 High (no OTel SDK wired), 4 Medium. Decision: Ship, but
list the High to address next sprint.
Example 3 — Repo with two services
Input: "check prod readiness"
Behavior: Detects two manifests, warns the user, asks which service to audit
and recommends running once per service.
Non-goals
- No secret scanning (use
auditing-env-files).
- No cloud-cost review.
- No penetration testing.
- No load testing (use
k6-load-testing-builder).
- No CI pipeline audit beyond the rollout artifact (use
ci-pipeline-optimizer).
- No DB migration safety review (use
database-migration-writer).
Security
- Scope: operates only within the current directory. Refuses absolute paths,
.. escapes, and home-dir reads.
- Read-only by default. Writes exactly one file (
./PRODUCTION-READINESS.md)
and only after explicit user confirmation. Never modifies tracked files.
- No network calls. Does not ping cloud providers, does not pull from
package registries, does not fetch manifests. All checks are offline.
- No secret output. If a check happens to find a literal-looking secret,
report the file:line and defer to
auditing-env-files for masked analysis.
- Least-privilege
allowed-tools: Read, Grep, Glob, Bash(python scripts/*),
Bash(git *). No Write without confirmation. No WebFetch, no WebSearch.
- Dependencies: Python 3.10+ standard library only. No pip installs.
- No destructive actions. Never runs deploys, never touches CI config files,
never pushes, never rebases.
1---2name: checking-production-readiness3description: Audits a service for production readiness before its first deploy or a major rollout — verifies health endpoints, graceful shutdown, structured logging, 12-factor config, observability hooks, secrets handling, and container/runtime basics. Use when the user asks to "check production readiness", "pre-deploy audit", "is this ready to ship?", or mentions SLOs, health checks, graceful shutdown, or observability gaps. Covers a deterministic 40-item checklist, severity scoring, and a punch-list output. Do NOT use for security audits of secrets in source (use auditing-env-files), cloud cost review, pen testing, or load testing — those are separate skills.4---56# Checking Production Readiness78## Overview910This skill walks through a 40-item checklist against a service's source tree and11generated artifacts (Dockerfile, k8s manifests, CI config). It does not run the12service or connect to cloud providers. It produces a punch-list graded by13severity so the team knows exactly what to fix before the deploy.1415## Quick reference1617| Area | Example checks |18|---|---|19| Health | `GET /healthz`, `GET /readyz`, distinct and correct |20| Shutdown | SIGTERM handler, drain timeout, in-flight request handling |21| Config | All config via env vars; schema-validated at boot; no commits with real values |22| Logging | Structured JSON, correlation id, no PII/secret leakage |23| Metrics | At least RED (Rate / Errors / Duration) exposed; `/metrics` for Prometheus |24| Tracing | OpenTelemetry SDK initialized; traceparent propagated through outbound calls |25| Errors | Error envelope consistent; stack traces never in response body |26| Dependencies | Pinned versions; lockfile present; `npm audit` / `pip-audit` clean |27| Container | Non-root user, minimal base, pinned digest, HEALTHCHECK or readiness probe |28| Rollout | Declared strategy (rolling, blue/green, canary); rollback documented |29| Docs | Runbook, SLOs, on-call rotation, dashboards linked from README |3031## Workflow3233```34Readiness check:35- [ ] Step 1: Confirm target project root36- [ ] Step 2: Detect stack (Node / Python / Go / Java) and framework37- [ ] Step 3: Run the 40-item checklist via scripts/check.py38- [ ] Step 4: Group findings by severity (Blocker / High / Medium / Info)39- [ ] Step 5: For each Blocker, propose a concrete fix40- [ ] Step 6: Emit punch-list to stdout; offer to write PRODUCTION-READINESS.md41- [ ] Step 7: Print the decision: Ship / Fix first / Needs deeper review42```4344### Step 1 — Scope4546Operate on the current directory. Refuse paths outside the project. Confirm the47directory contains at minimum one of: `package.json`, `pyproject.toml`,48`go.mod`, `pom.xml`, `build.gradle`, or `Cargo.toml`.4950### Step 2 — Stack detection5152Read the manifest file(s). Pick one primary stack. Emit a warning if multiple53services appear to live in the same root — suggest the user run the skill per54service.5556### Step 3 — Checklist execution5758```59python scripts/check.py60```6162The script runs each item against the project tree. Each item returns one of:63`pass`, `fail`, `warn`, `skip` with a short reason string.6465### Step 4 — Severity buckets6667- **Blocker** — will cause an incident on day 1 (no `/healthz`, no shutdown68 handler, secret committed, no logging).69- **High** — will cause an incident within weeks (no error envelope, no rate70 limiting, no metrics, no tracing).71- **Medium** — will bite on-call within a quarter (no structured logs, no SLOs72 defined, docs missing).73- **Info** — nice-to-have.7475### Step 5 — Per-blocker fix suggestions7677For each blocker, include:78- Exact file and line (when applicable).79- The concrete fix (code snippet or config change).80- Rationale: what incident it prevents.8182### Step 6 — Output format8384Print the punch-list to stdout first. Then ask:8586> "¿Querés que guarde esto como `./PRODUCTION-READINESS.md`? (y/N)"8788Only write on explicit confirmation. Use this template:8990```markdown91# Production readiness — <service> — <ISO date>9293## Decision: <Ship | Fix first | Needs deeper review>9495## Blockers (N)96- [ ] <file>:<line> — <check id> — <short reason>97 Fix: <concrete fix>9899## High (N)100...101102## Medium (N)103...104105## Info (N)106...107```108109### Step 7 — Decision rule110111- 0 Blockers and ≤2 High → Ship.112- 0 Blockers and >2 High → Fix first (the Highs together usually add up to an113 incident).114- ≥1 Blocker → Fix first.115- Tricky ambiguous cases → Needs deeper review, list unresolved questions.116117## The 40-item checklist (summary)1181191–5: Health endpoints present, distinct, correct status codes, readiness pings deps, liveness is trivial.1206–10: Graceful shutdown — SIGTERM handler, drain timeout, in-flight requests, connection pools, queue workers.12111–15: Config — env-only, schema-validated, no defaults for secrets, fail-fast on missing, `.env.example` up to date.12216–20: Logging — structured, level-configurable, correlation id, no PII/secret leakage, sensible redaction list.12321–25: Metrics — RED exposed, `/metrics` endpoint, cardinality safe, business metrics identified, no per-user labels.12426–30: Tracing — OTel SDK, sampled, propagation, DB spans, outbound HTTP instrumented.12531–33: Errors — consistent envelope, no stack leakage, 4xx vs 5xx correctly mapped.12634–36: Dependencies — lockfile, pinned, audit tool run, no unapproved licenses.12737–40: Container — non-root, pinned base digest, HEALTHCHECK, rollout strategy + rollback runbook linked.128129Full implementation in [scripts/check.py](scripts/check.py).130131## Examples132133**Example 1 — Greenfield Fastify service before first deploy**134Input: "is this Fastify service ready to ship to prod?"135Behavior: Detects Node + Fastify, runs 40 checks, reports 2 Blockers (no graceful136shutdown, no `/readyz` pinging DB), 3 High, 1 Medium. Outputs decision: Fix first.137Concrete fixes referenced by file:line.138139**Example 2 — Python worker that looks fine but has no tracing**140Input: "pre-deploy audit of my celery worker"141Behavior: 0 Blockers, 1 High (no OTel SDK wired), 4 Medium. Decision: Ship, but142list the High to address next sprint.143144**Example 3 — Repo with two services**145Input: "check prod readiness"146Behavior: Detects two manifests, warns the user, asks which service to audit147and recommends running once per service.148149## Non-goals150151- No secret scanning (use `auditing-env-files`).152- No cloud-cost review.153- No penetration testing.154- No load testing (use `k6-load-testing-builder`).155- No CI pipeline audit beyond the rollout artifact (use `ci-pipeline-optimizer`).156- No DB migration safety review (use `database-migration-writer`).157158## Security159160- **Scope**: operates only within the current directory. Refuses absolute paths,161 `..` escapes, and home-dir reads.162- **Read-only by default**. Writes exactly one file (`./PRODUCTION-READINESS.md`)163 and only after explicit user confirmation. Never modifies tracked files.164- **No network calls**. Does not ping cloud providers, does not pull from165 package registries, does not fetch manifests. All checks are offline.166- **No secret output**. If a check happens to find a literal-looking secret,167 report the file:line and defer to `auditing-env-files` for masked analysis.168- **Least-privilege `allowed-tools`**: `Read`, `Grep`, `Glob`, `Bash(python scripts/*)`,169 `Bash(git *)`. No `Write` without confirmation. No `WebFetch`, no `WebSearch`.170- **Dependencies**: Python 3.10+ standard library only. No pip installs.171- **No destructive actions**. Never runs deploys, never touches CI config files,172 never pushes, never rebases.