production-debugging — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited production-debugging (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Systematic approach to debugging production issues in Kubernetes microservice environments.
# What's the user seeing?
# - HTTP 500 error on /workers page
# - No reminder notifications
# - Data saved but logs show errors
# Document the symptom precisely before diving in# Start with the failing service
kubectl logs deploy/<service-name> -n <namespace> --tail=100
# Filter for errors
kubectl logs deploy/<service-name> -n <namespace> --tail=200 | grep -i -E "(error|exception|fail|warn)"
# Check specific container in multi-container pod
kubectl logs deploy/<service-name> -n <namespace> -c <container-name> --tail=100
# Common containers:
# - main app container (e.g., "api", "web")
# - daprd (Dapr sidecar)
# - init containers (e.g., "wait-for-db")For microservice issues, trace the full request path:
# 1. Frontend → API
kubectl logs deploy/web-dashboard -n taskflow --tail=50
# 2. API processing
kubectl logs deploy/taskflow-api -n taskflow --tail=100 | grep -i "endpoint-name"
# 3. API → External service (e.g., Dapr, SSO)
kubectl logs deploy/taskflow-api -n taskflow -c daprd --tail=50
# 4. Downstream service
kubectl logs deploy/notification-service -n taskflow --tail=50Common patterns to look for:
| Error Pattern | Likely Cause |
|---|---|
AttributeError: 'X' has no attribute 'Y' | Model/schema mismatch |
404 Not Found on internal call | Wrong endpoint URL |
greenlet_spawn has not been called | Async SQLAlchemy pattern issue |
event_type: None | Message format/unwrapping issue |
| Times off by hours | Timezone handling bug |
kubectl get pods -n taskflow
kubectl get pods -n taskflow -o wide # With node info# Main app logs
kubectl logs deploy/taskflow-api -n taskflow --tail=100
# Dapr sidecar logs
kubectl logs deploy/taskflow-api -n taskflow -c daprd --tail=100
# Follow logs in real-time
kubectl logs deploy/taskflow-api -n taskflow -f
# Logs from specific time
kubectl logs deploy/taskflow-api -n taskflow --since=5mkubectl describe pod <pod-name> -n taskflow
kubectl get events -n taskflow --sort-by='.lastTimestamp'# Shell into pod
kubectl exec -it deploy/taskflow-api -n taskflow -- /bin/sh
# Run specific command
kubectl exec deploy/taskflow-api -n taskflow -- env | grep DATABASESymptom: AttributeError: 'Model' has no attribute 'field'
Debug:
# Find the error
kubectl logs deploy/taskflow-api -n taskflow --tail=100 | grep -i "attribute"
# Check the model definition
grep -r "class Worker" apps/api/src/Fix: Ensure code references match actual model fields.
Symptom: 404 Not Found on internal service calls
Debug:
# Check what URL is being called
kubectl logs deploy/taskflow-api -n taskflow -c daprd --tail=100 | grep "404"
# Check what endpoints exist
kubectl exec deploy/taskflow-api -n taskflow -- curl localhost:8000/openapi.json | jq '.paths | keys'Fix: Match the callback URL to what the service exposes.
Symptom: Scheduled jobs fire at wrong times (hours off)
Debug:
# Check when job was scheduled vs when it should fire
kubectl logs deploy/taskflow-api -n taskflow | grep -i "scheduled"
# Compare times
# If local time 23:00 but scheduled for 23:00 UTC → timezone bugFix: Convert to UTC before storing/scheduling.
Symptom: Handler receives data but can't find expected fields
Debug:
# Add logging to see raw message
kubectl logs deploy/notification-service -n taskflow | grep -i "raw"
# Check message structure
# CloudEvent wraps payload in "data" fieldFix: Unwrap CloudEvent: event = raw.get("data", raw)
Symptom: greenlet_spawn has not been called
Debug:
# Find the line that crashes
kubectl logs deploy/notification-service -n taskflow | grep -A 20 "greenlet"Fix: Add await session.refresh(obj) after commit before accessing attributes.
# Dapr scheduler connection
kubectl logs deploy/taskflow-api -n taskflow -c daprd | grep -i "scheduler"
# Dapr API calls
kubectl logs deploy/taskflow-api -n taskflow -c daprd | grep "HTTP API Called"
# Dapr pub/sub
kubectl logs deploy/taskflow-api -n taskflow -c daprd | grep -i "publish"# What subscriptions are registered?
kubectl exec deploy/notification-service -n taskflow -- curl localhost:8001/dapr/subscribe# Publish test event from inside cluster
kubectl exec deploy/taskflow-api -n taskflow -- curl -X POST \
http://localhost:3500/v1.0/publish/taskflow-pubsub/test-topic \
-H "Content-Type: application/json" \
-d '{"test": true}'When investigating a production issue:
kubectl get pods)# GitHub Actions
gh run list --limit 5
# Check specific run
gh run view <run-id>
# Watch deployment
gh run watch# Check pod restart count (should be 0 for healthy pods)
kubectl get pods -n taskflow
# Check pod age (recent = just deployed)
kubectl get pods -n taskflow -o wide
# Verify new code is running
kubectl logs deploy/taskflow-api -n taskflow --tail=10 | head -5logger.info("[SERVICE] Received request: %s", request_summary)
logger.info("[SERVICE] Processing: step=%s, data=%s", step, safe_data)
logger.info("[SERVICE] Completed: result=%s", result_summary)
logger.error("[SERVICE] Failed: error=%s, context=%s", error, context)import uuid
@router.post("/tasks")
async def create_task(request: Request):
correlation_id = request.headers.get("X-Correlation-ID", str(uuid.uuid4()))
logger.info("[%s] Creating task", correlation_id)
# ... processing ...
logger.info("[%s] Task created: %d", correlation_id, task.id)def test_handles_missing_field():
"""Ensure graceful handling of missing data."""
response = client.post("/tasks", json={}) # Missing required field
assert response.status_code == 422 # Not 500!~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.