agent-engineering-skills 1.0.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 (48) hide show
  1. package/AGENTS.md +249 -0
  2. package/LICENSE +21 -0
  3. package/README.md +113 -0
  4. package/bin/cli.js +223 -0
  5. package/docs/agent-integration.md +200 -0
  6. package/docs/philosophy.md +131 -0
  7. package/docs/reference-authoring.md +117 -0
  8. package/docs/skill-authoring.md +126 -0
  9. package/examples/authorization-bypass.md +191 -0
  10. package/examples/frontend-review.md +244 -0
  11. package/examples/race-condition.md +128 -0
  12. package/examples/xp-reward-loop.md +123 -0
  13. package/package.json +45 -0
  14. package/references/engineering.yaml +88 -0
  15. package/references/frontend.yaml +139 -0
  16. package/references/product.yaml +54 -0
  17. package/references/research.yaml +88 -0
  18. package/references/security.yaml +85 -0
  19. package/references/ux.yaml +37 -0
  20. package/scripts/validate.py +454 -0
  21. package/skills/audit/adversarial-review/SKILL.md +190 -0
  22. package/skills/audit/business-logic-audit/SKILL.md +182 -0
  23. package/skills/audit/edge-case-hunter/SKILL.md +159 -0
  24. package/skills/audit/error-flow-audit/SKILL.md +184 -0
  25. package/skills/audit/state-consistency-audit/SKILL.md +174 -0
  26. package/skills/audit/user-flow-audit/SKILL.md +161 -0
  27. package/skills/frontend/accessibility-review/SKILL.md +186 -0
  28. package/skills/frontend/animation-review/SKILL.md +171 -0
  29. package/skills/frontend/interaction-design/SKILL.md +162 -0
  30. package/skills/frontend/ux-review/SKILL.md +172 -0
  31. package/skills/frontend/visual-quality-review/SKILL.md +160 -0
  32. package/skills/meta/research-router/SKILL.md +184 -0
  33. package/skills/meta/skill-router/SKILL.md +206 -0
  34. package/skills/product/gamification-audit/SKILL.md +213 -0
  35. package/skills/reliability/data-integrity-audit/SKILL.md +187 -0
  36. package/skills/reliability/idempotency-audit/SKILL.md +191 -0
  37. package/skills/reliability/race-condition-hunter/SKILL.md +181 -0
  38. package/skills/research/github-reference-research/SKILL.md +197 -0
  39. package/skills/research/implementation-research/SKILL.md +181 -0
  40. package/skills/research/market-research/SKILL.md +202 -0
  41. package/skills/research/reference-research/SKILL.md +186 -0
  42. package/skills/security/api-abuse-audit/SKILL.md +178 -0
  43. package/skills/security/authorization-audit/SKILL.md +176 -0
  44. package/skills/security/input-trust-audit/SKILL.md +178 -0
  45. package/templates/audit-report.md +89 -0
  46. package/templates/bug-report.md +107 -0
  47. package/templates/design-review.md +122 -0
  48. package/templates/research-report.md +96 -0
@@ -0,0 +1,182 @@
1
+ ---
2
+ name: business-logic-audit
3
+ description: Identifies business rules, invariants, limits, ownership, transitions, and rewards and for each asks where it is enforced, whether it can be bypassed, repeated, reversed, or raced.
4
+ category: audit
5
+ triggers:
6
+ - "audit business rules"
7
+ - "review invariants and limits"
8
+ - "check ownership and permissions logic"
9
+ - "audit a reward or scoring system"
10
+ - "verify rule enforcement server-side"
11
+ priority: high
12
+ ---
13
+
14
+ # Business Logic Audit
15
+
16
+ ## Objective
17
+
18
+ Ensinar o agente a extrair as **regras de negócio** implícitas em um sistema e, para
19
+ cada uma, aplicar um protocolo de cinco perguntas que expõe onde a regra é frágil:
20
+
21
+ ```text
22
+ Where is it enforced?
23
+ Can it be bypassed?
24
+ Can it be repeated?
25
+ Can it be reversed?
26
+ Can it race?
27
+ ```
28
+
29
+ A diferença entre "o código faz X" e "o negócio exige X e o código garante X" é onde
30
+ moram os bugs de lógica.
31
+
32
+ ## When to Use
33
+
34
+ * Quando o sistema tem regras: limites, cotas, ownership, permissões, transições de
35
+ estado, economia interna (XP, pontos, moedas, estoque).
36
+ * Antes de lançar features que envolvem valor transferível ou contável.
37
+ * Quando o pedido menciona "rules", "limits", "quotas", "ownership", "rewards",
38
+ "permissions", "state transitions".
39
+ * **Composição:** núcleo de quase toda auditoria de lógica. Pareia com
40
+ `gamification-audit` (regras de recompensa), `idempotency-audit` (repetições de
41
+ regra), `race-condition-hunter` (regras que dependem de read-then-write),
42
+ `authorization-audit` (ownership = autorização), `data-integrity-audit` (regras que
43
+ o banco deve impor), `input-trust-audit` (valores de regra confiados ao cliente).
44
+
45
+ ## Mental Model
46
+
47
+ Toda regra de negócio é, no fundo, um **invariant** — uma asserção que deve ser sempre
48
+ verdadeira. "Um usuário não pode dar XP a si mesmo." "O saldo nunca fica negativo."
49
+ "Um item deletado não pode ser editado." "Limite de 5 por dia."
50
+
51
+ O bug de lógica acontece quando o sistema *acredita* no invariant sem *garanti-lo*. O
52
+ modelo é:
53
+
54
+ ```text
55
+ regra (invariant) → onde é enforcement? → bypass? repeat? reverse? race?
56
+ ```
57
+
58
+ Se o enforcement está só no frontend, ou só em uma camada, ou em read-then-write sem
59
+ lock, o invariant é uma *crença*, não uma *garantia*. A skill transforma crenças em
60
+ perguntas e perguntas em evidência.
61
+
62
+ Classes de regra a procurar:
63
+
64
+ ```text
65
+ rules — o que deve/não deve acontecer
66
+ invariants — o que deve ser sempre verdadeiro
67
+ limits — cotas, máximos, mínimos, por-tempo
68
+ ownership — de quem é o recurso; quem pode agir
69
+ transitions — estados permitidos e proibidos
70
+ rewards — o que concede valor e sob quais condições
71
+ ```
72
+
73
+ ## Investigation Procedure
74
+
75
+ 1. **Inventariar regras.** Leia o fluxo e liste todas as regras implícitas. Para cada,
76
+ rotule a classe (rule/invariant/limit/ownership/transition/reward).
77
+ 2. **Para cada regra, responder às 5 perguntas:**
78
+ * **Where is it enforced?** — frontend? API? server handler? DB constraint? nenhuma?
79
+ * **Can it be bypassed?** — existe um caminho alternativo (outro endpoint, campo
80
+ extra, manipulação de ID) que contorna o enforcement?
81
+ * **Can it be repeated?** — executar a ação N vezes viola a regra? (limite diário
82
+ resetável por retry? reward por repetição?)
83
+ * **Can it be reversed?** — desfazer + refazer viola a regra? (reward concedida de
84
+ novo ao refazer?)
85
+ * **Can it race?** — a regra depende de ler estado e depois escrever? Dois requests
86
+ concorrentes passam pela checagem?
87
+ 3. **Triar por severidade** — regras sobre valor transferível (dinheiro, XP, estoque)
88
+ e ownership são mais graves que regras cosméticas.
89
+ 4. **Confirmar com evidência** — para cada "yes" nas perguntas, reproduzir ou apontar o
90
+ mecanismo no código.
91
+ 5. **Reportar** via `templates/audit-report.md`.
92
+
93
+ ## Questions to Ask
94
+
95
+ * Quais são todas as regras de negócio deste fluxo? (liste explicitamente)
96
+ * Para cada regra: onde exatamente ela é enforcement? É a única camada?
97
+ * A regra confia em algum valor enviado pelo cliente (price, role, xp, ownerId)?
98
+ * Se eu repetir a ação, a regra ainda vale? Ou o contador/limite é inconsistente?
99
+ * Se eu desfazer e refazer, o efeito é concedido duas vezes?
100
+ * A checagem lê estado e depois escreve baseada no que leu? Há janela de race?
101
+ * A regra é imposta por constraint do banco (unique, FK, check)? Ou só em código?
102
+ * Quem é o owner do recurso? A checagem de ownership é no servidor?
103
+ * Existem transições de estado que deveriam ser proibidas mas não são validadas?
104
+
105
+ ## Attack Patterns
106
+
107
+ ```text
108
+ bypass — alternative endpoint
109
+ fluxo oficial: POST /reward {reactionId} (valida regra "não self-reward")
110
+ endpoint direto: POST /admin/grant {userId, xp} (valida? ou é interno confiável?)
111
+
112
+ bypass — extra field / mass assignment
113
+ POST /update {name: "x"}
114
+ POST /update {name: "x", role: "admin"} (campo extra aceito → regra de role violada)
115
+
116
+ repeat — daily limit reset
117
+ POST /claim → +1 (contador "hoje": 1/5)
118
+ retry rápido → o contador é por-calendário ou por-janela? manipular timestamp?
119
+
120
+ reverse — reward refund + regrant
121
+ react → +10 XP
122
+ unreact → -10 XP (ou não?)
123
+ react → +10 XP
124
+ → se unreact não removeu XP, refazer = farming
125
+
126
+ race — check-then-act on a limit
127
+ request A: read "hoje: 4/5" → ok
128
+ request B: read "hoje: 4/5" → ok (mesma leitura)
129
+ request A: write "hoje: 5/5" + reward
130
+ request B: write "hoje: 5/5" + reward → 6/5, regra do limite violada
131
+
132
+ transition — illegal state reachable
133
+ DELETE /item → state: "deleted"
134
+ PUT /item {state: "active"} → permitido? transição proibida não checada?
135
+
136
+ ownership — authenticated ≠ authorized
137
+ GET /order/123 → 200 (é meu? ou só preciso estar logado?)
138
+ ```
139
+
140
+ ## Evidence Requirements
141
+
142
+ * **Nomear a regra e sua classe** (ex: "invariant: saldo não negativo").
143
+ * **Responder as 5 perguntas explicitamente** no finding — onde enforced, bypass,
144
+ repeat, reverse, race — mesmo que a resposta seja "não". Isto mostra que o protocolo
145
+ foi aplicado.
146
+ * **Mostrar o mecanismo da violação** — o endpoint/campo/sequência que contorna, ou o
147
+ read-then-write que abre race.
148
+ * **Escalar confiança:**
149
+ * `CONFIRMED` — reproduziu a violação da regra (ex: claim além do limite, reward
150
+ dupla).
151
+ * `HIGH CONFIDENCE` — código mostra enforcement faltando em um caminho claro.
152
+ * `POSSIBLE` — regra parece não enforced em um caminho plausível, não confirmado.
153
+ * `SPECULATIVE` — "deveria haver uma regra aqui" sem evidência de violação.
154
+
155
+ ## False Positives
156
+
157
+ * **Enforcement em múltiplas camadas** — se a regra é checada no handler E no banco
158
+ (constraint), um bypass aparente no handler é defendido pelo banco. Confirmar ambas
159
+ antes de reportar.
160
+ * **Regra é de UI, não de negócio** — "campo obrigatório no form" pode ser só UX; se o
161
+ backend aceita vazio legitimamente, não é bug de lógica.
162
+ * **Limite é soft por design** — alguns limites são orientativos, não duros. Verificar
163
+ a intenção de produto antes de reportar como defeito (marcar `POSSIBLE`).
164
+ * **Self-reward prevenido por design diferente** — talvez o sistema permita "self-XP"
165
+ em um contexto (admin) e proíba em outro. Não reportar bypass sem entender o modelo
166
+ de papéis.
167
+ * **Regra não existe** — se você *assume* uma regra que o produto não definiu, qualquer
168
+ "violação" é falso positivo. Liste a regra como hipótese e marque `SPECULATIVE` se
169
+ não há evidência de que ela deveria existir.
170
+
171
+ ## Output Format
172
+
173
+ Para cada regra com um "yes" em qualquer uma das 5 perguntas, um finding via
174
+ `templates/audit-report.md`. Em **Affected flow**, nomeie a regra violada. Em
175
+ **Reproduction**, mostre o caminho do bypass/repeat/reverse/race. Em **Root cause**,
176
+ diga *onde* o enforcement falta (camada, endpoint, ausência de constraint). Em
177
+ **Recommendation**, indique a camada que deve garantir o invariant (idealmente o banco,
178
+ ou lock/transaction no servidor).
179
+
180
+ Apresente o inventário de regras como tabela (regra | classe | onde enforced |
181
+ bypass? | repeat? | reverse? | race?), marcando as vulnerabilidades. Regras sobre valor
182
+ transferível e ownership primeiro.
@@ -0,0 +1,159 @@
1
+ ---
2
+ name: edge-case-hunter
3
+ description: Generates edge cases around null, empty, zero, negative, huge values, duplicates, Unicode, stale data, deleted data, expired data, and repeated valid actions, then checks whether the system handles each.
4
+ category: audit
5
+ triggers:
6
+ - "find edge cases"
7
+ - "test boundary values"
8
+ - "what about null empty zero negative huge"
9
+ - "stress inputs with edge values"
10
+ - "unicode and duplicate handling"
11
+ priority: high
12
+ ---
13
+
14
+ # Edge Case Hunter
15
+
16
+ ## Objective
17
+
18
+ Ensinar o agente a **gerar sistematicamente** casos de fronteira e verificar se o
19
+ sistema trata cada um. Ao contrário de skills que atacam lógica ou fluxo, esta ataca
20
+ **valores** — as entradas nos limites onde suposições sobre formato, magnitude e
21
+ conteúdo quebram.
22
+
23
+ ## When to Use
24
+
25
+ * Ao auditar qualquer função/campo que recebe input (formulários, APIs, imports,
26
+ parseadores, cálculos).
27
+ * Antes de confiar em um cálculo (saldo, XP, preço, contador, posição, índice).
28
+ * Quando o pedido menciona "edge cases", "boundary", "what about X values", "stress
29
+ inputs".
30
+ * **Composição:** complementar, não substitutiva. Rode junto com
31
+ `input-trust-audit` (esses valores viriam do cliente?), `business-logic-audit`
32
+ (limites que são regras), `error-flow-audit` (o que acontece quando o edge case
33
+ quebra), `data-integrity-audit` (o banco aceita esses valores?).
34
+
35
+ ## Mental Model
36
+
37
+ A maioria do código é testada no happy path com valores "redondos" (1, 10, "hello").
38
+ Bugs vivem nas **fronteiras** — onde o input deixa de ser "normal" e expõe uma suposição
39
+ não escrita: "não será nulo", "não será vazio", "será positivo", "cabe em um int",
40
+ "é ASCII", "é único", "ainda existe".
41
+
42
+ A skill usa uma lista canônica de eixos de fronteira e, para cada campo/entrada
43
+ relevante, pergunta "o que acontece se este valor for `<eixo>`?". É exaustivo por
44
+ intenção, mas **triado por relevância**: nem todo eixo aplica a todo campo.
45
+
46
+ Eixos canônicos (do `plan.md` §6):
47
+
48
+ ```text
49
+ null empty zero negative
50
+ huge values duplicates Unicode stale data
51
+ deleted data expired data repeated valid actions
52
+ ```
53
+
54
+ ## Investigation Procedure
55
+
56
+ 1. **Listar entradas.** Identifique todos os campos/parâmetros/entradas que o
57
+ componente recebe (do cliente, de outra camada, de um job, de um import).
58
+ 2. **Para cada entrada, mapear o tipo e as suposições** — número? string? referência a
59
+ entidade? data? Enumerar o que o código assume sobre ele.
60
+ 3. **Gerar casos por eixo.** Para cada entrada × eixo aplicável, formule o caso.
61
+ Ex: `balance` × `negative` → "saldo -50"; `name` × `Unicode` → "nome com
62
+ zero-width/emoji/RTR"; `parentId` × `deleted data` → "referencia entidade deletada".
63
+ 4. **Executar/verificar cada caso.** O que o sistema faz? Erro limpo? Silent fail?
64
+ Estado corrompido? Crash? Comportamento errado sem erro?
65
+ 5. **Triar.** Descarte casos onde o eixo não aplica (ex: `negative` em um enum).
66
+ Priorize casos que corrompem estado ou causam comportamento errado silencioso.
67
+ 6. **Confirmar com evidência** — reproduza o input e observe a saída/estado.
68
+ 7. **Reportar** via `templates/audit-report.md`.
69
+
70
+ ## Questions to Ask
71
+
72
+ * O que acontece se este campo for `null`? E vazio (`""`)? E só whitespace?
73
+ * E se for `0`? E `-1` / negativo?
74
+ * E se for enorme (overflow de int, string de 1MB, array de 10⁶ itens)?
75
+ * E se houver duplicata (dois iguais onde deveria ser único)?
76
+ * E se tiver Unicode exótico (zero-width joiner, RTL, emoji, combinando)?
77
+ * E se o dado referenciado foi deletado? (FK pendente, soft-deleted mas ainda usado)
78
+ * E se o dado está expirado? (token, sessão, oferta, cupom)
79
+ * E se for stale (cache desatualizado vs fonte)?
80
+ * E se a mesma ação válida for repetida N vezes? (limite, contador, reward)
81
+ * O erro (quando ocorre) é limpo e tratado, ou vaza crash/stack trace?
82
+
83
+ ## Attack Patterns
84
+
85
+ ```text
86
+ null
87
+ field: null → NullPointerException? 500? ou tratado como default?
88
+
89
+ empty
90
+ name: "" → validado? ou aceito e quebra display/sort?
91
+
92
+ zero
93
+ quantity: 0 → cálculo de total = 0 ok? ou divisão por zero downstream?
94
+ price: 0 → checkout grátis "válido"?
95
+
96
+ negative
97
+ amount: -50 → transfere -50 (inverte fluxo)? saldo fica negativo?
98
+
99
+ huge
100
+ count: 2147483648 → overflow int? loop eterno? OOM?
101
+ file: 10GB → limite de upload?
102
+
103
+ duplicate
104
+ POST /create {slug:"x"} twice → 409? ou cria dois?
105
+
106
+ Unicode
107
+ name: "a​​b" → zero-width; igual a "ab"? duplicata invisível?
108
+ name: "‮" → RTL override; rendering invertido
109
+
110
+ deleted data
111
+ POST /comment {postId: <deleted>} → cria comentário órfão?
112
+
113
+ expired data
114
+ redeem code expired → ainda resgata? ou checa expiração?
115
+
116
+ stale data
117
+ cache: balance=100, db: balance=50 → usa cache e permite gastar 100?
118
+
119
+ repeated valid action
120
+ claim reward 5× → limite por-janela respeitado? ou farming?
121
+ ```
122
+
123
+ ## Evidence Requirements
124
+
125
+ * **Nomear o eixo e o campo** testados.
126
+ * **Mostrar o input exato** usado (valor literal, não "um valor grande").
127
+ * **Mostrar a saída/estado resultante** — não só "quebra", mas *como* (erro 500,
128
+ silent success com estado errado, crash, comportamento correto).
129
+ * **Escalar confiança:**
130
+ * `CONFIRMED` — reproduziu com o input literal e observou o resultado.
131
+ * `HIGH CONFIDENCE` — código mostra caminho que não trata o eixo, sem reprodução.
132
+ * `POSSIBLE` — eixo plausível, caminho não confirmado.
133
+ * `SPECULATIVE` — "pode quebrar com X" sem rastrear.
134
+ * Priorize `silent success com estado errado` — é pior que crash, porque não alerta.
135
+
136
+ ## False Positives
137
+
138
+ * **Validação de tipo no boundary do framework** — se o ORM/schema rejeita null/empty
139
+ antes do handler, o caso é tratado. Confirmar antes de reportar.
140
+ * **Default intencional** — alguns campos legitimamente defaultam null/0 e o código
141
+ trata downstream. Não reportar "aceita null" se o nulo é intencional e tratado.
142
+ * **Unicode normalizado por design** — se o sistema normaliza (NFC) e colapsa
143
+ zero-width de propósito, "duplicata invisível" é tratada, não bug.
144
+ * **Soft delete intencional** — referenciar entidade "deletada" (soft) pode ser
145
+ desejado (histórico). Verificar se é hard ou soft delete antes de reportar.
146
+ * **Limite enorme não é defeito** — se o sistema *deve* aceitar arquivos grandes,
147
+ "aceita 10GB" não é bug; "não limita e dá OOM" seria.
148
+ * **Caso não aplica** — `negative` em um boolean/enum não aplica; não force.
149
+
150
+ ## Output Format
151
+
152
+ Para cada caso que produz comportamento errado (não só erro), um finding via
153
+ `templates/audit-report.md`. Em **Reproduction**, dê o input literal e o comando
154
+ request. Em **Actual behavior**, descreva exatamente o resultado observado. Em
155
+ **Recommendation**, indique validação (onde: schema vs handler vs sanitização).
156
+
157
+ Apresente a matriz de cobertura como tabela (entrada × eixos aplicáveis, marcando
158
+ ✓ tratado / ✗ falha / — não aplica). Isto documenta quais eixos foram testados e
159
+ previne retrabalho. Silenciosos (estado errado sem erro) primeiro; crashes depois.
@@ -0,0 +1,184 @@
1
+ ---
2
+ name: error-flow-audit
3
+ description: Investigates partial success, timeouts, lost responses, retries, crashes, and rollback failures to find states left inconsistent or operations left half-done when something fails mid-flight.
4
+ category: audit
5
+ triggers:
6
+ - "audit error handling"
7
+ - "what happens on failure mid-flow"
8
+ - "partial success and rollback"
9
+ - "retry and timeout behavior"
10
+ - "crash recovery and lost responses"
11
+ priority: high
12
+ ---
13
+
14
+ # Error Flow Audit
15
+
16
+ ## Objective
17
+
18
+ Ensinar o agente a parar de perguntar "isto funciona?" e perguntar **"o que acontece
19
+ quando isto falha no meio?"**. Toda operação multi-passo pode falhar entre os passos;
20
+ esta skill mapeia os pontos de falha e verifica se o sistema deixa o estado consistente
21
+ ou abandona o sistema em um estado parcial.
22
+
23
+ ```text
24
+ partial success timeouts lost responses retries crashes rollback failures
25
+ ```
26
+
27
+ ## When to Use
28
+
29
+ * Quando uma operação toca múltiplos recursos/serviços (DB + API externa + fila +
30
+ cache) e pode falhar entre eles.
31
+ * Quando há retries, timeouts, circuit breakers, ou webhooks.
32
+ * Quando uma falha pode deixar estado parcial (recurso criado mas notificação não
33
+ enviada; cobrança efetivada mas pedido não; metadados escritos mas arquivo não).
34
+ * Quando o pedido menciona "error handling", "rollback", "retry", "timeout", "what if
35
+ it fails", "partial", "idempotent on retry".
36
+ * **Composição:** pareia com `idempotency-audit` (retry de operação inteira),
37
+ `data-integrity-audit` (transação/rollback no banco), `state-consistency-audit`
38
+ (estado parcial = desync entre camadas), `user-flow-audit` (fluxo que falha num
39
+ passo intermediário), `race-condition-hunter` (falha concorrente com outra mutação).
40
+
41
+ ## Mental Model
42
+
43
+ O happy path é fácil. O perigo é o **caminho parcial**: a operação completa passo 1,
44
+ falha no passo 2, e agora o sistema tem o efeito do passo 1 sem o do passo 2 — um estado
45
+ que o happy path nunca produziria e que ninguém projetou para existir.
46
+
47
+ As duas armadilhas simétricas:
48
+
49
+ 1. **Sem rollback** — passo 1 efetivado, passo 2 falha, passo 1 não é desfeito. Estado
50
+ parcial persiste.
51
+ 2. **Rollback sem idempotência** — retry reexecuta passo 1 (já feito) e cria efeito
52
+ duplicado. Ou rollback desfaz e reexecuta do zero, mas o "efeito externo" (email,
53
+ cobrança) já ocorreu e não é reversível.
54
+
55
+ O modelo: para cada operação multi-passo, pergunte *qual passo é idempotente*, *qual
56
+ é reversível*, *qual tem efeito externo irreversível*, e *o que acontece se falhar
57
+ após cada um*. Pontos de não-retorno (efeito externo já disparado) são os mais críticos.
58
+
59
+ Classes de falha a investigar (do `plan.md` §6):
60
+
61
+ ```text
62
+ partial success — alguns passos efetivam, outros não
63
+ timeouts — chamada pendente; estado desconhecido (fez ou não fez?)
64
+ lost responses — servidor agiu mas o cliente não sabe; retry?
65
+ retries — reexecução; idempotente? ou duplica efeito?
66
+ crashes — processo morre mid-op; estado em disco consistente?
67
+ rollback failures — tentou desfazer e o rollback também falhou; agora o quê?
68
+ ```
69
+
70
+ ## Investigation Procedure
71
+
72
+ 1. **Decompor a operação em passos.** Liste cada efeito (write DB, call API externa,
73
+ enqueue, send email, update cache, emit event).
74
+ 2. **Rotular cada passo:** idempotente? reversível? efeito externo (irreversível)?
75
+ 3. **Para cada ponto de falha (após passo k), perguntar:**
76
+ * O estado parcial é consistente ou corrompido?
77
+ * Há rollback? O rollback cobre todos os passos k?
78
+ * O rollback é idempotente (safe to retry)?
79
+ * Há efeito externo irreversível já disparado antes do ponto de falha?
80
+ 4. **Testar timeout/lost-response:** se a chamada pendente, o sistema trata como
81
+ "feito", "não feito", ou "desconhecido"? O retry é seguro?
82
+ 5. **Testar retry:** reexecutar a operação inteira após falha — duplica algum efeito?
83
+ 6. **Testar crash mid-op:** se o processo morre entre passos, o estado em disco é
84
+ consistente ao reiniciar? Há recuperação/reconciliação?
85
+ 7. **Testar rollback failure:** se o rollback também falha, o sistema fica em quê?
86
+ Há alerta/reconciliação, ou silencioso?
87
+ 8. **Confirmar com evidência** — injete falha no passo k e observe o estado final.
88
+ 9. **Reportar** via `templates/audit-report.md`.
89
+
90
+ ## Questions to Ask
91
+
92
+ * Quais são os passos/efeitos desta operação? Qual ordem?
93
+ * Qual passo é o ponto de não-retorno (efeito externo irreversível)?
94
+ * Se falhar *após* o ponto de não-retorno, o que acontece?
95
+ * Há transação? Ela cobre todos os writes ou só alguns?
96
+ * Para chamada externa: timeout → estado desconhecido. Como o sistema resolve?
97
+ * Retry da operação inteira é idempotente? Ou duplica um efeito?
98
+ * Se o processo crashar entre passos, há reconciliação ao reiniciar?
99
+ * O rollback, se existe, é idempotente? E se o rollback falhar?
100
+ * Erros são tratados ou engolidos (empty catch)? Estado parcial é detectável?
101
+
102
+ ## Attack Patterns
103
+
104
+ ```text
105
+ partial success — no transaction
106
+ step 1: write db order "created" ✓ committed
107
+ step 2: charge payment ✗ fails
108
+ → order exists, never paid, no rollback. Estado parcial.
109
+
110
+ partial success — external effect before commit
111
+ step 1: call payment gateway ✓ charged (irreversível)
112
+ step 2: write db order "paid" ✗ db error
113
+ → cobrado, pedido não registrado. Ponto de não-retorno passado.
114
+
115
+ timeout → unknown state
116
+ call external API: 30s, no response
117
+ → agiu ou não? retry agora duplica se agiu (não-idempotente).
118
+
119
+ lost response → blind retry
120
+ server processes request, response lost in network
121
+ client retries → reexecuta → efeito duplicado se não-idempotente.
122
+
123
+ retry that doubles
124
+ create + send welcome email
125
+ fails after create, before email
126
+ retry → create again (duplica) se create não-idempotente.
127
+
128
+ crash mid-op, no recovery
129
+ step 1: decrement stock
130
+ crash
131
+ restart → stock decremented, order never created. Sem reconciliação.
132
+
133
+ rollback failure, silent
134
+ try: step1, step2
135
+ catch: undo step1 ← undo also fails
136
+ → step1 efetivado, sem log/alerta. Corrupção silenciosa.
137
+
138
+ empty catch / swallowed error
139
+ try { externalCall() } catch {}
140
+ → falha virou sucesso aparente; estado parcial não detectado.
141
+ ```
142
+
143
+ ## Evidence Requirements
144
+
145
+ * **Nomear o ponto de falha** (após qual passo) e o **estado parcial resultante**.
146
+ * **Rotular cada passo** (idempotente / reversível / efeito externo) no finding.
147
+ * **Mostrar o mecanismo** — onde falta transação, onde retry não é idempotente, onde
148
+ rollback não cobre, onde catch engole. Ou reprodução com falha injetada.
149
+ * **Escalar confiança:**
150
+ * `CONFIRMED` — injetou falha e observou estado parcial/corrompido.
151
+ * `HIGH CONFIDENCE` — código mostra ausência de transação/rollback/idempotência em
152
+ caminho claro.
153
+ * `POSSIBLE` — plausível, caminho não confirmado.
154
+ * `SPECULATIVE` — "pode falhar" sem rastrear.
155
+ * Estados parciais **com efeito externo irreversível** (dinheiro cobrado, email
156
+ enviado) e **silenciosos** (empty catch) são os mais graves.
157
+
158
+ ## False Positives
159
+
160
+ * **Transação cobre todos os writes** — se tudo está em uma DB transaction e nada de
161
+ externo ocorre antes do commit, "falha mid-op" é seguro (rollback automático).
162
+ Confirmar antes de reportar.
163
+ * **Operação é idempotente por design** — retry seguro significa "duplica" não é bug.
164
+ Relacionado a `idempotency-audit`; não duplique o finding.
165
+ * **Saga/outbox com reconciliação** — se há outbox + worker que reconcilia estado
166
+ parcial, a inconsistência é temporária e tratada. Reportar só se a reconciliação é
167
+ ausente/quebrada.
168
+ * **Timeout tratado como "unknown" com query+decide** — se após timeout o sistema
169
+ consulta o estado real antes de retry, é correto. Não reportar.
170
+ * **Empty catch é intencional e compensado** — raro, mas se há compensação downstream,
171
+ confirmar antes de reportar como defeito.
172
+
173
+ ## Output Format
174
+
175
+ Para cada ponto de falha que deixa estado parcial/corrompido, um finding via
176
+ `templates/audit-report.md`. Em **Reproduction**, descreva a falha injetada (qual
177
+ passo falha, como) e o estado final observado. Em **Affected flow**, nomeie a operação.
178
+ Em **Root cause**, diga o que falta (transação, rollback, idempotência no retry,
179
+ reconciliação, detecção de erro). Em **Recommendation**, indique a estratégia (transação
180
+ atómica, outbox/saga, idempotency key, query-on-timeout, alerta em rollback failure).
181
+
182
+ Apresente a decomposição como tabela (passo | efeito | idempotente? | reversível? |
183
+ efeito externo? | estado se falhar após). Pontos de não-retorno e estados silenciosos
184
+ primeiro.