oxe-cc 1.6.0 → 1.7.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/CHANGELOG.md +18 -0
- package/README.md +5 -3
- package/bin/lib/oxe-agent-install.cjs +125 -24
- package/bin/lib/oxe-release.cjs +1 -0
- package/bin/oxe-cc.js +87 -39
- package/commands/oxe/debug.md +6 -1
- package/commands/oxe/discuss.md +7 -2
- package/commands/oxe/execute.md +7 -2
- package/commands/oxe/plan-agent.md +7 -2
- package/commands/oxe/plan.md +7 -2
- package/commands/oxe/scan.md +6 -1
- package/commands/oxe/spec.md +6 -1
- package/commands/oxe/verify.md +6 -1
- package/docs/CONTENT-MIGRATION-AUDIT.md +49 -0
- package/docs/RUNTIME-SMOKE-MATRIX.md +1 -1
- package/lib/runtime/compiler/graph-compiler.js +32 -0
- package/lib/runtime/context/context-pack-builder.d.ts +15 -0
- package/lib/runtime/context/context-pack-builder.js +78 -0
- package/lib/runtime/events/catalog.d.ts +1 -1
- package/lib/runtime/events/catalog.js +5 -0
- package/lib/runtime/executor/action-tool-map.d.ts +3 -0
- package/lib/runtime/executor/action-tool-map.js +41 -0
- package/lib/runtime/executor/built-in-tools.d.ts +8 -0
- package/lib/runtime/executor/built-in-tools.js +267 -0
- package/lib/runtime/executor/index.d.ts +6 -0
- package/lib/runtime/executor/index.js +12 -0
- package/lib/runtime/executor/llm-task-executor.d.ts +29 -0
- package/lib/runtime/executor/llm-task-executor.js +138 -0
- package/lib/runtime/executor/node-prompt-builder.d.ts +3 -0
- package/lib/runtime/executor/node-prompt-builder.js +36 -0
- package/lib/runtime/executor/stream-completion.d.ts +38 -0
- package/lib/runtime/executor/stream-completion.js +105 -0
- package/lib/runtime/index.d.ts +1 -0
- package/lib/runtime/index.js +2 -0
- package/lib/runtime/models/failure.d.ts +5 -0
- package/lib/runtime/models/failure.js +2 -0
- package/lib/runtime/plugins/capability-adapter.d.ts +9 -0
- package/lib/runtime/plugins/capability-adapter.js +111 -8
- package/lib/runtime/plugins/plugin-abi.d.ts +8 -0
- package/lib/runtime/plugins/plugin-registry.d.ts +2 -1
- package/lib/runtime/plugins/plugin-registry.js +6 -1
- package/lib/runtime/reducers/run-state-reducer.js +39 -2
- package/lib/runtime/scheduler/scheduler.d.ts +14 -2
- package/lib/runtime/scheduler/scheduler.js +131 -11
- package/lib/runtime/verification/verification-manifest.d.ts +5 -2
- package/oxe/agents/oxe-assumptions-analyzer.md +136 -0
- package/oxe/agents/oxe-codebase-mapper.md +142 -0
- package/oxe/agents/oxe-debugger.md +145 -0
- package/oxe/agents/oxe-executor.md +139 -0
- package/oxe/agents/oxe-integration-checker.md +142 -0
- package/oxe/agents/oxe-plan-checker.md +143 -0
- package/oxe/agents/oxe-planner.md +151 -0
- package/oxe/agents/oxe-research-synthesizer.md +146 -0
- package/oxe/agents/oxe-researcher.md +163 -0
- package/oxe/agents/oxe-ui-auditor.md +151 -0
- package/oxe/agents/oxe-ui-checker.md +157 -0
- package/oxe/agents/oxe-ui-researcher.md +179 -0
- package/oxe/agents/oxe-validation-auditor.md +154 -0
- package/oxe/agents/oxe-verifier.md +132 -0
- package/oxe/personas/README.md +91 -39
- package/oxe/personas/architect.md +149 -37
- package/oxe/personas/db-specialist.md +149 -36
- package/oxe/personas/debugger.md +155 -38
- package/oxe/personas/executor.md +164 -38
- package/oxe/personas/planner.md +165 -36
- package/oxe/personas/researcher.md +148 -35
- package/oxe/personas/ui-specialist.md +164 -36
- package/oxe/personas/verifier.md +174 -39
- package/oxe/templates/FIXTURE-PACK.template.json +18 -11
- package/oxe/templates/FIXTURE-PACK.template.md +19 -10
- package/oxe/templates/IMPLEMENTATION-PACK.template.json +26 -10
- package/oxe/templates/IMPLEMENTATION-PACK.template.md +32 -20
- package/oxe/templates/PLAN.template.md +62 -31
- package/oxe/templates/REFERENCE-ANCHORS.template.md +14 -10
- package/oxe/templates/SUMMARY.template.md +50 -20
- package/oxe/workflows/debug.md +9 -7
- package/oxe/workflows/execute.md +11 -8
- package/oxe/workflows/forensics.md +5 -3
- package/oxe/workflows/plan.md +277 -0
- package/oxe/workflows/scan.md +355 -69
- package/oxe/workflows/spec.md +302 -9
- package/oxe/workflows/ui-review.md +5 -4
- package/oxe/workflows/ui-spec.md +4 -3
- package/oxe/workflows/verify.md +8 -5
- package/package.json +1 -1
- package/packages/runtime/package.json +1 -1
- package/packages/runtime/src/compiler/graph-compiler.ts +40 -0
- package/packages/runtime/src/context/context-pack-builder.ts +80 -0
- package/packages/runtime/src/events/catalog.ts +5 -0
- package/packages/runtime/src/executor/action-tool-map.ts +46 -0
- package/packages/runtime/src/executor/built-in-tools.ts +276 -0
- package/packages/runtime/src/executor/index.ts +6 -0
- package/packages/runtime/src/executor/llm-task-executor.ts +194 -0
- package/packages/runtime/src/executor/node-prompt-builder.ts +45 -0
- package/packages/runtime/src/executor/stream-completion.ts +145 -0
- package/packages/runtime/src/index.ts +3 -0
- package/packages/runtime/src/models/failure.ts +11 -0
- package/packages/runtime/src/plugins/capability-adapter.ts +117 -10
- package/packages/runtime/src/plugins/plugin-abi.ts +9 -0
- package/packages/runtime/src/plugins/plugin-registry.ts +10 -1
- package/packages/runtime/src/reducers/run-state-reducer.ts +59 -2
- package/packages/runtime/src/scheduler/scheduler.ts +152 -14
- package/packages/runtime/src/verification/verification-manifest.ts +12 -8
- package/vscode-extension/oxe-agents-1.7.0.vsix +0 -0
- package/vscode-extension/package.json +1 -1
package/oxe/workflows/spec.md
CHANGED
|
@@ -30,6 +30,10 @@ Se **`.oxe/config.json`** tiver `discuss_before_plan: true`: mencionar no final
|
|
|
30
30
|
|
|
31
31
|
**Discovery adaptativo:** antes da primeira pergunta, aplicar `oxe/workflows/references/adaptive-discovery.md`. Classificar a demanda, modular os blocos de perguntas conforme o domínio, limitar rodadas e consolidar incertezas estruturadas que depois alimentarão a confiança do plano.
|
|
32
32
|
|
|
33
|
+
**Rastreabilidade forte:** todo requisito `R-ID` precisa apontar para pelo menos um critério `A*` verificável, ou aparecer como v2/fora com justificativa. Critério sem método de verificação não entra como v1.
|
|
34
|
+
|
|
35
|
+
**Setup externo:** quando o sucesso depender de conta, variável de ambiente, dashboard, fila, banco, credencial, VPN ou recurso cloud, registrar em SPEC a seção **Setup externo e pré-condições**. O plano deve transformar isso em checkpoint ou tarefa explícita; não deixar como suposição solta.
|
|
36
|
+
|
|
33
37
|
**Resolução de sessão:** antes de ler ou escrever artefatos desta trilha, resolver `active_session` em `.oxe/STATE.md` conforme `oxe/workflows/references/session-path-resolution.md`. Com sessão ativa:
|
|
34
38
|
- `SPEC.md`, `ROADMAP.md` e `DISCUSS.md` vivem em `.oxe/<active_session>/spec/`
|
|
35
39
|
- `OBSERVATIONS.md`, `RESEARCH.md` e `research/` seguem o escopo da sessão
|
|
@@ -89,6 +93,7 @@ Usar templates: **`oxe/templates/SPEC.template.md`** e **`oxe/templates/ROADMAP.
|
|
|
89
93
|
- o que segue ambíguo;
|
|
90
94
|
- quais evidências faltam;
|
|
91
95
|
- quais riscos podem reduzir a confiança do plano.
|
|
96
|
+
- quais anchors, fixtures ou investigações serão obrigatórios para permitir `Confiança > 90%` no plano.
|
|
92
97
|
</fase_1_perguntas>
|
|
93
98
|
|
|
94
99
|
<fase_2_pesquisa>
|
|
@@ -111,6 +116,151 @@ Usar templates: **`oxe/templates/SPEC.template.md`** e **`oxe/templates/ROADMAP.
|
|
|
111
116
|
**Explorações grandes / sistemas legado:** ver **`oxe/workflows/references/legacy-brownfield.md`** — progressive disclosure por área, multiple sessions, epicos por trilha.
|
|
112
117
|
</fase_2_pesquisa>
|
|
113
118
|
|
|
119
|
+
<domain_question_library>
|
|
120
|
+
## Biblioteca de perguntas por domínio
|
|
121
|
+
|
|
122
|
+
Complemento adaptativo para a Fase 1. Quando o domínio for confirmado (via scan ou resposta da Fase 1), adicionar o bloco correspondente às perguntas de rodada 2 ou 3. **Nunca adicionar todos os blocos** — usar apenas os relevantes.
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
### Domínio: API REST / GraphQL
|
|
127
|
+
|
|
128
|
+
*Adicionar ao Bloco B quando o escopo toca endpoints ou contratos de API:*
|
|
129
|
+
|
|
130
|
+
- O contrato da API é público (consumido por outros times/clientes externos) ou interno?
|
|
131
|
+
- Quais endpoints existentes serão modificados vs criados do zero?
|
|
132
|
+
- Há versionamento de API (v1/v2)? O que acontece com clientes na versão antiga?
|
|
133
|
+
- Qual a estratégia de autenticação: JWT Bearer, API Key, OAuth, sessão?
|
|
134
|
+
- Há rate limiting, throttling ou quotas a considerar?
|
|
135
|
+
- Como erros de validação devem ser retornados (formato JSON, campos obrigatórios)?
|
|
136
|
+
- Há documentação de API (OpenAPI/Swagger) que deve ser atualizada junto?
|
|
137
|
+
|
|
138
|
+
*Critérios A* a sugerir (adaptar ao contexto):*
|
|
139
|
+
- `A-N: POST /recurso retorna 201 com payload correto quando input válido`
|
|
140
|
+
- `A-N: POST /recurso retorna 400 com campo errors[] quando input inválido`
|
|
141
|
+
- `A-N: GET /recurso retorna 401 sem Bearer token válido`
|
|
142
|
+
- `A-N: Stack trace ausente em todas as respostas de erro`
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
### Domínio: Autenticação e Autorização
|
|
147
|
+
|
|
148
|
+
*Adicionar ao Bloco B quando o escopo toca auth, sessões, permissões ou RBAC:*
|
|
149
|
+
|
|
150
|
+
- Qual o mecanismo de autenticação existente? Está sendo mantido ou substituído?
|
|
151
|
+
- Há multi-tenancy? Usuários de tenant A podem ver dados de tenant B?
|
|
152
|
+
- Qual o modelo de autorização: RBAC, ABAC, ACL, baseado em ownership?
|
|
153
|
+
- O que acontece com tokens existentes se o sistema de auth mudar?
|
|
154
|
+
- Como o logout funciona: client-side only, blacklist server-side, ou short TTL?
|
|
155
|
+
- Há requisitos de MFA, SSO ou integração com IdP externo (Keycloak, Auth0, SAML)?
|
|
156
|
+
- Qual o TTL dos tokens de acesso e de refresh?
|
|
157
|
+
|
|
158
|
+
*Critérios A* a sugerir:*
|
|
159
|
+
- `A-N: Rota protegida retorna 403 para usuário autenticado sem permissão`
|
|
160
|
+
- `A-N: Token expirado recebe 401, não 500`
|
|
161
|
+
- `A-N: Usuário de tenant A não retorna dados de tenant B em nenhum endpoint`
|
|
162
|
+
- `A-N: Senha armazenada como hash bcrypt/argon2 — nenhum plaintext no banco`
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
### Domínio: Banco de dados e Migrations
|
|
167
|
+
|
|
168
|
+
*Adicionar ao Bloco B quando o escopo toca schema ou dados persistidos:*
|
|
169
|
+
|
|
170
|
+
- Há dados existentes que serão afetados? Quantas linhas aproximadamente?
|
|
171
|
+
- A migration é aditiva (add column, new table) ou destrutiva (drop, rename, type change)?
|
|
172
|
+
- Qual é a janela de manutenção? A migration pode rodar online (zero-downtime)?
|
|
173
|
+
- Se a migration falhar no meio, qual o estado do banco? É reversível via `down()`?
|
|
174
|
+
- Há dependências: outras tabelas, serviços, ou queries que leem os campos afetados?
|
|
175
|
+
- Os índices existentes serão afetados? Há criação de índice em tabela grande (lock)?
|
|
176
|
+
- Há necessidade de backfill de dados? Com qual estratégia (batch, job assíncrono)?
|
|
177
|
+
|
|
178
|
+
*Critérios A* a sugerir:*
|
|
179
|
+
- `A-N: Migration é reversível via down() sem perda de dados`
|
|
180
|
+
- `A-N: Zero registros com campo NOT NULL ausente após migration`
|
|
181
|
+
- `A-N: Nenhum índice existente é dropado inadvertidamente`
|
|
182
|
+
- `A-N: Backfill completa sem timeout e sem bloquear leituras`
|
|
183
|
+
|
|
184
|
+
---
|
|
185
|
+
|
|
186
|
+
### Domínio: UI e Frontend
|
|
187
|
+
|
|
188
|
+
*Adicionar ao Bloco B quando o escopo toca interface de usuário:*
|
|
189
|
+
|
|
190
|
+
- Qual o dispositivo alvo primário — desktop, mobile, ambos?
|
|
191
|
+
- Há design system ou biblioteca de componentes obrigatória (ex.: Material, Tailwind)?
|
|
192
|
+
- O estado deve ser persistido entre reloads de página?
|
|
193
|
+
- Há requisitos de acessibilidade (WCAG)? Qual nível (A, AA, AAA)?
|
|
194
|
+
- Como carregamento de dados é gerenciado: loading state, error state, empty state?
|
|
195
|
+
- Há internacionalização (i18n) ou múltiplos idiomas a suportar?
|
|
196
|
+
- Qual a estratégia de tratamento de erros visível ao usuário?
|
|
197
|
+
|
|
198
|
+
*Critérios A* a sugerir:*
|
|
199
|
+
- `A-N: Componente exibe loading state enquanto dados carregam`
|
|
200
|
+
- `A-N: Erro de API exibe mensagem legível, não stack trace`
|
|
201
|
+
- `A-N: Formulário desabilita submit enquanto request está em andamento`
|
|
202
|
+
- `A-N: Todos os campos de formulário têm label associada (WCAG básico)`
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
### Domínio: Filas, Eventos e Processamento Assíncrono
|
|
207
|
+
|
|
208
|
+
*Adicionar ao Bloco B quando o escopo toca mensageria ou jobs:*
|
|
209
|
+
|
|
210
|
+
- O que acontece se a mensagem não puder ser processada? Há dead-letter queue?
|
|
211
|
+
- Qual a garantia de entrega: at-most-once, at-least-once, ou exactly-once?
|
|
212
|
+
- O consumer é idempotente? O que acontece se a mesma mensagem chegar duas vezes?
|
|
213
|
+
- Há ordering guarantee? As mensagens precisam ser processadas em ordem?
|
|
214
|
+
- Qual o SLA de processamento? Há timeout esperado?
|
|
215
|
+
- Como monitorar backlog? Há alertas quando a fila cresce além de N mensagens?
|
|
216
|
+
- Qual a estratégia de retry? Com backoff exponencial? Limite de tentativas?
|
|
217
|
+
|
|
218
|
+
*Critérios A* a sugerir:*
|
|
219
|
+
- `A-N: Consumer idempotente — processar a mesma mensagem 2x não duplica efeito`
|
|
220
|
+
- `A-N: Mensagem inválida vai para DLQ com metadados de diagnóstico`
|
|
221
|
+
- `A-N: Consumer continua operando após falha transiente (retry com backoff)`
|
|
222
|
+
- `A-N: Backlog não cresce indefinidamente — processamento acompanha produção`
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
### Domínio: Dados, ETL e Pipelines
|
|
227
|
+
|
|
228
|
+
*Adicionar ao Bloco B quando o escopo toca ingestão, transformação ou exportação:*
|
|
229
|
+
|
|
230
|
+
- Qual o volume de dados (linhas/dia, GB/hora)?
|
|
231
|
+
- Qual a janela de processamento: batch diário, near-realtime, ou streaming?
|
|
232
|
+
- O que acontece se o dado de entrada estiver malformado ou faltando campos?
|
|
233
|
+
- Há dependência de fuso horário? Como timestamps são normalizados?
|
|
234
|
+
- O pipeline é idempotente — reprocessar o mesmo input não duplica saída?
|
|
235
|
+
- Como o progresso é rastreado? Há checkpointing para retomada após falha?
|
|
236
|
+
- Quais são as métricas de qualidade de dados obrigatórias (completude, unicidade)?
|
|
237
|
+
|
|
238
|
+
*Critérios A* a sugerir:*
|
|
239
|
+
- `A-N: Registro inválido é rejeitado e vai para dead-letter com motivo explicito`
|
|
240
|
+
- `A-N: Reprocessar o mesmo input não duplica registros de saída`
|
|
241
|
+
- `A-N: Pipeline completa dentro da janela de SLA definida`
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
### Domínio: Infraestrutura e Deploy
|
|
246
|
+
|
|
247
|
+
*Adicionar ao Bloco B quando o escopo toca infraestrutura ou processo de deploy:*
|
|
248
|
+
|
|
249
|
+
- Em qual ambiente a mudança será implantada primeiro (dev/staging/prod)?
|
|
250
|
+
- Há downtime aceitável? Ou é obrigatório zero-downtime (rolling deploy)?
|
|
251
|
+
- Qual o processo de rollback se algo der errado em produção?
|
|
252
|
+
- Há variáveis de ambiente a adicionar? Quem configura em produção e quando?
|
|
253
|
+
- A mudança requer scaling ou mudança de capacidade (CPU, memória, instâncias)?
|
|
254
|
+
- Health checks ou readiness probes precisam ser atualizados?
|
|
255
|
+
- Como validar em produção: feature flag, canary release, A/B, smoke test?
|
|
256
|
+
|
|
257
|
+
*Critérios A* a sugerir:*
|
|
258
|
+
- `A-N: Deploy não causa downtime perceptível (< 30s de interrupção)`
|
|
259
|
+
- `A-N: Rollback é possível em < 15 minutos sem perda de dados`
|
|
260
|
+
- `A-N: Health check retorna 200 após deploy bem-sucedido`
|
|
261
|
+
- `A-N: Todas as variáveis de ambiente estão documentadas em SPEC antes do deploy`
|
|
262
|
+
</domain_question_library>
|
|
263
|
+
|
|
114
264
|
<fase_3_requisitos>
|
|
115
265
|
## Fase 3 — Requisitos
|
|
116
266
|
|
|
@@ -140,20 +290,85 @@ Usar templates: **`oxe/templates/SPEC.template.md`** e **`oxe/templates/ROADMAP.
|
|
|
140
290
|
|
|
141
291
|
**Objetivo:** propor proativamente critérios de hardening baseados no stack detectado, antes de criar o roteiro. Garante que segurança e robustez entrem na spec — e portanto no plan, nos testes e no verify — em vez de ficarem como auditoria pós-hoc.
|
|
142
292
|
|
|
143
|
-
**Referência:** `oxe/workflows/references/robustness-elevation.md`
|
|
293
|
+
**Referência canônica:** `oxe/workflows/references/robustness-elevation.md`
|
|
144
294
|
|
|
145
295
|
**Execução:**
|
|
146
296
|
|
|
147
|
-
1. **Detectar domínios** presentes: AUTH, API, DB, FRONTEND, FILE —
|
|
148
|
-
2. **Para cada domínio detectado**, percorrer o
|
|
149
|
-
3. **Propor** os critérios restantes como R-RB-NN com prioridade sugerida
|
|
150
|
-
4. **Apresentar ao usuário** em bloco único — domínios detectados, critérios propostos com justificativa breve para v1 críticos.
|
|
151
|
-
5. **Aguardar decisão** — usuário confirma, ajusta versão ou descarta
|
|
152
|
-
6. **Incorporar aprovados** na tabela da Fase 3; registrar descartados com justificativa
|
|
297
|
+
1. **Detectar domínios** presentes: AUTH, API, DB, FRONTEND, FILE — via scan artifacts ou inferência da Fase 1.
|
|
298
|
+
2. **Para cada domínio detectado**, percorrer o catálogo abaixo e filtrar critérios já cobertos por A* existentes.
|
|
299
|
+
3. **Propor** os critérios restantes como R-RB-NN com prioridade sugerida.
|
|
300
|
+
4. **Apresentar ao usuário** em bloco único — domínios detectados, critérios propostos com justificativa breve para os v1 críticos.
|
|
301
|
+
5. **Aguardar decisão** — usuário confirma, ajusta versão ou descarta.
|
|
302
|
+
6. **Incorporar aprovados** na tabela da Fase 3; registrar descartados com justificativa em "Suposições e riscos".
|
|
303
|
+
|
|
304
|
+
**Regra:** nunca forçar inclusão. Se o usuário descartar um v1 crítico, registrar o motivo explicitamente para auditoria futura.
|
|
153
305
|
|
|
154
|
-
**
|
|
306
|
+
**Pulável apenas se:** stack não se encaixa em nenhum domínio (ex.: script CLI puro sem auth, sem HTTP, sem DB). Nesse caso, registrar explicitamente: "Fase 3.5 não aplicável: [motivo]".
|
|
155
307
|
|
|
156
|
-
|
|
308
|
+
---
|
|
309
|
+
|
|
310
|
+
### Catálogo de critérios por domínio
|
|
311
|
+
|
|
312
|
+
#### AUTH — critérios de segurança de autenticação
|
|
313
|
+
|
|
314
|
+
| R-RB | Critério | Prioridade | Justificativa |
|
|
315
|
+
|------|----------|------------|---------------|
|
|
316
|
+
| R-RB-A01 | Senha nunca retornada em resposta de API (nem em log) | v1 crítico | Vazamento via resposta ou observabilidade |
|
|
317
|
+
| R-RB-A02 | Rate limit em tentativas de login falhas (ex.: 5/min por IP) | v1 crítico | Proteção contra brute force |
|
|
318
|
+
| R-RB-A03 | JWT valida `iss`, `aud`, `exp` e `iat` em toda rota protegida | v1 crítico | Tokens de outros sistemas aceitos |
|
|
319
|
+
| R-RB-A04 | Refresh token rotacionado a cada uso | v1 | Prevenção de token replay |
|
|
320
|
+
| R-RB-A05 | Logout invalida token server-side (blacklist ou short TTL) | v1 | Logout não impede uso do token |
|
|
321
|
+
| R-RB-A06 | Headers de segurança presentes: CSP, X-Frame-Options, HSTS | v2 | Proteção contra XSS/clickjacking |
|
|
322
|
+
| R-RB-A07 | Cookies com `Secure` + `HttpOnly` + `SameSite=Strict` | v1 se usa cookies | CSRF + XSS via cookie |
|
|
323
|
+
| R-RB-A08 | Credenciais de admin não hardcoded em código ou config | v1 crítico | Secret exposto no repositório |
|
|
324
|
+
|
|
325
|
+
#### API REST — critérios de segurança de endpoint
|
|
326
|
+
|
|
327
|
+
| R-RB | Critério | Prioridade | Justificativa |
|
|
328
|
+
|------|----------|------------|---------------|
|
|
329
|
+
| R-RB-R01 | Toda rota tem validação de schema de entrada (DTO/Zod/Joi) | v1 crítico | Input não validado = injection risk |
|
|
330
|
+
| R-RB-R02 | Erros de validação retornam 400 com campo `errors[]` estruturado | v1 | Feedback objetivo ao cliente |
|
|
331
|
+
| R-RB-R03 | Stack trace ausente em todas as respostas de erro (4xx e 5xx) | v1 crítico | Exposição de internals ao cliente |
|
|
332
|
+
| R-RB-R04 | Paginação obrigatória em listas (sem retornar N ilimitado) | v1 | DoS por dump de tabela grande |
|
|
333
|
+
| R-RB-R05 | Rate limiting em endpoints públicos e autenticados | v1 | Abuso de API |
|
|
334
|
+
| R-RB-R06 | CORS configurado explicitamente — nunca `Access-Control-Allow-Origin: *` em produção | v1 se frontend externo | Acesso cross-origin não intencional |
|
|
335
|
+
| R-RB-R07 | IDs de recursos opacos (UUID/ULID/nanoid, não int sequencial) | v2 | Enumeração de recursos |
|
|
336
|
+
| R-RB-R08 | Timeout em todas as chamadas a dependências externas | v1 | Hang em falha de dependency |
|
|
337
|
+
|
|
338
|
+
#### DB — critérios de segurança de banco de dados
|
|
339
|
+
|
|
340
|
+
| R-RB | Critério | Prioridade | Justificativa |
|
|
341
|
+
|------|----------|------------|---------------|
|
|
342
|
+
| R-RB-D01 | Queries usam prepared statements ou ORM — zero concatenação de string | v1 crítico | SQL injection |
|
|
343
|
+
| R-RB-D02 | Connection pool com tamanho máximo configurado | v1 | Esgotamento de conexões em load |
|
|
344
|
+
| R-RB-D03 | Transações em operações multi-step (atomicidade garantida) | v1 | Dados inconsistentes em falha parcial |
|
|
345
|
+
| R-RB-D04 | Migrations idempotentes e com `down()` reversível | v1 | Rollback impossível |
|
|
346
|
+
| R-RB-D05 | Campos sensíveis (PII, segredos) criptografados ou hasheados | v1 se há PII | Exposure em dump de banco |
|
|
347
|
+
| R-RB-D06 | Índices para queries de alta frequência | v2 | Degradação de performance sob load |
|
|
348
|
+
| R-RB-D07 | Soft delete preferido sobre hard delete em entidades de negócio | v2 | Perda acidental irrecuperável de dados |
|
|
349
|
+
|
|
350
|
+
#### FRONTEND — critérios de segurança de UI
|
|
351
|
+
|
|
352
|
+
| R-RB | Critério | Prioridade | Justificativa |
|
|
353
|
+
|------|----------|------------|---------------|
|
|
354
|
+
| R-RB-F01 | Dados do usuário escapados antes de renderizar no DOM | v1 crítico | XSS via conteúdo dinâmico |
|
|
355
|
+
| R-RB-F02 | Formulários têm proteção CSRF (token ou SameSite) | v1 se usa cookies/sessão | CSRF attack |
|
|
356
|
+
| R-RB-F03 | API keys / segredos ausentes no bundle client-side | v1 crítico | Exposição de credenciais via DevTools |
|
|
357
|
+
| R-RB-F04 | Loading, error e empty states implementados em todos os fluxos | v1 | UX quebrada em falha de rede |
|
|
358
|
+
| R-RB-F05 | Inputs sanitizados antes de envio (sem XSS via form) | v1 | Injection via campo de formulário |
|
|
359
|
+
| R-RB-F06 | Deep links funcionam no reload da página (rota não quebra) | v1 | UX ruim e links não compartilháveis |
|
|
360
|
+
| R-RB-F07 | Labels acessíveis em todos os inputs (WCAG 2.1 AA mínimo) | v2 | Acessibilidade básica |
|
|
361
|
+
|
|
362
|
+
#### FILE / Storage — critérios de segurança de upload
|
|
363
|
+
|
|
364
|
+
| R-RB | Critério | Prioridade | Justificativa |
|
|
365
|
+
|------|----------|------------|---------------|
|
|
366
|
+
| R-RB-S01 | Tipo de arquivo validado por magic bytes, não apenas extensão | v1 crítico | Upload de executável com extensão .jpg |
|
|
367
|
+
| R-RB-S02 | Tamanho de arquivo com limite máximo configurado | v1 crítico | DoS por upload de arquivo gigante |
|
|
368
|
+
| R-RB-S03 | Arquivos armazenados fora do webroot (não servíveis diretamente) | v1 crítico | Path traversal + execução remota |
|
|
369
|
+
| R-RB-S04 | Nome do arquivo sanitizado — nunca usar nome original do cliente | v1 | Path traversal no sistema de arquivos |
|
|
370
|
+
| R-RB-S05 | URLs de download com TTL (presigned URLs, não permanentes) | v1 se dados sensíveis | Vazamento por link compartilhado |
|
|
371
|
+
| R-RB-S06 | Scan de malware em uploads (se domínio crítico de segurança) | v2 | Upload e redistribuição de malware |
|
|
157
372
|
</fase_35_elevacao_robustez>
|
|
158
373
|
|
|
159
374
|
<fase_4_roteiro>
|
|
@@ -223,6 +438,84 @@ O resultado desta reflexão é **invisível ao usuário** — é trabalho intern
|
|
|
223
438
|
- evidências faltantes que podem reduzir a confiança do plano.
|
|
224
439
|
</auto_reflexao>
|
|
225
440
|
|
|
441
|
+
<spec_anti_patterns>
|
|
442
|
+
## Anti-padrões de especificação
|
|
443
|
+
|
|
444
|
+
Detectar e corrigir estes problemas antes de entregar a SPEC. A auto-reflexão da Fase 3.5 deve capturar a maioria, mas são registrados aqui como referência explícita para revisão manual.
|
|
445
|
+
|
|
446
|
+
---
|
|
447
|
+
|
|
448
|
+
### Critério A* não verificável
|
|
449
|
+
|
|
450
|
+
**Problema:** `A3 — Sistema deve ser escalável e performático`
|
|
451
|
+
**Por quê é ruim:** "escalável" e "performático" sem métrica são impossíveis de testar. O executor não sabe quando passou.
|
|
452
|
+
**Solução:** `A3 — Sistema responde < 200ms em p95 com 100 usuários simultâneos (teste k6 smoke em staging)` — métrica, percentil, carga, ambiente.
|
|
453
|
+
|
|
454
|
+
---
|
|
455
|
+
|
|
456
|
+
### Escopo creep implícito
|
|
457
|
+
|
|
458
|
+
**Problema:** usuário pediu "adicionar campo de telefone no perfil". A SPEC incluiu "refatorar módulo de perfil completo" em v1.
|
|
459
|
+
**Por quê é ruim:** o usuário não pediu refatoração — foi decisão unilateral do agente. Scope não autorizado.
|
|
460
|
+
**Solução:** incluir apenas o que emergiu da Fase 1/2. Refatorações sugeridas vão para v2 ou são registradas em CONCERNS com nota "sugerido, não solicitado".
|
|
461
|
+
|
|
462
|
+
---
|
|
463
|
+
|
|
464
|
+
### Suposição técnica não registrada
|
|
465
|
+
|
|
466
|
+
**Problema:** a SPEC integra com Stripe e assume que `STRIPE_SECRET_KEY` já está configurada em produção.
|
|
467
|
+
**Por quê é ruim:** o plan vai criar a integração, mas o executor vai falhar por falta de credencial sem diagnóstico claro.
|
|
468
|
+
**Solução:** toda suposição de ambiente vai explicitamente em "Setup externo e pré-condições" da SPEC. O plan converte suposições críticas em tarefas de verificação (Onda 1, action_type: `collect_evidence`).
|
|
469
|
+
|
|
470
|
+
---
|
|
471
|
+
|
|
472
|
+
### Requisito v1 que depende de v2
|
|
473
|
+
|
|
474
|
+
**Problema:** `R1 (v1) — Notificações em tempo real` depende de `R5 (v2) — WebSocket server`.
|
|
475
|
+
**Por quê é ruim:** o plano de v1 não pode executar R1 sem R5 existir. O plano vai falhar na verificação.
|
|
476
|
+
**Solução:** ou mover R1 para v2, ou mover R5 para v1, ou re-especificar R1 sem WebSocket (ex.: polling com SSE).
|
|
477
|
+
|
|
478
|
+
---
|
|
479
|
+
|
|
480
|
+
### Critérios que conflitam entre si
|
|
481
|
+
|
|
482
|
+
**Problema:** `A1 — Processar arquivo CSV em < 5s` e `A7 — Arquivo CSV pode ter até 1 GB`.
|
|
483
|
+
**Por quê é ruim:** 1 GB em 5s pode ser fisicamente impossível dependendo da infra. Os dois critérios são contraditórios sem especificação de condições.
|
|
484
|
+
**Solução:** tornar as condições consistentes: "< 5s para arquivos até 10 MB; processamento assíncrono para arquivos > 10 MB com status via polling".
|
|
485
|
+
|
|
486
|
+
---
|
|
487
|
+
|
|
488
|
+
### Fase 3.5 pulada sem justificativa
|
|
489
|
+
|
|
490
|
+
**Problema:** SPEC finalizada sem executar elevação de robustez, sem nota explicando por quê.
|
|
491
|
+
**Por quê é ruim:** vulnerabilidades conhecidas (XSS, SQL injection, brute force) não entram na v1 e viram dívida técnica imediata.
|
|
492
|
+
**Solução:** sempre executar Fase 3.5. Se o stack não se encaixa em nenhum domínio, registrar: "Fase 3.5 não aplicável: CLI puro sem HTTP, sem DB, sem auth".
|
|
493
|
+
|
|
494
|
+
---
|
|
495
|
+
|
|
496
|
+
### ROADMAP sem resultado demonstrável por fase
|
|
497
|
+
|
|
498
|
+
**Problema:** `Fase 1 — Implementar a lógica interna de processamento` sem resultado visível.
|
|
499
|
+
**Por quê é ruim:** fases sem resultado demonstrável são estágios de código interno que o usuário não consegue validar.
|
|
500
|
+
**Solução:** toda fase do ROADMAP deve ter resultado demonstrável: "Fase 1 — Usuário consegue fazer login, receber JWT válido e acessar rota protegida".
|
|
501
|
+
|
|
502
|
+
---
|
|
503
|
+
|
|
504
|
+
### Setup externo invisível na SPEC
|
|
505
|
+
|
|
506
|
+
**Problema:** SPEC menciona "integrar com serviço de email" sem listar as credenciais necessárias nem quem as configura.
|
|
507
|
+
**Por quê é ruim:** o plan vai criar a integração, mas vai falhar em staging/produção por falta de configuração externa.
|
|
508
|
+
**Solução:** adicionar seção obrigatória `## Setup externo e pré-condições` com: variáveis de ambiente necessárias, contas/recursos a criar, e quem é responsável por cada item.
|
|
509
|
+
|
|
510
|
+
---
|
|
511
|
+
|
|
512
|
+
### Requisito verificável apenas em produção
|
|
513
|
+
|
|
514
|
+
**Problema:** `A5 — Sistema envia email de boas-vindas para usuário real após cadastro`.
|
|
515
|
+
**Por quê é ruim:** não é possível verificar em CI/CD sem sandbox do provedor de email. O agente não tem acesso ao email real.
|
|
516
|
+
**Solução:** tornar verificável em ambiente controlado: `A5 — Integração com SendGrid sandbox envia email para endereço de teste; log confirma `202 Accepted` do provider`. Ou marcar explicitamente "verificação manual necessária" com critério de como realizar.
|
|
517
|
+
</spec_anti_patterns>
|
|
518
|
+
|
|
226
519
|
<fase_5_aprovacao>
|
|
227
520
|
## Fase 5 — Aprovação e próximo passo
|
|
228
521
|
|
|
@@ -12,14 +12,15 @@ Não substitui **`verify`**: cruza contrato UI; o verify global continua a amarr
|
|
|
12
12
|
|
|
13
13
|
<context>
|
|
14
14
|
- Aplicar `oxe/workflows/references/reasoning-review.md`. A revisão UI deve começar pelos achados e bloqueios, não por resumo.
|
|
15
|
-
- Se não existir `UI-SPEC.md`, pedir **`/oxe-ui-spec`** primeiro ou documentar em UI-REVIEW que a revisão é **ad hoc** (menos preferível).
|
|
16
|
-
- Incluir checklist curta (ex.: pilares: semântica, foco, contraste, mensagens de erro, mobile).
|
|
17
|
-
- **Bloqueios P0** (ex.: inacessível, fluxo quebrado) devem ser listados explicitamente; P1/P2 como melhorias.
|
|
15
|
+
- Se não existir `UI-SPEC.md`, pedir **`/oxe-ui-spec`** primeiro ou documentar em UI-REVIEW que a revisão é **ad hoc** (menos preferível).
|
|
16
|
+
- Incluir checklist curta (ex.: pilares: semântica, foco, contraste, mensagens de erro, mobile).
|
|
17
|
+
- **Bloqueios P0** (ex.: inacessível, fluxo quebrado) devem ser listados explicitamente; P1/P2 como melhorias.
|
|
18
|
+
- Agente especializado: quando disponível, usar `oxe-ui-auditor` para comparar implementação contra `UI-SPEC.md`, evidência visual e critérios A*.
|
|
18
19
|
</context>
|
|
19
20
|
|
|
20
21
|
<process>
|
|
21
22
|
1. Resolver `active_session` conforme `session-path-resolution.md`; ler `UI-SPEC.md` e `SPEC.md` do escopo resolvido e inspecionar ficheiros de UI relevantes (paths do PLAN ou indicados pelo utilizador).
|
|
22
|
-
2. Escrever **`UI-REVIEW.md`** no escopo de `verification/` da sessão ativa (ou `.oxe/` legado) com: **Data**, **Âmbito revisto**, **Checklist** (passou / falhou / N/A), **Bloqueios**, **Sugestões
|
|
23
|
+
2. Escrever **`UI-REVIEW.md`** no escopo de `verification/` da sessão ativa (ou `.oxe/` legado) com: **Data**, **Âmbito revisto**, **Checklist** (passou / falhou / N/A), **Bloqueios**, **Sugestões**, evidência visual quando disponível e divergências justificadas.
|
|
23
24
|
3. Atualizar **`.oxe/STATE.md`** global se útil (referência a UI-REVIEW pendente de verify).
|
|
24
25
|
4. Indicar no chat nesta ordem:
|
|
25
26
|
- **Findings**
|
package/oxe/workflows/ui-spec.md
CHANGED
|
@@ -12,13 +12,14 @@ Produzir **`.oxe/UI-SPEC.md`**: contrato de UI/UX derivado de **`.oxe/SPEC.md`**
|
|
|
12
12
|
|
|
13
13
|
<context>
|
|
14
14
|
- Se o projeto **não** tiver interface (só API/CLI/backend), não gerar UI-SPEC; indicar no chat que esta vertical não se aplica.
|
|
15
|
-
- Não substituir a SPEC: UI-SPEC **refina** entrega visual/UX alinhada aos **A***.
|
|
16
|
-
- Secções
|
|
15
|
+
- Não substituir a SPEC: UI-SPEC **refina** entrega visual/UX alinhada aos **A***.
|
|
16
|
+
- Secções obrigatórias em `UI-SPEC.md`: **Âmbito** (ecrãs/componentes), **Design system**, **Tokens**, **Estados** (vazio/carregamento/erro/sucesso), **Copywriting**, **Acessibilidade** (foco, labels, teclado), **Breakpoints**, **Registry safety** e **Checker sign-off**.
|
|
17
|
+
- Agentes úteis: `oxe-ui-researcher` cria o contrato; `oxe-ui-checker` valida se ele é implementável antes do plano.
|
|
17
18
|
</context>
|
|
18
19
|
|
|
19
20
|
<process>
|
|
20
21
|
1. Resolver `active_session` conforme `session-path-resolution.md`; ler `SPEC.md` do escopo resolvido e, se existirem, `OVERVIEW.md` / `CONVENTIONS.md` em `.oxe/codebase/`.
|
|
21
|
-
2. Criar ou atualizar **`UI-SPEC.md`** em `.oxe/<active_session>/spec/` (ou `.oxe/` legado) com as secções acima preenchidas de forma verificável (checklist ou critérios numerados **U1**, **U2**… opcionais).
|
|
22
|
+
2. Criar ou atualizar **`UI-SPEC.md`** em `.oxe/<active_session>/spec/` (ou `.oxe/` legado) com as secções acima preenchidas de forma verificável (checklist ou critérios numerados **U1**, **U2**… opcionais). Se componente externo/registry for citado, registrar origem, inspeção mínima e risco.
|
|
22
23
|
3. Atualizar **`.oxe/STATE.md`** global: nota de fase ou próximo passo `oxe:plan` (se ainda não há PLAN) ou manter `oxe:execute` se o plano já referencia UI.
|
|
23
24
|
4. Resumo no chat: o que ficou no UI-SPEC e como o **`/oxe-plan`** deve citar as secções (ex.: “cumprir UI-SPEC §2”).
|
|
24
25
|
</process>
|
package/oxe/workflows/verify.md
CHANGED
|
@@ -51,9 +51,10 @@ Ao receber qualquer argumento, verificar flags antes de iniciar o fluxo principa
|
|
|
51
51
|
- Seguir `oxe/workflows/references/flow-robustness-contract.md`. O verify não valida só se passou; valida também se o plano estava bem calibrado para começar.
|
|
52
52
|
- Antes da leitura ampla, resolver `.oxe/context/packs/verify.md` e `.oxe/context/packs/verify.json` como entrada prioritária do passo.
|
|
53
53
|
- Se o pack estiver fresco e coerente, usar `read_order`, `selected_artifacts`, `gaps` e `conflicts` como mapa primário da evidência. Se estiver stale, ausente ou com lacunas críticas, fazer fallback explícito para leitura direta e registar isso em `VERIFY.md`.
|
|
54
|
-
- **Runtime enterprise como caminho padrão:** quando `oxe-cc runtime` estiver disponível, executar ou solicitar `oxe-cc runtime verify --dir <projeto>` como caminho primário deste passo. Tratar `verification-manifest.json`, `residual-risk-ledger.json` e `evidence-coverage.json` da run ativa como fonte primária de evidência técnica, e o `VERIFY.md` projetado pelo runtime como base do artefato final.
|
|
55
|
-
- Se `runtime verify` retornar `partial`, continuar com as camadas manuais usando os gaps explícitos do runtime como backlog obrigatório da revisão; não cair silenciosamente para narrativa solta.
|
|
56
|
-
- Se o runtime não estiver compilado, indisponível ou não puder ser executado no ambiente atual, declarar `fallback legado` explicitamente antes de seguir com a verificação manual baseada em markdown e comandos locais.
|
|
54
|
+
- **Runtime enterprise como caminho padrão:** quando `oxe-cc runtime` estiver disponível, executar ou solicitar `oxe-cc runtime verify --dir <projeto>` como caminho primário deste passo. Tratar `verification-manifest.json`, `residual-risk-ledger.json` e `evidence-coverage.json` da run ativa como fonte primária de evidência técnica, e o `VERIFY.md` projetado pelo runtime como base do artefato final.
|
|
55
|
+
- Se `runtime verify` retornar `partial`, continuar com as camadas manuais usando os gaps explícitos do runtime como backlog obrigatório da revisão; não cair silenciosamente para narrativa solta.
|
|
56
|
+
- Se o runtime não estiver compilado, indisponível ou não puder ser executado no ambiente atual, declarar `fallback legado` explicitamente antes de seguir com a verificação manual baseada em markdown e comandos locais.
|
|
57
|
+
- **Agentes de verificação:** quando disponíveis, usar `oxe-verifier`, `oxe-integration-checker`, `oxe-validation-auditor` e `oxe-ui-auditor` como papéis auxiliares para auditar evidência, integração, lacunas de validação e UI. O resultado final continua sendo `VERIFY.md` + manifest/evidence do runtime.
|
|
57
58
|
- Ler `EXECUTION-RUNTIME.md` e `CHECKPOINTS.md` do escopo resolvido quando existirem. Eles são evidência tática para saber o que realmente foi executado, bloqueado, aprovado ou desviado.
|
|
58
59
|
- Se a trilha tocar Azure, ler `.oxe/cloud/azure/INVENTORY.md`, `SERVICEBUS.md`, `EVENTGRID.md`, `SQL.md` e `operations/*.md|json` para confirmar recursos reais, checkpoints e mutações aplicadas.
|
|
59
60
|
- **Observações CI como evidência:** se `OBSERVATIONS.md` do escopo resolvido tiver obs do tipo `ci_failure` com `CI-evidência` preenchida, usar como evidência adicional para critérios A* de qualidade (ex.: cobertura, build verde). Se obs tiver `ci_run_url`, referenciar na coluna **Evidência** da tabela de critérios. Se obs estiver `pendente` e critério A* de qualidade existir, marcar o critério como `evidence_pending_ci` — não como passou — até o CI ser resolvido.
|
|
@@ -73,12 +74,14 @@ Ao receber qualquer argumento, verificar flags antes de iniciar o fluxo principa
|
|
|
73
74
|
<camada_1_pre_exec_audit>
|
|
74
75
|
**Camada 1 — Auditoria de pré-execução** (roda *antes* de iniciar os comandos de verify)
|
|
75
76
|
|
|
76
|
-
Verificar que o PLAN.md está apto para verificação:
|
|
77
|
+
Verificar que o PLAN.md está apto para verificação:
|
|
77
78
|
1. Toda tarefa `### Tn` tem bloco **Verificar** com pelo menos Comando ou Manual.
|
|
78
79
|
2. Todo **Aceite vinculado** referencia IDs que existem na tabela de SPEC.md (`A1`, `A2`, …).
|
|
79
80
|
3. Se houver `DISCUSS.md` no escopo resolvido, toda decisão técnica com ID **D-NN** aparece em **Decisão vinculada:** de alguma tarefa (ou nota explícita de gap no PLAN).
|
|
80
81
|
4. Não há dependências `Tk` inválidas (ID inexistente no PLAN).
|
|
81
|
-
5. `PLAN.md` contém a seção **Autoavaliação do Plano** com `Melhor plano atual`, `Confiança` e rubrica preenchida.
|
|
82
|
+
5. `PLAN.md` contém a seção **Autoavaliação do Plano** com `Melhor plano atual`, `Confiança` e rubrica preenchida.
|
|
83
|
+
6. `IMPLEMENTATION-PACK`, `REFERENCE-ANCHORS` e `FIXTURE-PACK` existem quando a execução veio de plano e não possuem `critical_gap` não resolvido.
|
|
84
|
+
7. Tarefas de risco têm evidência executável ou fixture/UAT explicitamente justificada.
|
|
82
85
|
|
|
83
86
|
Se auditoria falhar: registrar na seção **Auditoria de pré-execução** do VERIFY.md os itens com problema e **pausar** — pedir correção do PLAN antes de continuar. Se o usuário forçar continuar com `--skip-audit`, documentar e prosseguir com aviso.
|
|
84
87
|
</camada_1_pre_exec_audit>
|
package/package.json
CHANGED
|
@@ -199,6 +199,46 @@ export function validateGraph(graph: ExecutionGraph): string[] {
|
|
|
199
199
|
}
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
+
// Validate mutation_scope conflicts between parallel nodes in the same wave
|
|
203
|
+
const waveMap = new Map<number, string[]>();
|
|
204
|
+
for (const [id, node] of graph.nodes) {
|
|
205
|
+
const list = waveMap.get(node.wave) ?? [];
|
|
206
|
+
waveMap.set(node.wave, [...list, id]);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
for (const [wave, waveNodeIds] of waveMap) {
|
|
210
|
+
for (let i = 0; i < waveNodeIds.length; i++) {
|
|
211
|
+
for (let j = i + 1; j < waveNodeIds.length; j++) {
|
|
212
|
+
const idA = waveNodeIds[i];
|
|
213
|
+
const idB = waveNodeIds[j];
|
|
214
|
+
const a = graph.nodes.get(idA)!;
|
|
215
|
+
const b = graph.nodes.get(idB)!;
|
|
216
|
+
const notDependent =
|
|
217
|
+
!a.depends_on.includes(idB) && !b.depends_on.includes(idA);
|
|
218
|
+
if (notDependent && a.mutation_scope.length > 0 && b.mutation_scope.length > 0) {
|
|
219
|
+
const overlap = a.mutation_scope.filter(p => b.mutation_scope.includes(p));
|
|
220
|
+
if (overlap.length > 0) {
|
|
221
|
+
errors.push(
|
|
222
|
+
`Wave ${wave}: nodes "${idA}" and "${idB}" mutate the same paths in parallel: ${overlap.join(', ')}`
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Validate wave ordering: a node must only depend on nodes from earlier waves
|
|
231
|
+
for (const [id, node] of graph.nodes) {
|
|
232
|
+
for (const dep of node.depends_on) {
|
|
233
|
+
const depNode = graph.nodes.get(dep);
|
|
234
|
+
if (depNode && depNode.wave >= node.wave) {
|
|
235
|
+
errors.push(
|
|
236
|
+
`Node "${id}" (wave ${node.wave}) depends on "${dep}" (wave ${depNode.wave}) — dependency must come from an earlier wave`
|
|
237
|
+
);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
202
242
|
return errors;
|
|
203
243
|
}
|
|
204
244
|
|
|
@@ -237,6 +237,86 @@ export class ContextPackBuilder {
|
|
|
237
237
|
return this.build(workItem, state, [], new Map(), lessons);
|
|
238
238
|
}
|
|
239
239
|
|
|
240
|
+
/**
|
|
241
|
+
* Remove artifacts with lowest relevance until the pack fits within targetTokens.
|
|
242
|
+
* Artifacts already sorted by relevance; we trim the tail.
|
|
243
|
+
*/
|
|
244
|
+
compact(pack: ContextPack, targetTokens: number): ContextPack {
|
|
245
|
+
if (estimateTokens(pack.artifacts.map((a) => a.content).join('\n')) <= targetTokens) {
|
|
246
|
+
return pack;
|
|
247
|
+
}
|
|
248
|
+
const sorted = [...pack.artifacts].sort((a, b) => b.relevanceScore - a.relevanceScore);
|
|
249
|
+
const trimmed: ContextArtifact[] = [];
|
|
250
|
+
let used = 0;
|
|
251
|
+
for (const artifact of sorted) {
|
|
252
|
+
const t = estimateTokens(artifact.content);
|
|
253
|
+
if (used + t > targetTokens) break;
|
|
254
|
+
trimmed.push(artifact);
|
|
255
|
+
used += t;
|
|
256
|
+
}
|
|
257
|
+
return {
|
|
258
|
+
...pack,
|
|
259
|
+
artifacts: trimmed,
|
|
260
|
+
redundancy_removed: pack.redundancy_removed + (pack.artifacts.length - trimmed.length),
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Merge groups of similar artifacts (cosine similarity >= threshold) into single
|
|
266
|
+
* combined artifacts to reduce redundancy without discarding information entirely.
|
|
267
|
+
*/
|
|
268
|
+
microCompact(artifacts: ContextArtifact[], similarityThreshold = 0.7): ContextArtifact[] {
|
|
269
|
+
const merged: ContextArtifact[] = [];
|
|
270
|
+
const used = new Set<number>();
|
|
271
|
+
|
|
272
|
+
for (let i = 0; i < artifacts.length; i++) {
|
|
273
|
+
if (used.has(i)) continue;
|
|
274
|
+
const group: ContextArtifact[] = [artifacts[i]];
|
|
275
|
+
for (let j = i + 1; j < artifacts.length; j++) {
|
|
276
|
+
if (!used.has(j) && cosineSimilarity(artifacts[i], artifacts[j]) >= similarityThreshold) {
|
|
277
|
+
group.push(artifacts[j]);
|
|
278
|
+
used.add(j);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
used.add(i);
|
|
282
|
+
if (group.length === 1) {
|
|
283
|
+
merged.push(group[0]);
|
|
284
|
+
} else {
|
|
285
|
+
const combinedContent = group
|
|
286
|
+
.map((a) => a.content)
|
|
287
|
+
.join('\n---\n')
|
|
288
|
+
.slice(0, 4000);
|
|
289
|
+
merged.push({
|
|
290
|
+
id: group[0].id,
|
|
291
|
+
kind: group[0].kind,
|
|
292
|
+
content: combinedContent,
|
|
293
|
+
relevanceScore: group.reduce((s, a) => s + a.relevanceScore, 0) / group.length,
|
|
294
|
+
tags: [...new Set(group.flatMap((a) => a.tags))],
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return merged;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Automatically compact a pack to fit within hardLimitTokens.
|
|
303
|
+
* First applies microCompact (lossless merging), then compact (trimming by relevance).
|
|
304
|
+
*/
|
|
305
|
+
autoCompact(pack: ContextPack, hardLimitTokens: number): ContextPack {
|
|
306
|
+
const currentTokens = estimateTokens(pack.artifacts.map((a) => a.content).join('\n'));
|
|
307
|
+
if (currentTokens <= hardLimitTokens) return pack;
|
|
308
|
+
|
|
309
|
+
const microCompacted = this.microCompact(pack.artifacts);
|
|
310
|
+
const removedByMicro = pack.artifacts.length - microCompacted.length;
|
|
311
|
+
|
|
312
|
+
const interim: ContextPack = {
|
|
313
|
+
...pack,
|
|
314
|
+
artifacts: microCompacted,
|
|
315
|
+
redundancy_removed: pack.redundancy_removed + removedByMicro,
|
|
316
|
+
};
|
|
317
|
+
return this.compact(interim, hardLimitTokens);
|
|
318
|
+
}
|
|
319
|
+
|
|
240
320
|
/**
|
|
241
321
|
* Filter artifacts to those whose path-like tags are within mutation_scope.
|
|
242
322
|
* L0/L1 tiers apply the filter; L2/L3 skip it (full access).
|
|
@@ -20,6 +20,11 @@ export const EVENT_TYPES = [
|
|
|
20
20
|
'RunCompleted',
|
|
21
21
|
'RetroPublished',
|
|
22
22
|
'LessonPromoted',
|
|
23
|
+
'RunAborted',
|
|
24
|
+
'RollbackExecuted',
|
|
25
|
+
'RollbackFailed',
|
|
26
|
+
'TaskErrorBoundaryTripped',
|
|
27
|
+
'WorkspaceDisposeFailed',
|
|
23
28
|
] as const;
|
|
24
29
|
|
|
25
30
|
export type EventType = (typeof EVENT_TYPES)[number];
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Action } from '../compiler/graph-compiler';
|
|
2
|
+
import { ALL_BUILT_IN_SCHEMAS, BUILT_IN_TOOLS } from './built-in-tools';
|
|
3
|
+
import type { ToolSchema } from './stream-completion';
|
|
4
|
+
|
|
5
|
+
const READ_TOOLS: ToolSchema[] = [
|
|
6
|
+
BUILT_IN_TOOLS.read_file.schema,
|
|
7
|
+
BUILT_IN_TOOLS.glob.schema,
|
|
8
|
+
BUILT_IN_TOOLS.grep.schema,
|
|
9
|
+
];
|
|
10
|
+
|
|
11
|
+
const PATCH_TOOLS: ToolSchema[] = [
|
|
12
|
+
BUILT_IN_TOOLS.read_file.schema,
|
|
13
|
+
BUILT_IN_TOOLS.write_file.schema,
|
|
14
|
+
BUILT_IN_TOOLS.patch_file.schema,
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
const RUN_TOOLS: ToolSchema[] = [BUILT_IN_TOOLS.run_command.schema];
|
|
18
|
+
|
|
19
|
+
const EVIDENCE_TOOLS: ToolSchema[] = [
|
|
20
|
+
BUILT_IN_TOOLS.read_file.schema,
|
|
21
|
+
BUILT_IN_TOOLS.glob.schema,
|
|
22
|
+
BUILT_IN_TOOLS.run_command.schema,
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
const ACTION_TOOL_MAP: Record<Action['type'], ToolSchema[]> = {
|
|
26
|
+
read_code: READ_TOOLS,
|
|
27
|
+
generate_patch: PATCH_TOOLS,
|
|
28
|
+
run_tests: RUN_TOOLS,
|
|
29
|
+
run_lint: RUN_TOOLS,
|
|
30
|
+
collect_evidence: EVIDENCE_TOOLS,
|
|
31
|
+
custom: ALL_BUILT_IN_SCHEMAS,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export function selectToolsForActions(actions: Action[]): ToolSchema[] {
|
|
35
|
+
const seen = new Set<string>();
|
|
36
|
+
const result: ToolSchema[] = [];
|
|
37
|
+
for (const action of actions) {
|
|
38
|
+
for (const tool of ACTION_TOOL_MAP[action.type] ?? ALL_BUILT_IN_SCHEMAS) {
|
|
39
|
+
if (!seen.has(tool.function.name)) {
|
|
40
|
+
seen.add(tool.function.name);
|
|
41
|
+
result.push(tool);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return result;
|
|
46
|
+
}
|