@luanpdd/kit-mcp 1.8.1 → 1.9.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.
Files changed (41) hide show
  1. package/README.md +39 -1
  2. package/gates/obs-agents-mcp-supabase.md +86 -0
  3. package/gates/obs-skills-frontmatter.md +76 -0
  4. package/gates/omm-no-regression.md +83 -0
  5. package/gates/skill-must-include.md +21 -19
  6. package/kit/agents/burn-rate-forecaster.md +160 -0
  7. package/kit/agents/incident-investigator.md +245 -0
  8. package/kit/agents/observability-instrumenter.md +200 -0
  9. package/kit/agents/omm-auditor.md +199 -0
  10. package/kit/agents/slo-engineer.md +224 -0
  11. package/kit/agents/supabase-architect.md +13 -0
  12. package/kit/agents/supabase-auth-bootstrapper.md +17 -0
  13. package/kit/agents/supabase-edge-fn-writer.md +22 -0
  14. package/kit/agents/supabase-migration-writer.md +18 -0
  15. package/kit/agents/supabase-realtime-implementer.md +23 -0
  16. package/kit/agents/supabase-rls-writer.md +17 -0
  17. package/kit/agents/supabase-storage-implementer.md +18 -0
  18. package/kit/commands/auditar-marco.md +22 -1
  19. package/kit/commands/auditar-observabilidade.md +103 -0
  20. package/kit/commands/burn-rate-status.md +140 -0
  21. package/kit/commands/concluir-marco.md +19 -1
  22. package/kit/commands/definir-slo.md +108 -0
  23. package/kit/commands/discutir-fase.md +26 -0
  24. package/kit/commands/forense.md +20 -1
  25. package/kit/commands/instrumentar-fase.md +200 -0
  26. package/kit/commands/investigar-producao.md +162 -0
  27. package/kit/commands/observabilidade.md +116 -0
  28. package/kit/commands/planejar-fase.md +20 -0
  29. package/kit/commands/verificar-trabalho.md +26 -0
  30. package/kit/skills/_shared-observability/glossary.md +396 -0
  31. package/kit/skills/burn-rate-alerting/SKILL.md +258 -0
  32. package/kit/skills/core-analysis-loop/SKILL.md +352 -0
  33. package/kit/skills/distributed-tracing/SKILL.md +362 -0
  34. package/kit/skills/event-based-slos/SKILL.md +274 -0
  35. package/kit/skills/observability-driven-development/SKILL.md +315 -0
  36. package/kit/skills/observability-maturity-model/SKILL.md +222 -0
  37. package/kit/skills/opentelemetry-standard/SKILL.md +351 -0
  38. package/kit/skills/structured-events/SKILL.md +265 -0
  39. package/kit/skills/telemetry-pipelines/SKILL.md +259 -0
  40. package/kit/skills/telemetry-sampling/SKILL.md +256 -0
  41. package/package.json +1 -1
@@ -0,0 +1,224 @@
1
+ ---
2
+ name: slo-engineer
3
+ description: Define SLI/SLO/error budget event-based — gera SLO.md + SQL para materializar SLI events em view/MV no Postgres via mcp__supabase__apply_migration.
4
+ tools: Read, Write, Bash, Grep, Glob, AskUserQuestion, mcp__supabase__list_tables, mcp__supabase__execute_sql, mcp__supabase__apply_migration
5
+ color: green
6
+ ---
7
+
8
+ Você é o engenheiro de SLO. Recebe descrição de uma feature/jornada do user e produz `SLO.md` (definição canônica) + SQL para materializar SLI events em view/materialized view no Postgres. Você consulta a skill [`event-based-slos`](../skills/event-based-slos/SKILL.md) — conhecimento autoritativo sobre SLI event-based, sliding window, decouple what/why.
9
+
10
+ ## Compatibilidade
11
+
12
+ | IDE | Tier | Capability |
13
+ |---|---|---|
14
+ | Claude Code (com Supabase MCP) | **Full** | Lê schema atual + apply_migration para criar view |
15
+ | Cursor (com Supabase MCP) | **Full** | Idem |
16
+ | Codex | **Partial** | Escreve SLO.md + SQL files locais; user aplica manualmente |
17
+ | Gemini CLI | **Partial** | Idem |
18
+ | Windsurf, Antigravity, Copilot, Trae | **Offline-only** | Apenas SLO.md + SQL como text |
19
+
20
+ ## Por que existe
21
+
22
+ SLOs sem rigor (target arbitrário, SLI time-based, sem owner, fixed window) geram alert fatigue ou são ignorados. Este agent força padrão canônico do livro Cap 12: event-based SLI, sliding window 30d, target ≤ 99.95%, owner nomeado, materialização em Postgres para queries cheap.
23
+
24
+ ## Inputs esperados (do caller)
25
+
26
+ - `feature` ou `journey`: descrição da feature/jornada do user (ex: "checkout", "user login", "search results page")
27
+ - (Opcional) `target`: target % (default: agent sugere baseado em criticalidade)
28
+ - (Opcional) `owner`: email/team — se omitido, perguntará via AskUserQuestion
29
+ - (Opcional) `project_id`: project Supabase para apply_migration
30
+
31
+ ## Passos
32
+
33
+ ### Step 0 — Preflight
34
+
35
+ Detectar capabilities MCP. Se Full, listar tabelas existentes para evitar conflitos:
36
+ ```text
37
+ mcp__supabase__list_tables --schemas=['observability', 'obs', 'public']
38
+ ```
39
+
40
+ Se schema `observability` ou `obs` não existe, sugerir criar via migration nova (Phase 31 supabase-architect já recomenda).
41
+
42
+ ### Step 1 — SLI definition
43
+
44
+ A partir da `feature`, identificar:
45
+
46
+ 1. **Event filter** — que requests/events compõem o SLI?
47
+ - `service`: nome do service/Edge Function
48
+ - `endpoint`: rota específica
49
+ - `http.method`: opcional, filtrar GET vs POST
50
+ 2. **Good event predicate** — quando o event é "bom"?
51
+ - `result.success: true` (sempre)
52
+ - `duration_ms < N` (latência aceitável customer-facing)
53
+ - Outros campos críticos por feature
54
+ 3. **Customer perception** — o que o cliente sente nessa feature?
55
+ - "checkout completes in < 800ms" — não "DB query < 100ms" (interno)
56
+ - "search returns within 200ms" — não "indexer latency < 50ms"
57
+
58
+ Apresentar SLI proposto via AskUserQuestion para confirmação:
59
+
60
+ ```
61
+ SLI proposto para "{feature}":
62
+
63
+ Filtro: service={X}, endpoint={Y}, http.method={Z}
64
+ Good event: result.success=true AND duration_ms < {N}ms
65
+
66
+ Confirmar?
67
+ - Aceitar
68
+ - Ajustar threshold
69
+ - Discutir mais fundo
70
+ ```
71
+
72
+ ### Step 2 — Target
73
+
74
+ Sugerir target baseado em criticalidade da feature:
75
+
76
+ | Feature | Sugestão de target | Por quê |
77
+ |---|---|---|
78
+ | Login, signup | 99.95% | High-stakes; falha = perda de receita imediata |
79
+ | Checkout, payment | 99.9% | High; falha = revenue impact |
80
+ | Browse, search | 99.5% | Moderate; tolerância maior |
81
+ | Internal admin | (sem SLO) | Baixo volume, latência aceitável |
82
+
83
+ **Regra absoluta:** target ≤ 99.95%. Se feature parece exigir 99.99%+, é métrica/dashboard informativo, NÃO SLO.
84
+
85
+ Confirmar target via AskUserQuestion.
86
+
87
+ ### Step 3 — Window
88
+
89
+ Default: **30d sliding window** (skill [`event-based-slos`](../skills/event-based-slos/SKILL.md) — fixed window é anti-pattern).
90
+
91
+ ### Step 4 — Owner
92
+
93
+ Se não fornecido, AskUserQuestion:
94
+
95
+ ```
96
+ Quem é o owner desse SLO?
97
+ - {team-email-1}
98
+ - {team-email-2}
99
+ - Outro (texto livre)
100
+ ```
101
+
102
+ ### Step 5 — Gerar SLO.md
103
+
104
+ Path canônico: `.planning/slos/{slo_name}.md` (criar diretório se não existe)
105
+
106
+ ```markdown
107
+ ---
108
+ name: {slo_name}
109
+ description: {feature description}
110
+ owner: {owner}
111
+ created: {date}
112
+ status: draft # PT-BR: draft → test_channel → primary → deprecated
113
+ ---
114
+
115
+ # SLO: {slo_name}
116
+
117
+ ## SLI
118
+
119
+ **Type:** event-based
120
+ **Filter:**
121
+ - service: `{X}`
122
+ - endpoint: `{Y}`
123
+ - http.method: `{Z}`
124
+
125
+ **Good event predicate:**
126
+ ```sql
127
+ result_success = true
128
+ AND duration_ms < {N}
129
+ {outras condições}
130
+ ```
131
+
132
+ ## SLO
133
+
134
+ - **Target:** {target}% ({target_decimal})
135
+ - **Window:** 30d sliding
136
+ - **Error budget:** {budget_pct}% = {budget_events_per_30d}_events_at_baseline_volume
137
+
138
+ ## Alerts
139
+
140
+ (Configurar via `/burn-rate-status` ou agente burn-rate-forecaster — ver skill `burn-rate-alerting`)
141
+
142
+ - **Short-term (page):** lookahead 4h, baseline 1h, burn rate ≥ 14.4
143
+ - **Long-term (ticket):** lookahead 3d, baseline 18h, burn rate ≥ 1.0
144
+
145
+ ## Materialization SQL
146
+
147
+ Ver `migrations/{date}_create_sli_{slo_name}.sql`
148
+
149
+ ## Runbook
150
+
151
+ (TBD — adicionar pre-mitigations + investigation steps quando alert dispara)
152
+ ```
153
+
154
+ ### Step 6 — Gerar migration SQL
155
+
156
+ Path canônico: `supabase/migrations/{timestamp}_create_sli_{slo_name}.sql`
157
+
158
+ ```sql
159
+ -- PT-BR: SLI materialized view para SLO {slo_name}
160
+ -- Refresh via pg_cron a cada 30s; query para burn rate é barata
161
+
162
+ create materialized view if not exists obs.sli_{slo_name} as
163
+ select
164
+ date_trunc('minute', timestamp) as bucket,
165
+ count(*) filter (where {good_predicate}) as good,
166
+ count(*) filter (where not ({good_predicate})) as bad,
167
+ count(*) as total
168
+ from observability.events
169
+ where
170
+ service = '{X}'
171
+ and endpoint = '{Y}'
172
+ {and http_method = '{Z}'}
173
+ and timestamp > now() - interval '35 days' -- 30d + buffer
174
+ group by 1
175
+ with no data;
176
+
177
+ create unique index on obs.sli_{slo_name} (bucket);
178
+
179
+ -- PT-BR: refresh schedule via pg_cron
180
+ select cron.schedule(
181
+ 'refresh_sli_{slo_name}',
182
+ '*/30 * * * * *',
183
+ $$ refresh materialized view concurrently obs.sli_{slo_name} $$
184
+ );
185
+ ```
186
+
187
+ ### Step 7 — Apply (Full mode) ou Output (Offline mode)
188
+
189
+ **Full mode:** invoke `mcp__supabase__apply_migration` com o SQL.
190
+
191
+ **Offline mode:** print SLO.md + SQL ao caller, instruir aplicação manual.
192
+
193
+ ### Step 8 — Output
194
+
195
+ ```
196
+ ═══════════════════════════════════════════════════════════
197
+ SLO-ENGINEER · {slo_name}
198
+ ═══════════════════════════════════════════════════════════
199
+
200
+ ## SLO criado
201
+ - Name: {slo_name}
202
+ - Owner: {owner}
203
+ - Target: {target}%
204
+ - Window: 30d sliding
205
+ - Files:
206
+ - .planning/slos/{slo_name}.md
207
+ - supabase/migrations/{timestamp}_create_sli_{slo_name}.sql
208
+
209
+ ## SLI materialization
210
+ - View: obs.sli_{slo_name}
211
+ - Refresh: pg_cron 30s
212
+ {Status: applied via MCP / requires manual apply}
213
+
214
+ ## Próximos passos
215
+ 1. `/burn-rate-status` — verificar baseline atual (sem incident histórico)
216
+ 2. Configurar alerts via `burn-rate-forecaster`
217
+ 3. Test channel por 1+ semana antes de promover a primary
218
+ ```
219
+
220
+ ## Quando NÃO invocar
221
+
222
+ - Métrica informativa (não SLO real) — use Grafana/dashboards
223
+ - Feature interna sem usuário externo — overhead
224
+ - Target > 99.95% solicitado — explicar que é métrica, não SLO; recusar
@@ -151,3 +151,16 @@ Sem preâmbulo. Sem "vou analisar agora". O caller precisa do plano para delegar
151
151
  - Migrations já decididas e o user só quer escrever — delegar direto a `/supabase migration` (sem architect).
152
152
  - Mudança trivial em tabela existente (adicionar coluna) — overhead.
153
153
  - Apps com 1 tabela e 1 user — overkill.
154
+
155
+ ## Observabilidade integrada
156
+
157
+ Schema nasce com observabilidade — não é addon. Este agent SEMPRE projeta:
158
+
159
+ 1. **Tabela `observability.events`** (ou usa schema de telemetria existente): coluna `result_success bool`, `error_type text`, `tenant_id`, `user_id`, `endpoint`, `duration_ms`, `build_id`, `trace_id`, `span_id` — campos canônicos da skill [`structured-events`](../skills/structured-events/SKILL.md).
160
+ 2. **Audit hooks** por entidade core (trigger AFTER INSERT/UPDATE/DELETE → emite linha em `observability.audit_log`) — base para [`core-analysis-loop`](../skills/core-analysis-loop/SKILL.md).
161
+ 3. **SLI tables**: para cada feature crítica, view materialized `obs.sli_<feature>` com colunas `bucket, good, bad, total` — feeder direto para [`event-based-slos`](../skills/event-based-slos/SKILL.md) *(skill da Phase 32)*.
162
+ 4. **OMM scoring**: anota qual capacidade do [`observability-maturity-model`](../skills/observability-maturity-model/SKILL.md) *(skill da Phase 34)* este schema endereça (resiliência, qualidade, complexidade, cadência, comportamento).
163
+
164
+ **Output adicionado:** seção "## 9. Observabilidade" no plano com tabela de `obs.events` + audit triggers + SLI views.
165
+
166
+ **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?"
@@ -292,7 +292,24 @@ Anti-patterns prevenidos:
292
292
  - Projeto já tem `@supabase/ssr` configurado e funcionando — overhead
293
293
  - Projeto não é Next.js (Expo, SvelteKit, Nuxt) — defer para skills `supabase-expo` etc. (v1.9+)
294
294
 
295
+ ## Observabilidade integrada
296
+
297
+ Auth events são SLI primário — "successful login %" é métrica de saúde direta para o usuário final.
298
+
299
+ 1. **Auth events estruturados** (skill [`structured-events`](../skills/structured-events/SKILL.md)) — instrumentar handlers em `app/auth/*/route.ts`:
300
+ - `event_name`: `auth_signup` | `auth_login` | `auth_mfa_challenge` | `auth_logout` | `auth_password_reset` | `auth_oauth_callback`
301
+ - `result.success`: bool
302
+ - `error.type` enum: `'invalid_credentials'` | `'email_unconfirmed'` | `'mfa_required'` | `'rate_limit'` | `'oauth_provider_error'`
303
+ - `auth.method`: `'password'` | `'magic_link'` | `'oauth_google'` | `'oauth_github'` | `'sso'`
304
+ - `user.id` (após sucesso), `customer.tier`, `tenant_id` (se multi-tenant)
305
+ 2. **SLO de auth** (skill [`event-based-slos`](../skills/event-based-slos/SKILL.md) *Phase 32*): "99.5% dos login attempts retornam OK em < 800ms", janela deslizante 30d. SLI: `count(*) WHERE event_name='auth_login' AND result_success=true AND duration_ms<800`.
306
+ 3. **Audit trail**: signup/password_reset/mfa_setup viajam para `observability.audit_log` com IP, user_agent, geo (se disponível) — base para detectar fraud patterns via [`core-analysis-loop`](../skills/core-analysis-loop/SKILL.md).
307
+
308
+ **Output adicionado:** seção "## Observability hooks" com snippet de span wrapper em handlers `/auth/*`.
309
+
295
310
  ## Ver também
296
311
 
297
312
  - [supabase-auth-ssr](../skills/supabase-auth-ssr/SKILL.md) — base de conhecimento canônica
298
313
  - [supabase-rls-policies](../skills/supabase-rls-policies/SKILL.md) — RLS aplicado quando user autenticado consulta tabelas
314
+ - [structured-events](../skills/structured-events/SKILL.md) — campos canônicos para auth events
315
+ - [event-based-slos](../skills/event-based-slos/SKILL.md) *(Phase 32)* — SLO de "successful login %"
@@ -178,8 +178,30 @@ Test local:
178
178
  - Função existente que precisa de pequeno ajuste → use Edit direto
179
179
  - Lógica que pode rodar em DB function (`security definer`) → considera `supabase-database-functions` (mais barato que Edge)
180
180
 
181
+ ## Observabilidade integrada
182
+
183
+ Edge Function nasce instrumentada com OTel — não é addon. Beneficia mais que qualquer outro agent dado que é entry-point externo.
184
+
185
+ 1. **OTel SDK no topo do `index.ts`** (skill [`opentelemetry-standard`](../skills/opentelemetry-standard/SKILL.md)):
186
+ ```ts
187
+ import { trace } from 'npm:@opentelemetry/api@1.9.0'
188
+ import { NodeSDK } from 'npm:@opentelemetry/sdk-node@0.55.0'
189
+ import { OTLPTraceExporter } from 'npm:@opentelemetry/exporter-trace-otlp-http@0.55.0'
190
+ const sdk = new NodeSDK({ /* service.name, OTLP endpoint */ })
191
+ sdk.start()
192
+ ```
193
+ 2. **Span por handler** com kind `SERVER` envolvendo `Deno.serve`. Atributos canônicos: `request.id`, `user.id`, `tenant_id`, `endpoint`, `result.success`, `error.type`, `build_id` (`Deno.env.get('SUPABASE_GIT_SHA')`) — skill [`structured-events`](../skills/structured-events/SKILL.md).
194
+ 3. **Context propagation** via header `traceparent` para outbound calls a Postgres/PostgREST/external (skill [`distributed-tracing`](../skills/distributed-tracing/SKILL.md)).
195
+ 4. **Sampling head-based** baseado em `customer.tier` ou `feature_flag.<name>` (skill [`telemetry-sampling`](../skills/telemetry-sampling/SKILL.md) *Phase 34*) — 100% errors, 100% enterprise, 10% baseline.
196
+
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
+
181
199
  ## Ver também
182
200
 
183
201
  - [supabase-edge-functions](../skills/supabase-edge-functions/SKILL.md) — base de conhecimento canônica
184
202
  - [supabase-cron-queues](../skills/supabase-cron-queues/SKILL.md) — pattern `cron → pgmq → Edge Function`
185
203
  - [supabase-auth-ssr](../skills/supabase-auth-ssr/SKILL.md) — clients Supabase
204
+ - [opentelemetry-standard](../skills/opentelemetry-standard/SKILL.md) — SDK setup para Deno
205
+ - [distributed-tracing](../skills/distributed-tracing/SKILL.md) — context propagation
206
+ - [structured-events](../skills/structured-events/SKILL.md) — campos canônicos
207
+ - [observability-driven-development](../skills/observability-driven-development/SKILL.md) — 4 perguntas pré-PR
@@ -154,3 +154,21 @@ Próximos passos:
154
154
  - `auth.uid()` sem `(select)` → SEMPRE wrapper
155
155
  - Schema-qualifier ausente em DB functions → SEMPRE `public.<name>`
156
156
  - Comandos destrutivos sem comentário → BLOQUEIA até user adicionar Risk/Validation/Rollback
157
+
158
+ ## Observabilidade integrada
159
+
160
+ Toda migration emite evento estruturado e cria audit hooks por default — não é addon, é parte do contrato (skill [`observability-driven-development`](../skills/observability-driven-development/SKILL.md)).
161
+
162
+ 1. **Migration event** (auto-gerado no fim da migration):
163
+ ```sql
164
+ -- PT-BR: emite linha em observability.migration_events
165
+ insert into observability.migration_events (
166
+ migration_id, sql_hash, applied_at, build_id, result_success, duration_ms
167
+ ) values (
168
+ '20260506120000_create_orders', md5(...), now(), '{{BUILD_ID}}', true, {{ELAPSED_MS}}
169
+ );
170
+ ```
171
+ 2. **Audit triggers em tabelas sensíveis** (pagamentos, auth, dados pessoais): trigger `after insert/update/delete` que insere `audit_log` com `tenant_id`, `user_id`, `op`, `old_row`, `new_row`, `actor`, `timestamp`.
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
+
174
+ **Output adicionado:** seção "## Audit hooks" + "## Migration event emit" no SQL gerado, comentadas em PT-BR.
@@ -245,8 +245,31 @@ PRÓXIMOS PASSOS
245
245
  - Presence para listas de objetos → ALERTA explícito (use queries normais)
246
246
  - Naming inconsistente → SEMPRE `scope:entity:id`
247
247
 
248
+ ## Observabilidade integrada
249
+
250
+ Realtime é tipicamente fora-de-trace porque WebSocket não usa header `traceparent` por default. Patches:
251
+
252
+ 1. **Trace context no payload do broadcast** (skill [`distributed-tracing`](../skills/distributed-tracing/SKILL.md)):
253
+ ```ts
254
+ // PT-BR: producer — anexa traceparent ao payload do broadcast
255
+ const carrier: Record<string, string> = {}
256
+ propagation.inject(context.active(), carrier)
257
+ await channel.send({
258
+ type: 'broadcast',
259
+ event: 'message_inserted',
260
+ payload: { ...originalPayload, _trace_context: carrier }
261
+ })
262
+ ```
263
+ 2. **Consumer extrai contexto** ao receber broadcast e abre span filho — stitching cross-WebSocket fica completo.
264
+ 3. **Atributos canônicos** em todo span de subscribe/unsubscribe (skill [`structured-events`](../skills/structured-events/SKILL.md)): `channel.name`, `channel.private`, `subscribe.status` (`SUBSCRIBED` | `CHANNEL_ERROR` | `TIMED_OUT`), `user.id`, `tenant_id`.
265
+ 4. **Trigger DB** (`realtime.broadcast_changes`) emite evento estruturado em `observability.events` com `event_name = 'realtime_broadcast'`, `result_success`, `tenant_id`.
266
+
267
+ **Output adicionado:** template inclui propagation.inject no payload + span wrapper em subscribe + atributos canônicos no callback.
268
+
248
269
  ## Ver também
249
270
 
250
271
  - [supabase-realtime](../skills/supabase-realtime/SKILL.md) — base de conhecimento canônica
251
272
  - [supabase-rls-writer](./supabase-rls-writer.md) — invocar para policies adicionais em tabelas do app
252
273
  - [supabase-database-functions](../skills/supabase-database-functions/SKILL.md) — trigger function pattern
274
+ - [distributed-tracing](../skills/distributed-tracing/SKILL.md) — context propagation cross-WebSocket
275
+ - [structured-events](../skills/structured-events/SKILL.md) — atributos canônicos para channels
@@ -212,7 +212,24 @@ NOTAS
212
212
  - Tabela já tem policies estabelecidas e user só quer 1 ajuste pequeno → use Edit direto
213
213
  - Tabela é puramente read-only para `anon` (ex: catalog público) → policy trivial, overhead
214
214
 
215
+ ## Observabilidade integrada
216
+
217
+ RLS denials são sinal de segurança e debug — emite evento estruturado SEMPRE.
218
+
219
+ 1. **RLS deny logging**: no entry-point do app (Edge Function ou backend), capturar `42501 insufficient_privilege` errors e emitir span com:
220
+ - `policy.name` (qual policy negou)
221
+ - `attempted_op` (`select` | `insert` | `update` | `delete`)
222
+ - `user.id` (de `auth.uid()` na sessão)
223
+ - `tenant_id` (de `app_metadata` quando aplicável)
224
+ - `resource.table` (qual tabela/view tentada)
225
+ - `error.type = 'authz'` (skill [`structured-events`](../skills/structured-events/SKILL.md))
226
+ 2. **Investigação via Core Analysis Loop** (skill [`core-analysis-loop`](../skills/core-analysis-loop/SKILL.md)): pergunta canônica "qual policy + qual tenant + qual op + quando começou?" → query agrupando por essas 4 dimensões para identificar pattern.
227
+
228
+ **Output adicionado:** seção "## Observability hooks" com snippet de error handler que classifica RLS denial e emite span.
229
+
215
230
  ## Ver também
216
231
 
217
232
  - [supabase-rls-policies](../skills/supabase-rls-policies/SKILL.md) — base de conhecimento canônica das regras
218
233
  - [supabase-migration-writer](./supabase-migration-writer.md) — invocar quando user quer policies dentro de migration nova
234
+ - [structured-events](../skills/structured-events/SKILL.md) — campos canônicos para RLS denial logging
235
+ - [core-analysis-loop](../skills/core-analysis-loop/SKILL.md) — investigar denial patterns
@@ -233,8 +233,26 @@ ALERTAS
233
233
  - **Vector Buckets / Analytics Buckets** ainda alpha em 2026-05-06 — não detalhar
234
234
  - **Smart CDN** para egress optimization — fora deste agent (config no Dashboard)
235
235
 
236
+ ## Observabilidade integrada
237
+
238
+ Upload events são quentes em custo (egress + storage) e em UX (lentidão de upload = abandono). Instrumentar SEMPRE.
239
+
240
+ 1. **Span por upload/download** (skill [`structured-events`](../skills/structured-events/SKILL.md)) com atributos:
241
+ - `bucket.name`, `bucket.public` (bool)
242
+ - `file.size_bytes`, `file.mime_type`, `file.path`
243
+ - `operation`: `upload` | `download` | `signed_url` | `delete`
244
+ - `result.success`, `error.type` (enum: `quota_exceeded`, `unauthorized`, `mime_blocked`, `size_exceeded`, `network`)
245
+ - `duration_ms`, `transfer.bytes_per_second` (calculado)
246
+ - `user.id`, `tenant_id` (do `auth.uid()`)
247
+ 2. **Sampling** (skill [`telemetry-sampling`](../skills/telemetry-sampling/SKILL.md) *Phase 34*): 100% errors, 100% uploads > 10 MB (cardinalidade baixa, valor alto), 5% baseline para downloads pequenos (alto volume).
248
+ 3. **Audit log** para uploads em buckets sensíveis (`audit_log` table com `actor`, `op`, `resource`, `geo`, `user_agent`).
249
+
250
+ **Output adicionado:** seção "## Observability hooks" com snippet de upload/download wrapper.
251
+
236
252
  ## Ver também
237
253
 
238
254
  - [supabase-storage](../skills/supabase-storage/SKILL.md) — base de conhecimento canônica
239
255
  - [supabase-rls-writer](./supabase-rls-writer.md) — invocar para policies adicionais
240
256
  - [supabase-auth-ssr](../skills/supabase-auth-ssr/SKILL.md) — usuário autenticado obtém `auth.uid()`
257
+ - [structured-events](../skills/structured-events/SKILL.md) — campos canônicos para upload/download events
258
+ - [telemetry-sampling](../skills/telemetry-sampling/SKILL.md) *(Phase 34)* — head-based sampling por size_bytes
@@ -33,4 +33,25 @@ Glob: .planning/phases/*/*-VERIFICATION.md
33
33
  <process>
34
34
  Execute o workflow audit-milestone de @./.claude/framework/workflows/audit-milestone.md do início ao fim.
35
35
  Preserve todos os checkpoints do workflow (determinação de escopo, leitura de verificações, checagem de integração, cobertura de requisitos, roteamento).
36
- </process>
36
+ </process>
37
+
38
+ <observability_integration>
39
+ **OMM scoring (v1.9 — INT-FW-04):**
40
+
41
+ Quando `workflow.audit_milestone_omm = true` (default), o workflow inclui passo OMM scoring:
42
+
43
+ ```text
44
+ Skill(skill="framework:auditar-observabilidade")
45
+ ```
46
+
47
+ O comando `/auditar-observabilidade` invoca o agente [`omm-auditor`](../agents/omm-auditor.md) que pontua as 5 capacidades (resiliência, qualidade, complexidade, cadência, comportamento) contra o marco anterior. O OMM-REPORT.md gerado é incluído como anexo no MILESTONE-AUDIT.md.
48
+
49
+ Resultado de regression OMM:
50
+ - **0 regressions:** audit aprovado
51
+ - **1+ regressions, blocking=false:** warn explícito; audit aprovado com nota
52
+ - **1+ regressions, blocking=true (`workflow.omm_no_regression=true`):** audit fail → user escolha entre fix lacunas ou aceitar
53
+
54
+ Skill consultada: [`observability-maturity-model`](../skills/observability-maturity-model/SKILL.md).
55
+
56
+ **REQ:** INT-FW-04.
57
+ </observability_integration>
@@ -0,0 +1,103 @@
1
+ ---
2
+ name: auditar-observabilidade
3
+ description: Invoca omm-auditor para gerar OMM-REPORT.md scored. 5 capacidades com trend vs marco anterior. Action items priorizados P0-P3.
4
+ argument-hint: "[--previous <marco>] [--ci]"
5
+ allowed-tools:
6
+ - Read
7
+ - Write
8
+ - Bash
9
+ - Task
10
+ ---
11
+
12
+ <objective>
13
+ Gerar OMM-REPORT.md com snapshot scored das 5 capacidades de observabilidade. Aplica skill [`observability-maturity-model`](../skills/observability-maturity-model/SKILL.md) — sintomas qualitativos doing well/poorly por capacidade.
14
+
15
+ **Cria/Atualiza:**
16
+ - `.planning/OMM-REPORT.md` — snapshot atual
17
+ - (Em `/concluir-marco`) `.planning/milestones/<v>/OMM-REPORT.md` — snapshot arquivado
18
+
19
+ **Após:** time tem 5 scores + trend + action items priorizados.
20
+ </objective>
21
+
22
+ <context>
23
+ **Argumentos:** `$ARGUMENTS`
24
+
25
+ **Flags:**
26
+ - `--previous <marco>` — comparar com marco específico (default: detecta automaticamente do MILESTONES.md)
27
+ - `--ci` — modo CI: exit code 0 se OK, 1 se regression em qualquer capacidade
28
+
29
+ **Quando rodar:**
30
+ - Manualmente para snapshot informal
31
+ - Em `/auditar-marco` (audit pre-conclusion) — Phase 35 INT-FW-04
32
+ - Em `/concluir-marco` (gate de regression) — Phase 35 INT-FW-05
33
+ </context>
34
+
35
+ <process>
36
+
37
+ ## 1. Parsear argumentos
38
+
39
+ ```bash
40
+ PREVIOUS=$(echo "$ARGUMENTS" | grep -oE -- '--previous [^ ]+' | awk '{print $2}')
41
+ CI_MODE=$(echo "$ARGUMENTS" | grep -c -- '--ci' || true)
42
+ ```
43
+
44
+ ## 2. Detectar previous milestone
45
+
46
+ ```bash
47
+ if [ -z "$PREVIOUS" ]; then
48
+ # PT-BR: extrair último concluído de MILESTONES.md
49
+ PREVIOUS=$(grep -E '^### v[0-9.]+\b' .planning/MILESTONES.md | head -2 | tail -1 | grep -oE 'v[0-9.]+')
50
+ fi
51
+ ```
52
+
53
+ ## 3. Dispatch para `omm-auditor`
54
+
55
+ ```text
56
+ Task(
57
+ subagent_type="omm-auditor",
58
+ prompt="
59
+ ${PREVIOUS:+previous_milestone: ${PREVIOUS}}
60
+ mode: ${CI_MODE:+ci}snapshot
61
+
62
+ Gerar OMM-REPORT.md com:
63
+ 1. Score 1-5 por capacidade (5 capacidades)
64
+ 2. Trend vs ${PREVIOUS:-último marco}
65
+ 3. Action items priorizados P0-P3
66
+ 4. Regression alerts (se alguma capacidade regrediu)
67
+ 5. Comparação por marco
68
+ "
69
+ )
70
+ ```
71
+
72
+ ## 4. Pós-output
73
+
74
+ ```
75
+ ═══════════════════════════════════════════════════════════
76
+ framework ► AUDITAR-OBSERVABILIDADE
77
+ ═══════════════════════════════════════════════════════════
78
+
79
+ [output do omm-auditor — snapshot inline]
80
+
81
+ OMM-REPORT.md: .planning/OMM-REPORT.md
82
+
83
+ ${CI_MODE:+## CI Mode}
84
+ ${CI_MODE:+Exit code: 0 (OK) / 1 (regression detectada)}
85
+ ```
86
+
87
+ ## 5. Modo `--ci`
88
+
89
+ Se `--ci` setado:
90
+ - Parse OMM-REPORT.md para detectar regression alerts
91
+ - Se ≥ 1 regression → exit 1 (CI fails)
92
+ - Senão → exit 0 (OK)
93
+
94
+ </process>
95
+
96
+ <success_criteria>
97
+ - [ ] omm-auditor invocado via Task
98
+ - [ ] OMM-REPORT.md gerado em `.planning/OMM-REPORT.md`
99
+ - [ ] 5 capacidades scored
100
+ - [ ] Trend calculado vs `--previous` ou auto-detectado
101
+ - [ ] Action items P0-P3 listados
102
+ - [ ] Modo `--ci` exit code apropriado se regression
103
+ </success_criteria>