@semacode/cli 3.0.0 → 3.5.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 (46) hide show
  1. package/dist/agentEntryPoints.js +78 -64
  2. package/dist/cliGrammar.js +4 -4
  3. package/dist/cliHelpTexto.js +6 -6
  4. package/dist/docs.part01.d.ts +4 -1
  5. package/dist/docs.part01.js +8 -0
  6. package/dist/docs.part02.js +9 -1
  7. package/dist/drift.part01.d.ts +7 -1
  8. package/dist/drift.part04.d.ts +14 -2
  9. package/dist/drift.part04.js +35 -2
  10. package/dist/drift.part09.d.ts +2 -2
  11. package/dist/drift.part09.js +10 -3
  12. package/dist/drift.part11.js +24 -3
  13. package/dist/drift.part14.js +2 -0
  14. package/dist/exemplosOficiais.d.ts +2 -1
  15. package/dist/exemplosOficiais.js +9 -3
  16. package/dist/geracaoCore.d.ts +1 -0
  17. package/dist/geracaoCore.js +2 -0
  18. package/dist/importador.part01.d.ts +1 -1
  19. package/dist/importador.part06.d.ts +2 -0
  20. package/dist/importador.part06.js +87 -1
  21. package/dist/importador.part09.js +7 -1
  22. package/dist/index.part04.js +13 -6
  23. package/dist/index.part07.d.ts +8 -2
  24. package/dist/index.part07.js +146 -4
  25. package/dist/index.part08.js +3 -3
  26. package/dist/initCommand.d.ts +1 -0
  27. package/dist/initCommand.js +15 -3
  28. package/dist/initTemplatesBase.js +78 -78
  29. package/dist/projetoConfig.js +2 -0
  30. package/dist/projetoLegado.js +18 -0
  31. package/dist/tipos.d.ts +1 -1
  32. package/dist/typescript-http-modelos.d.ts +1 -1
  33. package/dist/typescript-http-rotas.d.ts +1 -0
  34. package/dist/typescript-http-rotas.js +93 -0
  35. package/dist/typescript-http.d.ts +1 -1
  36. package/dist/typescript-http.js +1 -1
  37. package/dist/verificacaoCache.d.ts +25 -0
  38. package/dist/verificacaoCache.js +80 -0
  39. package/docs/syntax.md +14 -0
  40. package/exemplos/express_crud.sema +139 -0
  41. package/exemplos/fastify_crud.sema +146 -0
  42. package/node_modules/@sema/nucleo/dist/ir/conversor.part01.js +37 -38
  43. package/node_modules/@sema/nucleo/dist/ir/modelos.d.ts +1 -0
  44. package/node_modules/@sema/nucleo/dist/semantico/analisador.part01.d.ts +7 -0
  45. package/node_modules/@sema/nucleo/dist/semantico/analisador.part01.js +33 -10
  46. package/package.json +1 -1
@@ -146,13 +146,13 @@ Você está em um projeto governado por Sema. O contrato semântico vem antes de
146
146
 
147
147
  ## Primeira ação
148
148
 
149
- 1. Confirme \`AGENTS.md\` na raiz e rode \`sema --version\`. Se o shell não localizar o comando, use \`$HOME/.sema/bin/sema\` no macOS/Linux; no Windows, PowerShell usa \`sema.ps1\` no PATH, cmd.exe usa \`sema.cmd\`, e o fallback absoluto é \`& "$env:SystemRoot\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$HOME\\.sema\\bin\\sema-managed.ps1" --version\`. Só então declare a CLI indisponível.
150
- 2. Use a CLI local diretamente para ler o workspace: \`sema resumo --drift none\`, \`sema docs-impacto\`, \`sema inspecionar --drift none\`, \`sema drift --cache fresh\` e \`sema impacto\`. Na 3.0.0, \`sema --version\` continua texto SemVer exato; com \`--json\`, help e falhas de controle usam \`sema.cli.control/v1\`, enquanto comandos sintaticamente válidos usam o envelope exato de oito campos \`sema.cli.result/v1\`, com o resultado aninhado em \`payload\` e \`ok\` separado do veredito de domínio desse payload.
149
+ 1. Confirme \`AGENTS.md\` na raiz e rode \`sema --version\`. Se o shell não localizar o comando, use \`$HOME/.sema/bin/sema\` no macOS/Linux; no Windows, PowerShell usa \`sema.ps1\` no PATH, cmd.exe usa \`sema.cmd\`, e o fallback absoluto é \`& "$env:SystemRoot\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$HOME\\.sema\\bin\\sema-managed.ps1" --version\`. Só então declare a CLI indisponível.
150
+ 2. Use a CLI local diretamente para ler o workspace: \`sema resumo --drift none\`, \`sema docs-impacto\`, \`sema inspecionar --drift none\`, \`sema drift --cache fresh\` e \`sema impacto\`. Na 3.0.0, \`sema --version\` continua texto SemVer exato; com \`--json\`, help e falhas de controle usam \`sema.cli.control/v1\`, enquanto comandos sintaticamente válidos usam o envelope exato de oito campos \`sema.cli.result/v1\`, com o resultado aninhado em \`payload\` e \`ok\` separado do veredito de domínio desse payload.
151
151
  3. Se não estiver claro qual profile, workflow, pipeline, gerador ou adapter usar, rode \`sema descobrir recomendar --intencao "<objetivo>" --json\`; não execute automaticamente uma recomendação ambígua.
152
152
  4. Não use fonte externa de workspace para substituir a CLI local quando ela estiver operacional.
153
153
  5. Este boot é para workspace local em disco; se não houver workspace local, pare bloqueado em vez de inventar caminho.
154
154
  6. Antes de criar módulo, rota, task ou contrato, inspecione o contrato \`.sema\` aplicável.
155
- 7. Antes de editar código existente, rode \`sema drift --cache fresh\` e impacto pela CLI local.
155
+ 7. Antes de editar código existente, rode \`sema drift --cache fresh\` e impacto pela CLI local.
156
156
  8. Antes de criar ou corrigir \`.sema\`, use os exemplos oficiais na CLI local.
157
157
  9. Se qualquer etapa falhar, pare e diga que está bloqueado.
158
158
 
@@ -197,10 +197,10 @@ Score composto, \`achados[]\` e \`decisaoAgente\` são sinais para guiar a próx
197
197
  - Fraca: se o score passou, confira se cada achado tem evidência concreta; se não souber provar, pare.
198
198
  - Média: conecte regra, arquivo, contrato e evidência antes de concluir aderência.
199
199
  - Forte: não transforme regex, palavra-chave ou score 100 em ritual vazio; valide substância, risco e comportamento.
200
- - Consultas honestas: \`resumo\` e \`inspecionar\` usam \`--drift none\` por padrão; score, confiança, implementação, rotas e superfícies não observadas ficam nulos/não avaliados.
201
- - Se uma consulta executar drift explicitamente, \`payload.analiseDrift.sucesso\` expõe o resultado e uma falha solicitada retorna exit code diferente de zero.
202
- - Cache: \`sema drift\` usa \`fresh\` por padrão. \`--cache none\` ainda executa sem persistência; \`cache\` acelera extrações validadas, mas não é prova final.
203
- - Fechamento governado: se o \`payload\` de \`sema drift --cache fresh --json\` retornar \`sucesso:false\`, \`vinculos_quebrados\`, \`rotas_divergentes\` ou \`impls_quebrados\`, não diga que passou limpo. Corrija e rode drift de novo.
200
+ - Consultas honestas: \`resumo\` e \`inspecionar\` usam \`--drift none\` por padrão; score, confiança, implementação, rotas e superfícies não observadas ficam nulos/não avaliados.
201
+ - Se uma consulta executar drift explicitamente, \`payload.analiseDrift.sucesso\` expõe o resultado e uma falha solicitada retorna exit code diferente de zero.
202
+ - Cache: \`sema drift\` usa \`fresh\` por padrão. \`--cache none\` ainda executa sem persistência; \`cache\` acelera extrações validadas, mas não é prova final.
203
+ - Fechamento governado: se o \`payload\` de \`sema drift --cache fresh --json\` retornar \`sucesso:false\`, \`vinculos_quebrados\`, \`rotas_divergentes\` ou \`impls_quebrados\`, não diga que passou limpo. Corrija e rode drift de novo.
204
204
  - Experiência governada: se a tarefa cria ou altera site, sistema, app, UI, painel, jogo, CLI/TUI ou terminal, prove acabamento moderno, contextual e não genérico. Em UI estreita (ex. 390px), \`document.documentElement.scrollWidth <= document.documentElement.clientWidth\` precisa ser verdadeiro.
205
205
  - Caminho fora do workspace local aberto pelo usuário não substitui a pasta local.
206
206
 
@@ -248,7 +248,7 @@ export function renderizarSemaSmallModel(agentContextPack) {
248
248
  Leia isto primeiro se você tem pouco contexto, pouca memória, pouco tool use ou tendência a ignorar instruções longas.
249
249
 
250
250
  1. Não edite nada antes de chamar Sema.
251
- 2. Em workspace local, rode \`sema --version\`; se o shell falhar, use \`$HOME/.sema/bin/sema\` no macOS/Linux. No Windows, PowerShell usa \`sema.ps1\` no PATH e cmd.exe usa \`sema.cmd\`; o fallback absoluto é \`& "$env:SystemRoot\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$HOME\\.sema\\bin\\sema-managed.ps1" --version\`. Só então pare e peça instalação ou reparo.
251
+ 2. Em workspace local, rode \`sema --version\`; se o shell falhar, use \`$HOME/.sema/bin/sema\` no macOS/Linux. No Windows, PowerShell usa \`sema.ps1\` no PATH e cmd.exe usa \`sema.cmd\`; o fallback absoluto é \`& "$env:SystemRoot\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$HOME\\.sema\\bin\\sema-managed.ps1" --version\`. Só então pare e peça instalação ou reparo.
252
252
  3. Sema não contorna políticas da plataforma: ele governa contrato, escopo, drift, evidência e qualidade.
253
253
  4. Se aparecer alerta de política: pare, explique de forma neutra e não tente burlar filtro.
254
254
  5. Se não houver workspace local em disco: pare bloqueado e peça o fluxo apropriado; não invente leitura por caminho.
@@ -264,7 +264,7 @@ Leia isto primeiro se você tem pouco contexto, pouca memória, pouco tool use o
264
264
  15. Payload inline acima de ${LIMITE_CARACTERES_PAYLOAD_INLINE} caracteres não é lentidão: divida por responsabilidade; não aumente timeout para tentar passar limite de transporte.
265
265
  16. Se aparecer caminho que não pertence ao workspace local aberto pelo usuário, pare e confirme a fonte antes de agir.
266
266
  17. Se Sema estourar por timeout local: aumente o timeout e tente de novo. Não trate isso como falha do Sema.
267
- 18. Para fechamento, rode \`sema drift --cache fresh --json\`; cache persistente só acelera navegação e não é prova final. Se o \`payload\` retornar \`sucesso:false\`, \`vinculos_quebrados\`, \`rotas_divergentes\` ou \`impls_quebrados\`, não conclua. Na 3.0.0, não procure campos de domínio no topo do envelope \`sema.cli.result/v1\` nem use \`ok\` como substituto do veredito do payload.
267
+ 18. Para fechamento, rode \`sema drift --cache fresh --json\`; cache persistente só acelera navegação e não é prova final. Se o \`payload\` retornar \`sucesso:false\`, \`vinculos_quebrados\`, \`rotas_divergentes\` ou \`impls_quebrados\`, não conclua. Na 3.0.0, não procure campos de domínio no topo do envelope \`sema.cli.result/v1\` nem use \`ok\` como substituto do veredito do payload.
268
268
  19. Se a tarefa tiver site, sistema, app, UI, painel, jogo, CLI/TUI ou terminal: aplique acabamento moderno, contextual, responsivo/ergonômico, com hierarquia clara, estados e evidência. Em UI, valide mobile/desktop e prove \`scrollWidth <= clientWidth\` em viewport estreito como 390px.
269
269
  20. Não substitua o contexto Sema por AGENTS.md, README.md, busca local, inferência por nome ou bom senso.
270
270
 
@@ -287,7 +287,7 @@ Timeout:
287
287
  - Timeout local do agente não é falha do Sema.
288
288
  - Projeto inteiro: comece com ${politicaTimeout.timeoutInicialSegundos}s ou mais.
289
289
  - Escalonamento: ${politicaTimeout.escalonamentoSegundos.map((segundos) => `${segundos}s`).join(" -> ")}.
290
- - Se o projeto inteiro for lento, escopar para \`sema resumo <arquivo.sema> --micro --para mudanca --drift none\`.
290
+ - Se o projeto inteiro for lento, escopar para \`sema resumo <arquivo.sema> --micro --para mudanca --drift none\`.
291
291
  - ${politicaTimeout.ateQuandoTentar}
292
292
 
293
293
  Acabamento visual e terminal:
@@ -440,13 +440,13 @@ function renderizarInstrucaoCodexSema(agentContextPack) {
440
440
  Este workspace é governado por Sema. Antes de qualquer ação em código, contrato, documentação operacional, workflow, profile ou deploy:
441
441
 
442
442
  1. Leia \`${ARQUIVO_SEMA_BOOT}\`.
443
- 2. Rode \`sema --version\`; se o shell falhar, use \`$HOME/.sema/bin/sema\` no macOS/Linux. No Windows, PowerShell usa \`sema.ps1\` no PATH e cmd.exe usa \`sema.cmd\`; use \`& "$env:SystemRoot\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$HOME\\.sema\\bin\\sema-managed.ps1" --version\` como fallback absoluto. Só então pare e peça instalação ou reparo.
444
- 3. Use diretamente a CLI local: \`sema resumo --drift none\`, \`sema docs-impacto\`, \`sema inspecionar --drift none\`, \`sema drift --cache fresh\` e \`sema impacto\`. Na 3.0.0, \`sema --version\` continua texto SemVer exato; com \`--json\`, help e falhas de controle usam \`sema.cli.control/v1\`, enquanto comandos sintaticamente válidos usam o envelope exato de oito campos \`sema.cli.result/v1\`, com resultado em \`payload\` e \`ok\` distinto do veredito de domínio do payload.
443
+ 2. Rode \`sema --version\`; se o shell falhar, use \`$HOME/.sema/bin/sema\` no macOS/Linux. No Windows, PowerShell usa \`sema.ps1\` no PATH e cmd.exe usa \`sema.cmd\`; use \`& "$env:SystemRoot\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$HOME\\.sema\\bin\\sema-managed.ps1" --version\` como fallback absoluto. Só então pare e peça instalação ou reparo.
444
+ 3. Use diretamente a CLI local: \`sema resumo --drift none\`, \`sema docs-impacto\`, \`sema inspecionar --drift none\`, \`sema drift --cache fresh\` e \`sema impacto\`. Na 3.0.0, \`sema --version\` continua texto SemVer exato; com \`--json\`, help e falhas de controle usam \`sema.cli.control/v1\`, enquanto comandos sintaticamente válidos usam o envelope exato de oito campos \`sema.cli.result/v1\`, com resultado em \`payload\` e \`ok\` distinto do veredito de domínio do payload.
445
445
  4. Quando a capacidade correta não estiver clara, use \`sema descobrir recomendar --intencao "<objetivo>" --json\`; não autoexecute resultado ambíguo.
446
446
  5. Não use fonte externa de workspace para substituir a CLI local quando ela estiver operacional.
447
447
  6. Chame docs-impacto com a intenção declarada antes de agir.
448
448
  7. Chame inspecionar no contrato \`.sema\` aplicável.
449
- 8. Antes de editar código existente, rode \`sema drift --cache fresh\` e impacto.
449
+ 8. Antes de editar código existente, rode \`sema drift --cache fresh\` e impacto.
450
450
  9. Antes de criar ou editar \`.sema\`, use exemplos oficiais.
451
451
  10. Ao concluir mudança de contrato, rode validar.
452
452
  11. Antes de finalizar, use finalizar-mudanca com as docs lidas.
@@ -469,7 +469,7 @@ Timeout:
469
469
  - Timeout local do agente não é falha do Sema.
470
470
  - Se uma chamada Sema estourar, aumente o timeout e tente de novo antes de declarar bloqueio.
471
471
  - Para projeto inteiro, comece com ${politicaTimeout.timeoutInicialSegundos}s ou mais; se for lento, escale ${politicaTimeout.escalonamentoSegundos.map((segundos) => `${segundos}s`).join(" -> ")}.
472
- - Se possível, reduza escopo para \`sema resumo <arquivo.sema> --micro --para mudanca --drift none\`.
472
+ - Se possível, reduza escopo para \`sema resumo <arquivo.sema> --micro --para mudanca --drift none\`.
473
473
 
474
474
  Código governado:
475
475
  - Mantenha o marcador \`${agentContextPack.politicaCodigoGovernado.marcador}\` em código gerado ou governado.
@@ -482,8 +482,8 @@ Código governado:
482
482
  Sinal e evidência:
483
483
  - Score composto, \`achados[]\` e \`decisaoAgente\` orientam a ação; abaixo de 80 bloqueia, alvo evolui 0.5 ponto até 100, e nada substitui evidência concreta.
484
484
  - Palavra-chave ou regex passando não prova governança se contrato, código e comportamento não batem.
485
- - \`resumo\` e \`inspecionar\` usam \`--drift none\` por padrão; campos derivados nulos significam não avaliados, nunca zero.
486
- - \`sema drift --cache fresh --json\` com \`payload.sucesso:false\`, \`payload.vinculos_quebrados\`, \`payload.rotas_divergentes\` ou \`payload.impls_quebrados\` bloqueia fechamento. Cache persistente é aceleração, não prova final.
485
+ - \`resumo\` e \`inspecionar\` usam \`--drift none\` por padrão; campos derivados nulos significam não avaliados, nunca zero.
486
+ - \`sema drift --cache fresh --json\` com \`payload.sucesso:false\`, \`payload.vinculos_quebrados\`, \`payload.rotas_divergentes\` ou \`payload.impls_quebrados\` bloqueia fechamento. Cache persistente é aceleração, não prova final.
487
487
  - Caminho fora do workspace local aberto pelo usuário não substitui a pasta local.
488
488
 
489
489
  Acabamento visual e terminal:
@@ -589,6 +589,20 @@ impl {
589
589
 
590
590
  \`sema compilar --alvo javascript\` defines a generation target. \`impl { js: ... }\` defines the live-code origin linked to the contract. They are different layers and both are valid.
591
591
 
592
+ ## Layered \`impl\` Roles
593
+
594
+ Layered code (route + service + persistence in the same language) can declare one \`impl\` per role. Append a supported role to the origin: \`rota\`, \`servico\`, \`persistencia\` or \`repositorio\`.
595
+
596
+ \`\`\`sema
597
+ impl {
598
+ ts_rota: server.routes.monitores.criarMonitor
599
+ ts_servico: server.services.monitores.criarMonitor
600
+ ts_persistencia: server.repositories.monitores.criar
601
+ }
602
+ \`\`\`
603
+
604
+ Each origin-plus-role pair must appear at most once; the bare origin (for example \`ts\`) stays valid for single-layer tasks, and drift resolves every role independently.
605
+
592
606
  ## Small Canonical Lists
593
607
 
594
608
  - \`effects\`: \`persistencia\`, \`consulta\`, \`evento\`, \`auditoria\`, \`db.write\`, \`queue.publish\`, \`fs.write\`, \`network.egress\`, \`secret.read\`, \`shell.exec\`.
@@ -635,26 +649,26 @@ function renderizarDocFluxoPraticoSemaLocal(_agentContextPack) {
635
649
  This is the minimum workflow for Codex in a local workspace.
636
650
 
637
651
  1. Read \`${ARQUIVO_SEMA_BOOT}\`.
638
- 2. Run \`sema --version\`. If the shell cannot find it, use \`$HOME/.sema/bin/sema\` on macOS/Linux. On Windows, PowerShell resolves \`sema.ps1\` from PATH and cmd.exe resolves \`sema.cmd\`; use \`& "$env:SystemRoot\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$HOME\\.sema\\bin\\sema-managed.ps1" --version\` as the absolute fallback. Only then declare the CLI unavailable.
639
- 3. Run \`sema resumo --drift none\` for contract-only orientation; request \`--drift cache\` or \`--drift fresh\` only when code evidence is needed.
652
+ 2. Run \`sema --version\`. If the shell cannot find it, use \`$HOME/.sema/bin/sema\` on macOS/Linux. On Windows, PowerShell resolves \`sema.ps1\` from PATH and cmd.exe resolves \`sema.cmd\`; use \`& "$env:SystemRoot\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$HOME\\.sema\\bin\\sema-managed.ps1" --version\` as the absolute fallback. Only then declare the CLI unavailable.
653
+ 3. Run \`sema resumo --drift none\` for contract-only orientation; request \`--drift cache\` or \`--drift fresh\` only when code evidence is needed.
640
654
  4. Run \`sema docs-impacto --intencao "<change>" --json\`.
641
655
  5. Read every required document returned by the command.
642
656
  6. Read \`docs/commands.md\` before selecting a command or interpreting \`--saida\`.
643
657
  7. If the right capability is unclear, run \`sema descobrir recomendar --intencao "<goal>" --json\`; do not auto-run ambiguous recommendations.
644
658
  8. Use \`exemplos/\` and \`docs/syntax.md\` before creating or editing a contract.
645
- 9. Run \`sema drift --cache fresh\` and \`sema impacto\` before editing existing code.
659
+ 9. Run \`sema drift --cache fresh\` and \`sema impacto\` before editing existing code.
646
660
  10. Run \`sema formatar\` and \`sema validar\` after changing a \`.sema\` contract.
647
661
  11. Run \`sema finalizar-mudanca\` with the documents read before closure.
648
662
 
649
663
  Contract edit rule: \`.sema\` has its own size budget. Above ${LIMITE_AVISO_LINHAS_CONTRATO_SEMA} lines, plan a split by domain/capability; above ${LIMITE_BLOQUEIO_LINHAS_CONTRATO_SEMA}, do not create or edit before splitting. Do not use parte_1/parte_2 and do not force a 1:1 contract-to-file relationship; several contracts can govern the same file through \`vinculos\`.
650
664
 
651
- Closing rule: the \`payload\` of \`sema drift --cache fresh --json\` must return \`sucesso:true\`. If it reports \`sucesso:false\`, \`vinculos_quebrados\`, \`rotas_divergentes\`, or \`impls_quebrados\`, the task is still blocked. Passing unit tests or a cache hit do not replace fresh green drift. In 3.0.0, \`ok\` describes the CLI result path and never replaces a command-specific domain verdict.
652
-
653
- Focused drift rule: file and module scopes plan their physical file set before cataloging. They never fall back to a whole-project walk when no safe anchor exists. All indexers and semantic-budget checks reuse the same in-memory source read; a global walk is reserved for explicit \`--escopo projeto\`. Code discovery is deferred until that plan exists, homonymous candidates fail as ambiguous, and configured contract origins or code roots resolving outside the workspace are rejected before enumeration. \`inspecionar\`, \`impacto\`, and \`renomear-semantico\` preserve the same directed boundary. Missing local dependencies make coverage partial and block success.
654
-
655
- Cache rule: a closure gate should use \`sema drift <contrato> --escopo modulo --cache fresh --json\`. \`--cache none\` executes the same analysis without persistent-cache I/O, while \`--cache cache\` may reuse only extraction data whose schema, workspace identity, Git HEAD, plan, configuration, contracts, member paths, and strong content digests all match. Cache objects are stored in the operating system's user-cache directory, never below the workspace. A hit is acceleration, not evidence: final links, diagnostics, score, and success are always recalculated. Corruption or an unavailable cache degrades to an in-memory calculation.
656
-
657
- Query honesty rule: \`resumo\` and \`inspecionar\` default to \`--drift none\`. When analysis is skipped, score, confidence, implementation, routes, and other unobserved code claims inside the command payload must be \`null\` or explicitly marked not evaluated; zero is not a substitute for absent evidence.
665
+ Closing rule: the \`payload\` of \`sema drift --cache fresh --json\` must return \`sucesso:true\`. If it reports \`sucesso:false\`, \`vinculos_quebrados\`, \`rotas_divergentes\`, or \`impls_quebrados\`, the task is still blocked. Passing unit tests or a cache hit do not replace fresh green drift. In 3.0.0, \`ok\` describes the CLI result path and never replaces a command-specific domain verdict.
666
+
667
+ Focused drift rule: file and module scopes plan their physical file set before cataloging. They never fall back to a whole-project walk when no safe anchor exists. All indexers and semantic-budget checks reuse the same in-memory source read; a global walk is reserved for explicit \`--escopo projeto\`. Code discovery is deferred until that plan exists, homonymous candidates fail as ambiguous, and configured contract origins or code roots resolving outside the workspace are rejected before enumeration. \`inspecionar\`, \`impacto\`, and \`renomear-semantico\` preserve the same directed boundary. Missing local dependencies make coverage partial and block success.
668
+
669
+ Cache rule: a closure gate should use \`sema drift <contrato> --escopo modulo --cache fresh --json\`. \`--cache none\` executes the same analysis without persistent-cache I/O, while \`--cache cache\` may reuse only extraction data whose schema, workspace identity, Git HEAD, plan, configuration, contracts, member paths, and strong content digests all match. Cache objects are stored in the operating system's user-cache directory, never below the workspace. A hit is acceleration, not evidence: final links, diagnostics, score, and success are always recalculated. Corruption or an unavailable cache degrades to an in-memory calculation.
670
+
671
+ Query honesty rule: \`resumo\` and \`inspecionar\` default to \`--drift none\`. When analysis is skipped, score, confidence, implementation, routes, and other unobserved code claims inside the command payload must be \`null\` or explicitly marked not evaluated; zero is not a substitute for absent evidence.
658
672
 
659
673
  UI rule: if the task involves an interface, minimum evidence includes desktop and mobile. On a narrow viewport such as 390px, \`document.documentElement.scrollWidth <= document.documentElement.clientWidth\` must pass; horizontal scroll blocks closure.
660
674
 
@@ -690,31 +704,31 @@ Use this file when Codex does not know which command to run. A Sema command is a
690
704
  ## Minimum Local Flow
691
705
 
692
706
  \`\`\`bash
693
- sema --version
694
- sema resumo --drift none
695
- sema docs-impacto --intencao "<acao>" --json
696
- \`\`\`
697
-
698
- If \`sema\` is absent from \`PATH\`, use \`$HOME/.sema/bin/sema\` on macOS/Linux. On Windows, PowerShell resolves \`sema.ps1\` from PATH, cmd.exe resolves \`sema.cmd\`, and the absolute fallback is \`& "$env:SystemRoot\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$HOME\\.sema\\bin\\sema-managed.ps1" --version\`. \`sema skill sync --json\` repairs launcher and skill without touching the workspace or plugin caches.
699
-
700
- Then read every required doc returned by \`docs-impacto\`.
701
-
702
- ## Public JSON output
703
-
704
- \`sema --version\` stays plain exact SemVer text. With \`--json\`, help and command-control failures use exactly one six-field \`sema.cli.control/v1\` document on stdout with empty stderr. Every syntactically valid command uses exactly one eight-field \`sema.cli.result/v1\` document containing only \`schemaVersion\`, \`ok\`, \`kind\`, \`command\`, \`code\`, \`message\`, \`exitCode\`, and \`payload\`. The command-specific result is nested under \`payload\`, never \`data\`; envelope \`ok\` does not replace domain fields inside that payload. Valid structured domain failures use \`DOMAIN_ERROR\`, while uncaught runtime exceptions remain redacted \`FATAL_ERROR\` control failures.
705
-
706
- ## Global Distribution
707
-
708
- - \`sema skill status --json\`: diagnoses the managed launcher and bundled skill without writing.
709
- - \`sema skill sync --json\`: repairs only Sema-managed launcher and skill destinations; it never writes into the workspace or plugin caches.
710
-
711
- ## Contract and Discovery
707
+ sema --version
708
+ sema resumo --drift none
709
+ sema docs-impacto --intencao "<acao>" --json
710
+ \`\`\`
711
+
712
+ If \`sema\` is absent from \`PATH\`, use \`$HOME/.sema/bin/sema\` on macOS/Linux. On Windows, PowerShell resolves \`sema.ps1\` from PATH, cmd.exe resolves \`sema.cmd\`, and the absolute fallback is \`& "$env:SystemRoot\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "$HOME\\.sema\\bin\\sema-managed.ps1" --version\`. \`sema skill sync --json\` repairs launcher and skill without touching the workspace or plugin caches.
713
+
714
+ Then read every required doc returned by \`docs-impacto\`.
715
+
716
+ ## Public JSON output
717
+
718
+ \`sema --version\` stays plain exact SemVer text. With \`--json\`, help and command-control failures use exactly one six-field \`sema.cli.control/v1\` document on stdout with empty stderr. Every syntactically valid command uses exactly one eight-field \`sema.cli.result/v1\` document containing only \`schemaVersion\`, \`ok\`, \`kind\`, \`command\`, \`code\`, \`message\`, \`exitCode\`, and \`payload\`. The command-specific result is nested under \`payload\`, never \`data\`; envelope \`ok\` does not replace domain fields inside that payload. Valid structured domain failures use \`DOMAIN_ERROR\`, while uncaught runtime exceptions remain redacted \`FATAL_ERROR\` control failures.
719
+
720
+ ## Global Distribution
721
+
722
+ - \`sema skill status --json\`: diagnoses the managed launcher and bundled skill without writing.
723
+ - \`sema skill sync --json\`: repairs only Sema-managed launcher and skill destinations; it never writes into the workspace or plugin caches.
724
+
725
+ ## Contract and Discovery
712
726
 
713
727
  - \`sema iniciar --template <template> [--force]\`: creates a new Sema project and preserves existing files by default; \`--force\` is the only explicit overwrite path.
714
728
  - \`sema validar <arquivo-ou-pasta> --json\`: validates \`.sema\` contracts.
715
729
  - \`sema diagnosticos <arquivo.sema> --json\`: details errors and warnings.
716
730
  - \`sema formatar <arquivo-ou-pasta>\`: formats contracts.
717
- - \`sema inspecionar <arquivo-ou-pasta> [--drift <none|cache|fresh>] --json\`: shows the contract surface; drift is skipped by default.
731
+ - \`sema inspecionar <arquivo-ou-pasta> [--drift <none|cache|fresh>] --json\`: shows the contract surface; drift is skipped by default.
718
732
  - \`sema ast <arquivo.sema> --json\`: shows AST for syntax debugging.
719
733
  - \`sema ir <arquivo.sema> --json\`: shows the IR used by gates and generators.
720
734
  - \`sema descobrir catalogo --json\`: lists governance flows, profiles, specialized workflows, pipelines, generators, capability tokens, and adapters from their canonical registries.
@@ -725,24 +739,24 @@ Then read every required doc returned by \`docs-impacto\`.
725
739
  ## Change and Closure
726
740
 
727
741
  - \`sema docs-impacto --intencao "<acao>" --json\`: discovers required docs and documentary blockers.
728
- - \`sema drift <arquivo-ou-pasta> --escopo modulo [--cache <none|cache|fresh>] --json\`: plans a safe physical scope, then compares contract and implementation without a global fallback.
742
+ - \`sema drift <arquivo-ou-pasta> --escopo modulo [--cache <none|cache|fresh>] --json\`: plans a safe physical scope, then compares contract and implementation without a global fallback.
729
743
  - \`sema impacto <arquivo-ou-pasta> --alvo <token> --mudanca "<descricao>" --json\`: maps impact before changing behavior.
730
744
  - \`sema verificar <arquivo-ou-pasta> --json\`: runs aggregated final verification.
731
745
  - \`sema finalizar-mudanca --intencao "<acao>" --doc-lida <arquivo> --json\`: proves documentation reading before closure.
732
746
 
733
- Honest closure: unwrap drift JSON and treat its command payload as the source of truth. \`payload.sucesso:false\`, non-empty \`payload.vinculos_quebrados\`, non-empty \`payload.rotas_divergentes\`, or non-empty \`payload.impls_quebrados\` mean the change is not complete yet. Do not report "clean drift" without a green payload.
734
-
735
- Focused drift exposes its planned, declared, inferred, and missing files plus catalog visit/read metrics in \`escopo_aplicado\`. File and module scopes fail closed without a safe anchor, with homonymous implementation candidates, or with missing local dependencies; only \`--escopo projeto\` may walk every configured code root. Logical roots such as \`src\` are probed deterministically without a discovery walk. Configured contract origins and code roots are confined before enumeration, and \`inspecionar\`, \`impacto\`, and \`renomear-semantico\` reuse the same directed boundary without reopening arbitrary external paths.
736
-
737
- Drift analysis and cache modes are explicit:
738
-
739
- - \`sema drift\` defaults to \`--cache fresh\`. \`none\` still executes drift but performs zero persistent-cache I/O; \`cache\` reuses a fully validated extraction hit and publishes misses; \`fresh\` ignores hits, recalculates, and publishes the new extraction.
740
- - \`sema resumo\` and \`sema inspecionar\` default to \`--drift none\`. In that mode their payload does not execute drift and returns \`null\` for score, confidence, implementation, routes, or other code evidence that was not observed. Use \`--drift cache\` or \`--drift fresh\` when that evidence is required. \`--com-drift\` remains a temporary alias for \`--drift fresh\`.
741
- - When a query explicitly runs drift, \`payload.analiseDrift.sucesso\` exposes the result and a failed requested analysis returns a nonzero exit code.
742
- - The value aliases \`off\`, \`auto\`, and \`refresh\` normalize to \`none\`, \`cache\`, and \`fresh\` for one compatibility release and emit a structured deprecation warning. Wrong flags, repeated flags, conflicts, and invalid values fail instead of falling back silently.
743
- - Persistent cache objects live outside the workspace under the operating system's user-cache directory. Workspace identity is hashed; public JSON and events expose only an opaque key and \`$SEMA_CACHE/...\` paths. Corruption or cache unavailability becomes a miss and never changes the drift result. Only validated extraction data is reused; links, diagnostics, scores, and the final success decision are recalculated.
744
-
745
- A cache hit is acceleration, not final evidence; closure still requires fresh drift.
747
+ Honest closure: unwrap drift JSON and treat its command payload as the source of truth. \`payload.sucesso:false\`, non-empty \`payload.vinculos_quebrados\`, non-empty \`payload.rotas_divergentes\`, or non-empty \`payload.impls_quebrados\` mean the change is not complete yet. Do not report "clean drift" without a green payload.
748
+
749
+ Focused drift exposes its planned, declared, inferred, and missing files plus catalog visit/read metrics in \`escopo_aplicado\`. File and module scopes fail closed without a safe anchor, with homonymous implementation candidates, or with missing local dependencies; only \`--escopo projeto\` may walk every configured code root. Logical roots such as \`src\` are probed deterministically without a discovery walk. Configured contract origins and code roots are confined before enumeration, and \`inspecionar\`, \`impacto\`, and \`renomear-semantico\` reuse the same directed boundary without reopening arbitrary external paths.
750
+
751
+ Drift analysis and cache modes are explicit:
752
+
753
+ - \`sema drift\` defaults to \`--cache fresh\`. \`none\` still executes drift but performs zero persistent-cache I/O; \`cache\` reuses a fully validated extraction hit and publishes misses; \`fresh\` ignores hits, recalculates, and publishes the new extraction.
754
+ - \`sema resumo\` and \`sema inspecionar\` default to \`--drift none\`. In that mode their payload does not execute drift and returns \`null\` for score, confidence, implementation, routes, or other code evidence that was not observed. Use \`--drift cache\` or \`--drift fresh\` when that evidence is required. \`--com-drift\` remains a temporary alias for \`--drift fresh\`.
755
+ - When a query explicitly runs drift, \`payload.analiseDrift.sucesso\` exposes the result and a failed requested analysis returns a nonzero exit code.
756
+ - The value aliases \`off\`, \`auto\`, and \`refresh\` normalize to \`none\`, \`cache\`, and \`fresh\` for one compatibility release and emit a structured deprecation warning. Wrong flags, repeated flags, conflicts, and invalid values fail instead of falling back silently.
757
+ - Persistent cache objects live outside the workspace under the operating system's user-cache directory. Workspace identity is hashed; public JSON and events expose only an opaque key and \`$SEMA_CACHE/...\` paths. Corruption or cache unavailability becomes a miss and never changes the drift result. Only validated extraction data is reused; links, diagnostics, scores, and the final success decision are recalculated.
758
+
759
+ A cache hit is acceleration, not final evidence; closure still requires fresh drift.
746
760
 
747
761
  ## Sema Code
748
762
 
@@ -769,8 +783,8 @@ Ready UI rule: if the task generates an app, site, dashboard, form, or static HT
769
783
 
770
784
  - \`sema ajuda-ia\`: short guidance for Codex.
771
785
  - \`sema starter-ia\`: operational starter.
772
- - \`sema contexto-ia <arquivo.sema> --saida <dir> --json\`: AI context package.
773
- - \`sema resumo <arquivo-ou-pasta> [--drift <none|cache|fresh>] --json\`: compact context; drift is not executed unless requested.
786
+ - \`sema contexto-ia <arquivo.sema> --saida <dir> --json\`: AI context package.
787
+ - \`sema resumo <arquivo-ou-pasta> [--drift <none|cache|fresh>] --json\`: compact context; drift is not executed unless requested.
774
788
  - \`sema prompt-curto <arquivo-ou-pasta> --json\`: compact prompt.
775
789
  - \`sema sync-codex --json\`: synchronizes the official Codex entrypoint and local support docs.
776
790
  - \`sema instalar-exemplos --json\`: installs official examples in the workspace.
@@ -827,12 +841,12 @@ Spatial model and render mode are orthogonal: \`THREE_D + HEADLESS\` is valid, w
827
841
 
828
842
  ## Forbidden
829
843
 
830
- - Do not use an external workspace source to inspect a local workspace when \`sema --version\` or the managed launcher works.
844
+ - Do not use an external workspace source to inspect a local workspace when \`sema --version\` or the managed launcher works.
831
845
  - Do not search the entire disk for \`.sema\` syntax; use \`exemplos/\`, \`docs/syntax.md\`, and this catalog.
832
846
  - Do not stop after \`sema compilar\` if the contract target files still do not exist.
833
847
  - Do not replace \`sema compilar\` with \`sema testar\` when the contract requires generated code.
834
848
  - Do not create a Markdown report to pretend a gate ran.
835
- - Do not say drift passed when the unwrapped \`sema drift --cache fresh --json\` payload returned \`sucesso:false\`, a non-empty \`vinculos_quebrados\`, \`rotas_divergentes\`, or \`impls_quebrados\` list.
849
+ - Do not say drift passed when the unwrapped \`sema drift --cache fresh --json\` payload returned \`sucesso:false\`, a non-empty \`vinculos_quebrados\`, \`rotas_divergentes\`, or \`impls_quebrados\` list.
836
850
  - Do not declare a UI responsive without mobile/desktop proof; horizontal scroll at 390px blocks closure.
837
851
 
838
852
  Governed code policy: keep the \`SEMA-GOVERNED\` marker, split large code by real responsibility, preserve contract links, and never treat a generated output directory as the final delivery.
@@ -22,7 +22,7 @@ const TEMPLATES_INIT = new Set([
22
22
  "crud-simples", "auth-completo", "api-rest", "workflow", "pedido", "usuario", "upload",
23
23
  ]);
24
24
  const FONTES_IMPORTACAO = new Set([
25
- "nestjs", "fastapi", "flask", "nextjs", "nextjs-consumer", "react-vite-consumer",
25
+ "nestjs", "express", "fastify", "fastapi", "flask", "nextjs", "nextjs-consumer", "react-vite-consumer",
26
26
  "angular-consumer", "flutter-consumer", "firebase", "typescript", "javascript",
27
27
  "python", "dart", "lua", "dotnet", "java", "go", "rust", "cpp", "php",
28
28
  ]);
@@ -153,7 +153,7 @@ function validarSemArgumentos(args) {
153
153
  }
154
154
  function validarIniciar(args) {
155
155
  const parsed = parsearArgumentos(args, {
156
- opcoes: ["--template"], flags: ["--force"], maxPosicionais: 0,
156
+ opcoes: ["--template"], flags: ["--force", "--com-exemplos"], maxPosicionais: 0,
157
157
  });
158
158
  const template = parsed ? valorOpcao(parsed, "--template") : undefined;
159
159
  return parsed !== null && (template === undefined || TEMPLATES_INICIAR.has(template));
@@ -450,7 +450,7 @@ function validarComandoBasico(comando, args) {
450
450
  const estrutura = valorOpcao(parsed, "--estrutura"), framework = valorOpcao(parsed, "--framework");
451
451
  return Boolean(alvo && ALVOS_GERACAO.has(alvo)) && (!estrutura || ESTRUTURAS.has(estrutura)) && (!framework || FRAMEWORKS.has(framework));
452
452
  }
453
- case "verificar": return parsearArgumentos(args, { opcoes: ["--saida"], maxPosicionais: 1 }) !== null;
453
+ case "verificar": return parsearArgumentos(args, { opcoes: ["--saida", "--alvo"], flags: ["--sem-cache"], maxPosicionais: 1 }) !== null;
454
454
  case "formatar": return parsearArgumentos(args, { flags: ["--check"], maxPosicionais: 1 }) !== null;
455
455
  case "inspecionar": {
456
456
  const parsed = parsearArgumentos(args, { opcoes: ["--drift", "--cache"], flags: ["--com-drift"], maxPosicionais: 1 });
@@ -476,7 +476,7 @@ function validarComandoBasico(comando, args) {
476
476
  return parsed !== null && FONTES_IMPORTACAO.has(parsed.posicionais[0]);
477
477
  }
478
478
  case "docs-impacto": {
479
- const parsed = parsearArgumentos(args, { opcoes: ["--intencao", "--arquivo"], flags: ["--criar-ausentes"], repetiveis: ["--arquivo"], maxPosicionais: 64 });
479
+ const parsed = parsearArgumentos(args, { opcoes: ["--intencao", "--arquivo"], flags: ["--criar-ausentes", "--completo"], repetiveis: ["--arquivo"], maxPosicionais: 64 });
480
480
  return parsed !== null && Boolean(valorOpcao(parsed, "--intencao") ?? parsed.posicionais[0]);
481
481
  }
482
482
  case "finalizar-mudanca": {
@@ -25,11 +25,11 @@ export function criarAjudaRaiz(versao) {
25
25
  "",
26
26
  renderizarSecaoAscii("Fluxos rápidos", [
27
27
  "[1] Projeto novo / produção inicial",
28
- "sema iniciar --template <base|nestjs|fastapi|nextjs-api|nextjs-consumer|react-vite-consumer|angular-consumer|flutter-consumer> [--force]",
29
- "Arquivos existentes são preservados; use --force somente para sobrescrita explícita.",
28
+ "sema iniciar --template <base|nestjs|fastapi|nextjs-api|nextjs-consumer|react-vite-consumer|angular-consumer|flutter-consumer> [--force] [--com-exemplos]",
29
+ "Arquivos existentes são preservados; use --force somente para sobrescrita explícita. O starter de exemplos vem por padrão; --com-exemplos instala o pacote completo.",
30
30
  "sema validar contratos/<modulo>.sema --json",
31
31
  "sema compilar <arquivo-ou-pasta> --alvo <typescript|python|php|dart|lua|javascript|html|css|dotnet|cpp> --saida <diretorio>",
32
- "sema verificar <arquivo-ou-pasta> --json",
32
+ "sema verificar <arquivo-ou-pasta> [--saida <dir>] [--alvo <alvo>] [--sem-cache] --json",
33
33
  "",
34
34
  "[2] Editar projeto que já usa Sema",
35
35
  "sema inspecionar . [--drift <none|cache|fresh>] --json",
@@ -114,13 +114,13 @@ export function criarAjudaRaiz(versao) {
114
114
  "modos: drift direto usa fresh por padrão; --cache none ainda executa sem cache persistente; resumo/inspecionar usam --drift none por padrão e não fabricam evidência",
115
115
  "impacto: sema impacto <arquivo-ou-pasta> --alvo <token> [--mudanca <descricao>] [--escopo <arquivo|modulo|projeto>] [--json]",
116
116
  "renomeação: sema renomear-semantico <arquivo-ou-pasta> --de <nome-atual> --para <nome-novo> [--escopo <arquivo|modulo|projeto>] [--json]",
117
- "importação: sema importar <nestjs|fastapi|flask|nextjs|nextjs-consumer|react-vite-consumer|angular-consumer|flutter-consumer|firebase|dotnet|java|go|rust|cpp|php|typescript|python|dart> <diretorio> [--saida <diretorio>] [--namespace <base>] [--json]",
117
+ "importação: sema importar <nestjs|express|fastify|fastapi|flask|nextjs|nextjs-consumer|react-vite-consumer|angular-consumer|flutter-consumer|firebase|dotnet|java|go|rust|cpp|php|typescript|python|dart> <diretorio> [--saida <diretorio>] [--namespace <base>] [--json]",
118
118
  "validação: sema validar <arquivo-ou-pasta> [--json]",
119
119
  "diagnóstico: sema diagnosticos <arquivo.sema> [--json]",
120
120
  "geração: sema compilar <arquivo-ou-pasta> --alvo <typescript|python|php|dart|lua|javascript|html|css|dotnet|cpp> --saida <diretorio> [--estrutura <flat|modulos|backend>] [--framework <base|nestjs|fastapi>]",
121
121
  "teste local: sema testar <arquivo.sema> --alvo <typescript|python|php|dart|lua|javascript|html|css|dotnet|cpp> --saida <diretorio-temporario> [--estrutura <flat|modulos|backend>] [--framework <base|nestjs|fastapi>]",
122
122
  "aliases nativos: cs|csharp -> dotnet; c++|cxx|cc -> cpp (CLI e sema.config.json)",
123
- "verificação final: sema verificar <arquivo-ou-pasta> [--saida <diretorio-base>] [--json]",
123
+ "verificação final: sema verificar <arquivo-ou-pasta> [--saida <diretorio-base>] [--alvo <alvo>] [--sem-cache] [--json]",
124
124
  "formatação: sema formatar <arquivo-ou-pasta> [--check] [--json]",
125
125
  "author: sema author <iniciar|validar|briefing|revisar-cliches|validar-narrativa|validar-proibicoes> [arquivo] [--tema-sensivel] [--preset conto|romance|roteiro|lore|campanha] [--saida <arquivo>] [--texto <texto>] [--json]",
126
126
  "profile: sema profile validar <software|workflow|ops|game|simulation|legal|research|redacao|propostas|conversas> <arquivo-ou-pasta> [--maturidade draft|prototype|production|critical] [--preset <preset>] [--artefato <texto>|--artefato-arquivo <arquivo>] [--json]",
@@ -143,7 +143,7 @@ export function criarAjudaRaiz(versao) {
143
143
  "sema contexto-ia <arquivo.sema> [--saida <diretorio>] [--json]",
144
144
  "sema sync-codex [--json]",
145
145
  "sema instalar-exemplos [--json]",
146
- "sema docs-impacto --intencao <acao> [--arquivo <caminho>] [--criar-ausentes] [--json]",
146
+ "sema docs-impacto --intencao <acao> [--arquivo <caminho>] [--criar-ausentes] [--completo] [--json]",
147
147
  "sema finalizar-mudanca --intencao <acao> [--arquivo <caminho>] [--doc-lida <caminho>] [--json]",
148
148
  "sema author briefing <arquivo.sema> [--json]",
149
149
  "sema author revisar-cliches <arquivo.sema> [--texto <texto>|--texto-arquivo <arquivo>] [--texto-anterior <texto>|--texto-anterior-arquivo <arquivo>] [--json]",
@@ -19,9 +19,10 @@ export interface DocumentoObrigatorioMudanca {
19
19
  truncado?: boolean;
20
20
  template?: string;
21
21
  templatePendente?: boolean;
22
+ substancia?: boolean;
22
23
  }
23
24
  export interface BloqueioDocumentacaoMudanca {
24
- tipo: "documentacao_ausente" | "leitura_obrigatoria_nao_comprovada" | "documentacao_template_cru" | "arquivo_monolitico" | "codigo_governado_sem_cabecalho";
25
+ tipo: "documentacao_ausente" | "leitura_obrigatoria_nao_comprovada" | "documentacao_template_cru" | "documentacao_sem_substancia" | "arquivo_monolitico" | "codigo_governado_sem_cabecalho";
25
26
  severidade: 4 | 5;
26
27
  caminho: string;
27
28
  mensagem: string;
@@ -74,6 +75,8 @@ export declare const REGRAS_DOCUMENTACAO: RegraDocumentacao[];
74
75
  export declare function inferirCategorias(intencao: string, arquivosAlvo: string[]): string[];
75
76
  export declare function criarTemplateDoc(doc: DocumentoPlanejado, intencao: string, categorias: string[], arquivosAlvo: string[]): string;
76
77
  export declare function documentoPareceTemplateCriadoPelaSema(conteudo: string): boolean;
78
+ export declare const MINIMO_CARACTERES_SUBSTANCIA_DOC = 120;
79
+ export declare function documentoTemSubstancia(conteudo: string): boolean;
77
80
  export declare function resumoConteudo(conteudo: string): {
78
81
  conteudo: string;
79
82
  truncado: boolean;
@@ -289,6 +289,14 @@ export function documentoPareceTemplateCriadoPelaSema(conteudo) {
289
289
  ].some((placeholder) => texto.includes(placeholder));
290
290
  return criadoPelaSema && placeholderPendente;
291
291
  }
292
+ export const MINIMO_CARACTERES_SUBSTANCIA_DOC = 120;
293
+ export function documentoTemSubstancia(conteudo) {
294
+ const texto = normalizarTexto(conteudo)
295
+ .replace(/[#*_>`|-]/g, " ")
296
+ .replace(/\s+/g, " ")
297
+ .trim();
298
+ return texto.length >= MINIMO_CARACTERES_SUBSTANCIA_DOC;
299
+ }
292
300
  export function resumoConteudo(conteudo) {
293
301
  if (conteudo.length <= LIMITE_CONTEUDO_DOC) {
294
302
  return { conteudo, truncado: false };
@@ -4,7 +4,7 @@ import { readFile } from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import { emitirDiagnosticosArquivosOrcamento } from "./driftOrcamento.js";
6
6
  import { escreverArquivoWorkspaceSeguro, validarDestinosEscritaWorkspace, } from "./workspaceWrite.js";
7
- import { REGRAS_DOCUMENTACAO, adicionarDocsRaizExistentes, adicionarReadmesDeArquivos, caminhoEstaDentro, caminhoExiste, criarTemplateDoc, documentoPareceTemplateCriadoPelaSema, inferirCategorias, listarArquivosRecursivo, normalizarRelativo, normalizarTexto, resumoConteudo, termosRelacionamentoContratos } from "./docs.part01.js";
7
+ import { REGRAS_DOCUMENTACAO, adicionarDocsRaizExistentes, adicionarReadmesDeArquivos, caminhoEstaDentro, caminhoExiste, criarTemplateDoc, documentoPareceTemplateCriadoPelaSema, documentoTemSubstancia, inferirCategorias, listarArquivosRecursivo, normalizarRelativo, normalizarTexto, resumoConteudo, termosRelacionamentoContratos } from "./docs.part01.js";
8
8
  export async function adicionarContratosRelacionados(baseProjeto, intencao, arquivosAlvo, registrar) {
9
9
  const pastaContratos = path.join(baseProjeto, "contratos");
10
10
  if (!(await caminhoExiste(pastaContratos))) {
@@ -95,6 +95,7 @@ export async function resolverDocumentacaoObrigatoria(opcoes) {
95
95
  item.conteudo = conteudo.conteudo;
96
96
  item.truncado = conteudo.truncado;
97
97
  item.templatePendente = documentoPareceTemplateCriadoPelaSema(conteudoCompleto) || undefined;
98
+ item.substancia = documentoTemSubstancia(conteudoCompleto);
98
99
  }
99
100
  leituraObrigatoria.push(item);
100
101
  }
@@ -150,6 +151,7 @@ export async function verificarDocumentacaoMudanca(opcoes) {
150
151
  const setDocsLidas = new Set(docsLidas);
151
152
  const docsNaoLidas = impacto.leituraObrigatoria.filter((doc) => doc.existe && !setDocsLidas.has(doc.relativo));
152
153
  const docsTemplatePendentes = impacto.leituraObrigatoria.filter((doc) => (doc.existe && doc.templatePendente && setDocsLidas.has(doc.relativo)));
154
+ const docsSemSubstancia = impacto.leituraObrigatoria.filter((doc) => (doc.existe && !doc.templatePendente && doc.substancia === false));
153
155
  const diagnosticosOrcamento = await emitirDiagnosticosArquivosOrcamento({
154
156
  baseProjeto,
155
157
  arquivos: opcoes.arquivosAlvo ?? [],
@@ -174,6 +176,12 @@ export async function verificarDocumentacaoMudanca(opcoes) {
174
176
  caminho: doc.relativo,
175
177
  mensagem: `Documentacao obrigatoria ainda e template cru criado pela Sema: ${doc.relativo}. Edite com procedimento, validacao e rollback reais antes de finalizar.`,
176
178
  })),
179
+ ...docsSemSubstancia.map((doc) => ({
180
+ tipo: "documentacao_sem_substancia",
181
+ severidade: 4,
182
+ caminho: doc.relativo,
183
+ mensagem: `Documentacao obrigatoria sem substancia: ${doc.relativo}. O conteudo esta praticamente vazio; preencha procedimento, validacao e rollback reais antes de finalizar.`,
184
+ })),
177
185
  ...diagnosticosOrcamento
178
186
  .filter((diagnostico) => diagnostico.bloqueia)
179
187
  .map((diagnostico) => ({
@@ -13,7 +13,7 @@ export interface SimboloResolvido {
13
13
  }
14
14
  export type ConsumerFramework = "nextjs-consumer" | "react-vite-consumer" | "angular-consumer" | "flutter-consumer";
15
15
  export interface RotaResolvida {
16
- origem: "nestjs" | "fastapi" | "flask" | "nextjs" | ConsumerFramework | "firebase" | "dotnet" | "java" | "go" | "rust" | "php";
16
+ origem: "nestjs" | "express" | "fastify" | "fastapi" | "flask" | "nextjs" | ConsumerFramework | "firebase" | "dotnet" | "java" | "go" | "rust" | "php";
17
17
  metodo: string;
18
18
  caminho: string;
19
19
  arquivo: string;
@@ -47,6 +47,7 @@ export interface DiagnosticoDrift {
47
47
  linhas?: number;
48
48
  severidade?: "aviso" | "erro";
49
49
  limite_bloqueio_linhas?: number;
50
+ frameworksEsperados?: string[];
50
51
  mensagem: string;
51
52
  }
52
53
  export interface RegistroImplDrift {
@@ -124,6 +125,11 @@ export interface ResumoTaskDrift {
124
125
  implsQuebrados: number;
125
126
  semImplementacao: boolean;
126
127
  scoreSemantico: number;
128
+ evidenciaVerificacao?: {
129
+ sucesso: boolean;
130
+ quantidadeTestes: number;
131
+ alvo: string;
132
+ };
127
133
  confiancaVinculo: NivelConfiancaSemantica;
128
134
  riscoOperacional: NivelRiscoSemantico;
129
135
  lacunas: string[];
@@ -24,7 +24,19 @@ export declare function encontrarAncoraSuperficie(ir: IrModulo, superficie: IrSu
24
24
  } | undefined;
25
25
  export declare function calcularRiscoOperacional(task: IrTask): NivelRiscoSemantico;
26
26
  export declare function calcularConfiancaTask(task: IrTask, implsValidos: number, implsQuebrados: number, vinculosValidos: number, vinculosQuebrados: number): NivelConfiancaSemantica;
27
- export declare function calcularScoreTask(task: IrTask, implsValidos: number, implsQuebrados: number, vinculosValidos: number, vinculosQuebrados: number, semImplementacao: boolean): number;
27
+ export interface EvidenciaVerificacaoDrift {
28
+ sucesso: boolean;
29
+ quantidadeTestes: number;
30
+ alvo: string;
31
+ }
32
+ export declare function carregarEvidenciaVerificacaoDrift(opcoes: {
33
+ caminhoContrato: string;
34
+ nomeModulo: string;
35
+ alvo: string;
36
+ framework: string;
37
+ estrutura: string;
38
+ }): Promise<EvidenciaVerificacaoDrift | undefined>;
39
+ export declare function calcularScoreTask(task: IrTask, implsValidos: number, implsQuebrados: number, vinculosValidos: number, vinculosQuebrados: number, semImplementacao: boolean, evidenciaVerificada?: EvidenciaVerificacaoDrift): number;
28
40
  export declare function resumirLacunasTask(task: IrTask, semImplementacao: boolean, implsQuebrados: number, vinculosQuebrados: number, guardrails: {
29
41
  publica: boolean;
30
42
  sensivel: boolean;
@@ -37,7 +49,7 @@ export declare function resumirLacunasTask(task: IrTask, semImplementacao: boole
37
49
  dadosSensiveis: boolean;
38
50
  efeitoPrivilegiado: boolean;
39
51
  exigeSegredos: boolean;
40
- }): string[];
52
+ }, evidenciaVerificada?: EvidenciaVerificacaoDrift): string[];
41
53
  export declare function resumirOperacional(resultado: Omit<ResultadoDrift, "comando" | "sucesso">, politicaPontuacao?: PoliticaPontuacaoSemantica): ResultadoDrift["resumo_operacional"];
42
54
  export declare function paraIdentificadorModulo(valor: string): string;
43
55
  export declare function extrairTextoLiteral(expr?: ts.Expression): string | undefined;
@@ -154,7 +154,34 @@ export function calcularConfiancaTask(task, implsValidos, implsQuebrados, vincul
154
154
  }
155
155
  return "baixa";
156
156
  }
157
- export function calcularScoreTask(task, implsValidos, implsQuebrados, vinculosValidos, vinculosQuebrados, semImplementacao) {
157
+ export async function carregarEvidenciaVerificacaoDrift(opcoes) {
158
+ const { readFile } = await import("node:fs/promises");
159
+ const { calcularChaveVerificacao, carregarManifestoVerificacao } = await import("./verificacaoCache.js");
160
+ const pacoteCli = (await import("../package.json", { with: { type: "json" } })).default;
161
+ const conteudoContrato = await readFile(opcoes.caminhoContrato, "utf8").catch(() => "");
162
+ if (!conteudoContrato) {
163
+ return undefined;
164
+ }
165
+ const chave = calcularChaveVerificacao({
166
+ versaoCli: pacoteCli.version,
167
+ versaoNode: process.versions.node ?? "",
168
+ modulo: opcoes.nomeModulo,
169
+ alvo: opcoes.alvo,
170
+ framework: opcoes.framework,
171
+ estrutura: opcoes.estrutura,
172
+ conteudoContrato,
173
+ });
174
+ const manifesto = await carregarManifestoVerificacao(chave);
175
+ if (!manifesto) {
176
+ return undefined;
177
+ }
178
+ return {
179
+ sucesso: manifesto.sucesso,
180
+ quantidadeTestes: manifesto.quantidadeTestes,
181
+ alvo: manifesto.alvo,
182
+ };
183
+ }
184
+ export function calcularScoreTask(task, implsValidos, implsQuebrados, vinculosValidos, vinculosQuebrados, semImplementacao, evidenciaVerificada) {
158
185
  let score = 45;
159
186
  if (!semImplementacao && task.implementacoesExternas.length > 0) {
160
187
  score += 15;
@@ -169,9 +196,12 @@ export function calcularScoreTask(task, implsValidos, implsQuebrados, vinculosVa
169
196
  if (task.execucao.explicita) {
170
197
  score += 5;
171
198
  }
199
+ if (evidenciaVerificada?.sucesso && evidenciaVerificada.quantidadeTestes > 0) {
200
+ score += 8;
201
+ }
172
202
  return Math.max(0, Math.min(100, score));
173
203
  }
174
- export function resumirLacunasTask(task, semImplementacao, implsQuebrados, vinculosQuebrados, guardrails) {
204
+ export function resumirLacunasTask(task, semImplementacao, implsQuebrados, vinculosQuebrados, guardrails, evidenciaVerificada) {
175
205
  const lacunas = [];
176
206
  if (semImplementacao) {
177
207
  lacunas.push("sem_impl");
@@ -188,6 +218,9 @@ export function resumirLacunasTask(task, semImplementacao, implsQuebrados, vincu
188
218
  if (!task.execucao.explicita) {
189
219
  lacunas.push("execucao_implicita");
190
220
  }
221
+ if ((guardrails.publica || guardrails.sensivel) && !semImplementacao && !evidenciaVerificada) {
222
+ lacunas.push("sem_evidencia_verificada");
223
+ }
191
224
  if (guardrails.publica && !task.execucao.explicita) {
192
225
  lacunas.push("superficie_publica_sem_execucao");
193
226
  }
@@ -5,7 +5,7 @@ import { OpcoesDriftLegado, OrigemCodigoDrift, RecursoResolvido, RegistroPersist
5
5
  import { indexarPersistenciaDetalhada } from "./drift.part08.js";
6
6
  export declare function analisarPersistenciaReal(contexto: ContextoProjetoCarregado, mapaRecursos?: Map<string, RecursoResolvido[]>, detalhesPersistencia?: Awaited<ReturnType<typeof indexarPersistenciaDetalhada>>, opcoes?: OpcoesDriftLegado, mapaImpl?: Map<string, SimboloResolvido>): Promise<RegistroPersistenciaRealDrift[]>;
7
7
  export declare function normalizarCaminhoRota(caminho?: string): string;
8
- export declare function extrairFontesHttpTypeScript(fontesLegado: FonteLegado[]): Array<"nestjs" | "nextjs" | "firebase">;
8
+ export declare function extrairFontesHttpTypeScript(fontesLegado: FonteLegado[]): Array<"nestjs" | "nextjs" | "firebase" | "express" | "fastify">;
9
9
  export declare function extrairFontesHttpBackend(fontesLegado: FonteLegado[]): Array<"dotnet" | "java" | "go" | "rust" | "php">;
10
10
  export declare function ultimoSegmentoSimbolico(caminho: string): string;
11
11
  export declare function pontuarCandidatoDeclarado(candidato: SimboloResolvido, origem: OrigemCodigoDrift, caminhoDeclarado: string): SimboloCandidatoDrift | undefined;
@@ -14,7 +14,7 @@ export declare function deduplicarCandidatos(candidatos: SimboloCandidatoDrift[]
14
14
  export declare function ordenarCandidatos(candidatos: SimboloCandidatoDrift[]): SimboloCandidatoDrift[];
15
15
  export declare function sugerirCandidatosParaImpl(simbolos: SimboloResolvido[], origem: OrigemCodigoDrift, caminhoDeclarado: string): SimboloCandidatoDrift[];
16
16
  export declare function sugerirCandidatosParaTaskSemImpl(simbolos: SimboloResolvido[], nomeTask: string): SimboloCandidatoDrift[];
17
- export declare function escolherRotasEsperadas(task: IrTask, fontesLegado: FonteLegado[]): Array<"nestjs" | "fastapi" | "flask" | "nextjs" | "firebase" | "dotnet" | "java" | "go" | "rust" | "php">;
17
+ export declare function escolherRotasEsperadas(task: IrTask, fontesLegado: FonteLegado[]): Array<"nestjs" | "express" | "fastify" | "fastapi" | "flask" | "nextjs" | "firebase" | "dotnet" | "java" | "go" | "rust" | "php">;
18
18
  export declare function taskEhBridgeFirebase(task: IrTask): boolean;
19
19
  export declare function tiposAceitosParaRecursoPersistencia(recurso: IrRecursoPersistencia): TipoRecursoDrift[];
20
20
  export declare function nomesRecursoPersistencia(recurso: IrRecursoPersistencia): string[];