@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.
Files changed (117) hide show
  1. package/bin/cli.js +2 -2
  2. package/bin/mcp.js +6 -6
  3. package/bin/ui.js +74 -74
  4. package/gates/ai-prompt-stability.md +120 -120
  5. package/gates/budget-description.md +68 -68
  6. package/gates/confidence.md +29 -29
  7. package/gates/dependency-check.md +33 -33
  8. package/gates/dept-cycle-prevention.md +179 -179
  9. package/gates/golden-signals-coverage.md +133 -133
  10. package/gates/legacy-refactor-safety.md +178 -178
  11. package/gates/multi-tenant-rls-coverage.md +102 -102
  12. package/gates/no-personal-uuid.md +72 -72
  13. package/gates/obs-agents-mcp-supabase.md +86 -86
  14. package/gates/obs-skills-frontmatter.md +76 -76
  15. package/gates/observability-coverage.md +151 -151
  16. package/gates/omm-no-regression.md +83 -83
  17. package/gates/postmortem-template-required.md +127 -127
  18. package/gates/prr-checklist-coverage.md +128 -128
  19. package/gates/regression.md +32 -32
  20. package/gates/release-pipeline-policy.md +132 -132
  21. package/gates/secrets-scan.md +33 -33
  22. package/gates/service-role-not-in-user-facing.md +113 -113
  23. package/gates/skill-must-include.md +71 -71
  24. package/gates/sync-idempotent.md +62 -62
  25. package/gates/verify-phase-goal.md +34 -34
  26. package/kit/agents/designer-ui.md +216 -216
  27. package/kit/agents/workflow-generator.md +537 -167
  28. package/kit/commands/adicionar-backlog.md +1 -1
  29. package/kit/commands/adicionar-fase.md +1 -1
  30. package/kit/commands/adicionar-tarefa.md +1 -1
  31. package/kit/commands/auditar-observabilidade.md +103 -103
  32. package/kit/commands/auditar-toil.md +129 -129
  33. package/kit/commands/caracterizar-prompt.md +195 -195
  34. package/kit/commands/criar-workflow.md +158 -158
  35. package/kit/commands/definir-perfil.md +1 -1
  36. package/kit/commands/definir-slo.md +108 -108
  37. package/kit/commands/fio.md +1 -1
  38. package/kit/commands/golden-signals.md +142 -142
  39. package/kit/commands/instrumentar-fase.md +200 -200
  40. package/kit/commands/investigar-producao.md +162 -162
  41. package/kit/commands/observabilidade.md +118 -118
  42. package/kit/commands/postmortem.md +179 -179
  43. package/kit/commands/prr.md +205 -205
  44. package/kit/commands/publicar-rapido.md +207 -207
  45. package/kit/commands/risk-budget.md +220 -220
  46. package/kit/commands/sre.md +230 -230
  47. package/kit/file-manifest.json +424 -424
  48. package/kit/framework/references/output-style.md +22 -22
  49. package/kit/hooks/post-apply-migration.js +199 -199
  50. package/kit/hooks/sidecar-tool-publisher.js +210 -210
  51. package/kit/skills/_shared-dados-distribuidos/glossary.md +224 -224
  52. package/kit/skills/_shared-legacy/glossary.md +389 -389
  53. package/kit/skills/_shared-multi-tenant/glossary.md +186 -186
  54. package/kit/skills/_shared-observability/glossary.md +396 -396
  55. package/kit/skills/_shared-sre/glossary.md +712 -712
  56. package/kit/skills/_shared-supabase/glossary.md +234 -234
  57. package/kit/skills/blameless-postmortems/SKILL.md +340 -340
  58. package/kit/skills/burn-rate-alerting/SKILL.md +258 -258
  59. package/kit/skills/cascading-failures/SKILL.md +311 -311
  60. package/kit/skills/core-analysis-loop/SKILL.md +352 -352
  61. package/kit/skills/distributed-tracing/SKILL.md +362 -362
  62. package/kit/skills/dynamic-workflow-authoring/SKILL.md +327 -223
  63. package/kit/skills/eliminating-toil/SKILL.md +243 -243
  64. package/kit/skills/event-based-slos/SKILL.md +296 -296
  65. package/kit/skills/four-golden-signals/SKILL.md +314 -314
  66. package/kit/skills/hermetic-builds/SKILL.md +323 -323
  67. package/kit/skills/legacy-monster-methods/SKILL.md +444 -444
  68. package/kit/skills/llm-as-dependency/SKILL.md +436 -436
  69. package/kit/skills/load-shedding-graceful-degradation/SKILL.md +396 -396
  70. package/kit/skills/observability-driven-development/SKILL.md +315 -315
  71. package/kit/skills/observability-maturity-model/SKILL.md +222 -222
  72. package/kit/skills/opentelemetry-standard/SKILL.md +351 -351
  73. package/kit/skills/production-readiness-review/SKILL.md +305 -305
  74. package/kit/skills/release-engineering/SKILL.md +367 -367
  75. package/kit/skills/retry-strategies/SKILL.md +372 -372
  76. package/kit/skills/sre-risk-management/SKILL.md +221 -221
  77. package/kit/skills/structured-events/SKILL.md +265 -265
  78. package/kit/skills/supabase-cron-queues/SKILL.md +275 -275
  79. package/kit/skills/supabase-database-functions/SKILL.md +332 -332
  80. package/kit/skills/supabase-declarative-schema/SKILL.md +183 -183
  81. package/kit/skills/supabase-pgvector-rag/SKILL.md +253 -253
  82. package/kit/skills/supabase-postgres-style/SKILL.md +138 -138
  83. package/kit/skills/supabase-storage/SKILL.md +234 -234
  84. package/kit/skills/telemetry-pipelines/SKILL.md +259 -259
  85. package/kit/skills/telemetry-sampling/SKILL.md +256 -256
  86. package/kit/skills/ui-anti-padroes-ia/SKILL.md +261 -261
  87. package/kit/skills/ui-contexto-produto/SKILL.md +248 -248
  88. package/kit/skills/ui-cor-estrategia/SKILL.md +213 -213
  89. package/kit/skills/ui-critica-auditoria/SKILL.md +260 -260
  90. package/kit/skills/ui-motion-funcional/SKILL.md +264 -264
  91. package/kit/skills/ui-ritmo-espacial/SKILL.md +259 -259
  92. package/kit/skills/ui-tipografia/SKILL.md +211 -211
  93. package/package.json +1 -1
  94. package/src/cli/index.js +1114 -1114
  95. package/src/cli/render.js +194 -194
  96. package/src/cli/upgrade-check.js +135 -135
  97. package/src/core/error-redaction.js +76 -76
  98. package/src/core/failures.js +153 -153
  99. package/src/core/gate-runner.js +205 -205
  100. package/src/core/gates.js +82 -82
  101. package/src/core/logger.js +170 -170
  102. package/src/core/manifest-verify.js +174 -174
  103. package/src/core/metrics.js +268 -268
  104. package/src/core/notify.js +60 -60
  105. package/src/core/path-safety.js +141 -141
  106. package/src/core/replays.js +120 -120
  107. package/src/core/ui.js +185 -185
  108. package/src/mcp-server/install.js +149 -149
  109. package/src/mcp-server/roots.js +124 -124
  110. package/src/ui/auto-spawn.js +113 -113
  111. package/src/ui/browser.js +78 -78
  112. package/src/ui/client.js +130 -130
  113. package/src/ui/events.js +65 -65
  114. package/src/ui/lockfile.js +191 -191
  115. package/src/ui/port.js +67 -67
  116. package/src/ui/server.js +547 -547
  117. package/src/ui/wrapper.js +129 -129
@@ -1,223 +1,327 @@
1
- ---
2
- name: dynamic-workflow-authoring
3
- description: Use ao gerar/criticar `.workflow.js` (Opus 4.8+). Codifica os 6 patterns canonicos (Classify-Act, Fanout-Synthesize, Adversarial-Verify, Generate-Filter, Tournament, Loop-Done) + API rules.
4
- ---
5
-
6
- # Dynamic Workflow Authoring
7
-
8
- **Fonte canônica:** [A harness for every task — Anthropic blog](https://claude.com/blog/a-harness-for-every-task-dynamic-workflows-in-claude-code).
9
-
10
- Esta skill existe para que workflows gerados pelo kit sigam um vocabulário comum e não reinventem padrões. Consulte-a SEMPRE antes de materializar um `.workflow.js`.
11
-
12
- ## Os 6 patterns canônicos
13
-
14
- A primeira decisão de design é qual pattern usar ela determina a topologia do script. Todo workflow real ou é exatamente um destes ou uma composição limpa de dois.
15
-
16
- ### 1. Classify-And-Act
17
- **Quando:** tipos diferentes de entrada precisam de tratamentos diferentes.
18
- **Tasks:** ticket triage (severity → agent específico), content moderation (violation type → handler), routing de PRs por área de código.
19
- **API:**
20
- ```js
21
- phase('Classify')
22
- const cls = await agent(`Classifique X em uma de: A, B, C.`, { schema: CLS_SCHEMA })
23
- phase('Act')
24
- const result = await agent(PROMPTS[cls.label], { schema: ACT_SCHEMA })
25
- ```
26
- **Anti-pitfall:** classifier vagaroso anula o ganho — mantenha-o pequeno e schema-estruturado. Se o classifier precisa do contexto completo, considere se isn't really Fanout disfarçado.
27
-
28
- ### 2. Fanout-And-Synthesize
29
- **Quando:** N itens similares onde isolation previne interferência cruzada.
30
- **Tasks:** "renomeie User → Account em todos os arquivos", processar 80 currículos, auditar N Edge Functions, julgar N conversas.
31
- **API:**
32
- ```js
33
- phase('Fanout')
34
- const results = await pipeline(
35
- items,
36
- item => agent(`Process ${item.id}`, { phase: 'Fanout', schema: ITEM_SCHEMA })
37
- )
38
- phase('Synthesize')
39
- const summary = await agent(`Synthesize: ${JSON.stringify(results)}`, { schema: REPORT_SCHEMA })
40
- ```
41
- **Default:** `pipeline()` sobre `parallel()` barrier entre fanout e synthesize só se a síntese precisa de TODOS de uma vez.
42
-
43
- ### 3. Adversarial-Verification
44
- **Quando:** qualidade crítica, custo de falso-positivo > custo de revisão extra.
45
- **Tasks:** code review, fact-checking, audit de findings de segurança, qualquer "X é real ou ilusão?".
46
- **API:**
47
- ```js
48
- const finding = await agent(FIND_PROMPT, { phase: 'Find', schema: FINDING_SCHEMA })
49
- const verdict = await agent(
50
- `Você é cético. Tente REFUTAR: ${JSON.stringify(finding)}.
51
- Default: refuted=true em caso de dúvida.`,
52
- { phase: 'Verify', schema: VERDICT_SCHEMA }
53
- )
54
- if (verdict.confirmed) commit(finding)
55
- ```
56
- **Multi-voto:** quando o caso é cinza, spawne 3 verificadores independentes e exija majority:
57
- ```js
58
- const votes = await parallel(Array.from({length: 3}, () => () =>
59
- agent(`Refute: ${claim}`, { schema: VERDICT_SCHEMA })))
60
- const survives = votes.filter(Boolean).filter(v => !v.refuted).length >= 2
61
- ```
62
- **Perspective-diverse:** se o achado pode falhar de mais de uma forma, dê lentes DIFERENTES a cada verificador (correctness/security/perf) — diversidade pega o que redundância não pega.
63
-
64
- ### 4. Generate-And-Filter
65
- **Quando:** espaço de solução amplo, qualidade varia, descarte é barato.
66
- **Tasks:** gerar nomes de CLI/produto, brainstormar abordagens de design, listar hipóteses de bug.
67
- **API:**
68
- ```js
69
- phase('Generate')
70
- const candidates = (await parallel(Array.from({length: N}, (_, i) => () =>
71
- agent(GEN_PROMPT(i), { schema: GEN_SCHEMA })))).filter(Boolean)
72
- phase('Filter')
73
- const top = await agent(
74
- `Avalie e dê top ${K} pela rubrica: ${RUBRIC}. Candidatos: ${JSON.stringify(candidates)}`,
75
- { schema: TOP_SCHEMA }
76
- )
77
- ```
78
- **Varie o prompt do generator por índice** (i no exemplo acima) — gera diversidade. Se todos os generators têm exatamente o mesmo prompt, você paga N tokens pra obter ~1 resposta.
79
-
80
- ### 5. Tournament
81
- **Quando:** ranking qualitativo, julgamento relativo > absoluto.
82
- **Tasks:** ordenar 1000+ tickets por severidade, escolher melhor design entre N propostas, priorizar lista de bugs.
83
- **API:**
84
- ```js
85
- let bracket = candidates
86
- while (bracket.length > 1) {
87
- bracket = await pipeline(
88
- chunk(bracket, 2),
89
- pair => agent(
90
- `Compare A e B pela métrica X. Devolva winner.`,
91
- { phase: `Round-${bracket.length}`, schema: COMPARE_SCHEMA }
92
- ).then(r => r.winner)
93
- )
94
- }
95
- return bracket[0]
96
- ```
97
- **Anti-pitfall:** se a métrica é absoluta (score 0–10 estável), use Generate-And-Filter — Tournament é caro em wall-clock e tokens (log₂N rounds).
98
-
99
- ### 6. Loop-Until-Done
100
- **Quando:** volume desconhecido, condição de parada > contador fixo.
101
- **Tasks:** reproduzir flaky test até falhar, bug hunt até K rounds vazios, search com retry até confidence threshold.
102
- **API (loop-until-dry):**
103
- ```js
104
- const seen = new Set()
105
- let dry = 0
106
- while (dry < 2) {
107
- const fresh = (await agent(FIND_PROMPT, { schema: BUGS_SCHEMA })).bugs
108
- .filter(b => !seen.has(key(b)))
109
- if (!fresh.length) { dry++; continue }
110
- dry = 0
111
- fresh.forEach(b => seen.add(key(b)))
112
- // ... process fresh
113
- }
114
- ```
115
- **Loop-until-budget:** scale automático ao `+500k` do usuário:
116
- ```js
117
- while (budget.total && budget.remaining() > 50_000) {
118
- const r = await agent(FIND_PROMPT, { schema: BUGS_SCHEMA })
119
- if (!r.bugs.length) break
120
- bugs.push(...r.bugs)
121
- }
122
- ```
123
- **Guard sempre** em `budget.total` — `remaining()` é `Infinity` sem target e o loop bate o cap de 1000 agents.
124
-
125
- ## Regras DURAS da API (violar = workflow quebra)
126
-
127
- ### O `meta` é literal puro
128
- ```js
129
- // ✓ ok
130
- export const meta = {
131
- name: 'audit-pr-staleness',
132
- description: 'List PRs open >7d without review and rank by impact.',
133
- phases: [{ title: 'Discover' }, { title: 'Rank' }],
134
- }
135
-
136
- // ✗ quebra
137
- export const meta = {
138
- name: `audit-${type}-staleness`, // template literal
139
- description: getDesc(), // function call
140
- phases: [...DEFAULT_PHASES], // spread
141
- }
142
- ```
143
-
144
- ### Date.now / Math.random / argless `new Date()` são banidos
145
- Quebrariam o resume cache. Passe timestamps via `args` e varie randomness pelo `index` do pipeline/parallel.
146
-
147
- ```js
148
- // ok
149
- const nowIso = args?.nowIso // caller produz e passa
150
- const label = `gen-${i}` // i = índice do pipeline
151
-
152
- // quebra
153
- const ts = Date.now()
154
- const id = Math.random().toString(36)
155
- ```
156
-
157
- ### Todo `agent()` com saída estruturada usa `schema`
158
- Sem schema, o retorno é texto bruto e parsing fica frágil. Com schema (JSON Schema), o agent é forçado a chamar `StructuredOutput` e a validação acontece no tool-call layer (retry automático).
159
-
160
- ```js
161
- const SCHEMA = {
162
- type: 'object', required: ['rank', 'reason'],
163
- properties: { rank: { type: 'number' }, reason: { type: 'string' } }
164
- }
165
- const r = await agent(PROMPT, { schema: SCHEMA })
166
- // r.rank e r.reason garantidos do tipo
167
- ```
168
-
169
- ### `pipeline()` é o default; `parallel()` é exceção
170
- Use `parallel()` quando o próximo stage precisa de TODOS os resultados anteriores ao mesmo tempo. Caso contrário, `pipeline()` deixa o item rápido avançar enquanto o lento ainda processa.
171
-
172
- **Smell test:** se você escreveu `const a = await parallel(...); const b = transform(a); const c = await parallel(b.map(...))` — quase certo que deveria ser `pipeline(items, stage1, transform-inline, stage2)`.
173
-
174
- ### Concorrência tem cap real
175
- `min(16, cores 2)` por workflow. Em laptop de dev = ~14. Em CI/macOS pequeno = ~6. `parallel()`/`pipeline()` com 100 itens funciona — mas só ~10 rodam simultâneo.
176
-
177
- ### O budget é hard ceiling
178
- `budget.total` é o `+500k` do usuário. Quando `spent()` bate o `total`, próximas `agent()` calls **throw**. Sempre cheque antes de loops dinâmicos.
179
-
180
- ### Composição via `workflow()` é 1 nível
181
- `workflow('other-name', args)` pode chamar OUTRO workflow do registry. Mas o filho NÃO pode chamar outro `workflow()` — nesting > 1 throws. Use isto pra orquestrar fases grandes (Understand → Design → Implement → Review) cada uma como workflow separado.
182
-
183
- ## Reusar agents canônicos do kit
184
-
185
- Workflows gerados não precisam reinventar. Use `opts.agentType` pra delegar a um agent específico do kit:
186
-
187
- ```js
188
- const audit = await agent(
189
- `Audite Edge Function ${fn.name} pelos 4 golden signals.`,
190
- { agentType: 'observability-coverage-auditor', schema: AUDIT_SCHEMA }
191
- )
192
- ```
193
-
194
- Mapa rápido de quando reusar (consulte [`kit/agents/`](../../agents/) pra lista completa):
195
-
196
- | Sua necessidade | Agent canônico |
197
- |---|---|
198
- | Cobertura observability por Edge Fn | `observability-coverage-auditor` |
199
- | Isolamento cross-tenant (RLS) | `multi-tenant-isolation-auditor` |
200
- | Compliance LGPD | `lgpd-compliance-auditor` |
201
- | Hipóteses de bug em produção | `incident-investigator` |
202
- | Validar migration antes de aplicar | `schema-checker` |
203
- | Verificar refactor antes do código | `refactor-safety-auditor` |
204
- | Pesquisar fase / projeto | `phase-researcher` / `project-researcher` |
205
- | Designer de UI seguindo MARCA.md | `designer-ui` |
206
-
207
- ## Anti-pitfalls específicos
208
-
209
- **1. Silent caps.** Se o workflow corta cobertura (top-N, no-retry, sampling), `log()` o que foi descartado. Truncar em silêncio lê como "cobri tudo" quando não cobriu.
210
-
211
- **2. Synthesizer cego.** O último agent recebe `JSON.stringify(rows)` — se rows for 50MB de transcripts, ele estoura contexto. Pré-resuma cada item no stage anterior (campos só essenciais: id, score, top-3 evidence).
212
-
213
- **3. Dedup vs `confirmed`.** Loop-until-dry deve dedupar contra TODOS os itens vistos (`seen`), NÃO os confirmados. Senão findings judge-rejected reaparecem e o loop nunca converge.
214
-
215
- **4. Schema sem `required`.** JSON Schema sem `required` deixa o agent retornar `{}` válido. Sempre liste `required: [...]`.
216
-
217
- **5. Stage que mutate.** Stage 2 mutando o objeto vindo de stage 1 quebra resume cache. Crie objeto novo: `return { ...prev, extra: x }`.
218
-
219
- ## Ver também
220
-
221
- - [`kit/workflows/auditar-observabilidade-cobertura.workflow.js`](../../workflows/auditar-observabilidade-cobertura.workflow.js) exemplo canônico do pattern Fanout-And-Synthesize + Adversarial-Verification combinados
222
- - [`workflow-generator`](../../agents/workflow-generator.md) agent que consulta esta skill ao gerar `.workflow.js`
223
- - [`criar-workflow`](../../commands/criar-workflow.md) — slash-command entrypoint do gerador
1
+ ---
2
+ name: dynamic-workflow-authoring
3
+ description: Use ao gerar/criticar `.workflow.js` (Opus 4.8+). Codifica os 6 patterns canonicos (Classify-Act, Fanout-Synthesize, Adversarial-Verify, Generate-Filter, Tournament, Loop-Done) + API rules.
4
+ ---
5
+
6
+ # Dynamic Workflow Authoring
7
+
8
+ **Fonte canônica:** [A harness for every task — Anthropic blog](https://claude.com/blog/a-harness-for-every-task-dynamic-workflows-in-claude-code).
9
+
10
+ Esta skill existe para que workflows gerados pelo kit sigam um vocabulário comum e não reinventem padrões. Consulte-a SEMPRE antes de materializar um `.workflow.js`.
11
+
12
+ ## FATAL anti-patterns observados em produção (LEIA PRIMEIRO)
13
+
14
+ Estes 3 erros foram detectados em workflows gerados que falharam ao executar. Memorize antes de tocar em qualquer `.workflow.js`:
15
+
16
+ ### NUNCA `import` no topo
17
+
18
+ ```js
19
+ // ✗ QUEBRA — não existe esse módulo
20
+ import { agent, pipeline, parallel } from 'kit-mcp/workflow'
21
+ import * as Workflow from '@anthropic/workflows'
22
+ ```
23
+
24
+ ```js
25
+ // ✓ CORRETO — sem imports. agent/pipeline/parallel/phase/log/args/budget/workflow
26
+ // são INJETADOS COMO GLOBAIS pelo harness. Começe direto com export const meta.
27
+ export const meta = { /* ... */ }
28
+ phase('Discover')
29
+ const r = await agent('...', { schema: SCHEMA })
30
+ ```
31
+
32
+ ### ❌ NUNCA `export default` no body
33
+
34
+ ```js
35
+ // ✗ QUEBRA — o harness wrappeia o body ele mesmo
36
+ export default async function run() {
37
+ phase('Discover')
38
+ // ...
39
+ }
40
+
41
+ // QUEBRAvariantes
42
+ export default async () => { /* ... */ }
43
+ module.exports = async function () { /* ... */ }
44
+ ```
45
+
46
+ ```js
47
+ // ✓ CORRETO — body roda direto em async context após o meta
48
+ export const meta = { /* ... */ }
49
+
50
+ phase('Discover') // top-level
51
+ const r = await agent(/*...*/) // top-level await é OK
52
+ return { ok: true } // top-level return é OK
53
+ ```
54
+
55
+ ### ❌ NUNCA `agent({...})` com objeto na posição 1
56
+
57
+ ```js
58
+ // QUEBRA essa é a API do Task(subagent_type=...), NÃO do agent() do Workflow
59
+ const r = await agent({
60
+ name: 'auditor',
61
+ description: 'audita X',
62
+ tools: ['Read', 'Bash'],
63
+ systemPrompt: 'Você é um auditor...',
64
+ schema: SCHEMA,
65
+ })
66
+ ```
67
+
68
+ ```js
69
+ // ✓ CORRETO — primeiro argumento é STRING (o prompt), segundo é opts
70
+ const r = await agent(
71
+ 'Você é um auditor. Avalie X e devolva o resultado.',
72
+ { schema: SCHEMA, phase: 'Audit', label: 'audit:x' }
73
+ )
74
+
75
+ // Pra delegar para um agent canônico do kit, use opts.agentType:
76
+ const r = await agent(
77
+ 'Audite a Edge Function process-payments nos 4 golden signals.',
78
+ { agentType: 'observability-coverage-auditor', schema: AUDIT_SCHEMA }
79
+ )
80
+ ```
81
+
82
+ ## Assinaturas EXATAS dos globais injetados
83
+
84
+ ```ts
85
+ agent(prompt: string, opts?: {
86
+ label?: string,
87
+ phase?: string,
88
+ schema?: object, // JSON Schema com required: [...]
89
+ model?: string, // raro — usa o da sessão por default
90
+ isolation?: 'worktree', // EXPENSIVE quando agents mutam arquivos paralelo
91
+ agentType?: string, // delega pra um agent do kit (subagent_type)
92
+ }): Promise<any>
93
+
94
+ pipeline(items: any[], stage1: (item) => Promise<any>, stage2?: (prev, item, i) => Promise<any>, ...): Promise<any[]>
95
+ parallel(thunks: Array<() => Promise<any>>): Promise<any[]>
96
+ phase(title: string): void
97
+ log(message: string): void
98
+ workflow(nameOrRef: string | { scriptPath: string }, args?: any): Promise<any>
99
+
100
+ args: any // o args passado em Workflow({args: ...})
101
+ budget: { total: number|null, spent(): number, remaining(): number }
102
+ ```
103
+
104
+ ## Outras regras banidas
105
+
106
+ ```js
107
+ Date.now() // banido quebra resume cache
108
+ Math.random() // banido — idem
109
+ new Date() // banido sem argumento
110
+ new Date('2026-01-01') // ✓ OK
111
+ require(...) // sem CommonJS no body
112
+ import ... // sem ESM imports no body
113
+ fs / path / process // ✗ sem Node APIs — leitura/escrita de arquivos é via agent() rodando Bash/Read/Write
114
+ ```
115
+
116
+ ## Os 6 patterns canônicos
117
+
118
+ A primeira decisão de design é qual pattern usar — ela determina a topologia do script. Todo workflow real ou é exatamente um destes ou uma composição limpa de dois.
119
+
120
+ ### 1. Classify-And-Act
121
+ **Quando:** tipos diferentes de entrada precisam de tratamentos diferentes.
122
+ **Tasks:** ticket triage (severity → agent específico), content moderation (violation type → handler), routing de PRs por área de código.
123
+ **API:**
124
+ ```js
125
+ phase('Classify')
126
+ const cls = await agent(`Classifique X em uma de: A, B, C.`, { schema: CLS_SCHEMA })
127
+ phase('Act')
128
+ const result = await agent(PROMPTS[cls.label], { schema: ACT_SCHEMA })
129
+ ```
130
+ **Anti-pitfall:** classifier vagaroso anula o ganho — mantenha-o pequeno e schema-estruturado. Se o classifier precisa do contexto completo, considere se isn't really Fanout disfarçado.
131
+
132
+ ### 2. Fanout-And-Synthesize
133
+ **Quando:** N itens similares onde isolation previne interferência cruzada.
134
+ **Tasks:** "renomeie User → Account em todos os arquivos", processar 80 currículos, auditar N Edge Functions, julgar N conversas.
135
+ **API:**
136
+ ```js
137
+ phase('Fanout')
138
+ const results = await pipeline(
139
+ items,
140
+ item => agent(`Process ${item.id}`, { phase: 'Fanout', schema: ITEM_SCHEMA })
141
+ )
142
+ phase('Synthesize')
143
+ const summary = await agent(`Synthesize: ${JSON.stringify(results)}`, { schema: REPORT_SCHEMA })
144
+ ```
145
+ **Default:** `pipeline()` sobre `parallel()` barrier entre fanout e synthesize se a síntese precisa de TODOS de uma vez.
146
+
147
+ ### 3. Adversarial-Verification
148
+ **Quando:** qualidade crítica, custo de falso-positivo > custo de revisão extra.
149
+ **Tasks:** code review, fact-checking, audit de findings de segurança, qualquer "X é real ou ilusão?".
150
+ **API:**
151
+ ```js
152
+ const finding = await agent(FIND_PROMPT, { phase: 'Find', schema: FINDING_SCHEMA })
153
+ const verdict = await agent(
154
+ `Você é cético. Tente REFUTAR: ${JSON.stringify(finding)}.
155
+ Default: refuted=true em caso de dúvida.`,
156
+ { phase: 'Verify', schema: VERDICT_SCHEMA }
157
+ )
158
+ if (verdict.confirmed) commit(finding)
159
+ ```
160
+ **Multi-voto:** quando o caso é cinza, spawne 3 verificadores independentes e exija majority:
161
+ ```js
162
+ const votes = await parallel(Array.from({length: 3}, () => () =>
163
+ agent(`Refute: ${claim}`, { schema: VERDICT_SCHEMA })))
164
+ const survives = votes.filter(Boolean).filter(v => !v.refuted).length >= 2
165
+ ```
166
+ **Perspective-diverse:** se o achado pode falhar de mais de uma forma, dê lentes DIFERENTES a cada verificador (correctness/security/perf) — diversidade pega o que redundância não pega.
167
+
168
+ ### 4. Generate-And-Filter
169
+ **Quando:** espaço de solução amplo, qualidade varia, descarte é barato.
170
+ **Tasks:** gerar nomes de CLI/produto, brainstormar abordagens de design, listar hipóteses de bug.
171
+ **API:**
172
+ ```js
173
+ phase('Generate')
174
+ const candidates = (await parallel(Array.from({length: N}, (_, i) => () =>
175
+ agent(GEN_PROMPT(i), { schema: GEN_SCHEMA })))).filter(Boolean)
176
+ phase('Filter')
177
+ const top = await agent(
178
+ `Avalie e top ${K} pela rubrica: ${RUBRIC}. Candidatos: ${JSON.stringify(candidates)}`,
179
+ { schema: TOP_SCHEMA }
180
+ )
181
+ ```
182
+ **Varie o prompt do generator por índice** (i no exemplo acima) — gera diversidade. Se todos os generators têm exatamente o mesmo prompt, você paga N tokens pra obter ~1 resposta.
183
+
184
+ ### 5. Tournament
185
+ **Quando:** ranking qualitativo, julgamento relativo > absoluto.
186
+ **Tasks:** ordenar 1000+ tickets por severidade, escolher melhor design entre N propostas, priorizar lista de bugs.
187
+ **API:**
188
+ ```js
189
+ let bracket = candidates
190
+ while (bracket.length > 1) {
191
+ bracket = await pipeline(
192
+ chunk(bracket, 2),
193
+ pair => agent(
194
+ `Compare A e B pela métrica X. Devolva winner.`,
195
+ { phase: `Round-${bracket.length}`, schema: COMPARE_SCHEMA }
196
+ ).then(r => r.winner)
197
+ )
198
+ }
199
+ return bracket[0]
200
+ ```
201
+ **Anti-pitfall:** se a métrica é absoluta (score 0–10 estável), use Generate-And-Filter — Tournament é caro em wall-clock e tokens (log₂N rounds).
202
+
203
+ ### 6. Loop-Until-Done
204
+ **Quando:** volume desconhecido, condição de parada > contador fixo.
205
+ **Tasks:** reproduzir flaky test até falhar, bug hunt até K rounds vazios, search com retry até confidence threshold.
206
+ **API (loop-until-dry):**
207
+ ```js
208
+ const seen = new Set()
209
+ let dry = 0
210
+ while (dry < 2) {
211
+ const fresh = (await agent(FIND_PROMPT, { schema: BUGS_SCHEMA })).bugs
212
+ .filter(b => !seen.has(key(b)))
213
+ if (!fresh.length) { dry++; continue }
214
+ dry = 0
215
+ fresh.forEach(b => seen.add(key(b)))
216
+ // ... process fresh
217
+ }
218
+ ```
219
+ **Loop-until-budget:** scale automático ao `+500k` do usuário:
220
+ ```js
221
+ while (budget.total && budget.remaining() > 50_000) {
222
+ const r = await agent(FIND_PROMPT, { schema: BUGS_SCHEMA })
223
+ if (!r.bugs.length) break
224
+ bugs.push(...r.bugs)
225
+ }
226
+ ```
227
+ **Guard sempre** em `budget.total` — `remaining()` é `Infinity` sem target e o loop bate o cap de 1000 agents.
228
+
229
+ ## Regras DURAS da API (violar = workflow quebra)
230
+
231
+ ### O `meta` é literal puro
232
+ ```js
233
+ // ✓ ok
234
+ export const meta = {
235
+ name: 'audit-pr-staleness',
236
+ description: 'List PRs open >7d without review and rank by impact.',
237
+ phases: [{ title: 'Discover' }, { title: 'Rank' }],
238
+ }
239
+
240
+ // ✗ quebra
241
+ export const meta = {
242
+ name: `audit-${type}-staleness`, // template literal
243
+ description: getDesc(), // function call
244
+ phases: [...DEFAULT_PHASES], // spread
245
+ }
246
+ ```
247
+
248
+ ### Date.now / Math.random / argless `new Date()` são banidos
249
+ Quebrariam o resume cache. Passe timestamps via `args` e varie randomness pelo `index` do pipeline/parallel.
250
+
251
+ ```js
252
+ // ✓ ok
253
+ const nowIso = args?.nowIso // caller produz e passa
254
+ const label = `gen-${i}` // i = índice do pipeline
255
+
256
+ // ✗ quebra
257
+ const ts = Date.now()
258
+ const id = Math.random().toString(36)
259
+ ```
260
+
261
+ ### Todo `agent()` com saída estruturada usa `schema`
262
+ Sem schema, o retorno é texto bruto e parsing fica frágil. Com schema (JSON Schema), o agent é forçado a chamar `StructuredOutput` e a validação acontece no tool-call layer (retry automático).
263
+
264
+ ```js
265
+ const SCHEMA = {
266
+ type: 'object', required: ['rank', 'reason'],
267
+ properties: { rank: { type: 'number' }, reason: { type: 'string' } }
268
+ }
269
+ const r = await agent(PROMPT, { schema: SCHEMA })
270
+ // r.rank e r.reason garantidos do tipo
271
+ ```
272
+
273
+ ### `pipeline()` é o default; `parallel()` é exceção
274
+ Use `parallel()` SÓ quando o próximo stage precisa de TODOS os resultados anteriores ao mesmo tempo. Caso contrário, `pipeline()` deixa o item rápido avançar enquanto o lento ainda processa.
275
+
276
+ **Smell test:** se você escreveu `const a = await parallel(...); const b = transform(a); const c = await parallel(b.map(...))` — quase certo que deveria ser `pipeline(items, stage1, transform-inline, stage2)`.
277
+
278
+ ### Concorrência tem cap real
279
+ `min(16, cores − 2)` por workflow. Em laptop de dev = ~14. Em CI/macOS pequeno = ~6. `parallel()`/`pipeline()` com 100 itens funciona — mas só ~10 rodam simultâneo.
280
+
281
+ ### O budget é hard ceiling
282
+ `budget.total` é o `+500k` do usuário. Quando `spent()` bate o `total`, próximas `agent()` calls **throw**. Sempre cheque antes de loops dinâmicos.
283
+
284
+ ### Composição via `workflow()` é 1 nível
285
+ `workflow('other-name', args)` pode chamar OUTRO workflow do registry. Mas o filho NÃO pode chamar outro `workflow()` — nesting > 1 throws. Use isto pra orquestrar fases grandes (Understand → Design → Implement → Review) cada uma como workflow separado.
286
+
287
+ ## Reusar agents canônicos do kit
288
+
289
+ Workflows gerados não precisam reinventar. Use `opts.agentType` pra delegar a um agent específico do kit:
290
+
291
+ ```js
292
+ const audit = await agent(
293
+ `Audite Edge Function ${fn.name} pelos 4 golden signals.`,
294
+ { agentType: 'observability-coverage-auditor', schema: AUDIT_SCHEMA }
295
+ )
296
+ ```
297
+
298
+ Mapa rápido de quando reusar (consulte [`kit/agents/`](../../agents/) pra lista completa):
299
+
300
+ | Sua necessidade | Agent canônico |
301
+ |---|---|
302
+ | Cobertura observability por Edge Fn | `observability-coverage-auditor` |
303
+ | Isolamento cross-tenant (RLS) | `multi-tenant-isolation-auditor` |
304
+ | Compliance LGPD | `lgpd-compliance-auditor` |
305
+ | Hipóteses de bug em produção | `incident-investigator` |
306
+ | Validar migration antes de aplicar | `schema-checker` |
307
+ | Verificar refactor antes do código | `refactor-safety-auditor` |
308
+ | Pesquisar fase / projeto | `phase-researcher` / `project-researcher` |
309
+ | Designer de UI seguindo MARCA.md | `designer-ui` |
310
+
311
+ ## Anti-pitfalls específicos
312
+
313
+ **1. Silent caps.** Se o workflow corta cobertura (top-N, no-retry, sampling), `log()` o que foi descartado. Truncar em silêncio lê como "cobri tudo" quando não cobriu.
314
+
315
+ **2. Synthesizer cego.** O último agent recebe `JSON.stringify(rows)` — se rows for 50MB de transcripts, ele estoura contexto. Pré-resuma cada item no stage anterior (campos só essenciais: id, score, top-3 evidence).
316
+
317
+ **3. Dedup vs `confirmed`.** Loop-until-dry deve dedupar contra TODOS os itens vistos (`seen`), NÃO só os confirmados. Senão findings judge-rejected reaparecem e o loop nunca converge.
318
+
319
+ **4. Schema sem `required`.** JSON Schema sem `required` deixa o agent retornar `{}` válido. Sempre liste `required: [...]`.
320
+
321
+ **5. Stage que mutate.** Stage 2 mutando o objeto vindo de stage 1 quebra resume cache. Crie objeto novo: `return { ...prev, extra: x }`.
322
+
323
+ ## Ver também
324
+
325
+ - [`kit/workflows/auditar-observabilidade-cobertura.workflow.js`](../../workflows/auditar-observabilidade-cobertura.workflow.js) — exemplo canônico do pattern Fanout-And-Synthesize + Adversarial-Verification combinados
326
+ - [`workflow-generator`](../../agents/workflow-generator.md) — agent que consulta esta skill ao gerar `.workflow.js`
327
+ - [`criar-workflow`](../../commands/criar-workflow.md) — slash-command entrypoint do gerador