Transformando Incidentes em Guardrails
Incidentes sem guardrails se repetem. Guardrails são alertas, testes, regras de lint e checklists que tornam a mesma falha mais difícil ou visível mais cedo. Equipes Python os codificam em pytest, Ruff, revisão Alembic e alertas de queima de SLO.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
# pytest regressão do post-mortem INC-8842
def test_migration_uses_concurrently_for_large_tables():
sql = Path("alembic/versions/20260612_add_invoice_idx.py").read_text()
assert "CONCURRENTLY" in sql or "op.create_index" not in sql# Alerta: Indicador antecedente de profundidade da fila Celery
- alert: BillingQueueDepthHigh
expr: celery_queue_length{queue="billing"} > 10000
for: 5mQuando usar isso:
- Itens de ação pós-mortem precisam de entrega concreta
- A mesma classe de incidente ocorreu duas vezes em um trimestre
- Auditoria pede controles preventivos
- Fadiga de plantão por páginas barulhentas, mas evitáveis
Exemplo de Trabalho
"""guardrails_example.py - testes orientados por incidentes e verificações em tempo de execução."""
from __future__ import annotations
from dataclasses import dataclass
from pathlib import Path
@dataclass(frozen=True)
class Guardrail:
incident_id: str
kind: str # test | alert | lint | runbook
description: str
verify: str
GUARDRAILS: list[Guardrail] = [
Guardrail(
incident_id="INC-8842",
kind="test",
description="Índices de tabelas grandes usam CONCURRENTLY",
verify="pytest tests/test_migrations.py -k concurrently",
),
Guardrail(
incident_id="INC-9011",
kind="alert",
description="Taxa de queima do p95 do checkout",
verify="Grafana: CheckoutSLOBurn",
),
Guardrail(
incident_id="INC-9011",
kind="lint",
description="Sem sleep síncrono em rotas assíncronas",
verify="scripts/check_async_blocking.py no CI",
),
]
def audit_open_guardrails(registry: list[Guardrail]) -> None:
for g in registry:
print(f"[{g.incident_id}] {g.kind}: {g.description} -> {g.verify}")
if __name__ == "__main__":
audit_open_guardrails(GUARDRAILS)# tests/test_incident_9011_loop_block.py
import ast
from pathlib import Path
def test_no_time_sleep_in_async_functions():
src = Path("src/api/routes/checkout.py").read_text()
tree = ast.parse(src)
for node in ast.walk(tree):
if isinstance(node, ast.AsyncFunctionDef):
for child in ast.walk(node):
if isinstance(child, ast.Call):
func = child.func
if isinstance(func, ast.Attribute) and func.attr == "sleep":
raise AssertionError(f"time.sleep em async {node.name}")O que isso demonstra:
- Guardrails se conectam a IDs de incidentes para rastreabilidade
- Testes de regressão codificam mecânicas de falha específicas
- Scripts de CI capturam padrões de bloqueio assíncrono
- Revisão de operações audita comandos de verificação, não apenas o fechamento de tickets
Mergulho Profundo
Como Funciona
- Indicadores antecedentes - Profundidade da fila e espera do pool preveem 5xx antes que os clientes notem.
- Testes de regressão - Seguro barato; executado em todo PR que toca caminhos relacionados.
- Política de Lint/CI - Codifica itens de checklist de revisão que as máquinas aplicam.
- Atualizações de Runbook - Guardrails humanos quando a automação é impraticável.
- Métricas em guardrails - Rastreia o tempo médio para implementar itens de ação após SEV1.
Tipos de Guardrail
| Tipo | Exemplo | Verifica |
|---|---|---|
| Teste unitário/integração | Reexecuta SQL de migração ruim | CI verde |
| Teste de contrato | Esquema pydantic de API/worker | Mudança quebra bloqueada |
| Alerta | Queima de SLO 2x | Pager dispara em teste de staging |
| Regra customizada Ruff | Proíbe lru_cache(maxsize=None) | PR falha |
| Game day | Rollback em menos de 10m | RTO medido |
Notas Python
# pyproject.toml - pip-audit no CI
[tool.uv]
dev-dependencies = ["pip-audit>=2.7"]
# scripts/ci.sh
# uv run pip-audit -r requirements.lockArmadilhas
- Itens de ação que dizem "seja mais cuidadoso" - Não são guardrails. Correção: Exigir teste, alerta ou verificação automatizada por item.
- Alertas sem link para runbook - O plantão ignora ruído. Correção: Anotação aponta para etapas de mitigação.
- Testes que simulam o bug - A regressão nunca falha. Correção: Testar na fronteira de integração que falhou em produção.
- Guardrails em apenas um serviço - Equipe irmã repete o incidente. Correção: Plataforma promove o padrão para o repositório de template.
- Fechamento de tickets sem verificação - A deriva retorna. Correção: Revisão mensal de operações executa o comando
verifydo registro.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Checklist manual | Processo humano de baixa frequência | Falha técnica repetível |
| Mudança de arquitetura | Falha fundamental de design | Alerta único ausente |
| Remover funcionalidade | Risco excede valor | Caminho de receita principal |
| Engenharia do caos | Validar guardrail sob estresse | Antes que o monitoramento básico exista |
FAQs
Quantos guardrails por incidente?
Prefira 1-3 itens de alta alavancagem. Muitos diluem a propriedade.
Quem é o proprietário da entrega de guardrails?
O proprietário do serviço implementa; a plataforma é proprietária de templates compartilhados e hooks de CI.
Guardrails devem bloquear o deploy?
Sim para migrações e segurança. Apenas avisos para a primeira iteração, depois promova para falha forçada.
Como criar guardrails para problemas assíncronos?
Verificação estática de AST mais teste de tempo pytest sob carga concorrente no CI.
E sobre interrupções de terceiros?
Testes de circuit breaker e regressão de comportamento de fallback; runbook de comunicação de página de status.
Precisamos de um registro de guardrails?
Útil em escala - planilha ou YAML listando ID do incidente, comando verify, proprietário.
Como prevenir fadiga de alertas?
Ajuste os limiares com dados de incidentes; alerte sobre queima de SLO, não sobre picos únicos.
Aplicativos LLM podem ter guardrails?
Sim - suítes de avaliação para regressões de prompt, alertas de orçamento de tokens, testes de política de recusa.
Quando deletar um guardrail?
Quando o caminho do código for removido ou substituído por controle de plataforma. Documentar no changelog.
Como medir o sucesso?
Taxa de incidentes repetidos, tendência de MTTR e idade dos itens de ação < 30 dias.
Relacionados
- Post-Mortems e RCA sem Culpa - origem dos itens de ação
- Saúde do On-Call - alertas sustentáveis
- Modos Comuns de Falha de Produção - o que prevenir
- Testes pytest - página inicial de testes de regressão
- Linting e Formatação - política de CI
Versões de Stack: Esta página foi escrita para Python 3.14.0 (estável 3.14, manutenção 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, e uv 0.6+.