@semacode/cli 3.12.0 → 3.12.1

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.
@@ -774,7 +774,7 @@ Then read every required doc returned by \`docs-impacto\`.
774
774
 
775
775
  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.
776
776
 
777
- 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.
777
+ Focused drift exposes its planned, declared, inferred, and missing files plus catalog visit/read metrics in \`escopo_aplicado\`. A missing declared file or a missing code-referenced dependency is a blocker reported as \`vinculo_quebrado\`; a missing inferred candidate derived from an \`impl\` symbol is informational under \`arquivosAusentesInferidos\` and never blocks an implementation that resolved. 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.
778
778
 
779
779
  Drift analysis and cache modes are explicit:
780
780
 
@@ -177,6 +177,7 @@ export interface ConfiguracaoEscopoDriftAplicada {
177
177
  arquivosDeclarados?: string[];
178
178
  arquivosInferidos?: string[];
179
179
  arquivosAusentes?: string[];
180
+ arquivosAusentesInferidos?: string[];
180
181
  bloqueios?: string[];
181
182
  catalogo?: MetricasCatalogoDrift;
182
183
  cache?: EstadoCacheDriftAplicado;
@@ -148,6 +148,7 @@ export async function analisarDriftLegado(contexto, opcoes) {
148
148
  configuracaoEscopo.arquivosDeclarados = planoEscopo.arquivosDeclarados.map(relativoEscopo);
149
149
  configuracaoEscopo.arquivosInferidos = planoEscopo.arquivosInferidos.map(relativoEscopo);
150
150
  configuracaoEscopo.arquivosAusentes = planoEscopo.arquivosAusentes.map(relativoEscopo);
151
+ configuracaoEscopo.arquivosAusentesInferidos = planoEscopo.arquivosAusentesInferidos.map(relativoEscopo);
151
152
  const bloqueiosAnalise = new Set(planoEscopo.bloqueios);
152
153
  configuracaoEscopo.bloqueios = [...bloqueiosAnalise];
153
154
  configuracaoEscopo.catalogo = metricasCatalogo;
@@ -495,6 +495,7 @@ function representarPlanoCache(contexto, configuracao, plano) {
495
495
  arquivosDeclarados: ordenar(plano.arquivosDeclarados),
496
496
  arquivosInferidos: ordenar(plano.arquivosInferidos),
497
497
  arquivosAusentes: ordenar(plano.arquivosAusentes),
498
+ arquivosAusentesInferidos: ordenar(plano.arquivosAusentesInferidos),
498
499
  diretorios: ordenar(plano.diretorios),
499
500
  diretoriosCodigo: ordenar(contexto.diretoriosCodigo),
500
501
  ignorarWorktrees: configuracao.ignorarWorktrees,
@@ -11,6 +11,7 @@ export interface PlanoEscopoDrift {
11
11
  arquivosDeclarados: string[];
12
12
  arquivosInferidos: string[];
13
13
  arquivosAusentes: string[];
14
+ arquivosAusentesInferidos: string[];
14
15
  diretorios: string[];
15
16
  modulos: string[];
16
17
  cobertura: CoberturaEscopoDrift;
@@ -365,6 +365,7 @@ export async function planejarEscopoDrift(contexto, configuracao) {
365
365
  arquivosDeclarados: [],
366
366
  arquivosInferidos: [],
367
367
  arquivosAusentes: [],
368
+ arquivosAusentesInferidos: [],
368
369
  diretorios,
369
370
  modulos: contexto.modulosSelecionados
370
371
  .map((modulo) => modulo.resultado.ir?.nome)
@@ -382,6 +383,7 @@ export async function planejarEscopoDrift(contexto, configuracao) {
382
383
  .filter((ir) => Boolean(ir));
383
384
  const declarados = new Map();
384
385
  const ausentes = new Map();
386
+ const ausentesInferidos = new Map();
385
387
  const inferidos = new Map();
386
388
  const bloqueiosPlano = new Set();
387
389
  const raizReal = await realpath(contexto.baseProjeto);
@@ -440,7 +442,9 @@ export async function planejarEscopoDrift(contexto, configuracao) {
440
442
  }
441
443
  const primeiroCandidato = gruposCandidatos[0]?.[0];
442
444
  if (encontrados.length === 0 && primeiroCandidato) {
443
- ausentes.set(chaveCaminho(primeiroCandidato), primeiroCandidato);
445
+ // Candidato derivado do simbolo do impl, nao uma promessa do contrato:
446
+ // ausencia aqui e informacao de ancoragem, nunca vinculo quebrado.
447
+ ausentesInferidos.set(chaveCaminho(primeiroCandidato), primeiroCandidato);
444
448
  }
445
449
  }
446
450
  const raizesAncoradas = escolherDiretoriosLogicos(contexto, [...declarados.values(), ...inferidos.values()]);
@@ -470,6 +474,7 @@ export async function planejarEscopoDrift(contexto, configuracao) {
470
474
  }
471
475
  const arquivos = [...arquivosMesclados.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
472
476
  const arquivosAusentes = [...ausentes.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
477
+ const arquivosAusentesInferidos = [...ausentesInferidos.values()].sort((a, b) => a.localeCompare(b, "pt-BR"));
473
478
  const exigeAncoraCodigo = irs.some(moduloExigeAncoraCodigo);
474
479
  if (arquivos.length === 0
475
480
  && exigeAncoraCodigo
@@ -484,6 +489,7 @@ export async function planejarEscopoDrift(contexto, configuracao) {
484
489
  arquivosDeclarados: [...declarados.values()].sort((a, b) => a.localeCompare(b, "pt-BR")),
485
490
  arquivosInferidos: [...inferidos.values()].sort((a, b) => a.localeCompare(b, "pt-BR")),
486
491
  arquivosAusentes,
492
+ arquivosAusentesInferidos,
487
493
  diretorios: escolherDiretoriosLogicos(contexto, arquivos),
488
494
  modulos: irs.map((ir) => ir.nome),
489
495
  cobertura: arquivosAusentes.length === 0 && bloqueios.length === 0 ? "completa" : "parcial",
package/docs/commands.md CHANGED
@@ -53,7 +53,7 @@ Then read every required doc returned by `docs-impacto`.
53
53
 
54
54
  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.
55
55
 
56
- 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.
56
+ Focused drift exposes its planned, declared, inferred, and missing files plus catalog visit/read metrics in `escopo_aplicado`. A missing declared file or a missing code-referenced dependency is a blocker reported as `vinculo_quebrado`; a missing inferred candidate derived from an `impl` symbol is informational under `arquivosAusentesInferidos` and never blocks an implementation that resolved. 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.
57
57
 
58
58
  Drift analysis and cache modes are explicit:
59
59
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@semacode/cli",
3
- "version": "3.12.0",
3
+ "version": "3.12.1",
4
4
  "description": "Local-first semantic governance CLI for AI agents, proven with Claude, Codex, zCode (GLM) and Kimi: contracts, drift, impact, docs gates, and code generation.",
5
5
  "type": "module",
6
6
  "icon": "logo.png",