@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.
- package/README.md +1 -1
- package/bin/cli.js +2 -2
- package/bin/mcp.js +6 -6
- package/bin/ui.js +74 -74
- package/gates/ai-prompt-stability.md +120 -120
- package/gates/budget-description.md +68 -68
- package/gates/confidence.md +29 -29
- package/gates/dependency-check.md +33 -33
- package/gates/dept-cycle-prevention.md +179 -179
- package/gates/golden-signals-coverage.md +133 -133
- package/gates/legacy-refactor-safety.md +178 -178
- package/gates/multi-tenant-rls-coverage.md +102 -102
- package/gates/no-personal-uuid.md +72 -72
- package/gates/obs-agents-mcp-supabase.md +86 -86
- package/gates/obs-skills-frontmatter.md +76 -76
- package/gates/observability-coverage.md +151 -151
- package/gates/omm-no-regression.md +83 -83
- package/gates/postmortem-template-required.md +127 -127
- package/gates/prr-checklist-coverage.md +128 -128
- package/gates/regression.md +32 -32
- package/gates/release-pipeline-policy.md +132 -132
- package/gates/secrets-scan.md +33 -33
- package/gates/service-role-not-in-user-facing.md +113 -113
- package/gates/skill-must-include.md +71 -71
- package/gates/sync-idempotent.md +62 -62
- package/gates/verify-phase-goal.md +34 -34
- package/kit/agents/designer-ui.md +216 -216
- package/kit/agents/workflow-generator.md +537 -0
- package/kit/commands/adicionar-backlog.md +1 -1
- package/kit/commands/adicionar-fase.md +1 -1
- package/kit/commands/adicionar-tarefa.md +1 -1
- package/kit/commands/auditar-observabilidade.md +103 -103
- package/kit/commands/auditar-toil.md +129 -129
- package/kit/commands/caracterizar-prompt.md +195 -195
- package/kit/commands/criar-workflow.md +158 -0
- package/kit/commands/definir-perfil.md +1 -1
- package/kit/commands/definir-slo.md +108 -108
- package/kit/commands/fio.md +1 -1
- package/kit/commands/golden-signals.md +142 -142
- package/kit/commands/instrumentar-fase.md +200 -200
- package/kit/commands/investigar-producao.md +162 -162
- package/kit/commands/observabilidade.md +118 -118
- package/kit/commands/postmortem.md +179 -179
- package/kit/commands/prr.md +205 -205
- package/kit/commands/publicar-rapido.md +207 -207
- package/kit/commands/risk-budget.md +220 -220
- package/kit/commands/sre.md +230 -230
- package/kit/file-manifest.json +5 -2
- package/kit/framework/references/output-style.md +22 -22
- package/kit/hooks/post-apply-migration.js +199 -199
- package/kit/hooks/sidecar-tool-publisher.js +210 -210
- package/kit/skills/_shared-dados-distribuidos/glossary.md +224 -224
- package/kit/skills/_shared-legacy/glossary.md +389 -389
- package/kit/skills/_shared-multi-tenant/glossary.md +186 -186
- package/kit/skills/_shared-observability/glossary.md +396 -396
- package/kit/skills/_shared-sre/glossary.md +712 -712
- package/kit/skills/_shared-supabase/glossary.md +234 -234
- package/kit/skills/blameless-postmortems/SKILL.md +340 -340
- package/kit/skills/burn-rate-alerting/SKILL.md +258 -258
- package/kit/skills/cascading-failures/SKILL.md +311 -311
- package/kit/skills/core-analysis-loop/SKILL.md +352 -352
- package/kit/skills/distributed-tracing/SKILL.md +362 -362
- package/kit/skills/dynamic-workflow-authoring/SKILL.md +327 -0
- package/kit/skills/eliminating-toil/SKILL.md +243 -243
- package/kit/skills/event-based-slos/SKILL.md +296 -296
- package/kit/skills/four-golden-signals/SKILL.md +314 -314
- package/kit/skills/hermetic-builds/SKILL.md +323 -323
- package/kit/skills/legacy-monster-methods/SKILL.md +444 -444
- package/kit/skills/llm-as-dependency/SKILL.md +436 -436
- package/kit/skills/load-shedding-graceful-degradation/SKILL.md +396 -396
- package/kit/skills/observability-driven-development/SKILL.md +315 -315
- package/kit/skills/observability-maturity-model/SKILL.md +222 -222
- package/kit/skills/opentelemetry-standard/SKILL.md +351 -351
- package/kit/skills/production-readiness-review/SKILL.md +305 -305
- package/kit/skills/release-engineering/SKILL.md +367 -367
- package/kit/skills/retry-strategies/SKILL.md +372 -372
- package/kit/skills/sre-risk-management/SKILL.md +221 -221
- package/kit/skills/structured-events/SKILL.md +265 -265
- package/kit/skills/supabase-cron-queues/SKILL.md +275 -275
- package/kit/skills/supabase-database-functions/SKILL.md +332 -332
- package/kit/skills/supabase-declarative-schema/SKILL.md +183 -183
- package/kit/skills/supabase-pgvector-rag/SKILL.md +253 -253
- package/kit/skills/supabase-postgres-style/SKILL.md +138 -138
- package/kit/skills/supabase-storage/SKILL.md +234 -234
- package/kit/skills/telemetry-pipelines/SKILL.md +259 -259
- package/kit/skills/telemetry-sampling/SKILL.md +256 -256
- package/kit/skills/ui-anti-padroes-ia/SKILL.md +261 -261
- package/kit/skills/ui-contexto-produto/SKILL.md +248 -248
- package/kit/skills/ui-cor-estrategia/SKILL.md +213 -213
- package/kit/skills/ui-critica-auditoria/SKILL.md +260 -260
- package/kit/skills/ui-motion-funcional/SKILL.md +264 -264
- package/kit/skills/ui-ritmo-espacial/SKILL.md +259 -259
- package/kit/skills/ui-tipografia/SKILL.md +211 -211
- package/package.json +1 -1
- package/src/cli/index.js +1114 -1114
- package/src/cli/render.js +194 -194
- package/src/cli/upgrade-check.js +135 -135
- package/src/core/error-redaction.js +76 -76
- package/src/core/failures.js +153 -153
- package/src/core/gate-runner.js +205 -205
- package/src/core/gates.js +82 -82
- package/src/core/logger.js +170 -170
- package/src/core/manifest-verify.js +174 -174
- package/src/core/metrics.js +268 -268
- package/src/core/notify.js +60 -60
- package/src/core/path-safety.js +141 -141
- package/src/core/replays.js +120 -120
- package/src/core/ui.js +185 -185
- package/src/mcp-server/install.js +149 -149
- package/src/mcp-server/roots.js +124 -124
- package/src/ui/auto-spawn.js +113 -113
- package/src/ui/browser.js +78 -78
- package/src/ui/client.js +130 -130
- package/src/ui/events.js +65 -65
- package/src/ui/lockfile.js +191 -191
- package/src/ui/port.js +67 -67
- package/src/ui/server.js +547 -547
- package/src/ui/wrapper.js +129 -129
|
@@ -0,0 +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
|
+
## 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
|
+
// ✗ QUEBRA — variantes
|
|
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 — só 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 só 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 dê 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
|