@devtrack-solution/codesdd 1.2.3 → 1.2.4-rc3

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 (139) hide show
  1. package/.sdd/skills/curated/devtrack-api/SKILL.md +12 -5
  2. package/.sdd/skills/curated/devtrack-api/agents/claude-code.yaml +8 -0
  3. package/.sdd/skills/curated/devtrack-api/agents/codex.yaml +8 -0
  4. package/.sdd/skills/curated/devtrack-api/agents/cursor.yaml +8 -0
  5. package/.sdd/skills/curated/devtrack-api/agents/gemini.yaml +8 -0
  6. package/.sdd/skills/curated/devtrack-api/agents/kimi.yaml +8 -0
  7. package/.sdd/skills/curated/devtrack-api/agents/openai.yaml +4 -2
  8. package/.sdd/skills/curated/devtrack-api/agents/opencode.yaml +10 -0
  9. package/.sdd/skills/curated/devtrack-api/references/application-presentation.md +2 -2
  10. package/.sdd/skills/curated/devtrack-api/references/contract-pack.yaml +55 -0
  11. package/.sdd/skills/curated/devtrack-api/references/domain-modeling.md +13 -13
  12. package/.sdd/skills/curated/devtrack-api/references/foundation-layout.md +2 -3
  13. package/.sdd/skills/curated/devtrack-api/references/implementation-checklist.md +1 -1
  14. package/.sdd/skills/curated/devtrack-api/references/portable-agent-contract.md +41 -0
  15. package/.sdd/skills/curated/devtrack-api/references/typeorm-infrastructure.md +7 -9
  16. package/README.md +159 -5
  17. package/dist/applications/sdd/index.d.ts +16 -0
  18. package/dist/applications/sdd/index.js +16 -0
  19. package/dist/commands/config.js +171 -10
  20. package/dist/commands/sdd/execution.js +345 -15
  21. package/dist/commands/sdd/plugin.js +5 -0
  22. package/dist/commands/sdd/shared.d.ts +1 -0
  23. package/dist/commands/sdd/shared.js +10 -0
  24. package/dist/commands/sdd.js +38 -3
  25. package/dist/core/cli/command-matrix.js +9 -0
  26. package/dist/core/cli-command-quality.js +9 -0
  27. package/dist/core/completions/command-registry.js +45 -0
  28. package/dist/core/config-schema.d.ts +18 -1
  29. package/dist/core/config-schema.js +48 -5
  30. package/dist/core/global-config.d.ts +16 -0
  31. package/dist/core/sdd/agent-binding.d.ts +10 -10
  32. package/dist/core/sdd/agent-runtime-contract.d.ts +204 -0
  33. package/dist/core/sdd/agent-runtime-contract.js +200 -0
  34. package/dist/core/sdd/check.d.ts +2 -0
  35. package/dist/core/sdd/check.js +40 -2
  36. package/dist/core/sdd/coordination/coordination-adapters.d.ts +15 -8
  37. package/dist/core/sdd/coordination/coordination-adapters.js +43 -15
  38. package/dist/core/sdd/coordination/index.d.ts +1 -0
  39. package/dist/core/sdd/coordination/index.js +1 -0
  40. package/dist/core/sdd/coordination/redis-runtime.d.ts +131 -0
  41. package/dist/core/sdd/coordination/redis-runtime.js +698 -0
  42. package/dist/core/sdd/deepagent-contracts.d.ts +98 -4
  43. package/dist/core/sdd/deepagent-contracts.js +62 -0
  44. package/dist/core/sdd/default-bootstrap-files.d.ts +2 -2
  45. package/dist/core/sdd/default-bootstrap-files.js +14 -8
  46. package/dist/core/sdd/default-skills.js +108 -4
  47. package/dist/core/sdd/devtrack-api-appliance.d.ts +8 -1
  48. package/dist/core/sdd/devtrack-api-appliance.js +46 -23
  49. package/dist/core/sdd/docs-sync.js +21 -15
  50. package/dist/core/sdd/domain/capability-diff.d.ts +63 -0
  51. package/dist/core/sdd/domain/capability-diff.js +200 -0
  52. package/dist/core/sdd/domain/change-safety-guardrails.d.ts +74 -0
  53. package/dist/core/sdd/domain/change-safety-guardrails.js +333 -0
  54. package/dist/core/sdd/domain/semantic-intent-classifier.d.ts +29 -0
  55. package/dist/core/sdd/domain/semantic-intent-classifier.js +117 -0
  56. package/dist/core/sdd/foundation-artifact-map-validator.d.ts +16 -0
  57. package/dist/core/sdd/foundation-artifact-map-validator.js +71 -0
  58. package/dist/core/sdd/foundation-layer-manifest.d.ts +24 -0
  59. package/dist/core/sdd/foundation-layer-manifest.js +117 -0
  60. package/dist/core/sdd/intent-guard.d.ts +22 -0
  61. package/dist/core/sdd/intent-guard.js +67 -0
  62. package/dist/core/sdd/json-schema.js +9 -1
  63. package/dist/core/sdd/legacy-operations.js +76 -1
  64. package/dist/core/sdd/migrate-workspace.js +39 -0
  65. package/dist/core/sdd/package-security-gates.d.ts +21 -0
  66. package/dist/core/sdd/package-security-gates.js +119 -0
  67. package/dist/core/sdd/package-structure-gate.js +3 -8
  68. package/dist/core/sdd/parallel-feat-automation.d.ts +181 -3
  69. package/dist/core/sdd/parallel-feat-automation.js +212 -0
  70. package/dist/core/sdd/plugin-broker.d.ts +223 -4
  71. package/dist/core/sdd/plugin-broker.js +10 -0
  72. package/dist/core/sdd/plugin-cli.d.ts +30 -0
  73. package/dist/core/sdd/plugin-cli.js +70 -3
  74. package/dist/core/sdd/plugin-evidence.d.ts +73 -0
  75. package/dist/core/sdd/plugin-manifest.d.ts +69 -1
  76. package/dist/core/sdd/plugin-manifest.js +10 -0
  77. package/dist/core/sdd/plugin-policy-pack.d.ts +1 -1
  78. package/dist/core/sdd/plugin-registry.d.ts +141 -5
  79. package/dist/core/sdd/plugin-sdk-contract.d.ts +363 -0
  80. package/dist/core/sdd/plugin-sdk-contract.js +268 -0
  81. package/dist/core/sdd/plugin-skill-binding.d.ts +1 -1
  82. package/dist/core/sdd/quality-validation.d.ts +84 -11
  83. package/dist/core/sdd/release-readiness.d.ts +19 -0
  84. package/dist/core/sdd/release-readiness.js +472 -0
  85. package/dist/core/sdd/runtime-boundary-contract.d.ts +45 -0
  86. package/dist/core/sdd/runtime-boundary-contract.js +90 -0
  87. package/dist/core/sdd/sdk-agent-plugin-quality-gates.d.ts +150 -0
  88. package/dist/core/sdd/sdk-agent-plugin-quality-gates.js +258 -0
  89. package/dist/core/sdd/services/agent-run.service.d.ts +38 -6
  90. package/dist/core/sdd/services/agent-run.service.js +73 -1
  91. package/dist/core/sdd/services/capability-diff.service.d.ts +18 -0
  92. package/dist/core/sdd/services/capability-diff.service.js +26 -0
  93. package/dist/core/sdd/services/change-safety-preflight.service.d.ts +17 -0
  94. package/dist/core/sdd/services/change-safety-preflight.service.js +17 -0
  95. package/dist/core/sdd/services/context.service.d.ts +43 -340
  96. package/dist/core/sdd/services/context.service.js +323 -9
  97. package/dist/core/sdd/services/finalize.service.d.ts +25 -0
  98. package/dist/core/sdd/services/finalize.service.js +178 -16
  99. package/dist/core/sdd/services/frontend-impact.service.d.ts +1 -1
  100. package/dist/core/sdd/services/semantic-intent-classifier.service.d.ts +6 -0
  101. package/dist/core/sdd/services/semantic-intent-classifier.service.js +7 -0
  102. package/dist/core/sdd/state.d.ts +1 -0
  103. package/dist/core/sdd/state.js +251 -29
  104. package/dist/core/sdd/store/sdd-stores.js +2 -2
  105. package/dist/core/sdd/structural-health.d.ts +13 -13
  106. package/dist/core/sdd/types.d.ts +27 -12
  107. package/dist/core/sdd/types.js +4 -0
  108. package/dist/core/sdd/views.js +17 -0
  109. package/dist/core/sdd/workspace-schemas.d.ts +387 -7
  110. package/dist/core/sdd/workspace-schemas.js +196 -64
  111. package/dist/domains/sdd/index.d.ts +6 -0
  112. package/dist/domains/sdd/index.js +6 -0
  113. package/dist/infrastructures/sdd/index.d.ts +7 -0
  114. package/dist/infrastructures/sdd/index.js +6 -0
  115. package/dist/presentations/cli/sdd/index.d.ts +3 -0
  116. package/dist/presentations/cli/sdd/index.js +3 -0
  117. package/dist/shared/sdd/index.d.ts +3 -0
  118. package/dist/shared/sdd/index.js +2 -0
  119. package/package.json +9 -6
  120. package/schemas/sdd/2-plan.schema.json +207 -2
  121. package/schemas/sdd/5-quality.schema.json +281 -25
  122. package/schemas/sdd/agent-runtime-command-plan.schema.json +212 -0
  123. package/schemas/sdd/agent-runtime-opencode-run-evidence.schema.json +270 -0
  124. package/schemas/sdd/codesdd-plugin.schema.json +171 -0
  125. package/schemas/sdd/deepagent-run-request.schema.json +316 -0
  126. package/schemas/sdd/parallel-feat-automation-plan.schema.json +89 -0
  127. package/schemas/sdd/parallel-feat-scheduler-request.schema.json +116 -0
  128. package/schemas/sdd/parallel-feat-scheduler-result.schema.json +404 -0
  129. package/schemas/sdd/plugin-artifact-manifest.schema.json +109 -0
  130. package/schemas/sdd/plugin-artifact-map.schema.json +223 -0
  131. package/schemas/sdd/plugin-evidence-manifest.schema.json +109 -0
  132. package/schemas/sdd/plugin-language-runtime.schema.json +103 -0
  133. package/schemas/sdd/plugin-package-governance.schema.json +74 -0
  134. package/schemas/sdd/plugin-registry.schema.json +171 -0
  135. package/schemas/sdd/plugin-runtime-invocation-plan.schema.json +109 -0
  136. package/schemas/sdd/quality-evidence-bundle.schema.json +109 -0
  137. package/schemas/sdd/sdk-agent-plugin-quality-gate-input.schema.json +168 -0
  138. package/schemas/sdd/sdk-agent-plugin-quality-gate-report.schema.json +160 -0
  139. package/schemas/sdd/workspace-catalog.schema.json +3776 -398
package/README.md CHANGED
@@ -73,6 +73,9 @@ Para a iniciativa EPIC-0065, o projeto formaliza a seguinte fronteira canonica:
73
73
  - CodeSDD e o control plane soberano: estado canonico (`.sdd/state/*.yaml`), lifecycle, EPIC/FEAT, ADR, politicas, qualidade, evidencia e finalize.
74
74
  - DeepAgents e execution plane governado: planejamento tatico, delegacao de subagentes, execucao em sandbox, memoria tatica controlada e coleta de evidencia estruturada.
75
75
  - Plugins operam como plano de construcao deterministico via broker e envelopes; Reversa opera como pipeline especializado de engenharia reversa.
76
+ - Planos de plugin standalone validam `package_governance`, runtime de linguagem e fronteira de storage antes de qualquer adaptador tratar a operacao como executavel.
77
+ - O core agora possui uma casca Foundation-like incremental em `src/domains`, `src/applications`, `src/infrastructures`, `src/presentations` e `src/shared`; detalhes em `docs/codesdd-foundation-layer-migration.md`.
78
+ - Gates de qualidade para SDK/agentes/plugins agregam governanca de pacote, runtime de linguagem, artifact map, planos DeepAgents/Codex/OpenCode, compliance de plugin e cobertura por escopo em `src/core/sdd/sdk-agent-plugin-quality-gates.ts`.
76
79
  - Nenhum runtime de agente pode virar fonte paralela de verdade para o estado operacional do projeto.
77
80
 
78
81
  Pacote ADR obrigatorio da iniciativa:
@@ -116,6 +119,14 @@ bloqueado sem instanciar agente; no modo `fake`, executa o adapter
116
119
  deterministico sem credenciais; e no modo `deepagents-js`, so materializa o
117
120
  adapter nativo quando os feature toggles, modelo, credencial de launcher e
118
121
  politicas passam. Falhas de prontidao viram evidencia estruturada fail-closed.
122
+ Para validar uma mudanca antes de invocar runtime, use
123
+ `codesdd sdd preflight <FEAT-ID> --intent-operation <op> --write-scope <glob> --planned-writes <path> --json`.
124
+ Esse comando executa os mesmos guardrails de mutacao com `runtime_skipped: true`
125
+ e emite telemetria segura em `evidence.guardrail_telemetry`, contendo apenas
126
+ decisao, status por gate, nivel de risco e classificacoes agregadas, sem paths
127
+ brutos, texto de objetivo ou valores de override. Os cenarios golden de
128
+ EPIC-0078 cobrem catalogo aditivo permitido, substituicao bloqueada, override
129
+ valido, override invalido e refactor amplo legitimo.
119
130
  O smoke operacional padrao esta em `pnpm run test:deepagents-smoke`, cobrindo
120
131
  `disabled` e `fake` sem segredos nem rede; o smoke real de provedor so roda com
121
132
  `CODESDD_DEEPAGENTS_PROVIDER_SMOKE=1`, modelo, chave de launcher e dominio de
@@ -144,7 +155,7 @@ a precedencia valida usa `AZURE_OPENAI_DEPLOYMENT_NAME`, depois
144
155
 
145
156
  Redis e uma fronteira opcional para coordenacao tecnica de locks, cache, filas e eventos. Ele nao substitui a autoridade operacional de `.sdd/state/*.yaml`.
146
157
 
147
- Por padrao, CodeSDD usa locks em filesystem, cache L1 em memoria e cache L2 em `~/.codesdd/cache/projects/<fingerprint>/coordination`. A fabrica `createFilesystemFirstCoordinationAdapters` em `src/core/sdd/coordination/` mantem esse comportamento mesmo quando Redis e solicitado, ate que um adaptador Redis real seja instalado.
158
+ Por padrao, CodeSDD usa locks em filesystem, cache L1 em memoria e cache L2 em `~/.codesdd/cache/projects/<fingerprint>/coordination`. Quando Redis esta configurado e responde a ping, o runtime usa o cliente oficial `redis` para operar em modo `hybrid`: L1 em memoria, Redis como acelerador/coordenador distribuido e filesystem como fallback descartavel.
148
159
 
149
160
  Variaveis reconhecidas:
150
161
 
@@ -152,10 +163,39 @@ Variaveis reconhecidas:
152
163
  - `REDIS_URL`: fallback quando `CODESDD_REDIS_URL` nao estiver definida.
153
164
  - `CODESDD_REDIS_ENABLED=true`: marca Redis como solicitado mesmo sem URL.
154
165
  - `CODESDD_REDIS_NAMESPACE`: namespace logico; padrao `codesdd`.
166
+ - `CODESDD_REDIS_TLS=true`: ativa TLS quando a URL nao usar `rediss://`.
167
+ - `CODESDD_REDIS_FALLBACK=filesystem|none`: controla degradacao quando Redis falha.
168
+ - `CODESDD_REDIS_CONNECT_TIMEOUT_MS`, `CODESDD_REDIS_COMMAND_TIMEOUT_MS`, `CODESDD_REDIS_MAX_RETRIES`, `CODESDD_REDIS_CACHE_TTL_MS`, `CODESDD_REDIS_LOCK_TTL_MS`.
169
+
170
+ Exemplo seguro em `~/.codesdd/config.toml`:
171
+
172
+ ```toml
173
+ [redis]
174
+ enabled = true
175
+ url_env = "CODESDD_REDIS_URL"
176
+ namespace = "codesdd"
177
+ fallback = "filesystem"
178
+ connect_timeout_ms = 500
179
+ command_timeout_ms = 1000
180
+ max_retries = 2
181
+ cache_default_ttl_ms = 300000
182
+ lock_ttl_ms = 30000
183
+ stream_max_len = 10000
184
+ ```
185
+
186
+ Mantenha a URL real no shell, password manager ou secret store do CI:
187
+
188
+ ```bash
189
+ export CODESDD_REDIS_URL="redis://localhost:6379"
190
+ ```
191
+
192
+ `codesdd config doctor --json` e `codesdd config redis status --json` reportam `disabled`, `requested-unavailable`, `ready`, `degraded` ou `blocked` sem imprimir usuario, senha ou token da URL. Operacoes adicionais:
155
193
 
156
- Enquanto o cliente Redis nao existir no runtime, o status exposto e `requested-unavailable` e os defaults filesystem-first continuam autoritativos.
194
+ - `codesdd config redis ping`
195
+ - `codesdd config redis bench --iterations 20`
196
+ - `codesdd config redis flush-namespace --yes`
157
197
 
158
- `codesdd config list` exibe o status atual da fronteira Redis e o namespace efetivo sem imprimir segredos.
198
+ Redis nunca deve armazenar estado canonico do projeto, chaves de API, tokens, senhas, respostas cruas de providers ou dados pessoais. Use `docs/redis-operations.md` para o runbook completo.
159
199
 
160
200
  ## Contrato de nomenclatura
161
201
 
@@ -247,6 +287,9 @@ Se o terminal nao encontrar `codesdd`, a instalacao provavelmente foi concluida,
247
287
  - O tier `projects` usa fingerprint por raiz de projeto para evitar colisao de cache entre repositorios.
248
288
  - `codesdd config init` cria/normaliza `~/.codesdd/config.toml`, `~/.codesdd/cache/**` e `~/.codesdd/env.zsh` com conteudo nao secreto.
249
289
  - Em shell Zsh, `codesdd config init` garante um bloco idempotente no `~/.zshrc` para `source ~/.codesdd/env.zsh`.
290
+ - A fronteira funcional e validavel: estado versionado do projeto fica em `.sdd`; config/runtime/cache comum fica em `~/.codesdd`; `.codesdd` dentro do repositorio e invalido para novo estado.
291
+ - `codesdd config doctor --json` expoe `storage_boundary` com `project_state_dir`, `global_runtime_dir`, `global_cache_dir`, tiers de cache e regras de separacao.
292
+ - `codesdd sdd plugin plan --project-root <path>` reutiliza essa fronteira para bloquear writes de plugin em `.codesdd` local e expor `workcell_runner.standalone.storage_boundary`.
250
293
  - O perfil gerado por `codesdd config init` e fail-closed: DeepAgents fica
251
294
  desabilitado, runtime `disabled`, provider smoke `0` e rede `disabled` ate
252
295
  que um operador habilite explicitamente um provedor live.
@@ -330,6 +373,18 @@ pnpm run quality:review
330
373
  - `cleanup:install`: faz a limpeza acima e tambem remove `node_modules/` e lockfiles alternativos locais (`package-lock.json`, `yarn.lock`, `bun.lock*`), preservando o `pnpm-lock.yaml` versionado.
331
374
  - `quality:review`: executa build, lint, testes, cobertura, validacao SDD e pack-version sem remover `node_modules/` nem executar `pnpm install`; use em revisoes/auditorias que nao devem limpar o workspace.
332
375
 
376
+ Antes de release, gere o resumo nao mutante de prontidao:
377
+
378
+ ```bash
379
+ codesdd sdd release-readiness --strict
380
+ ```
381
+
382
+ O comando verifica saude SDD, FEATs ativos, scripts de CI parity, metadata do
383
+ pacote, fronteira de `.npmrc`, allowlist de publicacao, varredura de segredos
384
+ de alta confianca, proveniencia/SBOM, smoke de instalacao via tarball com
385
+ bootstrap da CLI, plano de rollback com `npm deprecate`, schemas essenciais e
386
+ docs de release/seguranca.
387
+
333
388
  ## Como iniciar em um projeto novo
334
389
 
335
390
  Entre no repositorio onde voce quer usar o sistema e rode:
@@ -467,6 +522,19 @@ If there is no ready FEAT, onboarding now returns guided steps such as creating
467
522
  codesdd sdd next
468
523
  ```
469
524
 
525
+ Para operar o plano sem adivinhar, use:
526
+
527
+ ```bash
528
+ codesdd sdd plan-status
529
+ codesdd sdd execute-next --dry-run
530
+ codesdd sdd execute-next
531
+ ```
532
+
533
+ `plan-status` mostra FEATs ativas, a proxima lista ranqueada e a acao
534
+ recomendada. `execute-next` usa o mesmo ranking de `next` e chama `sdd start`
535
+ para a primeira FEAT pronta; use `--dry-run` para auditar a escolha sem mudar
536
+ estado.
537
+
470
538
  Auditar a saude de evolucao do proprio processo SDD (ciclo recomendado: semestral):
471
539
 
472
540
  ```bash
@@ -567,6 +635,42 @@ workspace ativa.
567
635
  codesdd sdd context FEAT-0001
568
636
  ```
569
637
 
638
+ Para reduzir consumo de contexto, `sdd context` aceita modos de budget:
639
+ `--budget compact`, `--budget standard` e `--budget full` (`--compact` e
640
+ `--full` sao atalhos). O modo `compact` preserva os campos principais e reduz
641
+ listas grandes como `read_order`, `core_docs`, contratos, servicos e
642
+ predecessores; a resposta inclui `context_budget` com estimativa de caracteres
643
+ e campos truncados. Antes de truncar, listas conhecidas passam por dedupe
644
+ deterministico, preservando a primeira ocorrencia e registrando a reducao em
645
+ `context_budget.deduped_fields`.
646
+
647
+ Quando o budget omite itens, a resposta tambem inclui
648
+ `progressive_disclosure`, com contagem por campo e um `reveal_command` para
649
+ reemitir o contexto completo (`codesdd sdd context <REF> --full --json`). Isso
650
+ permite usar o pacote compacto como plano inicial sem perder a trilha de como
651
+ expandir detalhes sob demanda.
652
+
653
+ O pacote budgetado tambem usa cache descartavel em
654
+ `~/.codesdd/cache/projects/<project-fingerprint>/context-summary`, isolado pelo
655
+ fingerprint do projeto e por um fingerprint dos arquivos `.sdd/state` e da
656
+ workspace da entidade. A resposta inclui `context_cache` com `hit`, `key`,
657
+ `project_fingerprint` e `source_fingerprint`; quando a fonte muda, a chave muda
658
+ e o pacote e recalculado.
659
+
660
+ Quando a tarefa depende de economia de contexto, registre a medicao em
661
+ `5-quality.yaml` usando `token_budget_gates.telemetry`. O gate aceita
662
+ `budget_chars`, `actual_chars`, `efficiency_percent`, `gate` e `evidence_ref`;
663
+ o Q95 usa a pior eficiencia estruturada e trata `gate: fail` ou eficiencia
664
+ abaixo de `fail_below_percent` como bloqueio de qualidade.
665
+
666
+ Para estabilizar validacoes longas, `5-quality.yaml` tambem aceita
667
+ `runtime_quality_gates`. Use `performance[]` para registrar duracao, p95,
668
+ memoria ou CPU com `threshold`, `actual` e `gate`; use `flakiness[]` para
669
+ registrar `attempts`, `failures` ou `failure_rate_percent`. Quando houver
670
+ telemetria, o Q95 incorpora o pior sinal de performance/flakiness no eixo de
671
+ integridade; sem telemetria, o score permanece neutro para manter compatibilidade
672
+ com workspaces antigos.
673
+
570
674
  4.1 Expor a fundacao MCP para agentes externos
571
675
 
572
676
  No repositorio local, use o entrypoint versionado do checkout atual para validar
@@ -621,6 +725,13 @@ A fundacao MCP do CodeSDD e agnostica a provedor e publica o envelope
621
725
  `codesdd.context`, `codesdd.query`, `codesdd.read` e os demais nomes
622
726
  `codesdd.*` documentados pelo manifest.
623
727
 
728
+ Agent Runtime v2 exporta planos de comando para DeepAgents, Codex exec e
729
+ OpenCode run. Para OpenCode, o contrato
730
+ `agent-runtime-opencode-run-evidence.schema.json` registra execucao,
731
+ artefatos, validacoes e trechos redigidos sem permitir escrita direta em
732
+ estado SDD; o `finalize` do CodeSDD continua sendo o unico escritor canonico
733
+ do ciclo de vida.
734
+
624
735
  Perfis aceitos por `--provider`: `codex`, `claude-code`, `kimmy-code`,
625
736
  `kilo-code`, `open-code` e `generic`. Para OpenCode/Open Code, o bridge MCP usa
626
737
  o identificador `open-code`; `opencode` aparece em contratos antigos de
@@ -643,6 +754,16 @@ Se você já estiver dentro de `.sdd/active/FEAT-####/`, o `finalize` também po
643
754
  inferir a FEAT alvo sem `--ref`, priorizando o workspace ativo atual antes de
644
755
  cair para a fila pendente padrão.
645
756
 
757
+ Após consolidar uma FEAT, o resultado de `sdd finalize` inclui
758
+ `post_finalize_replan` com as próximas FEATs prontas, ondas e contagens de
759
+ bloqueios/conflitos recalculadas a partir do estado canônico. Em saída texto, o
760
+ CLI mostra as primeiras próximas FEATs para orientar execução encadeada.
761
+
762
+ `.sdd/state/finalize-queue.yaml` separa fila ativa de historico: `items` guarda
763
+ somente finalizacoes `PENDING`, enquanto `history` guarda finalizacoes `DONE`.
764
+ O `check` reporta pendentes e concluidas separadamente, e a view
765
+ `.sdd/planning/finalize-queue.md` mostra a fila ativa mais o historico recente.
766
+
646
767
  Quando `requires_adr: true` ou o `2-plan.yaml` ativo declara impacto
647
768
  arquitetural sensivel, o `finalize` exige ADR existente e válido pela lente `adr`
648
769
  (seções `Contexto`, `Decisão`, `Consequências` e sem frase proibida de
@@ -659,6 +780,24 @@ contrato operacional das skills: registre uma entrada em
659
780
  Sem esse rastro, o fluxo fica bloqueado como qualquer outra evidência de
660
781
  qualidade obrigatória.
661
782
 
783
+ O `2-plan.yaml` gerado inclui `governance`, que declara a fronteira canônica
784
+ `codesdd-canonical-sdd-state`, os artefatos de planejamento envolvidos, refs de
785
+ decisão, escritas de estado previstas, plano de rollback e gates de validação.
786
+ O schema aceita workspaces históricos sem esse bloco por compatibilidade, mas
787
+ novos planos devem manter esse contrato preenchido.
788
+
789
+ O mesmo `2-plan.yaml` também inclui `execution_plan`, que explicita se a FEAT
790
+ roda como `single-feature`, `parallel-wave` ou `chained-features`, sempre com
791
+ `state_boundary_ref: codesdd-canonical-sdd-state`. O plano lista comandos,
792
+ quais passos podem escrever estado, `allowed_state_writes`, escritas proibidas
793
+ como `.codesdd/**` e os artefatos de handoff esperados. Planos de automação
794
+ paralela exportados em `schemas/sdd/parallel-feat-automation-plan.schema.json`
795
+ carregam a mesma fronteira para que execução encadeada não crie estado oculto.
796
+ O scheduler encadeado consome FEATs com `blocked_by`, `status` e `lock_domains`,
797
+ trata predecessores `DONE` como âncoras já satisfeitas, divide ondas para evitar
798
+ locks concorrentes e reporta dependências não agendáveis no resultado exportado
799
+ em `schemas/sdd/parallel-feat-scheduler-result.schema.json`.
800
+
662
801
  O `5-quality.yaml` agora também precisa fechar a rastreabilidade viva da
663
802
  workspace: preencha `traceability.spec_anchor` com o `updated_at` atual do
664
803
  `1-spec.yaml`, referencie a entrada correspondente do `4-changelog.yaml`, e
@@ -667,6 +806,11 @@ requisito -> `code_refs` -> `test_refs` -> `evidence_refs`. O `finalize`,
667
806
  `check` e `diagnose` passam a bloquear ou sinalizar drift quando a spec muda e
668
807
  esse vínculo não é revisitado.
669
808
 
809
+ O ledger `q95_ledger` limita todos os percentuais a `0..100`, exige pesos que
810
+ somam `100` e impede `status: pass` quando `score` fica abaixo de `threshold`.
811
+ Isso mantém o Q95 auditável antes de qualquer automação de release ou execução
812
+ encadeada consumir o resultado.
813
+
670
814
  O `finalize` também executa validação pós-active de lifecycle: a FEAT não pode
671
815
  ter cópia semântica em `.sdd/archive/<FEAT-ID>`, deve sair de `.sdd/active/` e
672
816
  deve aparecer uma única vez em `.sdd/archived/<FEAT-ID>`. `sdd check` e
@@ -804,7 +948,7 @@ The SDD bootstrap installs local curation in:
804
948
  .sdd/skills/curated/
805
949
  ```
806
950
 
807
- The default curation currently includes 66 skills across 8 bundles (canonical source: `.sdd/state/skill-catalog.yaml`).
951
+ The default curation currently includes 79 skills across 11 bundles (canonical source: `.sdd/state/skill-catalog.yaml`).
808
952
  Skill catalog entries now follow the v2 metadata contract with `token_budget`, `integrity_hash`, `deterministic_pair`, `deprecated_at`, and `superseded_by` for routing governance and lifecycle traceability.
809
953
  `codesdd sdd skills sync` now enforces SHA-256 drift detection by layer: canonical curated skills block sync on `missing/modified` manifest hash, while user-extension skills emit non-blocking alerts so local customization remains possible.
810
954
 
@@ -817,13 +961,19 @@ Entre elas:
817
961
  - `planning-normalizer-sdd`
818
962
  - `api-clean-flask-langgraph` (bundle `python-agentic-backend`)
819
963
  - `devtrack-api` (bundle `architecture-backend`, canonical DevTrack/NestJS/TypeORM API architecture)
964
+ - `devtrack-angular` (bundle `frontend-product`, canonical DevTrack Angular Admin architecture)
965
+ - `devtrack-flutter` (bundle `frontend-product`, canonical DevTrack Flutter/Dart architecture)
820
966
 
821
- Skill routing is operational, not decorative. When `codesdd sdd context <FEAT-ID>` returns `recommended_skills`, or when a user explicitly directs a skill, the agent must read and follow that skill before implementation and record one `skill_evidence` entry per required skill in `.sdd/active/<FEAT-ID>/5-quality.yaml` before finalize. For API/backend work without an explicit alternative skill/profile, `devtrack-api` is the default architecture and naming source. Explicit Python/Flask API work remains routed to `api-clean-flask-langgraph`.
967
+ Skill routing is operational, not decorative. When `codesdd sdd context <FEAT-ID>` returns `recommended_skills`, or when a user explicitly directs a skill, the agent must read and follow that skill before implementation and record one `skill_evidence` entry per required skill in `.sdd/active/<FEAT-ID>/5-quality.yaml` before finalize. For API/backend work without an explicit alternative skill/profile, `devtrack-api` is the default architecture and naming source. Angular Admin/backoffice work that names admin pages, dashboards, CRUD, data grids, admin Formly, admin NGXS/state, official Angular framework patterns, permissions, reports, workflow, admin realtime, or admin chat uses `devtrack-angular`. Flutter/Dart work that names Flutter apps, widgets, routing, localization, responsive layout, JSON, HTTP, previews, widget tests, integration tests, go_router, ARB, or l10n uses `devtrack-flutter`. Explicit Python/Flask API work remains routed to `api-clean-flask-langgraph`.
822
968
 
823
969
  The `devtrack-api` skill has a Foundation-layout conformance test. When the Foundation checkout is not at `/Volumes/WORKSPACE/DEVTRACK_TOOLS/devtrack-foundation-api`, set `CODESDD_FOUNDATION_API_ROOT=/path/to/devtrack-foundation-api` before running `pnpm test -- test/specs/devtrack-api-foundation-layout.test.ts`.
824
970
 
825
971
  The executable `devtrack-api` contract pack lives in `.sdd/skills/curated/devtrack-api/references/contract-pack.yaml`. It defines the `prototype`, `foundation-compatible`, and `enterprise-strict` profiles, P0/P1/P2 severity semantics, early package-preview expectations, import/alias and TypeORM drift rules, and the `codesdd-validate` plus field-evidence drift maps consumed by later governance gates.
826
972
 
973
+ The executable `devtrack-angular` contract pack lives in `.sdd/skills/curated/devtrack-angular/references/contract-pack.yaml`. It defines portable agent adapters, `prototype`, `production-admin`, and `enterprise-admin` profiles, pages-first Angular Admin architecture rules, Formly/NGXS/realtime/admin gates, official Angular skills mapping, and evidence expectations for Angular Admin delivery.
974
+
975
+ The executable `devtrack-flutter` contract pack lives in `.sdd/skills/curated/devtrack-flutter/references/contract-pack.yaml`. It defines portable agent adapters, `prototype`, `production-flutter`, and `enterprise-flutter` profiles, layered Flutter architecture rules, routing/localization/layout/data/test gates, official Flutter skills mapping, and evidence expectations for Flutter/Dart delivery.
976
+
827
977
  Consumer copies of `devtrack-api` are one-way CodeSDD materializations, not durable edit targets. The sync policy lives in `.sdd/skills/curated/devtrack-api/references/consumer-sync-policy.md`: update the consumer project through its CodeSDD update/bootstrap flow, compare the consumer copy with the canonical CodeSDD source, and record source version plus diff evidence in the consumer FEAT quality or handoff.
828
978
 
829
979
  Field validation for `devtrack-api` is governed by `.sdd/skills/curated/devtrack-api/references/field-validation-protocol.md`. A consumer project must keep its own evidence showing at least two detailed implementation debates and closure of divergence classes D-01 through D-08; CodeSDD keeps the protocol and external reference, not private consumer ledgers.
@@ -891,6 +1041,8 @@ Onboarding e operacao:
891
1041
  - `codesdd sdd orientar system`
892
1042
  - `codesdd sdd next`
893
1043
  - `codesdd sdd next --max-agents <N>` (limita o tamanho da primeira onda e lista itens adiados)
1044
+ - `codesdd sdd plan-status`
1045
+ - `codesdd sdd execute-next --dry-run`
894
1046
  - `codesdd sdd start FEAT-0001 --fluxo direto|padrao|rigoroso`
895
1047
  - `codesdd sdd aprovar FEAT-0001 --etapa proposta|planejamento|tarefas`
896
1048
  - `codesdd sdd context FEAT-0001`
@@ -1004,6 +1156,8 @@ Operational authority:
1004
1156
 
1005
1157
  Initial operational directives:
1006
1158
  - CodeSDD is the official planner for any build request; other planners or agent-native plans are secondary execution aids only.
1159
+ - In initialized CodeSDD repositories, any user request that implies implementation, file edits, validation, execution, or finalize must be treated as requiring CodeSDD planning unless the user explicitly marks it as read-only or outside CodeSDD.
1160
+ - For change requests, agents must bind the work to an active or ready FEAT through `codesdd sdd next` and `codesdd sdd context <FEAT-ID>` before implementation; agent-native plans may only decompose execution after that CodeSDD context exists.
1007
1161
  - For API/backend work, use `devtrack-api` by default unless the user or SDD context explicitly selects another skill/profile; Python/Flask API work stays routed to `api-clean-flask-langgraph`.
1008
1162
  - During init, onboard, insight, and debate flows, CodeSDD-managed agent instruction blocks must be inspected and reconfigured when they drift from this contract.
1009
1163
  - Commit requests must follow Conventional Commits, selective staging, and grouping by modified directory plus change protocol (`src`, `.sdd`, docs, config, infra, dependencies, or generated files).
@@ -0,0 +1,16 @@
1
+ export { ApproveService } from '../../core/sdd/services/approve.service.js';
2
+ export { BreakdownService } from '../../core/sdd/services/breakdown.service.js';
3
+ export { ContextService } from '../../core/sdd/services/context.service.js';
4
+ export { DebateService } from '../../core/sdd/services/debate.service.js';
5
+ export { DecideService } from '../../core/sdd/services/decide.service.js';
6
+ export { DeepAgentsRunService, type DeepAgentsRunRequest, type DeepAgentsRunResult } from '../../core/sdd/services/agent-run.service.js';
7
+ export { FeatureLintService, collectTaskCommands, formatFeatureLintReport, isFoundationPrescriptiveFeature, type FeatureLintFinding, type FeatureLintOptions, type FeatureLintReport, } from '../../core/sdd/services/feature-lint.service.js';
8
+ export { FinalizeService } from '../../core/sdd/services/finalize.service.js';
9
+ export { FrontendGapService } from '../../core/sdd/services/frontend-gap.service.js';
10
+ export { FrontendImpactService } from '../../core/sdd/services/frontend-impact.service.js';
11
+ export { GovernanceControlPlaneService } from '../../core/sdd/services/governance-control-plane.service.js';
12
+ export { InsightService } from '../../core/sdd/services/insight.service.js';
13
+ export { NextService } from '../../core/sdd/services/next.service.js';
14
+ export { OnboardService } from '../../core/sdd/services/onboard.service.js';
15
+ export { StartService } from '../../core/sdd/services/start.service.js';
16
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,16 @@
1
+ export { ApproveService } from '../../core/sdd/services/approve.service.js';
2
+ export { BreakdownService } from '../../core/sdd/services/breakdown.service.js';
3
+ export { ContextService } from '../../core/sdd/services/context.service.js';
4
+ export { DebateService } from '../../core/sdd/services/debate.service.js';
5
+ export { DecideService } from '../../core/sdd/services/decide.service.js';
6
+ export { DeepAgentsRunService } from '../../core/sdd/services/agent-run.service.js';
7
+ export { FeatureLintService, collectTaskCommands, formatFeatureLintReport, isFoundationPrescriptiveFeature, } from '../../core/sdd/services/feature-lint.service.js';
8
+ export { FinalizeService } from '../../core/sdd/services/finalize.service.js';
9
+ export { FrontendGapService } from '../../core/sdd/services/frontend-gap.service.js';
10
+ export { FrontendImpactService } from '../../core/sdd/services/frontend-impact.service.js';
11
+ export { GovernanceControlPlaneService } from '../../core/sdd/services/governance-control-plane.service.js';
12
+ export { InsightService } from '../../core/sdd/services/insight.service.js';
13
+ export { NextService } from '../../core/sdd/services/next.service.js';
14
+ export { OnboardService } from '../../core/sdd/services/onboard.service.js';
15
+ export { StartService } from '../../core/sdd/services/start.service.js';
16
+ //# sourceMappingURL=index.js.map
@@ -8,7 +8,8 @@ import { CORE_WORKFLOWS, ALL_WORKFLOWS, getProfileWorkflows } from '../core/prof
8
8
  import { hasProjectConfigDrift } from '../core/profile-sync-drift.js';
9
9
  import { CLI_NAME } from '../core/branding.js';
10
10
  import { resolveLegacySpecLiveRoot } from '../core/sdd/services/legacy-capability.service.js';
11
- import { resolveRedisBoundaryConfig } from '../core/sdd/coordination/index.js';
11
+ import { buildRedisOperationalReport, deleteKeysByPrefix, RedisClientFactory, resolveRedisBoundaryConfig, runRedisBenchmark, } from '../core/sdd/coordination/index.js';
12
+ import { buildCodesddStorageBoundaryReport } from '../core/sdd/runtime-boundary-contract.js';
12
13
  import { buildDeepAgentsOperationalPreflight, createDeepAgentsPolicySnapshot, } from '../core/sdd/deepagents/policy.js';
13
14
  import { detectShell } from '../utils/shell-detection.js';
14
15
  import { ZshInstaller } from '../core/completions/installers/zsh-installer.js';
@@ -70,6 +71,10 @@ function buildCodesddEnvTemplate() {
70
71
  'export CODESDD_DEEPAGENTS_RUNTIME="${CODESDD_DEEPAGENTS_RUNTIME:-disabled}"',
71
72
  'export CODESDD_AGENT_NETWORK_POLICY="${CODESDD_AGENT_NETWORK_POLICY:-disabled}"',
72
73
  'export CODESDD_DEEPAGENTS_PROVIDER_SMOKE="${CODESDD_DEEPAGENTS_PROVIDER_SMOKE:-0}"',
74
+ 'export CODESDD_REDIS_ENABLED="${CODESDD_REDIS_ENABLED:-false}"',
75
+ 'export CODESDD_REDIS_NAMESPACE="${CODESDD_REDIS_NAMESPACE:-codesdd}"',
76
+ '# export CODESDD_REDIS_URL="redis://localhost:6379"',
77
+ '# export CODESDD_REDIS_FALLBACK="filesystem"',
73
78
  '# Optional live-provider launcher references. Keep values in your shell,',
74
79
  '# password manager, CI secret store, or another untracked launcher context.',
75
80
  '# export CODESDD_DEEPAGENTS_ENABLED=true',
@@ -255,11 +260,15 @@ export function registerConfigCommand(program) {
255
260
  .command('doctor')
256
261
  .description('Run operational readiness checks for DeepAgents/Azure, cache, and Redis boundary')
257
262
  .option('--json', 'Output as JSON')
258
- .action((options) => {
263
+ .action(async (options) => {
259
264
  const snapshot = createDeepAgentsPolicySnapshot(process.env);
260
265
  const preflight = buildDeepAgentsOperationalPreflight(snapshot, process.env);
261
- const redisBoundary = resolveRedisBoundaryConfig(process.env);
266
+ const redisReport = await buildRedisOperationalReport({
267
+ env: process.env,
268
+ globalConfig: getGlobalConfig(),
269
+ });
262
270
  const cacheTiers = getGlobalCacheTierDirs();
271
+ const storageBoundary = buildCodesddStorageBoundaryReport(process.cwd());
263
272
  const report = {
264
273
  schema_version: 1,
265
274
  global_config_path: getGlobalConfigPath(),
@@ -267,10 +276,17 @@ export function registerConfigCommand(program) {
267
276
  root: getGlobalCacheDir(),
268
277
  tiers: Object.keys(cacheTiers),
269
278
  },
279
+ storage_boundary: storageBoundary,
270
280
  redis: {
271
- requested: redisBoundary.requested,
272
- namespace: redisBoundary.namespace,
273
- status: redisBoundary.requested ? 'requested-unavailable' : 'disabled',
281
+ requested: redisReport.requested,
282
+ namespace: redisReport.namespace,
283
+ status: redisReport.status,
284
+ fallback: redisReport.fallback,
285
+ redacted_url: redisReport.redacted_url,
286
+ latency_ms: redisReport.latency_ms,
287
+ reason: redisReport.reason,
288
+ validation_errors: redisReport.validation_errors,
289
+ warnings: redisReport.warnings,
274
290
  },
275
291
  deepagents: preflight,
276
292
  };
@@ -281,16 +297,153 @@ export function registerConfigCommand(program) {
281
297
  console.log(`Global config: ${report.global_config_path}`);
282
298
  console.log(`Cache root: ${report.cache.root}`);
283
299
  console.log(`Cache tiers: ${report.cache.tiers.join(', ')}`);
284
- console.log(`Redis: ${report.redis.status} (namespace=${report.redis.namespace})`);
300
+ console.log(`Project state: ${report.storage_boundary.project_state_dir}`);
301
+ console.log(`Global runtime: ${report.storage_boundary.global_runtime_dir}`);
302
+ console.log(`Redis: ${report.redis.status} (namespace=${report.redis.namespace}, fallback=${report.redis.fallback})`);
303
+ if (report.redis.redacted_url) {
304
+ console.log(`Redis URL: ${report.redis.redacted_url}`);
305
+ }
306
+ if (report.redis.latency_ms !== undefined) {
307
+ console.log(`Redis latency: ${report.redis.latency_ms}ms`);
308
+ }
309
+ console.log(`Redis reason: ${report.redis.reason}`);
310
+ for (const warning of report.redis.warnings) {
311
+ console.log(`- ${warning}`);
312
+ }
313
+ for (const error of report.redis.validation_errors) {
314
+ console.log(`- ${error}`);
315
+ }
285
316
  console.log(`DeepAgents preflight: ${preflight.status}`);
286
317
  for (const reason of preflight.reasons) {
287
318
  console.log(`- ${reason}`);
288
319
  }
289
320
  }
290
- if (preflight.status === 'blocked') {
321
+ if (preflight.status === 'blocked' || redisReport.status === 'blocked') {
291
322
  process.exitCode = 1;
292
323
  }
293
324
  });
325
+ const redisCmd = configCmd
326
+ .command('redis')
327
+ .description('Inspect and operate the optional Redis runtime backend');
328
+ redisCmd
329
+ .command('status')
330
+ .description('Show Redis runtime status')
331
+ .option('--json', 'Output as JSON')
332
+ .action(async (options) => {
333
+ const report = await buildRedisOperationalReport({
334
+ env: process.env,
335
+ globalConfig: getGlobalConfig(),
336
+ });
337
+ if (options.json) {
338
+ console.log(JSON.stringify(report, null, 2));
339
+ return;
340
+ }
341
+ console.log(`Redis: ${report.status}`);
342
+ console.log(`Namespace: ${report.namespace}`);
343
+ console.log(`Fallback: ${report.fallback}`);
344
+ if (report.redacted_url)
345
+ console.log(`URL: ${report.redacted_url}`);
346
+ if (report.latency_ms !== undefined)
347
+ console.log(`Latency: ${report.latency_ms}ms`);
348
+ console.log(`Reason: ${report.reason}`);
349
+ if (report.status === 'blocked')
350
+ process.exitCode = 1;
351
+ });
352
+ redisCmd
353
+ .command('ping')
354
+ .description('Ping Redis using the effective CodeSDD configuration')
355
+ .option('--json', 'Output as JSON')
356
+ .action(async (options) => {
357
+ const report = await buildRedisOperationalReport({
358
+ env: process.env,
359
+ globalConfig: getGlobalConfig(),
360
+ });
361
+ if (options.json) {
362
+ console.log(JSON.stringify(report, null, 2));
363
+ }
364
+ else {
365
+ console.log(`Redis ping: ${report.status}`);
366
+ if (report.latency_ms !== undefined)
367
+ console.log(`Latency: ${report.latency_ms}ms`);
368
+ console.log(report.reason);
369
+ }
370
+ if (report.status !== 'ready')
371
+ process.exitCode = 1;
372
+ });
373
+ redisCmd
374
+ .command('bench')
375
+ .description('Run a short redacted Redis latency benchmark')
376
+ .option('--json', 'Output as JSON')
377
+ .option('--iterations <n>', 'Number of benchmark iterations')
378
+ .action(async (options) => {
379
+ const iterations = options.iterations ? Number.parseInt(options.iterations, 10) : undefined;
380
+ const report = await runRedisBenchmark({
381
+ env: process.env,
382
+ globalConfig: getGlobalConfig(),
383
+ iterations,
384
+ });
385
+ if (options.json) {
386
+ console.log(JSON.stringify(report, null, 2));
387
+ }
388
+ else {
389
+ console.log(`Redis benchmark: ${report.status}`);
390
+ console.log(`Namespace: ${report.namespace}`);
391
+ console.log(`Iterations: ${report.iterations}`);
392
+ if (report.p50_ms !== undefined)
393
+ console.log(`p50: ${report.p50_ms}ms`);
394
+ if (report.p95_ms !== undefined)
395
+ console.log(`p95: ${report.p95_ms}ms`);
396
+ console.log(`Reason: ${report.reason}`);
397
+ }
398
+ if (report.status !== 'ready')
399
+ process.exitCode = 1;
400
+ });
401
+ redisCmd
402
+ .command('flush-namespace')
403
+ .description('Delete only keys under the effective CodeSDD Redis namespace')
404
+ .option('--json', 'Output as JSON')
405
+ .option('-y, --yes', 'Confirm namespace-scoped deletion')
406
+ .action(async (options) => {
407
+ const config = resolveRedisBoundaryConfig(process.env, getGlobalConfig());
408
+ if (!options.yes) {
409
+ console.error('Error: --yes is required to flush the CodeSDD Redis namespace.');
410
+ process.exitCode = 1;
411
+ return;
412
+ }
413
+ const report = await buildRedisOperationalReport({
414
+ env: process.env,
415
+ globalConfig: getGlobalConfig(),
416
+ });
417
+ if (report.status !== 'ready') {
418
+ if (options.json) {
419
+ console.log(JSON.stringify({ ...report, deleted_keys: 0 }, null, 2));
420
+ }
421
+ else {
422
+ console.log(`Redis namespace flush skipped: ${report.reason}`);
423
+ }
424
+ process.exitCode = 1;
425
+ return;
426
+ }
427
+ const factory = new RedisClientFactory(config);
428
+ try {
429
+ const deleted = await deleteKeysByPrefix(factory, `${config.namespace}:`);
430
+ const payload = {
431
+ schema_version: 1,
432
+ namespace: config.namespace,
433
+ deleted_keys: deleted,
434
+ status: 'ok',
435
+ };
436
+ if (options.json) {
437
+ console.log(JSON.stringify(payload, null, 2));
438
+ }
439
+ else {
440
+ console.log(`Deleted ${deleted} Redis key(s) under namespace ${config.namespace}.`);
441
+ }
442
+ }
443
+ finally {
444
+ await factory.close();
445
+ }
446
+ });
294
447
  // config list
295
448
  configCmd
296
449
  .command('list')
@@ -331,11 +484,19 @@ export function registerConfigCommand(program) {
331
484
  console.log(`\nCache settings:`);
332
485
  console.log(` root: ${getGlobalCacheDir()}`);
333
486
  console.log(` tiers: ${Object.keys(cacheTiers).join(', ')}`);
334
- const redisBoundary = resolveRedisBoundaryConfig(process.env);
335
- const redisStatus = redisBoundary.requested ? 'requested-unavailable (filesystem-first fallback)' : 'disabled';
487
+ const redisBoundary = resolveRedisBoundaryConfig(process.env, config);
488
+ const redisStatus = redisBoundary.validationErrors.length > 0
489
+ ? 'blocked'
490
+ : redisBoundary.requested
491
+ ? 'requested-unavailable or ready after ping'
492
+ : 'disabled';
336
493
  console.log(`\nRedis boundary:`);
337
494
  console.log(` status: ${redisStatus}`);
338
495
  console.log(` namespace: ${redisBoundary.namespace}`);
496
+ console.log(` fallback: ${redisBoundary.fallback}`);
497
+ if (redisBoundary.redactedUrl) {
498
+ console.log(` url: ${redisBoundary.redactedUrl}`);
499
+ }
339
500
  }
340
501
  });
341
502
  // config get