@luanpdd/kit-mcp 1.34.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.
Files changed (118) hide show
  1. package/README.md +1 -1
  2. package/bin/cli.js +2 -2
  3. package/bin/mcp.js +6 -6
  4. package/bin/ui.js +74 -74
  5. package/gates/ai-prompt-stability.md +120 -120
  6. package/gates/budget-description.md +68 -68
  7. package/gates/confidence.md +29 -29
  8. package/gates/dependency-check.md +33 -33
  9. package/gates/dept-cycle-prevention.md +179 -179
  10. package/gates/golden-signals-coverage.md +133 -133
  11. package/gates/legacy-refactor-safety.md +178 -178
  12. package/gates/multi-tenant-rls-coverage.md +102 -102
  13. package/gates/no-personal-uuid.md +72 -72
  14. package/gates/obs-agents-mcp-supabase.md +86 -86
  15. package/gates/obs-skills-frontmatter.md +76 -76
  16. package/gates/observability-coverage.md +151 -151
  17. package/gates/omm-no-regression.md +83 -83
  18. package/gates/postmortem-template-required.md +127 -127
  19. package/gates/prr-checklist-coverage.md +128 -128
  20. package/gates/regression.md +32 -32
  21. package/gates/release-pipeline-policy.md +132 -132
  22. package/gates/secrets-scan.md +33 -33
  23. package/gates/service-role-not-in-user-facing.md +113 -113
  24. package/gates/skill-must-include.md +71 -71
  25. package/gates/sync-idempotent.md +62 -62
  26. package/gates/verify-phase-goal.md +34 -34
  27. package/kit/agents/designer-ui.md +216 -216
  28. package/kit/agents/workflow-generator.md +537 -0
  29. package/kit/commands/adicionar-backlog.md +1 -1
  30. package/kit/commands/adicionar-fase.md +1 -1
  31. package/kit/commands/adicionar-tarefa.md +1 -1
  32. package/kit/commands/auditar-observabilidade.md +103 -103
  33. package/kit/commands/auditar-toil.md +129 -129
  34. package/kit/commands/caracterizar-prompt.md +195 -195
  35. package/kit/commands/criar-workflow.md +158 -0
  36. package/kit/commands/definir-perfil.md +1 -1
  37. package/kit/commands/definir-slo.md +108 -108
  38. package/kit/commands/fio.md +1 -1
  39. package/kit/commands/golden-signals.md +142 -142
  40. package/kit/commands/instrumentar-fase.md +200 -200
  41. package/kit/commands/investigar-producao.md +162 -162
  42. package/kit/commands/observabilidade.md +118 -118
  43. package/kit/commands/postmortem.md +179 -179
  44. package/kit/commands/prr.md +205 -205
  45. package/kit/commands/publicar-rapido.md +207 -207
  46. package/kit/commands/risk-budget.md +220 -220
  47. package/kit/commands/sre.md +230 -230
  48. package/kit/file-manifest.json +5 -2
  49. package/kit/framework/references/output-style.md +22 -22
  50. package/kit/hooks/post-apply-migration.js +199 -199
  51. package/kit/hooks/sidecar-tool-publisher.js +210 -210
  52. package/kit/skills/_shared-dados-distribuidos/glossary.md +224 -224
  53. package/kit/skills/_shared-legacy/glossary.md +389 -389
  54. package/kit/skills/_shared-multi-tenant/glossary.md +186 -186
  55. package/kit/skills/_shared-observability/glossary.md +396 -396
  56. package/kit/skills/_shared-sre/glossary.md +712 -712
  57. package/kit/skills/_shared-supabase/glossary.md +234 -234
  58. package/kit/skills/blameless-postmortems/SKILL.md +340 -340
  59. package/kit/skills/burn-rate-alerting/SKILL.md +258 -258
  60. package/kit/skills/cascading-failures/SKILL.md +311 -311
  61. package/kit/skills/core-analysis-loop/SKILL.md +352 -352
  62. package/kit/skills/distributed-tracing/SKILL.md +362 -362
  63. package/kit/skills/dynamic-workflow-authoring/SKILL.md +327 -0
  64. package/kit/skills/eliminating-toil/SKILL.md +243 -243
  65. package/kit/skills/event-based-slos/SKILL.md +296 -296
  66. package/kit/skills/four-golden-signals/SKILL.md +314 -314
  67. package/kit/skills/hermetic-builds/SKILL.md +323 -323
  68. package/kit/skills/legacy-monster-methods/SKILL.md +444 -444
  69. package/kit/skills/llm-as-dependency/SKILL.md +436 -436
  70. package/kit/skills/load-shedding-graceful-degradation/SKILL.md +396 -396
  71. package/kit/skills/observability-driven-development/SKILL.md +315 -315
  72. package/kit/skills/observability-maturity-model/SKILL.md +222 -222
  73. package/kit/skills/opentelemetry-standard/SKILL.md +351 -351
  74. package/kit/skills/production-readiness-review/SKILL.md +305 -305
  75. package/kit/skills/release-engineering/SKILL.md +367 -367
  76. package/kit/skills/retry-strategies/SKILL.md +372 -372
  77. package/kit/skills/sre-risk-management/SKILL.md +221 -221
  78. package/kit/skills/structured-events/SKILL.md +265 -265
  79. package/kit/skills/supabase-cron-queues/SKILL.md +275 -275
  80. package/kit/skills/supabase-database-functions/SKILL.md +332 -332
  81. package/kit/skills/supabase-declarative-schema/SKILL.md +183 -183
  82. package/kit/skills/supabase-pgvector-rag/SKILL.md +253 -253
  83. package/kit/skills/supabase-postgres-style/SKILL.md +138 -138
  84. package/kit/skills/supabase-storage/SKILL.md +234 -234
  85. package/kit/skills/telemetry-pipelines/SKILL.md +259 -259
  86. package/kit/skills/telemetry-sampling/SKILL.md +256 -256
  87. package/kit/skills/ui-anti-padroes-ia/SKILL.md +261 -261
  88. package/kit/skills/ui-contexto-produto/SKILL.md +248 -248
  89. package/kit/skills/ui-cor-estrategia/SKILL.md +213 -213
  90. package/kit/skills/ui-critica-auditoria/SKILL.md +260 -260
  91. package/kit/skills/ui-motion-funcional/SKILL.md +264 -264
  92. package/kit/skills/ui-ritmo-espacial/SKILL.md +259 -259
  93. package/kit/skills/ui-tipografia/SKILL.md +211 -211
  94. package/package.json +1 -1
  95. package/src/cli/index.js +1114 -1114
  96. package/src/cli/render.js +194 -194
  97. package/src/cli/upgrade-check.js +135 -135
  98. package/src/core/error-redaction.js +76 -76
  99. package/src/core/failures.js +153 -153
  100. package/src/core/gate-runner.js +205 -205
  101. package/src/core/gates.js +82 -82
  102. package/src/core/logger.js +170 -170
  103. package/src/core/manifest-verify.js +174 -174
  104. package/src/core/metrics.js +268 -268
  105. package/src/core/notify.js +60 -60
  106. package/src/core/path-safety.js +141 -141
  107. package/src/core/replays.js +120 -120
  108. package/src/core/ui.js +185 -185
  109. package/src/mcp-server/install.js +149 -149
  110. package/src/mcp-server/roots.js +124 -124
  111. package/src/ui/auto-spawn.js +113 -113
  112. package/src/ui/browser.js +78 -78
  113. package/src/ui/client.js +130 -130
  114. package/src/ui/events.js +65 -65
  115. package/src/ui/lockfile.js +191 -191
  116. package/src/ui/port.js +67 -67
  117. package/src/ui/server.js +547 -547
  118. package/src/ui/wrapper.js +129 -129
@@ -1,315 +1,315 @@
1
- ---
2
- name: observability-driven-development
3
- description: Use ao bundlear telemetria com nova feature — 4 perguntas pré-PR, instrumentação shift-left, auto-page do autor por 30-60min após merge. Análogo TDD para produção.
4
- ---
5
-
6
- # Observabilidade — Observability-Driven Development (ODD)
7
-
8
- ## Quando usar
9
-
10
- LLM carrega esta skill ao escrever nova feature, planejar fase, ou code review. Trigger phrases:
11
-
12
- - "ODD", "observability-driven development"
13
- - "como sei que essa feature funciona em prod?"
14
- - "instrumentar antes do PR"
15
- - "shift-left observability"
16
- - "auto-page do autor"
17
- - "bundle telemetry com feature"
18
-
19
- ## As 4 perguntas pré-PR (canônicas)
20
-
21
- Antes de submeter PR, todo autor responde EM CÓDIGO:
22
-
23
- | # | Pergunta | Como instrumentar |
24
- |---|----------|-------------------|
25
- | **1** | **Faz o que esperei?** | `result.success` boolean por evento + atributos do happy path (`order.id`, `user.id`) |
26
- | **2** | **Compara à versão anterior?** | `build_id` em todo evento — permite `WHERE build_id = X vs build_id = Y` |
27
- | **3** | **Usuários estão usando?** | Atributo de identidade (`user.id`, `tenant_id`, `customer.tier`) e do path do request (`endpoint`, `feature_flag.<name>`) |
28
- | **4** | **Anomalias emergem?** | `error.type` enumerado + `duration_ms` + capturar todos os branches de código (try/catch + early returns) |
29
-
30
- **Sem isso, o PR não é mergeável.** Não é regra burocrática — é a diferença entre "funciona em testes" e "funciona em produção".
31
-
32
- ## Regras absolutas
33
-
34
- - **Bundle telemetria com a feature** — instrumentação não é fase separada. Mesmo PR adiciona feature + spans + atributos.
35
- - **Auto-page o autor por 30-60min após merge** — feedback loop curto. "Fui eu, eu sei o que era e eu posso reverter." NUNCA pular essa janela.
36
- - **Decouple deploy de release** — feature flag por default. Deploy = código em prod desligado; release = liga aos poucos.
37
- - **Test em prod com subset** — 1% de tráfego com flag ativada > 100% rollout em horário de baixa.
38
- - **Rollback < rollforward em duvida** — observabilidade rica mostra o que está errado em segundos, mas só se você não rolou-back o evidência primeiro. Pause primeiro, investigue, então decida.
39
- - **Toda code branch = atributo** — `if (x) { ... } else { ... }` precisa emitir atributo de qual branch foi tomada (`branch_taken: 'fast_path'` vs `'slow_path'`).
40
- - **Tighten do feedback loop é o objetivo** — minutos do commit ao prod, não dias. Cada hora de delay multiplica custo de debug.
41
-
42
- ## Patterns canônicos
43
-
44
- ### Pattern: feature instrumentada nasce ODD-compliant
45
-
46
- ```ts
47
- // PT-BR: feature nova "novo método de pagamento" — instrumentação BUNDLED
48
- import { trace, SpanStatusCode } from '@opentelemetry/api'
49
-
50
- const tracer = trace.getTracer('payments')
51
-
52
- export async function processPaymentV2(req: PaymentRequest) {
53
- return tracer.startActiveSpan('process_payment_v2', async (span) => {
54
- // PT-BR: Pergunta 3 — quem está usando?
55
- span.setAttribute('user.id', req.user.id)
56
- span.setAttribute('customer.tier', req.user.tier)
57
- span.setAttribute('tenant_id', req.user.tenant)
58
- span.setAttribute('endpoint', '/api/v2/payments')
59
-
60
- // PT-BR: Pergunta 2 — qual versão?
61
- span.setAttribute('build_id', process.env.BUILD_ID ?? 'dev')
62
- span.setAttribute('feature_flag.payments_v2', true) // PT-BR: assumed via flag
63
- span.setAttribute('payment.method', req.method) // novo: 'pix' | 'crypto' | 'card'
64
-
65
- // PT-BR: Pergunta 4 — atributo por branch
66
- if (req.amount > 1_000_00) {
67
- span.setAttribute('branch_taken', 'high_value')
68
- span.setAttribute('requires_3ds', true)
69
- } else {
70
- span.setAttribute('branch_taken', 'standard')
71
- span.setAttribute('requires_3ds', false)
72
- }
73
-
74
- try {
75
- const result = await chargeProvider(req)
76
-
77
- // PT-BR: Pergunta 1 — fez o que esperei?
78
- span.setAttribute('result.success', true)
79
- span.setAttribute('payment.id', result.id)
80
- span.setAttribute('payment.processor_response', result.processorCode)
81
- span.setStatus({ code: SpanStatusCode.OK })
82
- return result
83
- } catch (e) {
84
- // PT-BR: Pergunta 4 — anomalia identificada com type enum
85
- span.setAttribute('result.success', false)
86
- span.setAttribute('error.type', classify(e)) // 'provider_down' | 'declined' | 'fraud_block'
87
- span.setAttribute('error.processor_code', e.code)
88
- span.setStatus({ code: SpanStatusCode.ERROR })
89
- throw e
90
- } finally {
91
- span.end()
92
- }
93
- })
94
- }
95
- ```
96
-
97
- ### Pattern: auto-page autor (config CI/CD)
98
-
99
- ```yaml
100
- # PT-BR: GitHub Actions ou equivalente — paginar autor após merge
101
- # .github/workflows/post-merge-watch.yml
102
- name: post-merge-watch
103
- on:
104
- push:
105
- branches: [main]
106
- jobs:
107
- page-author:
108
- runs-on: ubuntu-latest
109
- steps:
110
- - name: Page commit author for 30-60min
111
- run: |
112
- AUTHOR_EMAIL="${{ github.event.head_commit.author.email }}"
113
- PAGER_TOKEN="${{ secrets.PAGERDUTY_TOKEN }}"
114
- # PT-BR: criar policy temporária — alertas SLO route para AUTHOR_EMAIL
115
- # por 45 minutos. Após, retorna ao on-call normal.
116
- curl -X POST https://api.pagerduty.com/oncall_overrides \
117
- -H "Authorization: Token token=$PAGER_TOKEN" \
118
- -d "{
119
- \"override\": {
120
- \"start\": \"$(date -u +%FT%TZ)\",
121
- \"end\": \"$(date -u -d '+45 minutes' +%FT%TZ)\",
122
- \"user\": {\"email\": \"$AUTHOR_EMAIL\"}
123
- }
124
- }"
125
- ```
126
-
127
- ### Pattern: deploy ≠ release (feature flag)
128
-
129
- ```ts
130
- // PT-BR: deploy do código com flag DESLIGADA
131
- const isV2Enabled = (req: Request): boolean => {
132
- // PT-BR: 0% inicialmente — deploy = código em prod, mas dormente
133
- if (!flags.isEnabled('payments_v2', { user_id: req.user.id })) {
134
- return false
135
- }
136
- return true
137
- }
138
-
139
- export async function processPayment(req: PaymentRequest) {
140
- if (isV2Enabled(req)) {
141
- return processPaymentV2(req)
142
- }
143
- return processPaymentV1(req)
144
- }
145
-
146
- // PT-BR: depois do deploy, release gradual:
147
- // 1. flag.set('payments_v2', { user_id: 'me' }) — só dev
148
- // 2. flag.set('payments_v2', { customer.tier: 'free' }, 1%) — 1% free users
149
- // 3. observe SLO + error rate; se OK, sobe para 10%, 50%, 100%
150
- ```
151
-
152
- ### Pattern: comparar versão antes/depois (Pergunta 2)
153
-
154
- ```sql
155
- -- PT-BR: SLI antes vs depois do deploy do build_id `abc123`
156
- -- Mostra error_rate per build, agrupado por versão
157
- select
158
- build_id,
159
- count(*) as total,
160
- sum(case when result_success = false then 1 else 0 end) as errors,
161
- 100.0 * sum(case when result_success = false then 1 else 0 end) / count(*) as error_pct,
162
- percentile_cont(0.99) within group (order by duration_ms) as p99_ms
163
- from observability.spans
164
- where
165
- service_name = 'payments'
166
- and timestamp > '2026-05-06 10:00'
167
- and build_id in ('v1.5.2', 'v1.5.3') -- versão anterior + atual
168
- group by build_id;
169
-
170
- -- PT-BR: se v1.5.3 tem error_pct ou p99_ms > v1.5.2 → regressão. Rollback ou fix.
171
- ```
172
-
173
- ### Pattern: instrumentação shift-left no PLAN.md de fase
174
-
175
- ```markdown
176
- # PLAN: Fase 42 — Novo método de pagamento
177
-
178
- ## Tarefas
179
-
180
- | # | Task | Output |
181
- |---|------|--------|
182
- | 1 | Implementar `processPaymentV2` em `src/payments/v2.ts` | função |
183
- | 2 | **Instrumentação OTel — bundled** | spans + atributos |
184
- | 3 | Adicionar feature flag `payments_v2` | flag config |
185
- | 4 | Tests unitários | tests/v2.spec.ts |
186
- | 5 | **ODD — 4 perguntas validadas** | comments no PR |
187
-
188
- ## ODD — Validação das 4 perguntas
189
-
190
- 1. **Faz o que esperei?**
191
- - Span `process_payment_v2` com atributo `result.success`
192
- - Query: `SELECT count(*) WHERE result_success=true / count(*)` deve ser ≥ 99% após release
193
-
194
- 2. **Compara à versão anterior?**
195
- - `build_id` em todo span permite cross-version
196
- - Query: ver "Pattern: comparar versão" acima
197
-
198
- 3. **Usuários estão usando?**
199
- - `customer.tier`, `payment.method` permitem slice & dice
200
- - Query: `SELECT customer.tier, payment.method, count(*) FROM ... WHERE feature_flag.payments_v2=true GROUP BY 1,2`
201
-
202
- 4. **Anomalias emergem?**
203
- - `error.type` enum: `'provider_down'`, `'declined'`, `'fraud_block'`
204
- - `branch_taken` para code paths
205
- - Alert: SLO burn rate > 2 sobre `WHERE feature_flag.payments_v2=true`
206
- ```
207
-
208
- ## Anti-patterns
209
-
210
- ### ANTI: instrumentação como fase separada
211
-
212
- ```text
213
- ANTI: "Vamos shipá-la primeiro, instrumentar na próxima sprint."
214
-
215
- PROBLEMA: você está em prod cego. Quando algo quebrar, você não tem dados para
216
- investigar. Adicionar instrumentação depois requer redeploy, que é
217
- arriscado durante incident.
218
-
219
- CERTO: instrumentação NO MESMO PR da feature. Não-negociável.
220
- ```
221
-
222
- ### ANTI: glass castle (medo de mexer em prod)
223
-
224
- ```text
225
- ANTI: "Não deploy hoje, é véspera de feriado."
226
- "Não deploy depois das 17h."
227
- "Vamos esperar a próxima janela de manutenção."
228
- (Equipe deploya 1× por semana, em batches grandes)
229
-
230
- PROBLEMA: deploys raros = deploys grandes = mais código mudando = mais risco.
231
- Cada deploy fica mais perigoso por sua raridade. Cycle vicioso.
232
-
233
- CERTO: deploy frequente (várias vezes ao dia) com features pequenas atrás de flags.
234
- Cada deploy quase nada. Reverter quase nada se quebra. Confiança aumenta.
235
- ```
236
-
237
- ### ANTI: rollback antes de investigar
238
-
239
- ```text
240
- ANTI: alerta dispara → rollback automático → "voltou ao normal" → ninguém
241
- investiga porque "tá funcionando agora"
242
-
243
- PROBLEMA: você perdeu a evidência. Próximo incident similar começa do zero.
244
- Padrão de regressão acumula tech debt invisível.
245
-
246
- CERTO: pause feature flag (não rollback do deploy) → investigue com observability →
247
- fix root cause → re-release. Rollback só se investigation tomar > 30min.
248
- ```
249
-
250
- ### ANTI: testar com 100% rollout em horário de baixa
251
-
252
- ```text
253
- ANTI: "Faz deploy 4h da manhã quando ninguém usa."
254
-
255
- PROBLEMA: você está rodando com 100% de risk em condições não-realistas.
256
- 0 tráfego = 0 sinal. Quando bug aparecer no horário de pico, você
257
- não terá dados.
258
-
259
- CERTO: deploy a qualquer hora atrás de feature flag em 1% → observe → 10% → 100%.
260
- Bugs aparecem no progressive rollout, não no horário de pico.
261
- ```
262
-
263
- ### ANTI: paginar on-call em vez do autor
264
-
265
- ```text
266
- ANTI: alerta dispara 2h após merge → on-call (que não escreveu o código) é paginado
267
-
268
- PROBLEMA: on-call não tem contexto. Vai procurar "que mudou ultimamente" — toma 30min.
269
- Autor está dormindo / fora do contexto. Feedback loop quebrado.
270
-
271
- CERTO: por 30-60min após merge, alertas vão para o AUTOR. Ele tem o contexto fresco,
272
- sabe o que mudou, pode reverter ou fix em 5min. Após janela, volta para on-call.
273
- ```
274
-
275
- ### ANTI: instrumentação só em happy path
276
-
277
- ```text
278
- ANTI: span com atributos só no `try` block; catch sem instrumentação
279
-
280
- PROBLEMA: você não sabe nada sobre falhas. Pergunta 4 (anomalias) impossível de responder.
281
-
282
- CERTO: cada `catch` adiciona `error.type` enum + `error.message` + `result.success=false`.
283
- Cada early return adiciona `branch_taken: 'short_circuit_validation'` etc.
284
- ```
285
-
286
- ## Verificação
287
-
288
- Antes de mergear PR, verificar as 4 perguntas:
289
-
290
- | # | Pergunta | Validação |
291
- |---|----------|-----------|
292
- | 1 | **Faz o que esperei?** | Existe atributo `result.success` em algum span do código tocado? |
293
- | 2 | **Compara à versão anterior?** | `build_id` é setado no span? (geralmente em SDK setup, validar uma vez) |
294
- | 3 | **Usuários estão usando?** | Existe `user.id` ou `tenant_id` ou `customer.tier` no span? |
295
- | 4 | **Anomalias emergem?** | `catch` blocks emitem `error.type` enum? branches if/else emitem `branch_taken`? |
296
-
297
- Se qualquer pergunta = NÃO → PR não mergeable. Adicione instrumentação.
298
-
299
- Após merge:
300
- - ✅ Feature flag desligada por default? (deploy ≠ release)
301
- - ✅ Auto-page do autor configurado por 30-60min?
302
- - ✅ SLI/SLO baseline sabido para comparação pré/pós release?
303
-
304
- ---
305
-
306
- ## Ver também
307
-
308
- - `kit/skills/_shared-observability/glossary.md` — termos canônicos, ODD, glass castle
309
- - `kit/skills/structured-events/SKILL.md` — campos canônicos
310
- - `kit/skills/distributed-tracing/SKILL.md` — instrumentação cross-service
311
- - `kit/skills/event-based-slos/SKILL.md` *(Phase 32)* — SLI para baseline pré/pós release
312
- - `kit/agents/observability-instrumenter.md` — agente que gera instrumentação
313
- - `kit/commands/instrumentar-fase.md` — comando que aplica ODD em fases
314
-
315
- *Material-fonte: Observability Engineering (O'Reilly, 2022) — Cap 11: "Observability-Driven Development".*
1
+ ---
2
+ name: observability-driven-development
3
+ description: Use ao bundlear telemetria com nova feature — 4 perguntas pré-PR, instrumentação shift-left, auto-page do autor por 30-60min após merge. Análogo TDD para produção.
4
+ ---
5
+
6
+ # Observabilidade — Observability-Driven Development (ODD)
7
+
8
+ ## Quando usar
9
+
10
+ LLM carrega esta skill ao escrever nova feature, planejar fase, ou code review. Trigger phrases:
11
+
12
+ - "ODD", "observability-driven development"
13
+ - "como sei que essa feature funciona em prod?"
14
+ - "instrumentar antes do PR"
15
+ - "shift-left observability"
16
+ - "auto-page do autor"
17
+ - "bundle telemetry com feature"
18
+
19
+ ## As 4 perguntas pré-PR (canônicas)
20
+
21
+ Antes de submeter PR, todo autor responde EM CÓDIGO:
22
+
23
+ | # | Pergunta | Como instrumentar |
24
+ |---|----------|-------------------|
25
+ | **1** | **Faz o que esperei?** | `result.success` boolean por evento + atributos do happy path (`order.id`, `user.id`) |
26
+ | **2** | **Compara à versão anterior?** | `build_id` em todo evento — permite `WHERE build_id = X vs build_id = Y` |
27
+ | **3** | **Usuários estão usando?** | Atributo de identidade (`user.id`, `tenant_id`, `customer.tier`) e do path do request (`endpoint`, `feature_flag.<name>`) |
28
+ | **4** | **Anomalias emergem?** | `error.type` enumerado + `duration_ms` + capturar todos os branches de código (try/catch + early returns) |
29
+
30
+ **Sem isso, o PR não é mergeável.** Não é regra burocrática — é a diferença entre "funciona em testes" e "funciona em produção".
31
+
32
+ ## Regras absolutas
33
+
34
+ - **Bundle telemetria com a feature** — instrumentação não é fase separada. Mesmo PR adiciona feature + spans + atributos.
35
+ - **Auto-page o autor por 30-60min após merge** — feedback loop curto. "Fui eu, eu sei o que era e eu posso reverter." NUNCA pular essa janela.
36
+ - **Decouple deploy de release** — feature flag por default. Deploy = código em prod desligado; release = liga aos poucos.
37
+ - **Test em prod com subset** — 1% de tráfego com flag ativada > 100% rollout em horário de baixa.
38
+ - **Rollback < rollforward em duvida** — observabilidade rica mostra o que está errado em segundos, mas só se você não rolou-back o evidência primeiro. Pause primeiro, investigue, então decida.
39
+ - **Toda code branch = atributo** — `if (x) { ... } else { ... }` precisa emitir atributo de qual branch foi tomada (`branch_taken: 'fast_path'` vs `'slow_path'`).
40
+ - **Tighten do feedback loop é o objetivo** — minutos do commit ao prod, não dias. Cada hora de delay multiplica custo de debug.
41
+
42
+ ## Patterns canônicos
43
+
44
+ ### Pattern: feature instrumentada nasce ODD-compliant
45
+
46
+ ```ts
47
+ // PT-BR: feature nova "novo método de pagamento" — instrumentação BUNDLED
48
+ import { trace, SpanStatusCode } from '@opentelemetry/api'
49
+
50
+ const tracer = trace.getTracer('payments')
51
+
52
+ export async function processPaymentV2(req: PaymentRequest) {
53
+ return tracer.startActiveSpan('process_payment_v2', async (span) => {
54
+ // PT-BR: Pergunta 3 — quem está usando?
55
+ span.setAttribute('user.id', req.user.id)
56
+ span.setAttribute('customer.tier', req.user.tier)
57
+ span.setAttribute('tenant_id', req.user.tenant)
58
+ span.setAttribute('endpoint', '/api/v2/payments')
59
+
60
+ // PT-BR: Pergunta 2 — qual versão?
61
+ span.setAttribute('build_id', process.env.BUILD_ID ?? 'dev')
62
+ span.setAttribute('feature_flag.payments_v2', true) // PT-BR: assumed via flag
63
+ span.setAttribute('payment.method', req.method) // novo: 'pix' | 'crypto' | 'card'
64
+
65
+ // PT-BR: Pergunta 4 — atributo por branch
66
+ if (req.amount > 1_000_00) {
67
+ span.setAttribute('branch_taken', 'high_value')
68
+ span.setAttribute('requires_3ds', true)
69
+ } else {
70
+ span.setAttribute('branch_taken', 'standard')
71
+ span.setAttribute('requires_3ds', false)
72
+ }
73
+
74
+ try {
75
+ const result = await chargeProvider(req)
76
+
77
+ // PT-BR: Pergunta 1 — fez o que esperei?
78
+ span.setAttribute('result.success', true)
79
+ span.setAttribute('payment.id', result.id)
80
+ span.setAttribute('payment.processor_response', result.processorCode)
81
+ span.setStatus({ code: SpanStatusCode.OK })
82
+ return result
83
+ } catch (e) {
84
+ // PT-BR: Pergunta 4 — anomalia identificada com type enum
85
+ span.setAttribute('result.success', false)
86
+ span.setAttribute('error.type', classify(e)) // 'provider_down' | 'declined' | 'fraud_block'
87
+ span.setAttribute('error.processor_code', e.code)
88
+ span.setStatus({ code: SpanStatusCode.ERROR })
89
+ throw e
90
+ } finally {
91
+ span.end()
92
+ }
93
+ })
94
+ }
95
+ ```
96
+
97
+ ### Pattern: auto-page autor (config CI/CD)
98
+
99
+ ```yaml
100
+ # PT-BR: GitHub Actions ou equivalente — paginar autor após merge
101
+ # .github/workflows/post-merge-watch.yml
102
+ name: post-merge-watch
103
+ on:
104
+ push:
105
+ branches: [main]
106
+ jobs:
107
+ page-author:
108
+ runs-on: ubuntu-latest
109
+ steps:
110
+ - name: Page commit author for 30-60min
111
+ run: |
112
+ AUTHOR_EMAIL="${{ github.event.head_commit.author.email }}"
113
+ PAGER_TOKEN="${{ secrets.PAGERDUTY_TOKEN }}"
114
+ # PT-BR: criar policy temporária — alertas SLO route para AUTHOR_EMAIL
115
+ # por 45 minutos. Após, retorna ao on-call normal.
116
+ curl -X POST https://api.pagerduty.com/oncall_overrides \
117
+ -H "Authorization: Token token=$PAGER_TOKEN" \
118
+ -d "{
119
+ \"override\": {
120
+ \"start\": \"$(date -u +%FT%TZ)\",
121
+ \"end\": \"$(date -u -d '+45 minutes' +%FT%TZ)\",
122
+ \"user\": {\"email\": \"$AUTHOR_EMAIL\"}
123
+ }
124
+ }"
125
+ ```
126
+
127
+ ### Pattern: deploy ≠ release (feature flag)
128
+
129
+ ```ts
130
+ // PT-BR: deploy do código com flag DESLIGADA
131
+ const isV2Enabled = (req: Request): boolean => {
132
+ // PT-BR: 0% inicialmente — deploy = código em prod, mas dormente
133
+ if (!flags.isEnabled('payments_v2', { user_id: req.user.id })) {
134
+ return false
135
+ }
136
+ return true
137
+ }
138
+
139
+ export async function processPayment(req: PaymentRequest) {
140
+ if (isV2Enabled(req)) {
141
+ return processPaymentV2(req)
142
+ }
143
+ return processPaymentV1(req)
144
+ }
145
+
146
+ // PT-BR: depois do deploy, release gradual:
147
+ // 1. flag.set('payments_v2', { user_id: 'me' }) — só dev
148
+ // 2. flag.set('payments_v2', { customer.tier: 'free' }, 1%) — 1% free users
149
+ // 3. observe SLO + error rate; se OK, sobe para 10%, 50%, 100%
150
+ ```
151
+
152
+ ### Pattern: comparar versão antes/depois (Pergunta 2)
153
+
154
+ ```sql
155
+ -- PT-BR: SLI antes vs depois do deploy do build_id `abc123`
156
+ -- Mostra error_rate per build, agrupado por versão
157
+ select
158
+ build_id,
159
+ count(*) as total,
160
+ sum(case when result_success = false then 1 else 0 end) as errors,
161
+ 100.0 * sum(case when result_success = false then 1 else 0 end) / count(*) as error_pct,
162
+ percentile_cont(0.99) within group (order by duration_ms) as p99_ms
163
+ from observability.spans
164
+ where
165
+ service_name = 'payments'
166
+ and timestamp > '2026-05-06 10:00'
167
+ and build_id in ('v1.5.2', 'v1.5.3') -- versão anterior + atual
168
+ group by build_id;
169
+
170
+ -- PT-BR: se v1.5.3 tem error_pct ou p99_ms > v1.5.2 → regressão. Rollback ou fix.
171
+ ```
172
+
173
+ ### Pattern: instrumentação shift-left no PLAN.md de fase
174
+
175
+ ```markdown
176
+ # PLAN: Fase 42 — Novo método de pagamento
177
+
178
+ ## Tarefas
179
+
180
+ | # | Task | Output |
181
+ |---|------|--------|
182
+ | 1 | Implementar `processPaymentV2` em `src/payments/v2.ts` | função |
183
+ | 2 | **Instrumentação OTel — bundled** | spans + atributos |
184
+ | 3 | Adicionar feature flag `payments_v2` | flag config |
185
+ | 4 | Tests unitários | tests/v2.spec.ts |
186
+ | 5 | **ODD — 4 perguntas validadas** | comments no PR |
187
+
188
+ ## ODD — Validação das 4 perguntas
189
+
190
+ 1. **Faz o que esperei?**
191
+ - Span `process_payment_v2` com atributo `result.success`
192
+ - Query: `SELECT count(*) WHERE result_success=true / count(*)` deve ser ≥ 99% após release
193
+
194
+ 2. **Compara à versão anterior?**
195
+ - `build_id` em todo span permite cross-version
196
+ - Query: ver "Pattern: comparar versão" acima
197
+
198
+ 3. **Usuários estão usando?**
199
+ - `customer.tier`, `payment.method` permitem slice & dice
200
+ - Query: `SELECT customer.tier, payment.method, count(*) FROM ... WHERE feature_flag.payments_v2=true GROUP BY 1,2`
201
+
202
+ 4. **Anomalias emergem?**
203
+ - `error.type` enum: `'provider_down'`, `'declined'`, `'fraud_block'`
204
+ - `branch_taken` para code paths
205
+ - Alert: SLO burn rate > 2 sobre `WHERE feature_flag.payments_v2=true`
206
+ ```
207
+
208
+ ## Anti-patterns
209
+
210
+ ### ANTI: instrumentação como fase separada
211
+
212
+ ```text
213
+ ANTI: "Vamos shipá-la primeiro, instrumentar na próxima sprint."
214
+
215
+ PROBLEMA: você está em prod cego. Quando algo quebrar, você não tem dados para
216
+ investigar. Adicionar instrumentação depois requer redeploy, que é
217
+ arriscado durante incident.
218
+
219
+ CERTO: instrumentação NO MESMO PR da feature. Não-negociável.
220
+ ```
221
+
222
+ ### ANTI: glass castle (medo de mexer em prod)
223
+
224
+ ```text
225
+ ANTI: "Não deploy hoje, é véspera de feriado."
226
+ "Não deploy depois das 17h."
227
+ "Vamos esperar a próxima janela de manutenção."
228
+ (Equipe deploya 1× por semana, em batches grandes)
229
+
230
+ PROBLEMA: deploys raros = deploys grandes = mais código mudando = mais risco.
231
+ Cada deploy fica mais perigoso por sua raridade. Cycle vicioso.
232
+
233
+ CERTO: deploy frequente (várias vezes ao dia) com features pequenas atrás de flags.
234
+ Cada deploy quase nada. Reverter quase nada se quebra. Confiança aumenta.
235
+ ```
236
+
237
+ ### ANTI: rollback antes de investigar
238
+
239
+ ```text
240
+ ANTI: alerta dispara → rollback automático → "voltou ao normal" → ninguém
241
+ investiga porque "tá funcionando agora"
242
+
243
+ PROBLEMA: você perdeu a evidência. Próximo incident similar começa do zero.
244
+ Padrão de regressão acumula tech debt invisível.
245
+
246
+ CERTO: pause feature flag (não rollback do deploy) → investigue com observability →
247
+ fix root cause → re-release. Rollback só se investigation tomar > 30min.
248
+ ```
249
+
250
+ ### ANTI: testar com 100% rollout em horário de baixa
251
+
252
+ ```text
253
+ ANTI: "Faz deploy 4h da manhã quando ninguém usa."
254
+
255
+ PROBLEMA: você está rodando com 100% de risk em condições não-realistas.
256
+ 0 tráfego = 0 sinal. Quando bug aparecer no horário de pico, você
257
+ não terá dados.
258
+
259
+ CERTO: deploy a qualquer hora atrás de feature flag em 1% → observe → 10% → 100%.
260
+ Bugs aparecem no progressive rollout, não no horário de pico.
261
+ ```
262
+
263
+ ### ANTI: paginar on-call em vez do autor
264
+
265
+ ```text
266
+ ANTI: alerta dispara 2h após merge → on-call (que não escreveu o código) é paginado
267
+
268
+ PROBLEMA: on-call não tem contexto. Vai procurar "que mudou ultimamente" — toma 30min.
269
+ Autor está dormindo / fora do contexto. Feedback loop quebrado.
270
+
271
+ CERTO: por 30-60min após merge, alertas vão para o AUTOR. Ele tem o contexto fresco,
272
+ sabe o que mudou, pode reverter ou fix em 5min. Após janela, volta para on-call.
273
+ ```
274
+
275
+ ### ANTI: instrumentação só em happy path
276
+
277
+ ```text
278
+ ANTI: span com atributos só no `try` block; catch sem instrumentação
279
+
280
+ PROBLEMA: você não sabe nada sobre falhas. Pergunta 4 (anomalias) impossível de responder.
281
+
282
+ CERTO: cada `catch` adiciona `error.type` enum + `error.message` + `result.success=false`.
283
+ Cada early return adiciona `branch_taken: 'short_circuit_validation'` etc.
284
+ ```
285
+
286
+ ## Verificação
287
+
288
+ Antes de mergear PR, verificar as 4 perguntas:
289
+
290
+ | # | Pergunta | Validação |
291
+ |---|----------|-----------|
292
+ | 1 | **Faz o que esperei?** | Existe atributo `result.success` em algum span do código tocado? |
293
+ | 2 | **Compara à versão anterior?** | `build_id` é setado no span? (geralmente em SDK setup, validar uma vez) |
294
+ | 3 | **Usuários estão usando?** | Existe `user.id` ou `tenant_id` ou `customer.tier` no span? |
295
+ | 4 | **Anomalias emergem?** | `catch` blocks emitem `error.type` enum? branches if/else emitem `branch_taken`? |
296
+
297
+ Se qualquer pergunta = NÃO → PR não mergeable. Adicione instrumentação.
298
+
299
+ Após merge:
300
+ - ✅ Feature flag desligada por default? (deploy ≠ release)
301
+ - ✅ Auto-page do autor configurado por 30-60min?
302
+ - ✅ SLI/SLO baseline sabido para comparação pré/pós release?
303
+
304
+ ---
305
+
306
+ ## Ver também
307
+
308
+ - `kit/skills/_shared-observability/glossary.md` — termos canônicos, ODD, glass castle
309
+ - `kit/skills/structured-events/SKILL.md` — campos canônicos
310
+ - `kit/skills/distributed-tracing/SKILL.md` — instrumentação cross-service
311
+ - `kit/skills/event-based-slos/SKILL.md` *(Phase 32)* — SLI para baseline pré/pós release
312
+ - `kit/agents/observability-instrumenter.md` — agente que gera instrumentação
313
+ - `kit/commands/instrumentar-fase.md` — comando que aplica ODD em fases
314
+
315
+ *Material-fonte: Observability Engineering (O'Reilly, 2022) — Cap 11: "Observability-Driven Development".*