@luanpdd/kit-mcp 1.35.0 → 1.36.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/bin/cli.js +2 -2
- package/bin/mcp.js +6 -6
- package/bin/ui.js +74 -74
- package/gates/ai-prompt-stability.md +120 -120
- package/gates/budget-description.md +68 -68
- package/gates/confidence.md +29 -29
- package/gates/dependency-check.md +33 -33
- package/gates/dept-cycle-prevention.md +179 -179
- package/gates/golden-signals-coverage.md +133 -133
- package/gates/legacy-refactor-safety.md +178 -178
- package/gates/multi-tenant-rls-coverage.md +102 -102
- package/gates/no-personal-uuid.md +72 -72
- package/gates/obs-agents-mcp-supabase.md +86 -86
- package/gates/obs-skills-frontmatter.md +76 -76
- package/gates/observability-coverage.md +151 -151
- package/gates/omm-no-regression.md +83 -83
- package/gates/postmortem-template-required.md +127 -127
- package/gates/prr-checklist-coverage.md +128 -128
- package/gates/regression.md +32 -32
- package/gates/release-pipeline-policy.md +132 -132
- package/gates/secrets-scan.md +33 -33
- package/gates/service-role-not-in-user-facing.md +113 -113
- package/gates/skill-must-include.md +71 -71
- package/gates/sync-idempotent.md +62 -62
- package/gates/verify-phase-goal.md +34 -34
- package/kit/agents/designer-ui.md +216 -216
- package/kit/agents/workflow-generator.md +537 -167
- package/kit/commands/adicionar-backlog.md +1 -1
- package/kit/commands/adicionar-fase.md +1 -1
- package/kit/commands/adicionar-tarefa.md +1 -1
- package/kit/commands/auditar-observabilidade.md +103 -103
- package/kit/commands/auditar-toil.md +129 -129
- package/kit/commands/caracterizar-prompt.md +195 -195
- package/kit/commands/criar-workflow.md +158 -158
- package/kit/commands/definir-perfil.md +1 -1
- package/kit/commands/definir-slo.md +108 -108
- package/kit/commands/fio.md +1 -1
- package/kit/commands/golden-signals.md +142 -142
- package/kit/commands/instrumentar-fase.md +200 -200
- package/kit/commands/investigar-producao.md +162 -162
- package/kit/commands/observabilidade.md +118 -118
- package/kit/commands/postmortem.md +179 -179
- package/kit/commands/prr.md +205 -205
- package/kit/commands/publicar-rapido.md +207 -207
- package/kit/commands/risk-budget.md +220 -220
- package/kit/commands/sre.md +230 -230
- package/kit/file-manifest.json +424 -424
- package/kit/framework/references/output-style.md +22 -22
- package/kit/hooks/post-apply-migration.js +199 -199
- package/kit/hooks/sidecar-tool-publisher.js +210 -210
- package/kit/skills/_shared-dados-distribuidos/glossary.md +224 -224
- package/kit/skills/_shared-legacy/glossary.md +389 -389
- package/kit/skills/_shared-multi-tenant/glossary.md +186 -186
- package/kit/skills/_shared-observability/glossary.md +396 -396
- package/kit/skills/_shared-sre/glossary.md +712 -712
- package/kit/skills/_shared-supabase/glossary.md +234 -234
- package/kit/skills/blameless-postmortems/SKILL.md +340 -340
- package/kit/skills/burn-rate-alerting/SKILL.md +258 -258
- package/kit/skills/cascading-failures/SKILL.md +311 -311
- package/kit/skills/core-analysis-loop/SKILL.md +352 -352
- package/kit/skills/distributed-tracing/SKILL.md +362 -362
- package/kit/skills/dynamic-workflow-authoring/SKILL.md +327 -223
- package/kit/skills/eliminating-toil/SKILL.md +243 -243
- package/kit/skills/event-based-slos/SKILL.md +296 -296
- package/kit/skills/four-golden-signals/SKILL.md +314 -314
- package/kit/skills/hermetic-builds/SKILL.md +323 -323
- package/kit/skills/legacy-monster-methods/SKILL.md +444 -444
- package/kit/skills/llm-as-dependency/SKILL.md +436 -436
- package/kit/skills/load-shedding-graceful-degradation/SKILL.md +396 -396
- package/kit/skills/observability-driven-development/SKILL.md +315 -315
- package/kit/skills/observability-maturity-model/SKILL.md +222 -222
- package/kit/skills/opentelemetry-standard/SKILL.md +351 -351
- package/kit/skills/production-readiness-review/SKILL.md +305 -305
- package/kit/skills/release-engineering/SKILL.md +367 -367
- package/kit/skills/retry-strategies/SKILL.md +372 -372
- package/kit/skills/sre-risk-management/SKILL.md +221 -221
- package/kit/skills/structured-events/SKILL.md +265 -265
- package/kit/skills/supabase-cron-queues/SKILL.md +275 -275
- package/kit/skills/supabase-database-functions/SKILL.md +332 -332
- package/kit/skills/supabase-declarative-schema/SKILL.md +183 -183
- package/kit/skills/supabase-pgvector-rag/SKILL.md +253 -253
- package/kit/skills/supabase-postgres-style/SKILL.md +138 -138
- package/kit/skills/supabase-storage/SKILL.md +234 -234
- package/kit/skills/telemetry-pipelines/SKILL.md +259 -259
- package/kit/skills/telemetry-sampling/SKILL.md +256 -256
- package/kit/skills/ui-anti-padroes-ia/SKILL.md +261 -261
- package/kit/skills/ui-contexto-produto/SKILL.md +248 -248
- package/kit/skills/ui-cor-estrategia/SKILL.md +213 -213
- package/kit/skills/ui-critica-auditoria/SKILL.md +260 -260
- package/kit/skills/ui-motion-funcional/SKILL.md +264 -264
- package/kit/skills/ui-ritmo-espacial/SKILL.md +259 -259
- package/kit/skills/ui-tipografia/SKILL.md +211 -211
- package/package.json +1 -1
- package/src/cli/index.js +1114 -1114
- package/src/cli/render.js +194 -194
- package/src/cli/upgrade-check.js +135 -135
- package/src/core/error-redaction.js +76 -76
- package/src/core/failures.js +153 -153
- package/src/core/gate-runner.js +205 -205
- package/src/core/gates.js +82 -82
- package/src/core/logger.js +170 -170
- package/src/core/manifest-verify.js +174 -174
- package/src/core/metrics.js +268 -268
- package/src/core/notify.js +60 -60
- package/src/core/path-safety.js +141 -141
- package/src/core/replays.js +120 -120
- package/src/core/ui.js +185 -185
- package/src/mcp-server/install.js +149 -149
- package/src/mcp-server/roots.js +124 -124
- package/src/ui/auto-spawn.js +113 -113
- package/src/ui/browser.js +78 -78
- package/src/ui/client.js +130 -130
- package/src/ui/events.js +65 -65
- package/src/ui/lockfile.js +191 -191
- package/src/ui/port.js +67 -67
- package/src/ui/server.js +547 -547
- package/src/ui/wrapper.js +129 -129
|
@@ -1,352 +1,352 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: core-analysis-loop
|
|
3
|
-
description: Use ao debugar produção — método científico iterativo (sintoma → hipótese de dados → validação via query → root cause). Substitui dashboard-flipping e debug-by-intuition.
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Observabilidade — Core Analysis Loop
|
|
7
|
-
|
|
8
|
-
## Quando usar
|
|
9
|
-
|
|
10
|
-
LLM carrega esta skill ao investigar incidente, debugar comportamento de produção, ou validar hipótese sobre sistema. Trigger phrases:
|
|
11
|
-
|
|
12
|
-
- "investigar incidente", "debugar produção"
|
|
13
|
-
- "qual a causa raiz", "root cause analysis"
|
|
14
|
-
- "core analysis loop"
|
|
15
|
-
- "debug from first principles"
|
|
16
|
-
- "alerta disparou — onde começo?"
|
|
17
|
-
- "SLO burn — como descobrir o que quebrou?"
|
|
18
|
-
|
|
19
|
-
## Regras absolutas
|
|
20
|
-
|
|
21
|
-
- **Hipóteses vêm de DADOS, não intuição** — você não precisa conhecer o sistema. Comece com query `SELECT * WHERE result.success = false LIMIT 10` e itere.
|
|
22
|
-
- **NUNCA chute "deve ser X"** — toda hipótese é validada com query antes de aceitar. Se você está confiante mas não verificou, pare e verifique.
|
|
23
|
-
- **GROUP BY iterativo** — sempre comece amplo e estreite. Erro 5xx → group by `error.type` → group by `tenant_id` → group by `endpoint` → root cause.
|
|
24
|
-
- **Cardinalidade alta é sua amiga** — debug por user_id específico é só possível se você instrumentou alta cardinalidade (skill `structured-events`).
|
|
25
|
-
- **Documente a trilha** — cada hipótese, query, resultado, próxima hipótese. `incident-investigator` salva em `.planning/investigations/<id>.md`.
|
|
26
|
-
- **Pare quando achar root cause** — não vá além. "Tenant X em endpoint Y excedeu rate limit" é root cause; o "porquê tenant X excedeu" é um próximo loop separado.
|
|
27
|
-
- **Refute hipóteses agressivamente** — busque evidência CONTRA, não A FAVOR. Bias de confirmação é o inimigo.
|
|
28
|
-
- **Não confie em dashboards** — eles foram criados para problemas conhecidos. Você está investigando algo emergente.
|
|
29
|
-
|
|
30
|
-
## As 4 fases do Core Analysis Loop
|
|
31
|
-
|
|
32
|
-
```text
|
|
33
|
-
┌────────────────────────────────────────────────────────────────┐
|
|
34
|
-
│ │
|
|
35
|
-
│ ┌──────────────────┐ │
|
|
36
|
-
│ │ 1. SINTOMA │ Algo está errado (alerta, complaint, │
|
|
37
|
-
│ │ │ SLO burn, métrica anômala) │
|
|
38
|
-
│ └────────┬─────────┘ │
|
|
39
|
-
│ ↓ │
|
|
40
|
-
│ ┌──────────────────┐ │
|
|
41
|
-
│ │ 2. HIPÓTESE │ Olhar para os DADOS (não intuição): │
|
|
42
|
-
│ │ DE DADOS │ query inicial ampla; ver o que aparece │
|
|
43
|
-
│ └────────┬─────────┘ │
|
|
44
|
-
│ ↓ │
|
|
45
|
-
│ ┌──────────────────┐ │
|
|
46
|
-
│ │ 3. VALIDAÇÃO │ Refinar com GROUP BY + WHERE. │
|
|
47
|
-
│ │ POR QUERY │ Tem evidência? Sim → próxima hipótese │
|
|
48
|
-
│ └────────┬─────────┘ Não → volta para 2 com hipótese nova │
|
|
49
|
-
│ ↓ │
|
|
50
|
-
│ ┌──────────────────┐ │
|
|
51
|
-
│ │ 4. ITERAR │ Foi para 2 (refinou hipótese) │
|
|
52
|
-
│ │ OU PARAR │ ou parar (achou root cause) │
|
|
53
|
-
│ └──────────────────┘ │
|
|
54
|
-
│ │
|
|
55
|
-
└────────────────────────────────────────────────────────────────┘
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
## Patterns canônicos
|
|
59
|
-
|
|
60
|
-
### Pattern: investigação completa (exemplo realista)
|
|
61
|
-
|
|
62
|
-
```text
|
|
63
|
-
SINTOMA:
|
|
64
|
-
Alerta disparou às 14:32 — "checkout SLO burn rate = 8" (4× acima de 2 normal)
|
|
65
|
-
|
|
66
|
-
HIPÓTESE 1 — qual tipo de erro domina?
|
|
67
|
-
Query:
|
|
68
|
-
select error.type, count(*)
|
|
69
|
-
from spans
|
|
70
|
-
where service.name = 'checkout'
|
|
71
|
-
and result.success = false
|
|
72
|
-
and timestamp > '2026-05-06 14:00'
|
|
73
|
-
group by 1
|
|
74
|
-
order by count(*) desc
|
|
75
|
-
Resultado:
|
|
76
|
-
rate_limit | 7,234 (78%)
|
|
77
|
-
timeout | 892 (10%)
|
|
78
|
-
validation | 452 ( 5%)
|
|
79
|
-
db_conflict | 338 ( 4%)
|
|
80
|
-
auth | 215 ( 2%)
|
|
81
|
-
|
|
82
|
-
VALIDAÇÃO: rate_limit é o dominante. Foco aqui.
|
|
83
|
-
|
|
84
|
-
HIPÓTESE 2 — qual tenant está sofrendo rate_limit?
|
|
85
|
-
Query:
|
|
86
|
-
select tenant_id, count(*)
|
|
87
|
-
from spans
|
|
88
|
-
where service.name = 'checkout'
|
|
89
|
-
and error.type = 'rate_limit'
|
|
90
|
-
and timestamp > '2026-05-06 14:00'
|
|
91
|
-
group by 1
|
|
92
|
-
order by count(*) desc
|
|
93
|
-
Resultado:
|
|
94
|
-
acme-corp | 6,872 (95%)
|
|
95
|
-
other | 362 ( 5%)
|
|
96
|
-
|
|
97
|
-
VALIDAÇÃO: tenant acme-corp domina. Não é spread cross-tenant.
|
|
98
|
-
|
|
99
|
-
HIPÓTESE 3 — qual endpoint específico de acme está hitando rate_limit?
|
|
100
|
-
Query:
|
|
101
|
-
select endpoint, count(*)
|
|
102
|
-
from spans
|
|
103
|
-
where tenant_id = 'acme-corp'
|
|
104
|
-
and error.type = 'rate_limit'
|
|
105
|
-
and timestamp > '2026-05-06 14:00'
|
|
106
|
-
group by 1
|
|
107
|
-
Resultado:
|
|
108
|
-
/api/v1/bulk_orders | 6,872 (100%)
|
|
109
|
-
|
|
110
|
-
VALIDAÇÃO: 100% concentrado em /api/v1/bulk_orders.
|
|
111
|
-
|
|
112
|
-
HIPÓTESE 4 — começou quando exatamente?
|
|
113
|
-
Query:
|
|
114
|
-
select date_trunc('minute', timestamp) as minute, count(*)
|
|
115
|
-
from spans
|
|
116
|
-
where tenant_id = 'acme-corp'
|
|
117
|
-
and endpoint = '/api/v1/bulk_orders'
|
|
118
|
-
and timestamp > '2026-05-06 13:00'
|
|
119
|
-
group by 1 order by 1
|
|
120
|
-
Resultado:
|
|
121
|
-
13:00–13:59 | 200/min (normal)
|
|
122
|
-
14:00–14:01 | 230/min
|
|
123
|
-
14:02 | 8,500/min <-- spike!
|
|
124
|
-
14:03+ | 7,800/min
|
|
125
|
-
|
|
126
|
-
ROOT CAUSE: tenant acme-corp começou às 14:02 a fazer bulk_orders ~40× acima do normal.
|
|
127
|
-
|
|
128
|
-
Possíveis causas (próximo loop, fora deste escopo):
|
|
129
|
-
a) Bug do lado deles (loop infinito num cron deles)
|
|
130
|
-
b) Migração de dados que deveria ser one-shot virou continuous
|
|
131
|
-
c) Ataque
|
|
132
|
-
|
|
133
|
-
AÇÃO IMEDIATA:
|
|
134
|
-
1. Aumentar quota OU contactar acme-corp para entender
|
|
135
|
-
2. Adicionar circuit breaker em /api/v1/bulk_orders
|
|
136
|
-
3. Próximo loop: investigar PORQUÊ acme acelerou às 14:02
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
### Pattern: query inicial ampla (BFS, não DFS)
|
|
140
|
-
|
|
141
|
-
```sql
|
|
142
|
-
-- PT-BR: comece SEMPRE amplo. Group by por dimensão de alta cardinalidade
|
|
143
|
-
-- Não chute — deixe a query mostrar o que domina.
|
|
144
|
-
select
|
|
145
|
-
error_type,
|
|
146
|
-
tenant_id,
|
|
147
|
-
endpoint,
|
|
148
|
-
customer_tier,
|
|
149
|
-
count(*) as occurrences
|
|
150
|
-
from observability.spans
|
|
151
|
-
where
|
|
152
|
-
service_name = 'checkout'
|
|
153
|
-
and result_success = false
|
|
154
|
-
and timestamp > now() - interval '30 minutes'
|
|
155
|
-
group by 1, 2, 3, 4
|
|
156
|
-
order by occurrences desc
|
|
157
|
-
limit 30;
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### Pattern: refutar hipótese (bias check)
|
|
161
|
-
|
|
162
|
-
```sql
|
|
163
|
-
-- PT-BR: hipótese — "deploy às 14:00 causou problema"
|
|
164
|
-
-- Buscar EVIDÊNCIA CONTRA: comparar build_id antes/depois
|
|
165
|
-
select
|
|
166
|
-
build_id,
|
|
167
|
-
date_trunc('minute', timestamp) as minute,
|
|
168
|
-
sum(case when result_success = false then 1 else 0 end) as errors,
|
|
169
|
-
count(*) as total,
|
|
170
|
-
sum(case when result_success = false then 1 else 0 end)::float / count(*) as error_rate
|
|
171
|
-
from observability.spans
|
|
172
|
-
where timestamp between '2026-05-06 13:30' and '2026-05-06 14:30'
|
|
173
|
-
group by 1, 2
|
|
174
|
-
order by 2;
|
|
175
|
-
|
|
176
|
-
-- PT-BR: se error_rate é igual em build_id antigo e novo → deploy NÃO foi a causa
|
|
177
|
-
-- Refutado. Próxima hipótese.
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### Pattern: investigação em incident-investigator (Supabase)
|
|
181
|
-
|
|
182
|
-
```text
|
|
183
|
-
PT-BR: usando MCP tools em sequência, mantendo estado em .planning/investigations/<id>.md
|
|
184
|
-
|
|
185
|
-
1. mcp__supabase__get_logs --service api --filter "status_code >= 500" --limit 100
|
|
186
|
-
→ identifica padrão "rate_limit" dominando
|
|
187
|
-
|
|
188
|
-
2. mcp__supabase__execute_sql --query "
|
|
189
|
-
select tenant_id, count(*)
|
|
190
|
-
from logs.api
|
|
191
|
-
where status = 429 and timestamp > now() - interval '1 hour'
|
|
192
|
-
group by 1 order by 2 desc"
|
|
193
|
-
→ tenant acme-corp = 95%
|
|
194
|
-
|
|
195
|
-
3. mcp__supabase__get_advisors --type performance
|
|
196
|
-
→ "índice missing em bulk_orders.tenant_id" (hipótese paralela: pode ser causa upstream)
|
|
197
|
-
|
|
198
|
-
4. mcp__supabase__execute_sql --query "
|
|
199
|
-
select date_trunc('minute', timestamp) m, count(*)
|
|
200
|
-
from logs.api
|
|
201
|
-
where tenant_id = 'acme-corp' and path = '/api/v1/bulk_orders'
|
|
202
|
-
group by 1 order by 1"
|
|
203
|
-
→ spike em 14:02
|
|
204
|
-
|
|
205
|
-
ROOT CAUSE: tenant acme spike de bulk_orders às 14:02.
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
### Pattern: documentação da trilha (formato canônico)
|
|
209
|
-
|
|
210
|
-
```markdown
|
|
211
|
-
# Investigation: incident-2026-05-06-checkout-burn
|
|
212
|
-
|
|
213
|
-
**Started:** 2026-05-06 14:35
|
|
214
|
-
**Trigger:** SLO burn rate alert (checkout) = 8
|
|
215
|
-
|
|
216
|
-
## Sintoma inicial
|
|
217
|
-
- Alerta SLO burn rate=8 (4× acima do normal)
|
|
218
|
-
- p99 latency normal — não é problema de performance
|
|
219
|
-
|
|
220
|
-
## Hipóteses
|
|
221
|
-
|
|
222
|
-
### H1: qual tipo de erro domina?
|
|
223
|
-
- Query: `select error_type, count(*) from spans where ...`
|
|
224
|
-
- Resultado: rate_limit = 78%
|
|
225
|
-
- Status: VALIDATED — rate_limit é o foco
|
|
226
|
-
|
|
227
|
-
### H2: qual tenant?
|
|
228
|
-
- Query: `select tenant_id, count(*) where error_type='rate_limit'`
|
|
229
|
-
- Resultado: acme-corp = 95%
|
|
230
|
-
- Status: VALIDATED — concentrado
|
|
231
|
-
|
|
232
|
-
### H3: qual endpoint?
|
|
233
|
-
- Query: `select endpoint, count(*) where tenant_id='acme-corp' and error_type='rate_limit'`
|
|
234
|
-
- Resultado: /api/v1/bulk_orders = 100%
|
|
235
|
-
- Status: VALIDATED — endpoint único
|
|
236
|
-
|
|
237
|
-
### H4: quando começou?
|
|
238
|
-
- Query: time series por minuto desde 13:00
|
|
239
|
-
- Resultado: spike às 14:02 (200 → 8500/min)
|
|
240
|
-
- Status: VALIDATED — timestamp confirmado
|
|
241
|
-
|
|
242
|
-
## Root Cause
|
|
243
|
-
Tenant acme-corp começou às 14:02 a fazer bulk_orders 40× acima do baseline,
|
|
244
|
-
saturando rate limit do endpoint /api/v1/bulk_orders.
|
|
245
|
-
|
|
246
|
-
## Action Items
|
|
247
|
-
- [x] Page on-call (já feito antes da investigação começar)
|
|
248
|
-
- [ ] Contactar acme-corp para entender o que mudou às 14:02
|
|
249
|
-
- [ ] Adicionar circuit breaker em /api/v1/bulk_orders
|
|
250
|
-
- [ ] Próximo loop: por que acme acelerou? (separado deste)
|
|
251
|
-
|
|
252
|
-
## Lições / Tooling Gaps
|
|
253
|
-
- Faltou índice em (tenant_id, endpoint, timestamp) para query H3 ser rápida
|
|
254
|
-
- Logflare retention é só 24h — investigations além disso requerem export
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
## Anti-patterns
|
|
258
|
-
|
|
259
|
-
### ANTI: dashboard-flipping
|
|
260
|
-
|
|
261
|
-
```text
|
|
262
|
-
ANTI: ver spike no dashboard A, abrir B C D E procurando "shape similar"
|
|
263
|
-
|
|
264
|
-
PROBLEMA: pattern matching humano não escala. Você está limitado pelos dashboards
|
|
265
|
-
que alguém criou no passado para problemas conhecidos. Falhas emergentes
|
|
266
|
-
não têm dashboards.
|
|
267
|
-
|
|
268
|
-
CERTO: Core Analysis Loop — comece com query ampla, deixe os dados conduzirem.
|
|
269
|
-
```
|
|
270
|
-
|
|
271
|
-
### ANTI: debug from intuition
|
|
272
|
-
|
|
273
|
-
```text
|
|
274
|
-
ANTI: "Deve ser o cache" → mexer no cache → não funciona → "Deve ser o DB"...
|
|
275
|
-
|
|
276
|
-
PROBLEMA: chutes baseados em scar tissue não escalam. Engenheiros novos no time
|
|
277
|
-
ficam paralisados. Cada incident é uma redescoberta.
|
|
278
|
-
|
|
279
|
-
CERTO: comece sem assumir nada. SELECT WHERE result.success=false; veja o que aparece.
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
### ANTI: confirmar hipótese sem refutar
|
|
283
|
-
|
|
284
|
-
```text
|
|
285
|
-
ANTI: "Acho que é rate_limit" → query confirma 78% rate_limit → "Resolvi!" → fim
|
|
286
|
-
|
|
287
|
-
PROBLEMA: 78% não é 100%. Os outros 22% (timeouts, validation) podem ter causa
|
|
288
|
-
comum (mesma origem). Você parou cedo demais.
|
|
289
|
-
|
|
290
|
-
CERTO: validar que rate_limit explica o burn (não só representa maioria).
|
|
291
|
-
Calcular: sem os rate_limits, burn rate cai para? Se sim → confirmado.
|
|
292
|
-
Se não → há causa concorrente.
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
### ANTI: parar antes de identificar quem/onde/quando
|
|
296
|
-
|
|
297
|
-
```text
|
|
298
|
-
ANTI: "É rate_limit" → ticket criado → end
|
|
299
|
-
|
|
300
|
-
PROBLEMA: ações imediatas (aumentar quota? circuit breaker? contactar tenant?)
|
|
301
|
-
dependem de quem (tenant), onde (endpoint) e quando (timing).
|
|
302
|
-
|
|
303
|
-
CERTO: 4 dimensões mínimas — error.type + tenant + endpoint + timestamp inicial.
|
|
304
|
-
Sem isso, não há ação possível.
|
|
305
|
-
```
|
|
306
|
-
|
|
307
|
-
### ANTI: misturar 2 incidentes em 1 loop
|
|
308
|
-
|
|
309
|
-
```text
|
|
310
|
-
ANTI: "Por que checkout queimando?" + "Por que tenant acme acelerou?" — tudo junto
|
|
311
|
-
|
|
312
|
-
PROBLEMA: você nunca termina nem um nem outro. Loop fica infinito.
|
|
313
|
-
|
|
314
|
-
CERTO: 1 loop = 1 incident. Achou root cause de "por que checkout queimando"
|
|
315
|
-
(= acme spike) → PARE. Abra novo loop "por que acme spike às 14:02".
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
### ANTI: não documentar a trilha
|
|
319
|
-
|
|
320
|
-
```text
|
|
321
|
-
ANTI: investigar mentalmente, achar root cause, escrever postmortem horas depois
|
|
322
|
-
|
|
323
|
-
PROBLEMA: você esqueceu o caminho. Time não aprende. Próximo incident similar
|
|
324
|
-
recomeça do zero. Bias retrospectivo torce a narrativa.
|
|
325
|
-
|
|
326
|
-
CERTO: incident-investigator agent salva trilha em tempo real
|
|
327
|
-
em .planning/investigations/<id>.md (cada hipótese + query + resultado)
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
## Verificação
|
|
331
|
-
|
|
332
|
-
Antes de marcar incident como resolvido via Core Analysis Loop:
|
|
333
|
-
|
|
334
|
-
1. **Root cause é causal, não correlação** — "X aconteceu antes de Y" não é causa. "X causa Y" requer mecanismo explícito.
|
|
335
|
-
2. **4 dimensões mínimas** — error.type + identidade (user/tenant) + endpoint/component + timestamp inicial
|
|
336
|
-
3. **Próxima ação concreta** — root cause aponta para 1+ ações imediatas (mitigation, fix, escalation)
|
|
337
|
-
4. **Trilha documentada** — `.planning/investigations/<id>.md` tem todas as hipóteses (validated + refuted)
|
|
338
|
-
5. **Sem chutes não-validados** — cada hipótese tem query + resultado citado, não "achei que..."
|
|
339
|
-
6. **Sem dashboard-flipping nas notas** — só queries SQL/MCP, não "olhei o dashboard X"
|
|
340
|
-
7. **Próximo loop separado** — se há "por que" do "por que" (causa do tenant ter acelerado), abre-se outro loop
|
|
341
|
-
|
|
342
|
-
---
|
|
343
|
-
|
|
344
|
-
## Ver também
|
|
345
|
-
|
|
346
|
-
- `kit/skills/_shared-observability/glossary.md` — Core Analysis Loop, first principles, anti-patterns
|
|
347
|
-
- `kit/skills/structured-events/SKILL.md` — high cardinality é pré-requisito para queries ad hoc
|
|
348
|
-
- `kit/skills/distributed-tracing/SKILL.md` — trace_id permite focar 1 request específico
|
|
349
|
-
- `kit/agents/incident-investigator.md` *(Phase 30)* — agente que aplica este loop com MCP Supabase
|
|
350
|
-
- `kit/commands/investigar-producao.md` *(Phase 30)* — comando que lança o agente
|
|
351
|
-
|
|
352
|
-
*Material-fonte: Observability Engineering (O'Reilly, 2022) — Cap 8: "Analyzing Events to Achieve Observability".*
|
|
1
|
+
---
|
|
2
|
+
name: core-analysis-loop
|
|
3
|
+
description: Use ao debugar produção — método científico iterativo (sintoma → hipótese de dados → validação via query → root cause). Substitui dashboard-flipping e debug-by-intuition.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Observabilidade — Core Analysis Loop
|
|
7
|
+
|
|
8
|
+
## Quando usar
|
|
9
|
+
|
|
10
|
+
LLM carrega esta skill ao investigar incidente, debugar comportamento de produção, ou validar hipótese sobre sistema. Trigger phrases:
|
|
11
|
+
|
|
12
|
+
- "investigar incidente", "debugar produção"
|
|
13
|
+
- "qual a causa raiz", "root cause analysis"
|
|
14
|
+
- "core analysis loop"
|
|
15
|
+
- "debug from first principles"
|
|
16
|
+
- "alerta disparou — onde começo?"
|
|
17
|
+
- "SLO burn — como descobrir o que quebrou?"
|
|
18
|
+
|
|
19
|
+
## Regras absolutas
|
|
20
|
+
|
|
21
|
+
- **Hipóteses vêm de DADOS, não intuição** — você não precisa conhecer o sistema. Comece com query `SELECT * WHERE result.success = false LIMIT 10` e itere.
|
|
22
|
+
- **NUNCA chute "deve ser X"** — toda hipótese é validada com query antes de aceitar. Se você está confiante mas não verificou, pare e verifique.
|
|
23
|
+
- **GROUP BY iterativo** — sempre comece amplo e estreite. Erro 5xx → group by `error.type` → group by `tenant_id` → group by `endpoint` → root cause.
|
|
24
|
+
- **Cardinalidade alta é sua amiga** — debug por user_id específico é só possível se você instrumentou alta cardinalidade (skill `structured-events`).
|
|
25
|
+
- **Documente a trilha** — cada hipótese, query, resultado, próxima hipótese. `incident-investigator` salva em `.planning/investigations/<id>.md`.
|
|
26
|
+
- **Pare quando achar root cause** — não vá além. "Tenant X em endpoint Y excedeu rate limit" é root cause; o "porquê tenant X excedeu" é um próximo loop separado.
|
|
27
|
+
- **Refute hipóteses agressivamente** — busque evidência CONTRA, não A FAVOR. Bias de confirmação é o inimigo.
|
|
28
|
+
- **Não confie em dashboards** — eles foram criados para problemas conhecidos. Você está investigando algo emergente.
|
|
29
|
+
|
|
30
|
+
## As 4 fases do Core Analysis Loop
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
┌────────────────────────────────────────────────────────────────┐
|
|
34
|
+
│ │
|
|
35
|
+
│ ┌──────────────────┐ │
|
|
36
|
+
│ │ 1. SINTOMA │ Algo está errado (alerta, complaint, │
|
|
37
|
+
│ │ │ SLO burn, métrica anômala) │
|
|
38
|
+
│ └────────┬─────────┘ │
|
|
39
|
+
│ ↓ │
|
|
40
|
+
│ ┌──────────────────┐ │
|
|
41
|
+
│ │ 2. HIPÓTESE │ Olhar para os DADOS (não intuição): │
|
|
42
|
+
│ │ DE DADOS │ query inicial ampla; ver o que aparece │
|
|
43
|
+
│ └────────┬─────────┘ │
|
|
44
|
+
│ ↓ │
|
|
45
|
+
│ ┌──────────────────┐ │
|
|
46
|
+
│ │ 3. VALIDAÇÃO │ Refinar com GROUP BY + WHERE. │
|
|
47
|
+
│ │ POR QUERY │ Tem evidência? Sim → próxima hipótese │
|
|
48
|
+
│ └────────┬─────────┘ Não → volta para 2 com hipótese nova │
|
|
49
|
+
│ ↓ │
|
|
50
|
+
│ ┌──────────────────┐ │
|
|
51
|
+
│ │ 4. ITERAR │ Foi para 2 (refinou hipótese) │
|
|
52
|
+
│ │ OU PARAR │ ou parar (achou root cause) │
|
|
53
|
+
│ └──────────────────┘ │
|
|
54
|
+
│ │
|
|
55
|
+
└────────────────────────────────────────────────────────────────┘
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Patterns canônicos
|
|
59
|
+
|
|
60
|
+
### Pattern: investigação completa (exemplo realista)
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
SINTOMA:
|
|
64
|
+
Alerta disparou às 14:32 — "checkout SLO burn rate = 8" (4× acima de 2 normal)
|
|
65
|
+
|
|
66
|
+
HIPÓTESE 1 — qual tipo de erro domina?
|
|
67
|
+
Query:
|
|
68
|
+
select error.type, count(*)
|
|
69
|
+
from spans
|
|
70
|
+
where service.name = 'checkout'
|
|
71
|
+
and result.success = false
|
|
72
|
+
and timestamp > '2026-05-06 14:00'
|
|
73
|
+
group by 1
|
|
74
|
+
order by count(*) desc
|
|
75
|
+
Resultado:
|
|
76
|
+
rate_limit | 7,234 (78%)
|
|
77
|
+
timeout | 892 (10%)
|
|
78
|
+
validation | 452 ( 5%)
|
|
79
|
+
db_conflict | 338 ( 4%)
|
|
80
|
+
auth | 215 ( 2%)
|
|
81
|
+
|
|
82
|
+
VALIDAÇÃO: rate_limit é o dominante. Foco aqui.
|
|
83
|
+
|
|
84
|
+
HIPÓTESE 2 — qual tenant está sofrendo rate_limit?
|
|
85
|
+
Query:
|
|
86
|
+
select tenant_id, count(*)
|
|
87
|
+
from spans
|
|
88
|
+
where service.name = 'checkout'
|
|
89
|
+
and error.type = 'rate_limit'
|
|
90
|
+
and timestamp > '2026-05-06 14:00'
|
|
91
|
+
group by 1
|
|
92
|
+
order by count(*) desc
|
|
93
|
+
Resultado:
|
|
94
|
+
acme-corp | 6,872 (95%)
|
|
95
|
+
other | 362 ( 5%)
|
|
96
|
+
|
|
97
|
+
VALIDAÇÃO: tenant acme-corp domina. Não é spread cross-tenant.
|
|
98
|
+
|
|
99
|
+
HIPÓTESE 3 — qual endpoint específico de acme está hitando rate_limit?
|
|
100
|
+
Query:
|
|
101
|
+
select endpoint, count(*)
|
|
102
|
+
from spans
|
|
103
|
+
where tenant_id = 'acme-corp'
|
|
104
|
+
and error.type = 'rate_limit'
|
|
105
|
+
and timestamp > '2026-05-06 14:00'
|
|
106
|
+
group by 1
|
|
107
|
+
Resultado:
|
|
108
|
+
/api/v1/bulk_orders | 6,872 (100%)
|
|
109
|
+
|
|
110
|
+
VALIDAÇÃO: 100% concentrado em /api/v1/bulk_orders.
|
|
111
|
+
|
|
112
|
+
HIPÓTESE 4 — começou quando exatamente?
|
|
113
|
+
Query:
|
|
114
|
+
select date_trunc('minute', timestamp) as minute, count(*)
|
|
115
|
+
from spans
|
|
116
|
+
where tenant_id = 'acme-corp'
|
|
117
|
+
and endpoint = '/api/v1/bulk_orders'
|
|
118
|
+
and timestamp > '2026-05-06 13:00'
|
|
119
|
+
group by 1 order by 1
|
|
120
|
+
Resultado:
|
|
121
|
+
13:00–13:59 | 200/min (normal)
|
|
122
|
+
14:00–14:01 | 230/min
|
|
123
|
+
14:02 | 8,500/min <-- spike!
|
|
124
|
+
14:03+ | 7,800/min
|
|
125
|
+
|
|
126
|
+
ROOT CAUSE: tenant acme-corp começou às 14:02 a fazer bulk_orders ~40× acima do normal.
|
|
127
|
+
|
|
128
|
+
Possíveis causas (próximo loop, fora deste escopo):
|
|
129
|
+
a) Bug do lado deles (loop infinito num cron deles)
|
|
130
|
+
b) Migração de dados que deveria ser one-shot virou continuous
|
|
131
|
+
c) Ataque
|
|
132
|
+
|
|
133
|
+
AÇÃO IMEDIATA:
|
|
134
|
+
1. Aumentar quota OU contactar acme-corp para entender
|
|
135
|
+
2. Adicionar circuit breaker em /api/v1/bulk_orders
|
|
136
|
+
3. Próximo loop: investigar PORQUÊ acme acelerou às 14:02
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Pattern: query inicial ampla (BFS, não DFS)
|
|
140
|
+
|
|
141
|
+
```sql
|
|
142
|
+
-- PT-BR: comece SEMPRE amplo. Group by por dimensão de alta cardinalidade
|
|
143
|
+
-- Não chute — deixe a query mostrar o que domina.
|
|
144
|
+
select
|
|
145
|
+
error_type,
|
|
146
|
+
tenant_id,
|
|
147
|
+
endpoint,
|
|
148
|
+
customer_tier,
|
|
149
|
+
count(*) as occurrences
|
|
150
|
+
from observability.spans
|
|
151
|
+
where
|
|
152
|
+
service_name = 'checkout'
|
|
153
|
+
and result_success = false
|
|
154
|
+
and timestamp > now() - interval '30 minutes'
|
|
155
|
+
group by 1, 2, 3, 4
|
|
156
|
+
order by occurrences desc
|
|
157
|
+
limit 30;
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
### Pattern: refutar hipótese (bias check)
|
|
161
|
+
|
|
162
|
+
```sql
|
|
163
|
+
-- PT-BR: hipótese — "deploy às 14:00 causou problema"
|
|
164
|
+
-- Buscar EVIDÊNCIA CONTRA: comparar build_id antes/depois
|
|
165
|
+
select
|
|
166
|
+
build_id,
|
|
167
|
+
date_trunc('minute', timestamp) as minute,
|
|
168
|
+
sum(case when result_success = false then 1 else 0 end) as errors,
|
|
169
|
+
count(*) as total,
|
|
170
|
+
sum(case when result_success = false then 1 else 0 end)::float / count(*) as error_rate
|
|
171
|
+
from observability.spans
|
|
172
|
+
where timestamp between '2026-05-06 13:30' and '2026-05-06 14:30'
|
|
173
|
+
group by 1, 2
|
|
174
|
+
order by 2;
|
|
175
|
+
|
|
176
|
+
-- PT-BR: se error_rate é igual em build_id antigo e novo → deploy NÃO foi a causa
|
|
177
|
+
-- Refutado. Próxima hipótese.
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Pattern: investigação em incident-investigator (Supabase)
|
|
181
|
+
|
|
182
|
+
```text
|
|
183
|
+
PT-BR: usando MCP tools em sequência, mantendo estado em .planning/investigations/<id>.md
|
|
184
|
+
|
|
185
|
+
1. mcp__supabase__get_logs --service api --filter "status_code >= 500" --limit 100
|
|
186
|
+
→ identifica padrão "rate_limit" dominando
|
|
187
|
+
|
|
188
|
+
2. mcp__supabase__execute_sql --query "
|
|
189
|
+
select tenant_id, count(*)
|
|
190
|
+
from logs.api
|
|
191
|
+
where status = 429 and timestamp > now() - interval '1 hour'
|
|
192
|
+
group by 1 order by 2 desc"
|
|
193
|
+
→ tenant acme-corp = 95%
|
|
194
|
+
|
|
195
|
+
3. mcp__supabase__get_advisors --type performance
|
|
196
|
+
→ "índice missing em bulk_orders.tenant_id" (hipótese paralela: pode ser causa upstream)
|
|
197
|
+
|
|
198
|
+
4. mcp__supabase__execute_sql --query "
|
|
199
|
+
select date_trunc('minute', timestamp) m, count(*)
|
|
200
|
+
from logs.api
|
|
201
|
+
where tenant_id = 'acme-corp' and path = '/api/v1/bulk_orders'
|
|
202
|
+
group by 1 order by 1"
|
|
203
|
+
→ spike em 14:02
|
|
204
|
+
|
|
205
|
+
ROOT CAUSE: tenant acme spike de bulk_orders às 14:02.
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### Pattern: documentação da trilha (formato canônico)
|
|
209
|
+
|
|
210
|
+
```markdown
|
|
211
|
+
# Investigation: incident-2026-05-06-checkout-burn
|
|
212
|
+
|
|
213
|
+
**Started:** 2026-05-06 14:35
|
|
214
|
+
**Trigger:** SLO burn rate alert (checkout) = 8
|
|
215
|
+
|
|
216
|
+
## Sintoma inicial
|
|
217
|
+
- Alerta SLO burn rate=8 (4× acima do normal)
|
|
218
|
+
- p99 latency normal — não é problema de performance
|
|
219
|
+
|
|
220
|
+
## Hipóteses
|
|
221
|
+
|
|
222
|
+
### H1: qual tipo de erro domina?
|
|
223
|
+
- Query: `select error_type, count(*) from spans where ...`
|
|
224
|
+
- Resultado: rate_limit = 78%
|
|
225
|
+
- Status: VALIDATED — rate_limit é o foco
|
|
226
|
+
|
|
227
|
+
### H2: qual tenant?
|
|
228
|
+
- Query: `select tenant_id, count(*) where error_type='rate_limit'`
|
|
229
|
+
- Resultado: acme-corp = 95%
|
|
230
|
+
- Status: VALIDATED — concentrado
|
|
231
|
+
|
|
232
|
+
### H3: qual endpoint?
|
|
233
|
+
- Query: `select endpoint, count(*) where tenant_id='acme-corp' and error_type='rate_limit'`
|
|
234
|
+
- Resultado: /api/v1/bulk_orders = 100%
|
|
235
|
+
- Status: VALIDATED — endpoint único
|
|
236
|
+
|
|
237
|
+
### H4: quando começou?
|
|
238
|
+
- Query: time series por minuto desde 13:00
|
|
239
|
+
- Resultado: spike às 14:02 (200 → 8500/min)
|
|
240
|
+
- Status: VALIDATED — timestamp confirmado
|
|
241
|
+
|
|
242
|
+
## Root Cause
|
|
243
|
+
Tenant acme-corp começou às 14:02 a fazer bulk_orders 40× acima do baseline,
|
|
244
|
+
saturando rate limit do endpoint /api/v1/bulk_orders.
|
|
245
|
+
|
|
246
|
+
## Action Items
|
|
247
|
+
- [x] Page on-call (já feito antes da investigação começar)
|
|
248
|
+
- [ ] Contactar acme-corp para entender o que mudou às 14:02
|
|
249
|
+
- [ ] Adicionar circuit breaker em /api/v1/bulk_orders
|
|
250
|
+
- [ ] Próximo loop: por que acme acelerou? (separado deste)
|
|
251
|
+
|
|
252
|
+
## Lições / Tooling Gaps
|
|
253
|
+
- Faltou índice em (tenant_id, endpoint, timestamp) para query H3 ser rápida
|
|
254
|
+
- Logflare retention é só 24h — investigations além disso requerem export
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## Anti-patterns
|
|
258
|
+
|
|
259
|
+
### ANTI: dashboard-flipping
|
|
260
|
+
|
|
261
|
+
```text
|
|
262
|
+
ANTI: ver spike no dashboard A, abrir B C D E procurando "shape similar"
|
|
263
|
+
|
|
264
|
+
PROBLEMA: pattern matching humano não escala. Você está limitado pelos dashboards
|
|
265
|
+
que alguém criou no passado para problemas conhecidos. Falhas emergentes
|
|
266
|
+
não têm dashboards.
|
|
267
|
+
|
|
268
|
+
CERTO: Core Analysis Loop — comece com query ampla, deixe os dados conduzirem.
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### ANTI: debug from intuition
|
|
272
|
+
|
|
273
|
+
```text
|
|
274
|
+
ANTI: "Deve ser o cache" → mexer no cache → não funciona → "Deve ser o DB"...
|
|
275
|
+
|
|
276
|
+
PROBLEMA: chutes baseados em scar tissue não escalam. Engenheiros novos no time
|
|
277
|
+
ficam paralisados. Cada incident é uma redescoberta.
|
|
278
|
+
|
|
279
|
+
CERTO: comece sem assumir nada. SELECT WHERE result.success=false; veja o que aparece.
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### ANTI: confirmar hipótese sem refutar
|
|
283
|
+
|
|
284
|
+
```text
|
|
285
|
+
ANTI: "Acho que é rate_limit" → query confirma 78% rate_limit → "Resolvi!" → fim
|
|
286
|
+
|
|
287
|
+
PROBLEMA: 78% não é 100%. Os outros 22% (timeouts, validation) podem ter causa
|
|
288
|
+
comum (mesma origem). Você parou cedo demais.
|
|
289
|
+
|
|
290
|
+
CERTO: validar que rate_limit explica o burn (não só representa maioria).
|
|
291
|
+
Calcular: sem os rate_limits, burn rate cai para? Se sim → confirmado.
|
|
292
|
+
Se não → há causa concorrente.
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
### ANTI: parar antes de identificar quem/onde/quando
|
|
296
|
+
|
|
297
|
+
```text
|
|
298
|
+
ANTI: "É rate_limit" → ticket criado → end
|
|
299
|
+
|
|
300
|
+
PROBLEMA: ações imediatas (aumentar quota? circuit breaker? contactar tenant?)
|
|
301
|
+
dependem de quem (tenant), onde (endpoint) e quando (timing).
|
|
302
|
+
|
|
303
|
+
CERTO: 4 dimensões mínimas — error.type + tenant + endpoint + timestamp inicial.
|
|
304
|
+
Sem isso, não há ação possível.
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
### ANTI: misturar 2 incidentes em 1 loop
|
|
308
|
+
|
|
309
|
+
```text
|
|
310
|
+
ANTI: "Por que checkout queimando?" + "Por que tenant acme acelerou?" — tudo junto
|
|
311
|
+
|
|
312
|
+
PROBLEMA: você nunca termina nem um nem outro. Loop fica infinito.
|
|
313
|
+
|
|
314
|
+
CERTO: 1 loop = 1 incident. Achou root cause de "por que checkout queimando"
|
|
315
|
+
(= acme spike) → PARE. Abra novo loop "por que acme spike às 14:02".
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### ANTI: não documentar a trilha
|
|
319
|
+
|
|
320
|
+
```text
|
|
321
|
+
ANTI: investigar mentalmente, achar root cause, escrever postmortem horas depois
|
|
322
|
+
|
|
323
|
+
PROBLEMA: você esqueceu o caminho. Time não aprende. Próximo incident similar
|
|
324
|
+
recomeça do zero. Bias retrospectivo torce a narrativa.
|
|
325
|
+
|
|
326
|
+
CERTO: incident-investigator agent salva trilha em tempo real
|
|
327
|
+
em .planning/investigations/<id>.md (cada hipótese + query + resultado)
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
## Verificação
|
|
331
|
+
|
|
332
|
+
Antes de marcar incident como resolvido via Core Analysis Loop:
|
|
333
|
+
|
|
334
|
+
1. **Root cause é causal, não correlação** — "X aconteceu antes de Y" não é causa. "X causa Y" requer mecanismo explícito.
|
|
335
|
+
2. **4 dimensões mínimas** — error.type + identidade (user/tenant) + endpoint/component + timestamp inicial
|
|
336
|
+
3. **Próxima ação concreta** — root cause aponta para 1+ ações imediatas (mitigation, fix, escalation)
|
|
337
|
+
4. **Trilha documentada** — `.planning/investigations/<id>.md` tem todas as hipóteses (validated + refuted)
|
|
338
|
+
5. **Sem chutes não-validados** — cada hipótese tem query + resultado citado, não "achei que..."
|
|
339
|
+
6. **Sem dashboard-flipping nas notas** — só queries SQL/MCP, não "olhei o dashboard X"
|
|
340
|
+
7. **Próximo loop separado** — se há "por que" do "por que" (causa do tenant ter acelerado), abre-se outro loop
|
|
341
|
+
|
|
342
|
+
---
|
|
343
|
+
|
|
344
|
+
## Ver também
|
|
345
|
+
|
|
346
|
+
- `kit/skills/_shared-observability/glossary.md` — Core Analysis Loop, first principles, anti-patterns
|
|
347
|
+
- `kit/skills/structured-events/SKILL.md` — high cardinality é pré-requisito para queries ad hoc
|
|
348
|
+
- `kit/skills/distributed-tracing/SKILL.md` — trace_id permite focar 1 request específico
|
|
349
|
+
- `kit/agents/incident-investigator.md` *(Phase 30)* — agente que aplica este loop com MCP Supabase
|
|
350
|
+
- `kit/commands/investigar-producao.md` *(Phase 30)* — comando que lança o agente
|
|
351
|
+
|
|
352
|
+
*Material-fonte: Observability Engineering (O'Reilly, 2022) — Cap 8: "Analyzing Events to Achieve Observability".*
|