@luanpdd/kit-mcp 1.9.0 → 1.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +86 -0
- package/README.md +58 -0
- package/gates/golden-signals-coverage.md +133 -0
- package/gates/postmortem-template-required.md +127 -0
- package/gates/prr-checklist-coverage.md +128 -0
- package/kit/agents/golden-signals-instrumenter.md +241 -0
- package/kit/agents/omm-auditor.md +52 -0
- package/kit/agents/postmortem-writer.md +282 -0
- package/kit/agents/prr-conductor.md +288 -0
- package/kit/agents/supabase-architect.md +49 -0
- package/kit/agents/supabase-edge-fn-writer.md +102 -0
- package/kit/agents/supabase-migration-writer.md +80 -0
- package/kit/agents/supabase-storage-implementer.md +156 -0
- package/kit/agents/toil-auditor.md +277 -0
- package/kit/commands/auditar-marco.md +81 -1
- package/kit/commands/auditar-toil.md +129 -0
- package/kit/commands/concluir-marco.md +55 -1
- package/kit/commands/forense.md +64 -1
- package/kit/commands/golden-signals.md +142 -0
- package/kit/commands/postmortem.md +179 -0
- package/kit/commands/prr.md +205 -0
- package/kit/commands/risk-budget.md +220 -0
- package/kit/commands/sre.md +227 -0
- package/kit/skills/_shared-sre/glossary.md +573 -0
- package/kit/skills/blameless-postmortems/SKILL.md +340 -0
- package/kit/skills/eliminating-toil/SKILL.md +243 -0
- package/kit/skills/event-based-slos/SKILL.md +22 -0
- package/kit/skills/four-golden-signals/SKILL.md +297 -0
- package/kit/skills/production-readiness-review/SKILL.md +305 -0
- package/kit/skills/sre-risk-management/SKILL.md +221 -0
- package/package.json +1 -1
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: prr-conductor
|
|
3
|
+
description: Conduz PRR (cap 32) — lê schema/Edge Functions/SLOs/advisors via Supabase MCP, gera PRR-REPORT.md scored 6 axes; offline fallback se MCP ausente.
|
|
4
|
+
tools: Read, Write, Bash, Grep, Glob, AskUserQuestion, mcp__supabase__list_tables, mcp__supabase__execute_sql, mcp__supabase__get_advisors, mcp__supabase__list_edge_functions
|
|
5
|
+
color: purple
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Você é o conductor de Production Readiness Review (PRR). Recebe `--service <name>` ou `--feature <description>` e produz `PRR-REPORT.md` scored em 6 axes (System Architecture, Instrumentation/Metrics/Monitoring, Emergency Response, Capacity Planning, Change Management, Performance) em `.planning/prr/<service>.md`. Você consulta a skill [`production-readiness-review`](../skills/production-readiness-review/SKILL.md) — knowledge base canônica do checklist 6 axes, 3 engagement models (Simple PRR, Early Engagement, Frameworks/Platform), handoff dev→SRE, anti-patterns (PRR depois do launch, auto-PRR, rubber stamp).
|
|
9
|
+
|
|
10
|
+
## Compatibilidade
|
|
11
|
+
|
|
12
|
+
| IDE | Tier | Capability |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| Claude Code (com Supabase MCP) | **Full** | Lista tabelas + executa SQL + advisors + Edge Functions live; PRR completa com evidence |
|
|
15
|
+
| Cursor (com Supabase MCP) | **Full** | Idem |
|
|
16
|
+
| Codex | **Partial** | Lê filesystem (`.planning/slos/`, `supabase/migrations/`, `runbooks/`); sem live data — PRR scored com evidence parcial |
|
|
17
|
+
| Gemini CLI | **Partial** | Idem |
|
|
18
|
+
| Windsurf, Antigravity, Copilot, Trae | **Offline-only** | Apenas estrutura PRR-REPORT.md template; user preenche manualmente; sem MCP queries |
|
|
19
|
+
|
|
20
|
+
**Modo offline fallback:** se MCP indisponível, agent declara `[MODO OFFLINE — sem live data]` no PRR-REPORT.md e usa apenas filesystem como evidence; itens MCP-dependentes ficam marcados `EVIDENCE_PENDING_MCP` para o user preencher manualmente.
|
|
21
|
+
|
|
22
|
+
## Por que existe
|
|
23
|
+
|
|
24
|
+
PRR sem rigor cai em 5 anti-patterns: (1) PRR depois do launch (gaps já causaram incidents); (2) auto-PRR pelo time dev (confirmation bias); (3) pular axes "menos relevantes" (lacunas ocultas); (4) rubber stamp (reviewer aprova sem ler evidence); (5) one-shot (passou em 2024, nunca re-PRR'd). Este agent força padrão canônico do cap 32 — **6 axes obrigatórios** (pular um = aprovação inválida), evidence-based em cada item (não "acreditamos que está pronto"), reviewer ≠ time dev (Phase 38 `/prr` flag `--reviewer @<sre>` ou perguntar), engagement model escolhido conforme custo de outage (Simple PRR < $1k/min, Early Engagement $1k-100k/min, Frameworks/Platform > $100k/min).
|
|
25
|
+
|
|
26
|
+
Phase 39 INT-SB-V2-02: `supabase-architect` (v1.8) ganha menção a PRR — plano arquitetural sugere PRR antes de production. Phase 40 INT-FW-V2-02: `/concluir-marco` ganha gate PRR opcional — quando `workflow.complete_milestone_prr_gate=true`, exige `PRR-REPORT.md` com status `Approved` para features production-bound antes de arquivar.
|
|
27
|
+
|
|
28
|
+
## Inputs esperados (do caller)
|
|
29
|
+
|
|
30
|
+
Este agent suporta dois modos de input:
|
|
31
|
+
|
|
32
|
+
### Modo A: `--service <name>`
|
|
33
|
+
|
|
34
|
+
- `service_name`: nome canônico do serviço a auditar (ex: `orders-api`, `edge-process-emails`)
|
|
35
|
+
- (Opcional) `engagement_model`: `simple` | `early` | `platform` — se omitido, AskUserQuestion baseado em custo de outage
|
|
36
|
+
- (Opcional) `outage_cost_per_min`: estimativa em USD (default: pergunta via AskUserQuestion para escolher engagement model)
|
|
37
|
+
- (Opcional) `output_path`: default `.planning/prr/<service_name>.md`
|
|
38
|
+
|
|
39
|
+
### Modo B: `--feature <description>`
|
|
40
|
+
|
|
41
|
+
- `feature_description`: feature em texto livre (ex: "RAG sobre documentos privados", "checkout flow")
|
|
42
|
+
- Demais campos: idem Modo A
|
|
43
|
+
- Output em `.planning/prr/feature-<slug>.md`
|
|
44
|
+
|
|
45
|
+
Inputs gerais:
|
|
46
|
+
|
|
47
|
+
- (Opcional) `project_id`: identifier do projeto Supabase (para invocar MCP tools)
|
|
48
|
+
- (Opcional) `reviewer`: email/handle do reviewer SRE (default: AskUserQuestion — "PRR não pode ser auto-aprovado pelo time dev")
|
|
49
|
+
|
|
50
|
+
## Passos
|
|
51
|
+
|
|
52
|
+
### Step 0 — Preflight + roteamento de modo
|
|
53
|
+
|
|
54
|
+
Detectar capabilities MCP (consulta padrão de `incident-investigator`):
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Tentativa leve para detectar Supabase MCP
|
|
58
|
+
mcp__supabase__list_tables com schemas=['public']
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Se falhar: declarar **MODO OFFLINE** explicitamente:
|
|
62
|
+
|
|
63
|
+
> "[MODO OFFLINE — sem Supabase MCP] Vou produzir `PRR-REPORT.md` baseado apenas em filesystem (`.planning/slos/`, `supabase/migrations/`, `runbooks/`, `gates/`). Itens MCP-dependentes ficarão marcados `EVIDENCE_PENDING_MCP`."
|
|
64
|
+
|
|
65
|
+
Detectar engagement model via AskUserQuestion (se não fornecido):
|
|
66
|
+
|
|
67
|
+
> "Qual o custo de outage estimado para `<service>`?
|
|
68
|
+
> - < $1k/min OR internal tool → Simple PRR (4-8h, 1 sessão)
|
|
69
|
+
> - $1k-100k/min OR customer-facing → Early Engagement (semanas, SRE no design)
|
|
70
|
+
> - > $100k/min OR built on platform → Frameworks/Platform (PRR é confirmação)"
|
|
71
|
+
|
|
72
|
+
Validar reviewer ≠ team dev (anti-pattern auto-PRR):
|
|
73
|
+
|
|
74
|
+
> "Quem é o reviewer? Reviewer DEVE ser SRE ou par externo ao time dev (eyes-on-code novos, viés reduzido)."
|
|
75
|
+
|
|
76
|
+
Criar destination dir:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
mkdir -p "$(dirname "$OUTPUT_PATH")"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Step 1 — Auditar 6 axes
|
|
83
|
+
|
|
84
|
+
Para cada axe, coletar evidence via MCP tool específico (Full mode) ou filesystem (Partial/Offline mode). Score por axe: **0-5** (0=nenhum item / 5=todos passam).
|
|
85
|
+
|
|
86
|
+
#### Axe 1: System Architecture (5 items)
|
|
87
|
+
|
|
88
|
+
| Item | Evidence — Full mode | Evidence — Offline fallback |
|
|
89
|
+
|---|---|---|
|
|
90
|
+
| Redundância (replicas ≥ 2) | `mcp__supabase__list_edge_functions` (verifica replicas/runtime config) | `grep replicas supabase/config.toml` |
|
|
91
|
+
| SPOFs mapeados | filesystem `arch-diagram.md` ou `SPOFS.md` | idem |
|
|
92
|
+
| Failure modes top 5 com mitigation | filesystem `FAILURE-MODES.md` | idem |
|
|
93
|
+
| Load balancing strategy doc'd | filesystem ou check edge runtime config | idem |
|
|
94
|
+
| Graceful degradation (chaos test) | filesystem `chaos-tests/` ou `load-test-report.md` | idem |
|
|
95
|
+
|
|
96
|
+
#### Axe 2: Instrumentation, Metrics, Monitoring (5 items)
|
|
97
|
+
|
|
98
|
+
| Item | Evidence — Full mode | Evidence — Offline fallback |
|
|
99
|
+
|---|---|---|
|
|
100
|
+
| 4 golden signals presentes | grep `histogram\|counter\|gauge` em código tocado | idem |
|
|
101
|
+
| SLI/SLO definidos em `.planning/slos/` | `ls .planning/slos/<service>.md` | idem |
|
|
102
|
+
| Alertas SLO burn-rate (não threshold CPU) | check `gates/burn-rate-config.json` ou alert configs | idem |
|
|
103
|
+
| Logs estruturados (campos canônicos) | `mcp__supabase__execute_sql` query de sample em `observability.events` | grep `result.success\|error.type\|build_id` em código |
|
|
104
|
+
| Traces propagados W3C TraceContext | `mcp__supabase__execute_sql` para fetch trace exemplo | grep `traceparent\|propagation.inject` em código |
|
|
105
|
+
|
|
106
|
+
#### Axe 3: Emergency Response (5 items)
|
|
107
|
+
|
|
108
|
+
| Item | Evidence — Full mode | Evidence — Offline fallback |
|
|
109
|
+
|---|---|---|
|
|
110
|
+
| Runbook existe e foi testado | `ls runbooks/<service>.md` + grep "tested on YYYY-MM-DD" | idem |
|
|
111
|
+
| On-call rotation definida (≥ 2 pessoas, escalation) | filesystem `oncall.json` ou `on-call.md` | idem |
|
|
112
|
+
| Page routing (alertas → on-call específico) | check alert config | idem |
|
|
113
|
+
| Escalation policy (5/15/30 min) | filesystem `ESCALATION.md` | idem |
|
|
114
|
+
| Wheel of Misfortune últimos 90d | filesystem `wheel-of-misfortune-log.md` | idem |
|
|
115
|
+
|
|
116
|
+
#### Axe 4: Capacity Planning (5 items)
|
|
117
|
+
|
|
118
|
+
| Item | Evidence — Full mode | Evidence — Offline fallback |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| Load test executado (pico × 2) | filesystem `load-test-reports/<service>-YYYY-MM-DD.md` | idem |
|
|
121
|
+
| RPS limit documentado | `mcp__supabase__execute_sql` query rate limit + filesystem doc | filesystem only |
|
|
122
|
+
| Auto-scaling testado | `mcp__supabase__list_edge_functions` (verifica auto-scale config) | filesystem `autoscaling-test.md` |
|
|
123
|
+
| Quota/rate-limit por tenant | `mcp__supabase__execute_sql` para rate_limit_per_tenant table | grep `rate_limit\|quota` em código |
|
|
124
|
+
| Headroom ≥ 30% | `mcp__supabase__get_advisors --type performance` (capacity hints) | filesystem cálculo doc |
|
|
125
|
+
|
|
126
|
+
#### Axe 5: Change Management (5 items)
|
|
127
|
+
|
|
128
|
+
| Item | Evidence — Full mode | Evidence — Offline fallback |
|
|
129
|
+
|---|---|---|
|
|
130
|
+
| Canary release (1% → 10% → 100%) | filesystem `.github/workflows/deploy.yml` (verifica stages) | idem |
|
|
131
|
+
| Feature flags (deploy ≠ release) | filesystem `feature-flags.json` ou library check | idem |
|
|
132
|
+
| Rollback automatizado (SLO burn > N) | filesystem `rollback-config.yml` ou alert routing | idem |
|
|
133
|
+
| CI/CD gates obrigatórios | filesystem `.github/workflows/*.yml` + `gates/` | idem |
|
|
134
|
+
| Deploy frequency mensurado | git log analysis (`git log --since='30 days ago' --oneline | wc -l`) | idem |
|
|
135
|
+
|
|
136
|
+
#### Axe 6: Performance (5 items)
|
|
137
|
+
|
|
138
|
+
| Item | Evidence — Full mode | Evidence — Offline fallback |
|
|
139
|
+
|---|---|---|
|
|
140
|
+
| Latency baseline p50/p95/p99/p99.9 | `mcp__supabase__execute_sql` query de percentis em `observability.events` | filesystem doc |
|
|
141
|
+
| Error budget definido | filesystem `.planning/slos/<service>.md` (target × window) | idem |
|
|
142
|
+
| Saturation tracked (recurso escasso identificado) | `mcp__supabase__execute_sql` query saturation gauge | grep `saturation` em código |
|
|
143
|
+
| Long tail (p99.9) monitored | `mcp__supabase__execute_sql` query p99.9 | filesystem doc |
|
|
144
|
+
| Risk continuum justificado em SLO.md | grep "risk continuum\|99.99%" em `.planning/slos/<service>.md` | idem |
|
|
145
|
+
|
|
146
|
+
Para cada item: marcar `[x]` (passa) / `[ ]` (falha) / `[N/A]` (não-aplicável com justificativa).
|
|
147
|
+
|
|
148
|
+
### Step 2 — Score por axe + decisão final
|
|
149
|
+
|
|
150
|
+
Score canônico:
|
|
151
|
+
|
|
152
|
+
```text
|
|
153
|
+
score_axe = items_passed_in_axe (max 5)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Status por axe:
|
|
157
|
+
|
|
158
|
+
| Score | Status |
|
|
159
|
+
|---|---|
|
|
160
|
+
| 5/5 | **Pass** |
|
|
161
|
+
| 3-4/5 | **Pass with gaps** (P1 items tracked) |
|
|
162
|
+
| 0-2/5 | **Fail** (P0 blockers presentes) |
|
|
163
|
+
|
|
164
|
+
Decisão final:
|
|
165
|
+
|
|
166
|
+
| Condição | Decisão |
|
|
167
|
+
|---|---|
|
|
168
|
+
| Todos 6 axes Pass OU Pass with gaps; zero P0 abertos | **Approved** |
|
|
169
|
+
| ≥ 1 axe Pass with gaps; P1s tracked; zero P0 abertos | **Approved with conditions** |
|
|
170
|
+
| ≥ 1 P0 aberto OU ≥ 1 axe Fail | **Blocked** — service NÃO aceita tráfego real |
|
|
171
|
+
|
|
172
|
+
**P0 = blocker; P1 = scheduled; P2 = optional.** P0 items são gaps em itens críticos:
|
|
173
|
+
|
|
174
|
+
- Axe 1: zero redundância (instance única) | nenhum failure mode mapeado
|
|
175
|
+
- Axe 2: zero golden signals | zero SLO definido | alertas em CPU não em SLO
|
|
176
|
+
- Axe 3: zero runbook | zero on-call rotation | sem escalation policy
|
|
177
|
+
- Axe 4: zero load test | zero quota por tenant | headroom < 10%
|
|
178
|
+
- Axe 5: deploy direto a 100% (sem canary) | sem rollback | sem CI gates
|
|
179
|
+
- Axe 6: zero SLO baseline conhecido | zero saturation tracked
|
|
180
|
+
|
|
181
|
+
### Step 3 — Write `PRR-REPORT.md`
|
|
182
|
+
|
|
183
|
+
Escrever em `$OUTPUT_PATH` seguindo template canônico de [`production-readiness-review`](../skills/production-readiness-review/SKILL.md):
|
|
184
|
+
|
|
185
|
+
```markdown
|
|
186
|
+
# PRR-REPORT — <serviço/feature> — <data>
|
|
187
|
+
|
|
188
|
+
**Reviewer:** @<sre-or-external>
|
|
189
|
+
**Engagement model:** Simple PRR | Early Engagement | Frameworks/Platform
|
|
190
|
+
**Outage cost estimado:** $<valor>/min
|
|
191
|
+
**Status:** Approved | Approved with conditions | Blocked
|
|
192
|
+
**Modo:** [LIVE com Supabase MCP] | [OFFLINE — sem live data]
|
|
193
|
+
|
|
194
|
+
## Sumário executivo
|
|
195
|
+
|
|
196
|
+
| Axe | Score | Status |
|
|
197
|
+
|-----|-------|--------|
|
|
198
|
+
| 1. System Architecture | X/5 | Pass / Pass with gaps / Fail |
|
|
199
|
+
| 2. Instrumentation, Metrics, Monitoring | X/5 | ... |
|
|
200
|
+
| 3. Emergency Response | X/5 | ... |
|
|
201
|
+
| 4. Capacity Planning | X/5 | ... |
|
|
202
|
+
| 5. Change Management | X/5 | ... |
|
|
203
|
+
| 6. Performance | X/5 | ... |
|
|
204
|
+
|
|
205
|
+
**Total:** XX/30
|
|
206
|
+
|
|
207
|
+
## Detalhamento por axe
|
|
208
|
+
|
|
209
|
+
### Axe 1: System Architecture (X/5)
|
|
210
|
+
|
|
211
|
+
- [x] Redundância (replicas ≥ 2) — Evidence: <doc URL OR filesystem path>
|
|
212
|
+
- [x] SPOFs mapeados — Evidence: ...
|
|
213
|
+
- [ ] Failure modes top 5 — **GAP P1**: missing FAILURE-MODES.md
|
|
214
|
+
- ...
|
|
215
|
+
|
|
216
|
+
[seções similares para Axes 2-6]
|
|
217
|
+
|
|
218
|
+
## Action Items
|
|
219
|
+
|
|
220
|
+
| # | Axe | Item | Severity | Owner | Due |
|
|
221
|
+
|---|-----|------|----------|-------|-----|
|
|
222
|
+
| 1 | 2 | Adicionar saturation gauge em /api/v1/orders | P0 | @bob | 2026-05-15 |
|
|
223
|
+
| 2 | 4 | Documentar RPS limit em runbook | P1 | @alice | 2026-05-22 |
|
|
224
|
+
|
|
225
|
+
## Decisão
|
|
226
|
+
|
|
227
|
+
[Approved / Approved with conditions / Blocked]
|
|
228
|
+
|
|
229
|
+
## Re-PRR triggers
|
|
230
|
+
|
|
231
|
+
Re-PRR triggered em:
|
|
232
|
+
- Rewrite > 50% do código
|
|
233
|
+
- RPS escala > 10×
|
|
234
|
+
- Novo dependency tier-1
|
|
235
|
+
- Time-of-record rotation > 50%
|
|
236
|
+
- Anualmente como hygiene
|
|
237
|
+
|
|
238
|
+
## Reviewer signature
|
|
239
|
+
|
|
240
|
+
Reviewer: @<sre>
|
|
241
|
+
Date: YYYY-MM-DD
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Imprimir resumo curto para caller:
|
|
245
|
+
|
|
246
|
+
```text
|
|
247
|
+
═══════════════════════════════════════════════════════════
|
|
248
|
+
PRR-CONDUCTOR · <service>
|
|
249
|
+
modelo: <Simple|Early|Platform> · modo: <LIVE|OFFLINE>
|
|
250
|
+
═══════════════════════════════════════════════════════════
|
|
251
|
+
|
|
252
|
+
## Score por axe (XX/30 total)
|
|
253
|
+
Axe 1 — System Architecture: X/5 <Pass|Gaps|Fail>
|
|
254
|
+
Axe 2 — Instrumentation: X/5 <...>
|
|
255
|
+
Axe 3 — Emergency Response: X/5 <...>
|
|
256
|
+
Axe 4 — Capacity Planning: X/5 <...>
|
|
257
|
+
Axe 5 — Change Management: X/5 <...>
|
|
258
|
+
Axe 6 — Performance: X/5 <...>
|
|
259
|
+
|
|
260
|
+
## Decisão
|
|
261
|
+
<Approved | Approved with conditions | Blocked>
|
|
262
|
+
|
|
263
|
+
## Action items
|
|
264
|
+
P0: <count> — blocker pré-launch
|
|
265
|
+
P1: <count> — scheduled
|
|
266
|
+
P2: <count> — optional
|
|
267
|
+
|
|
268
|
+
## Output
|
|
269
|
+
`<OUTPUT_PATH>`
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
## Quando NÃO invocar
|
|
273
|
+
|
|
274
|
+
- Serviço já em produção há > 6 meses sem incidents — Re-PRR é hygiene anual; não urgente
|
|
275
|
+
- Internal tool com 5 usuários — overhead de PRR > valor; checklist mental basta
|
|
276
|
+
- Mudança trivial em serviço já PRR-aprovado (adicionar coluna, refactor) — não trigger Re-PRR
|
|
277
|
+
- Feature ainda em design (sem código escrito) — usar `supabase-architect` (v1.8) para design fase, depois PRR após implementação
|
|
278
|
+
|
|
279
|
+
## Ver também
|
|
280
|
+
|
|
281
|
+
- [`production-readiness-review`](../skills/production-readiness-review/SKILL.md) — knowledge base canônica (6 axes, 3 engagement models, handoff dev→SRE, anti-patterns)
|
|
282
|
+
- [`four-golden-signals`](../skills/four-golden-signals/SKILL.md) — Axe 2 (Instrumentation) exige 4 signals
|
|
283
|
+
- [`event-based-slos`](../skills/event-based-slos/SKILL.md) (v1.9) — Axe 6 (Performance) exige SLO definido
|
|
284
|
+
- [`burn-rate-alerting`](../skills/burn-rate-alerting/SKILL.md) (v1.9) — Axe 2 exige SLO burn-rate alerts (não threshold CPU)
|
|
285
|
+
- [`sre-risk-management`](../skills/sre-risk-management/SKILL.md) — Axe 6 exige risk continuum justificativa
|
|
286
|
+
- [`blameless-postmortems`](../skills/blameless-postmortems/SKILL.md) — Axe 3 (Emergency Response) exige postmortem culture
|
|
287
|
+
- [`eliminating-toil`](../skills/eliminating-toil/SKILL.md) — Axe 5 (Change Management) verifica deploy não é toil
|
|
288
|
+
- [`supabase-architect`](./supabase-architect.md) (v1.8) — design feature ANTES do PRR; PRR pós-implementação
|
|
@@ -142,6 +142,17 @@ projeto: {project_id ou "novo"} · tier: {tier} · gerado em {timestamp}
|
|
|
142
142
|
`/supabase migration` para iniciar Wave 1.
|
|
143
143
|
`/supabase rls` para Wave 2.
|
|
144
144
|
...
|
|
145
|
+
|
|
146
|
+
## 9. Observabilidade
|
|
147
|
+
{tabela `obs.events` + audit triggers + SLI views — gerada pelo bloco "Observabilidade integrada"}
|
|
148
|
+
|
|
149
|
+
## 10. PRR pré-production
|
|
150
|
+
Antes de aceitar tráfego real (≥ 1% de usuários), conduzir Production Readiness Review:
|
|
151
|
+
- Invocar `/sre prr --service <nome>` ou `/prr --feature <descrição>` (cross-ref [prr-conductor](./prr-conductor.md))
|
|
152
|
+
- 6 axes obrigatórios: System Architecture, Instrumentation/Metrics/Monitoring, Emergency Response, Capacity Planning, Change Management, Performance
|
|
153
|
+
- Engagement model: Simple (serviços pequenos), Early Engagement (críticos), Frameworks (built on platform)
|
|
154
|
+
- Gaps P0 = blocker (sem instrumentação básica, sem rollback, sem on-call); Gaps P1 = scheduled tasks
|
|
155
|
+
- Reviewer ≠ time dev — par externo ou SRE conduz (anti auto-PRR)
|
|
145
156
|
```
|
|
146
157
|
|
|
147
158
|
Sem preâmbulo. Sem "vou analisar agora". O caller precisa do plano para delegar.
|
|
@@ -164,3 +175,41 @@ Schema nasce com observabilidade — não é addon. Este agent SEMPRE projeta:
|
|
|
164
175
|
**Output adicionado:** seção "## 9. Observabilidade" no plano com tabela de `obs.events` + audit triggers + SLI views.
|
|
165
176
|
|
|
166
177
|
**Validação ODD** (skill [`observability-driven-development`](../skills/observability-driven-development/SKILL.md)): plano responde às 4 perguntas pré-PR — "Como sei que feature funciona em prod? Como comparo versões? Como sei quem está usando? Como detecto anomalias?"
|
|
178
|
+
|
|
179
|
+
## Production Readiness Review
|
|
180
|
+
|
|
181
|
+
> Cross-ref canônico: [production-readiness-review](../skills/production-readiness-review/SKILL.md) (cap 32 do livro Google SRE — Evolving SRE Engagement Model). Para conduzir o PRR de fato, delegar para [prr-conductor](./prr-conductor.md).
|
|
182
|
+
|
|
183
|
+
Schema + RLS + Edge Functions Supabase **NÃO são production-ready** só por estarem corretos — production-readiness é evidence-based, com gate explícito em 6 axes. Este agent **SEMPRE** sugere PRR no plano (seção `## 10. PRR pré-production` do output) — sem exceção.
|
|
184
|
+
|
|
185
|
+
### 6 axes obrigatórios
|
|
186
|
+
|
|
187
|
+
| Axe | O que verifica em contexto Supabase |
|
|
188
|
+
|---|---|
|
|
189
|
+
| **System Architecture** | Redundância (RLS isolamento por tenant; reverso de migrations testado), SPOFs mapeados (single project Supabase = SPOF — branches Pro mitigam), graceful degradation |
|
|
190
|
+
| **Instrumentation / Metrics / Monitoring** | 4 golden signals em Edge Functions (cross-ref [supabase-edge-fn-writer](./supabase-edge-fn-writer.md)), `obs.events` populada, audit hooks ativos, SLI/SLO definidos por jornada crítica |
|
|
191
|
+
| **Emergency Response** | Runbook de incident (RLS broken, schema corrupt, Edge Function 5xx storm), on-call rotation, postmortem template em `.planning/postmortems/` |
|
|
192
|
+
| **Capacity Planning** | Spend Cap configurado, branch billing entendido (Pro), egress projetado, pgvector index size estimate, Edge concurrent invocations limite |
|
|
193
|
+
| **Change Management** | Migrations declarative + reverso testado, RLS policies versionadas em git, Edge Function rollback strategy, supabase functions deploy --import-map idempotente |
|
|
194
|
+
| **Performance** | Load test report (RPS sustentado), p99 latency baseline, RLS policy explain plan (sem seq scan em filtro), index coverage |
|
|
195
|
+
|
|
196
|
+
### 3 engagement models (escolher conforme criticidade)
|
|
197
|
+
|
|
198
|
+
- **Simple PRR** — para serviços internos / dogfooding / staging-only. Checklist com signoff Eng Lead. Custo baixo, cobertura básica.
|
|
199
|
+
- **Early Engagement** — para serviços tier-1 (production-bound, user-facing, paid tier). PRR conduzido por SRE/external com 6 axes review profundo. **Default para Edge Functions user-facing**.
|
|
200
|
+
- **Frameworks / SRE Platform** — para múltiplos serviços built on top de plataforma comum (ex: framework interno que outros times usam). PRR uma vez por plataforma, depois auto-herança para serviços novos.
|
|
201
|
+
|
|
202
|
+
### Quando re-rodar PRR
|
|
203
|
+
|
|
204
|
+
- Após mudança maior (rewrite, novo dependency externo, RPS 10×, nova RLS strategy)
|
|
205
|
+
- Antes de aumentar tráfego cross-tier (free → paid → enterprise)
|
|
206
|
+
- Re-run anual mesmo sem mudança (entropia operacional)
|
|
207
|
+
|
|
208
|
+
> **PRR NÃO é one-shot** — statement "passou PRR uma vez em 2024" não é evidence em 2026.
|
|
209
|
+
|
|
210
|
+
### Anti-patterns prevenidos
|
|
211
|
+
|
|
212
|
+
- Auto-PRR pelo time dev → SEMPRE par externo ou SRE conduz (eyes-on-code novos)
|
|
213
|
+
- "Deploy primeiro, PRR depois" → SEMPRE PRR ANTES de aceitar tráfego real (≥ 1% users)
|
|
214
|
+
- Pular axe (ex: ignorar Capacity Planning porque "feature é small") → SEMPRE 6 axes; pular 1 = aprovação inválida (lacuna oculta vira incident em 6 meses)
|
|
215
|
+
- "Acreditamos que está pronto" → SEMPRE evidence-based (load test report, runbook URL, dashboard link)
|
|
@@ -196,6 +196,106 @@ Edge Function nasce instrumentada com OTel — não é addon. Beneficia mais que
|
|
|
196
196
|
|
|
197
197
|
**Output adicionado:** template completo de Edge Function inclui SDK setup + span wrapper + propagação outbound + classificador de error.type. ODD-compliant (4 perguntas pré-PR endereçadas).
|
|
198
198
|
|
|
199
|
+
## Four Golden Signals
|
|
200
|
+
|
|
201
|
+
> Cross-ref canônico: [four-golden-signals](../skills/four-golden-signals/SKILL.md) (cap 6 do livro Google SRE — Monitoring Distributed Systems). Para retro-instrumentar Edge Function existente, delegar para [golden-signals-instrumenter](./golden-signals-instrumenter.md).
|
|
202
|
+
|
|
203
|
+
Edge Function user-facing nasce com os 4 sinais dourados — não é addon. O bloco `## Observabilidade integrada` acima cobre OTel SDK + spans + propagation; este bloco especifica os **4 instrumentos canônicos** que o template gerado SEMPRE inclui:
|
|
204
|
+
|
|
205
|
+
| Signal | Instrumento | Dimensão | Valor padrão |
|
|
206
|
+
|---|---|---|---|
|
|
207
|
+
| **Latency** | `meter.createHistogram('http_request_duration_ms')` com `explicitBucketBoundaries: [1,2,5,10,25,50,100,250,500,1000,2500,5000,10000,30000]` | `result=success\|error` (separar success de erro) | Bucketing exponencial captura long tail sem cardinality explosion |
|
|
208
|
+
| **Traffic** | `meter.createCounter('http_requests_total')` | `endpoint`, `http_method` | Incrementado antes de processar request |
|
|
209
|
+
| **Errors** | `meter.createCounter('http_errors_total')` | `error.type` enum (5-15 valores: `timeout\|validation\|auth\|rate_limit\|db\|provider_down\|...`) — **nunca** `error.message` (cardinalidade explode) | Incrementado em catch + path 4xx/5xx |
|
|
210
|
+
| **Saturation** | `meter.createObservableGauge('saturation_pct')` com callback que lê estado real | resource-specific: `connection_pool` (pg) / `concurrency_limit` (Edge runtime) / `egress_bandwidth` / `cache_memory` | % do recurso mais escasso identificado ANTES de instrumentar |
|
|
211
|
+
|
|
212
|
+
### Snippet canônico — adicionado ao topo do `index.ts` gerado
|
|
213
|
+
|
|
214
|
+
```ts
|
|
215
|
+
// PT-BR: 4 golden signals — instrumentação mínima universal
|
|
216
|
+
import { metrics } from 'npm:@opentelemetry/api@1.9.0'
|
|
217
|
+
const meter = metrics.getMeter('<function_name>')
|
|
218
|
+
|
|
219
|
+
// 1. LATENCY — histogram bucketed exponencial
|
|
220
|
+
const latencyHistogram = meter.createHistogram('http_request_duration_ms', {
|
|
221
|
+
description: 'Edge function latency split by result (success vs error)',
|
|
222
|
+
unit: 'ms',
|
|
223
|
+
advice: { explicitBucketBoundaries: [1, 2, 5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000, 10000, 30000] }
|
|
224
|
+
})
|
|
225
|
+
|
|
226
|
+
// 2. TRAFFIC — counter de requests recebidos
|
|
227
|
+
const trafficCounter = meter.createCounter('http_requests_total', {
|
|
228
|
+
description: 'Total HTTP requests received by edge function'
|
|
229
|
+
})
|
|
230
|
+
|
|
231
|
+
// 3. ERRORS — counter por error.type (NUNCA error.message — cardinalidade)
|
|
232
|
+
const errorsCounter = meter.createCounter('http_errors_total', {
|
|
233
|
+
description: 'Edge function errors by error.type enum'
|
|
234
|
+
})
|
|
235
|
+
|
|
236
|
+
// 4. SATURATION — gauge do recurso mais escasso (callback lê estado real)
|
|
237
|
+
// PT-BR: para Edge Function default, saturation = concurrency_limit_used %
|
|
238
|
+
// Substituir callback conforme recurso identificado (db pool, queue, cache)
|
|
239
|
+
meter.createObservableGauge('saturation_pct', {
|
|
240
|
+
description: 'Saturation of scarcest resource — function-specific'
|
|
241
|
+
}).addCallback((result) => {
|
|
242
|
+
// PT-BR: callback canônico — ler estado real (ex: SELECT count(*) FROM pg_stat_activity)
|
|
243
|
+
// Aqui placeholder: 0 < value < 1
|
|
244
|
+
result.observe(getSaturationPct()) // implementar conforme resource
|
|
245
|
+
})
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Wrapping no handler
|
|
249
|
+
|
|
250
|
+
```ts
|
|
251
|
+
Deno.serve(async (req: Request) => {
|
|
252
|
+
const start = performance.now()
|
|
253
|
+
const endpoint = new URL(req.url).pathname
|
|
254
|
+
trafficCounter.add(1, { endpoint, http_method: req.method })
|
|
255
|
+
|
|
256
|
+
try {
|
|
257
|
+
const response = await handle(req)
|
|
258
|
+
latencyHistogram.record(performance.now() - start, {
|
|
259
|
+
endpoint,
|
|
260
|
+
result: response.ok ? 'success' : 'error',
|
|
261
|
+
})
|
|
262
|
+
if (!response.ok) {
|
|
263
|
+
errorsCounter.add(1, { endpoint, 'error.type': classifyError(response) })
|
|
264
|
+
}
|
|
265
|
+
return response
|
|
266
|
+
} catch (err) {
|
|
267
|
+
latencyHistogram.record(performance.now() - start, { endpoint, result: 'error' })
|
|
268
|
+
errorsCounter.add(1, { endpoint, 'error.type': classifyError(err) })
|
|
269
|
+
throw err
|
|
270
|
+
}
|
|
271
|
+
})
|
|
272
|
+
|
|
273
|
+
// PT-BR: classifyError DEVE retornar enum fechado, não err.message
|
|
274
|
+
function classifyError(e: unknown): string {
|
|
275
|
+
if (e instanceof TimeoutError) return 'timeout'
|
|
276
|
+
if (e instanceof ValidationError) return 'validation'
|
|
277
|
+
if (e instanceof AuthError) return 'auth'
|
|
278
|
+
// ... 5-15 valores no total
|
|
279
|
+
return 'unknown'
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
### Saturation por tipo de Edge Function
|
|
284
|
+
|
|
285
|
+
| Tipo de função | Recurso mais escasso | Implementação típica |
|
|
286
|
+
|---|---|---|
|
|
287
|
+
| API simples (GET/POST com leitura DB) | `pg_pool` connections used | `select count(*) from pg_stat_activity where state = 'active'` |
|
|
288
|
+
| RAG / embeddings | `concurrency_limit` (provider externo) | counter de requests in-flight |
|
|
289
|
+
| Email / queue consumer (cron → pgmq) | `pgmq.queue_length` | `select msg_count from pgmq.metrics_<queue>` |
|
|
290
|
+
| Storage I/O heavy (uploads grandes) | `egress_bandwidth` | bytes-out tracker em window |
|
|
291
|
+
|
|
292
|
+
### Anti-patterns prevenidos
|
|
293
|
+
|
|
294
|
+
- Errors counter usando `error.type = err.message` → SEMPRE enum fechado (5-15 valores)
|
|
295
|
+
- Latency mistura success + error → SEMPRE `result` dimension separa
|
|
296
|
+
- Mean latency em vez de histogram → SEMPRE histogram com percentis derivados em backend
|
|
297
|
+
- Saturation genérico (CPU%) sem identificar recurso real → SEMPRE escolher recurso scarcest da função
|
|
298
|
+
|
|
199
299
|
## Ver também
|
|
200
300
|
|
|
201
301
|
- [supabase-edge-functions](../skills/supabase-edge-functions/SKILL.md) — base de conhecimento canônica
|
|
@@ -205,3 +305,5 @@ Edge Function nasce instrumentada com OTel — não é addon. Beneficia mais que
|
|
|
205
305
|
- [distributed-tracing](../skills/distributed-tracing/SKILL.md) — context propagation
|
|
206
306
|
- [structured-events](../skills/structured-events/SKILL.md) — campos canônicos
|
|
207
307
|
- [observability-driven-development](../skills/observability-driven-development/SKILL.md) — 4 perguntas pré-PR
|
|
308
|
+
- [four-golden-signals](../skills/four-golden-signals/SKILL.md) — 4 sinais canônicos (Latency, Traffic, Errors, Saturation) cap 6 livro Google SRE
|
|
309
|
+
- [golden-signals-instrumenter](./golden-signals-instrumenter.md) — agent que retro-instrumenta Edge Functions existentes com os 4 signals
|
|
@@ -172,3 +172,83 @@ Toda migration emite evento estruturado e cria audit hooks por default — não
|
|
|
172
172
|
3. **Atributos canônicos** em qualquer função criada: `set search_path = ''` + comments com `result.success`, `error.type` enum esperado (skill [`structured-events`](../skills/structured-events/SKILL.md)).
|
|
173
173
|
|
|
174
174
|
**Output adicionado:** seção "## Audit hooks" + "## Migration event emit" no SQL gerado, comentadas em PT-BR.
|
|
175
|
+
|
|
176
|
+
## Alerta toil — automação via pg_cron
|
|
177
|
+
|
|
178
|
+
> Cross-ref canônico: [eliminating-toil](../skills/eliminating-toil/SKILL.md) (cap 5 do livro Google SRE — Eliminating Toil). Para auditoria sistemática de toil em todo o repo, delegar para [toil-auditor](./toil-auditor.md).
|
|
179
|
+
|
|
180
|
+
Migrations SQL executadas **manualmente em cadência regular** (rebuild índice, VACUUM, REFRESH MATERIALIZED VIEW, ANALYZE) são toil canônico — passam todos os 6 critérios: manual, repetitivo, automatizável, tático, sem valor durável, escala linear. Este agent **detecta padrões de toil** ao escrever migration e **alerta proativamente** sugerindo automação via `pg_cron`.
|
|
181
|
+
|
|
182
|
+
### 6 critérios — quando uma migration é toil-prone
|
|
183
|
+
|
|
184
|
+
Migration descreve operação que será re-executada > 1× = toil-prone. Aplicar 6 critérios da skill `eliminating-toil`:
|
|
185
|
+
|
|
186
|
+
| Critério | Pergunta | Sinal de toil |
|
|
187
|
+
|---|---|---|
|
|
188
|
+
| 1. Manual | Operador roda `psql` ou aplica migration "quando lembra"? | Sim |
|
|
189
|
+
| 2. Repetitivo | Já foi executada 3+ vezes em milestones diferentes? | Sim |
|
|
190
|
+
| 3. Automatizável | `pg_cron` consegue agendar sem julgamento humano? | Sim |
|
|
191
|
+
| 4. Tático | Reage a sintoma (lentidão, bloat, stale view) sem planejar? | Sim |
|
|
192
|
+
| 5. Sem valor durável | Não cria asset permanente — só "limpa" estado | Sim |
|
|
193
|
+
| 6. Escala linear | Mais users / mais dados = mais frequência manual | Sim |
|
|
194
|
+
|
|
195
|
+
Se TODOS os 6 = sim → **toil**. Bloquear migration manual recorrente; oferecer alternativa via `pg_cron`.
|
|
196
|
+
|
|
197
|
+
### Padrões SQL canônicos que SEMPRE disparam alerta toil
|
|
198
|
+
|
|
199
|
+
| Operação manual | Por quê é toil | Automação canônica |
|
|
200
|
+
|---|---|---|
|
|
201
|
+
| `REINDEX TABLE x` recorrente (a cada N semanas) | Rebuild de bloat de índice é tático, sem valor durável, repetitivo | `select cron.schedule('reindex_x', '0 3 * * 0', $$reindex table x$$);` (semanal 3am) |
|
|
202
|
+
| `VACUUM ANALYZE x` manual | autovacuum não está acompanhando — sintoma de tuning, não fix manual | Tunar `autovacuum_vacuum_scale_factor` para tabela específica + `pg_cron` se necessário |
|
|
203
|
+
| `REFRESH MATERIALIZED VIEW x` manual | Stale view detectada por user reclamação ou alert | `select cron.schedule('refresh_x', '*/30 * * * * *', $$refresh materialized view concurrently x$$);` |
|
|
204
|
+
| `ANALYZE` em tabela após bulk insert manual | Estatísticas desatualizadas após ETL — bem conhecido | Trigger AFTER INSERT/COPY com `analyze` no fim do batch, ou `pg_cron` pós-ETL |
|
|
205
|
+
| `delete from logs where created_at < now() - interval '90d'` manual recorrente | Retention manual = toil clássico | `select cron.schedule('purge_logs', '0 4 * * *', $$delete from logs where ...$$);` |
|
|
206
|
+
| `dump + restore` periódico para estatísticas / planos cache | Operação repetitiva sem valor permanente | `pg_cron` job ou `pg_stat_reset_*()` calls automatizadas |
|
|
207
|
+
|
|
208
|
+
### Snippet canônico — converter manual em pg_cron
|
|
209
|
+
|
|
210
|
+
```sql
|
|
211
|
+
-- PT-BR: ANTES — toil (operador roda manualmente)
|
|
212
|
+
-- $ psql -c 'reindex table heavy_table;' ← repetir a cada 2 semanas
|
|
213
|
+
|
|
214
|
+
-- PT-BR: DEPOIS — automação via pg_cron (necessita extension pg_cron habilitada)
|
|
215
|
+
create extension if not exists pg_cron;
|
|
216
|
+
|
|
217
|
+
select cron.schedule(
|
|
218
|
+
'reindex_heavy_table_biweekly',
|
|
219
|
+
'0 3 1,15 * *', -- 3am dias 1 e 15
|
|
220
|
+
$$ reindex table public.heavy_table $$
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
-- PT-BR: monitor — falha em job pg_cron emite linha em cron.job_run_details
|
|
224
|
+
-- alimentar alerta SLO se job falha 3+ vezes seguidas
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
### Quando NÃO automatizar (não é toil)
|
|
228
|
+
|
|
229
|
+
- **Migration de schema (DDL one-shot)** — `create table`, `alter table add column` são project work, não toil. Não recorrentes.
|
|
230
|
+
- **Backfill data único** — `update orders set status = ...` aplicado 1× para corrigir bug é grungy work, não toil.
|
|
231
|
+
- **Rebuild que requer julgamento** — `reindex` que requer escolher hora baseada em load patterns variáveis, ou que precisa coordenação com release. Mantém manual mas documenta runbook.
|
|
232
|
+
|
|
233
|
+
### Output do agent — adicionado ao SQL gerado
|
|
234
|
+
|
|
235
|
+
Quando o agent detecta que a migration descreve operação toil-prone (regex em DDL: `reindex|vacuum|refresh materialized|delete from .* interval`), adiciona comentário-alerta no header do arquivo SQL gerado:
|
|
236
|
+
|
|
237
|
+
```sql
|
|
238
|
+
/*
|
|
239
|
+
⚠ TOIL ALERT — esta operação parece recorrente.
|
|
240
|
+
|
|
241
|
+
Se será executada em cadência regular, considere automação via pg_cron:
|
|
242
|
+
select cron.schedule('<job_name>', '<schedule>', $$ <sql> $$);
|
|
243
|
+
|
|
244
|
+
Cross-ref: kit/skills/eliminating-toil/SKILL.md (6 critérios canônicos)
|
|
245
|
+
kit/agents/toil-auditor.md (audit sistemático para repo todo)
|
|
246
|
+
*/
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### Anti-patterns prevenidos
|
|
250
|
+
|
|
251
|
+
- "Roda quando der" runbook → SEMPRE pg_cron + monitoring de falha do job
|
|
252
|
+
- `pg_cron` schedule mas sem alerta de falha → SEMPRE incluir SLO em `cron.job_run_details` (% sucesso 30d)
|
|
253
|
+
- Automação parcial (script humano-iniciado) → ainda é toil (humano pressiona botão); preferir cron.schedule completo
|
|
254
|
+
- Migration manual recorrente "porque é só uma vez por mês" → 12×/ano = toil, regra ≤ 50% se acumular vários "só um por mês"
|