@devtrack-solution/codesdd 1.2.2 → 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 (413) hide show
  1. package/.sdd/skills/curated/api-clean-flask-langgraph/SKILL.md +17 -17
  2. package/.sdd/skills/curated/devtrack-api/SKILL.md +170 -31
  3. package/.sdd/skills/curated/devtrack-api/agents/claude-code.yaml +8 -0
  4. package/.sdd/skills/curated/devtrack-api/agents/codex.yaml +8 -0
  5. package/.sdd/skills/curated/devtrack-api/agents/cursor.yaml +8 -0
  6. package/.sdd/skills/curated/devtrack-api/agents/gemini.yaml +8 -0
  7. package/.sdd/skills/curated/devtrack-api/agents/kimi.yaml +8 -0
  8. package/.sdd/skills/curated/devtrack-api/agents/openai.yaml +4 -2
  9. package/.sdd/skills/curated/devtrack-api/agents/opencode.yaml +10 -0
  10. package/.sdd/skills/curated/devtrack-api/references/application-presentation.md +2 -2
  11. package/.sdd/skills/curated/devtrack-api/references/architecture-governance.md +8 -7
  12. package/.sdd/skills/curated/devtrack-api/references/consumer-sync-policy.md +93 -0
  13. package/.sdd/skills/curated/devtrack-api/references/contract-pack.yaml +372 -0
  14. package/.sdd/skills/curated/devtrack-api/references/domain-modeling.md +13 -13
  15. package/.sdd/skills/curated/devtrack-api/references/field-validation-protocol.md +95 -0
  16. package/.sdd/skills/curated/devtrack-api/references/foundation-layout.md +294 -0
  17. package/.sdd/skills/curated/devtrack-api/references/implementation-checklist.md +5 -5
  18. package/.sdd/skills/curated/devtrack-api/references/imports-lint.md +4 -0
  19. package/.sdd/skills/curated/devtrack-api/references/portable-agent-contract.md +41 -0
  20. package/.sdd/skills/curated/devtrack-api/references/testing-validation.md +2 -2
  21. package/.sdd/skills/curated/devtrack-api/references/typeorm-infrastructure.md +7 -9
  22. package/LICENSE +1 -1
  23. package/README.md +399 -53
  24. package/bin/codesdd.js +3 -2
  25. package/dist/applications/sdd/index.d.ts +16 -0
  26. package/dist/applications/sdd/index.js +16 -0
  27. package/dist/cli/index.d.ts +2 -2
  28. package/dist/cli/index.js +11 -558
  29. package/dist/cli/program.d.ts +14 -0
  30. package/dist/cli/program.js +645 -0
  31. package/dist/commands/change.js +5 -5
  32. package/dist/commands/completion.d.ts +1 -1
  33. package/dist/commands/completion.js +9 -2
  34. package/dist/commands/config.js +320 -20
  35. package/dist/commands/feedback.js +1 -1
  36. package/dist/commands/schema.d.ts +63 -0
  37. package/dist/commands/schema.js +12 -12
  38. package/dist/commands/sdd/backlog.d.ts +3 -0
  39. package/dist/commands/sdd/backlog.js +54 -0
  40. package/dist/commands/sdd/execution.js +489 -28
  41. package/dist/commands/sdd/plugin.d.ts +3 -0
  42. package/dist/commands/sdd/plugin.js +158 -0
  43. package/dist/commands/sdd/shared.d.ts +1 -0
  44. package/dist/commands/sdd/shared.js +11 -22
  45. package/dist/commands/sdd/skills.js +7 -0
  46. package/dist/commands/sdd.js +107 -15
  47. package/dist/commands/spec.js +9 -9
  48. package/dist/commands/validate.js +6 -6
  49. package/dist/commands/workflow/instructions.js +6 -6
  50. package/dist/commands/workflow/new-change.js +3 -3
  51. package/dist/commands/workflow/shared.d.ts +1 -1
  52. package/dist/commands/workflow/shared.js +4 -4
  53. package/dist/core/archive.js +15 -5
  54. package/dist/core/artifact-graph/instruction-loader.d.ts +1 -1
  55. package/dist/core/artifact-graph/instruction-loader.js +3 -3
  56. package/dist/core/artifact-graph/resolver.d.ts +4 -4
  57. package/dist/core/artifact-graph/resolver.js +6 -6
  58. package/dist/core/branding.js +3 -3
  59. package/dist/core/cli/command-matrix.js +19 -1
  60. package/dist/core/cli-command-quality.d.ts +27 -0
  61. package/dist/core/cli-command-quality.js +180 -0
  62. package/dist/core/command-generation/adapters/costrict.d.ts +1 -1
  63. package/dist/core/command-generation/adapters/costrict.js +2 -2
  64. package/dist/core/command-generation/types.d.ts +1 -1
  65. package/dist/core/completions/command-registry.d.ts +1 -1
  66. package/dist/core/completions/command-registry.js +200 -12
  67. package/dist/core/completions/completion-provider.d.ts +14 -1
  68. package/dist/core/completions/completion-provider.js +29 -1
  69. package/dist/core/completions/generators/bash-generator.d.ts +1 -1
  70. package/dist/core/completions/generators/bash-generator.js +20 -12
  71. package/dist/core/completions/generators/fish-generator.d.ts +9 -1
  72. package/dist/core/completions/generators/fish-generator.js +39 -25
  73. package/dist/core/completions/generators/powershell-generator.d.ts +1 -1
  74. package/dist/core/completions/generators/powershell-generator.js +21 -11
  75. package/dist/core/completions/generators/zsh-generator.d.ts +3 -6
  76. package/dist/core/completions/generators/zsh-generator.js +21 -42
  77. package/dist/core/completions/installers/bash-installer.js +6 -6
  78. package/dist/core/completions/installers/fish-installer.js +1 -1
  79. package/dist/core/completions/installers/powershell-installer.js +14 -14
  80. package/dist/core/completions/installers/zsh-installer.d.ts +7 -1
  81. package/dist/core/completions/installers/zsh-installer.js +36 -8
  82. package/dist/core/completions/templates/bash-templates.d.ts +1 -1
  83. package/dist/core/completions/templates/bash-templates.js +12 -6
  84. package/dist/core/completions/templates/fish-templates.d.ts +2 -2
  85. package/dist/core/completions/templates/fish-templates.js +20 -9
  86. package/dist/core/completions/templates/powershell-templates.d.ts +1 -1
  87. package/dist/core/completions/templates/powershell-templates.js +13 -4
  88. package/dist/core/completions/templates/zsh-templates.d.ts +1 -1
  89. package/dist/core/completions/templates/zsh-templates.js +18 -9
  90. package/dist/core/config-schema.d.ts +20 -1
  91. package/dist/core/config-schema.js +70 -2
  92. package/dist/core/config.d.ts +3 -3
  93. package/dist/core/config.js +4 -4
  94. package/dist/core/global-config.d.ts +57 -12
  95. package/dist/core/global-config.js +344 -27
  96. package/dist/core/index.d.ts +1 -1
  97. package/dist/core/index.js +2 -2
  98. package/dist/core/init.d.ts +6 -1
  99. package/dist/core/init.js +99 -77
  100. package/dist/core/legacy-cleanup.d.ts +17 -17
  101. package/dist/core/legacy-cleanup.js +96 -79
  102. package/dist/core/list.js +18 -4
  103. package/dist/core/migration.d.ts +3 -1
  104. package/dist/core/migration.js +7 -8
  105. package/dist/core/parsers/change-parser.js +1 -1
  106. package/dist/core/parsers/markdown-parser.js +2 -2
  107. package/dist/core/profile-sync-drift.d.ts +1 -1
  108. package/dist/core/profile-sync-drift.js +13 -13
  109. package/dist/core/project-config.d.ts +4 -4
  110. package/dist/core/project-config.js +11 -11
  111. package/dist/core/schemas/change.schema.d.ts +1 -1
  112. package/dist/core/schemas/change.schema.js +1 -1
  113. package/dist/core/schemas/spec.schema.d.ts +1 -1
  114. package/dist/core/schemas/spec.schema.js +1 -1
  115. package/dist/core/sdd/adr.js +23 -1
  116. package/dist/core/sdd/agent-binding.d.ts +346 -0
  117. package/dist/core/sdd/agent-binding.js +343 -0
  118. package/dist/core/sdd/agent-runtime-contract.d.ts +204 -0
  119. package/dist/core/sdd/agent-runtime-contract.js +200 -0
  120. package/dist/core/sdd/backlog-cli.d.ts +16 -0
  121. package/dist/core/sdd/backlog-cli.js +146 -0
  122. package/dist/core/sdd/backlog-conflict-policy.d.ts +58 -0
  123. package/dist/core/sdd/backlog-conflict-policy.js +230 -0
  124. package/dist/core/sdd/backlog-projection.d.ts +8 -0
  125. package/dist/core/sdd/backlog-projection.js +89 -0
  126. package/dist/core/sdd/backlog-provider-contract.d.ts +252 -0
  127. package/dist/core/sdd/backlog-provider-contract.js +158 -0
  128. package/dist/core/sdd/bootstrap.js +2 -2
  129. package/dist/core/sdd/check.d.ts +44 -0
  130. package/dist/core/sdd/check.js +62 -24
  131. package/dist/core/sdd/contract.d.ts +13 -0
  132. package/dist/core/sdd/contract.js +36 -0
  133. package/dist/core/sdd/coordination/coordination-adapters.d.ts +53 -8
  134. package/dist/core/sdd/coordination/coordination-adapters.js +182 -16
  135. package/dist/core/sdd/coordination/index.d.ts +1 -0
  136. package/dist/core/sdd/coordination/index.js +1 -0
  137. package/dist/core/sdd/coordination/redis-runtime.d.ts +131 -0
  138. package/dist/core/sdd/coordination/redis-runtime.js +698 -0
  139. package/dist/core/sdd/deepagent-contracts.d.ts +370 -0
  140. package/dist/core/sdd/deepagent-contracts.js +235 -0
  141. package/dist/core/sdd/deepagents/adr-governor.d.ts +2 -0
  142. package/dist/core/sdd/deepagents/adr-governor.js +30 -0
  143. package/dist/core/sdd/deepagents/backend.d.ts +63 -0
  144. package/dist/core/sdd/deepagents/backend.js +174 -0
  145. package/dist/core/sdd/deepagents/codesdd-tools.d.ts +39 -0
  146. package/dist/core/sdd/deepagents/codesdd-tools.js +83 -0
  147. package/dist/core/sdd/deepagents/evidence-mapper.d.ts +86 -0
  148. package/dist/core/sdd/deepagents/evidence-mapper.js +178 -0
  149. package/dist/core/sdd/deepagents/model-provider.d.ts +53 -0
  150. package/dist/core/sdd/deepagents/model-provider.js +379 -0
  151. package/dist/core/sdd/deepagents/policy-enforcement.d.ts +30 -0
  152. package/dist/core/sdd/deepagents/policy-enforcement.js +90 -0
  153. package/dist/core/sdd/deepagents/policy.d.ts +75 -0
  154. package/dist/core/sdd/deepagents/policy.js +358 -0
  155. package/dist/core/sdd/deepagents/quality-witness.d.ts +3 -0
  156. package/dist/core/sdd/deepagents/quality-witness.js +77 -0
  157. package/dist/core/sdd/deepagents/reversa-subagents.d.ts +75 -0
  158. package/dist/core/sdd/deepagents/reversa-subagents.js +182 -0
  159. package/dist/core/sdd/deepagents/runtime-factory.d.ts +90 -0
  160. package/dist/core/sdd/deepagents/runtime-factory.js +231 -0
  161. package/dist/core/sdd/deepagents/runtime-loader.d.ts +16 -0
  162. package/dist/core/sdd/deepagents/runtime-loader.js +65 -0
  163. package/dist/core/sdd/default-bootstrap-files.d.ts +3 -3
  164. package/dist/core/sdd/default-bootstrap-files.js +50 -10
  165. package/dist/core/sdd/default-skills.d.ts +30 -0
  166. package/dist/core/sdd/default-skills.js +288 -8
  167. package/dist/core/sdd/devtrack-api-appliance.d.ts +91 -0
  168. package/dist/core/sdd/devtrack-api-appliance.js +280 -0
  169. package/dist/core/sdd/devtrack-api-architecture.d.ts +31 -0
  170. package/dist/core/sdd/devtrack-api-architecture.js +608 -0
  171. package/dist/core/sdd/devtrack-api-import-boundary.d.ts +19 -0
  172. package/dist/core/sdd/devtrack-api-import-boundary.js +32 -0
  173. package/dist/core/sdd/diagnose.d.ts +59 -0
  174. package/dist/core/sdd/diagnose.js +37 -37
  175. package/dist/core/sdd/docs-sync.js +54 -20
  176. package/dist/core/sdd/domain/capability-diff.d.ts +63 -0
  177. package/dist/core/sdd/domain/capability-diff.js +200 -0
  178. package/dist/core/sdd/domain/change-safety-guardrails.d.ts +74 -0
  179. package/dist/core/sdd/domain/change-safety-guardrails.js +333 -0
  180. package/dist/core/sdd/domain/post-active-validation.d.ts +7 -0
  181. package/dist/core/sdd/domain/post-active-validation.js +61 -0
  182. package/dist/core/sdd/domain/semantic-intent-classifier.d.ts +29 -0
  183. package/dist/core/sdd/domain/semantic-intent-classifier.js +117 -0
  184. package/dist/core/sdd/domain/transition-engine.js +1 -0
  185. package/dist/core/sdd/entity-reference.d.ts +5 -0
  186. package/dist/core/sdd/entity-reference.js +22 -0
  187. package/dist/core/sdd/foundation-artifact-map-validator.d.ts +16 -0
  188. package/dist/core/sdd/foundation-artifact-map-validator.js +71 -0
  189. package/dist/core/sdd/foundation-layer-manifest.d.ts +24 -0
  190. package/dist/core/sdd/foundation-layer-manifest.js +117 -0
  191. package/dist/core/sdd/governance-backfill.d.ts +31 -0
  192. package/dist/core/sdd/governance-backfill.js +359 -0
  193. package/dist/core/sdd/governance-parser.d.ts +21 -0
  194. package/dist/core/sdd/governance-parser.js +91 -0
  195. package/dist/core/sdd/governance-schemas.d.ts +245 -0
  196. package/dist/core/sdd/governance-schemas.js +143 -0
  197. package/dist/core/sdd/{import-openspec.d.ts → import-legacy-spec.d.ts} +7 -7
  198. package/dist/core/sdd/{import-openspec.js → import-legacy-spec.js} +21 -29
  199. package/dist/core/sdd/init.d.ts +3 -0
  200. package/dist/core/sdd/init.js +6 -3
  201. package/dist/core/sdd/intent-guard.d.ts +22 -0
  202. package/dist/core/sdd/intent-guard.js +67 -0
  203. package/dist/core/sdd/json-schema.js +108 -6
  204. package/dist/core/sdd/knowledge-graph.d.ts +45 -0
  205. package/dist/core/sdd/knowledge-graph.js +288 -0
  206. package/dist/core/sdd/legacy-operations.js +507 -44
  207. package/dist/core/sdd/lenses.d.ts +1 -0
  208. package/dist/core/sdd/lenses.js +29 -1
  209. package/dist/core/sdd/migrate-workspace.js +95 -2
  210. package/dist/core/sdd/migrate.d.ts +1 -1
  211. package/dist/core/sdd/migrate.js +36 -2
  212. package/dist/core/sdd/package-security-gates.d.ts +21 -0
  213. package/dist/core/sdd/package-security-gates.js +119 -0
  214. package/dist/core/sdd/package-structure-gate.d.ts +83 -0
  215. package/dist/core/sdd/package-structure-gate.js +357 -0
  216. package/dist/core/sdd/parallel-feat-automation.d.ts +330 -0
  217. package/dist/core/sdd/parallel-feat-automation.js +424 -0
  218. package/dist/core/sdd/plugin-broker.d.ts +777 -0
  219. package/dist/core/sdd/plugin-broker.js +492 -0
  220. package/dist/core/sdd/plugin-certification.d.ts +79 -0
  221. package/dist/core/sdd/plugin-certification.js +453 -0
  222. package/dist/core/sdd/plugin-cli.d.ts +139 -0
  223. package/dist/core/sdd/plugin-cli.js +265 -0
  224. package/dist/core/sdd/plugin-evidence.d.ts +348 -0
  225. package/dist/core/sdd/plugin-evidence.js +307 -0
  226. package/dist/core/sdd/plugin-manifest.d.ts +232 -0
  227. package/dist/core/sdd/plugin-manifest.js +225 -0
  228. package/dist/core/sdd/plugin-policy-pack.d.ts +88 -0
  229. package/dist/core/sdd/plugin-policy-pack.js +236 -0
  230. package/dist/core/sdd/plugin-policy.d.ts +68 -0
  231. package/dist/core/sdd/plugin-policy.js +212 -0
  232. package/dist/core/sdd/plugin-registry.d.ts +447 -0
  233. package/dist/core/sdd/plugin-registry.js +138 -0
  234. package/dist/core/sdd/plugin-sdk-contract.d.ts +363 -0
  235. package/dist/core/sdd/plugin-sdk-contract.js +268 -0
  236. package/dist/core/sdd/plugin-skill-binding.d.ts +151 -0
  237. package/dist/core/sdd/plugin-skill-binding.js +339 -0
  238. package/dist/core/sdd/quality-artifact-manifest-validator.d.ts +28 -0
  239. package/dist/core/sdd/quality-artifact-manifest-validator.js +167 -0
  240. package/dist/core/sdd/quality-evidence-renderer.d.ts +65 -0
  241. package/dist/core/sdd/quality-evidence-renderer.js +218 -0
  242. package/dist/core/sdd/quality-scenario-runner.d.ts +42 -0
  243. package/dist/core/sdd/quality-scenario-runner.js +613 -0
  244. package/dist/core/sdd/quality-validation.d.ts +620 -0
  245. package/dist/core/sdd/quality-validation.js +239 -0
  246. package/dist/core/sdd/release-readiness.d.ts +19 -0
  247. package/dist/core/sdd/release-readiness.js +472 -0
  248. package/dist/core/sdd/resolve-project-root.d.ts +2 -2
  249. package/dist/core/sdd/resolve-project-root.js +11 -5
  250. package/dist/core/sdd/runtime-boundary-contract.d.ts +45 -0
  251. package/dist/core/sdd/runtime-boundary-contract.js +90 -0
  252. package/dist/core/sdd/sanitize.d.ts +30 -1
  253. package/dist/core/sdd/sanitize.js +23 -23
  254. package/dist/core/sdd/sdk-agent-plugin-quality-gates.d.ts +150 -0
  255. package/dist/core/sdd/sdk-agent-plugin-quality-gates.js +258 -0
  256. package/dist/core/sdd/services/agent-run.service.d.ts +97 -0
  257. package/dist/core/sdd/services/agent-run.service.js +261 -0
  258. package/dist/core/sdd/services/breakdown.service.js +2 -1
  259. package/dist/core/sdd/services/capability-diff.service.d.ts +18 -0
  260. package/dist/core/sdd/services/capability-diff.service.js +26 -0
  261. package/dist/core/sdd/services/change-safety-preflight.service.d.ts +17 -0
  262. package/dist/core/sdd/services/change-safety-preflight.service.js +17 -0
  263. package/dist/core/sdd/services/context.service.d.ts +43 -340
  264. package/dist/core/sdd/services/context.service.js +341 -25
  265. package/dist/core/sdd/services/debate.service.js +15 -2
  266. package/dist/core/sdd/services/feature-lint.service.d.ts +22 -0
  267. package/dist/core/sdd/services/feature-lint.service.js +105 -5
  268. package/dist/core/sdd/services/finalize.service.d.ts +105 -0
  269. package/dist/core/sdd/services/finalize.service.js +499 -38
  270. package/dist/core/sdd/services/frontend-gap.service.js +22 -7
  271. package/dist/core/sdd/services/frontend-impact.service.d.ts +1 -1
  272. package/dist/core/sdd/services/governance-control-plane-runtime-adapters.d.ts +17 -0
  273. package/dist/core/sdd/services/governance-control-plane-runtime-adapters.js +38 -0
  274. package/dist/core/sdd/services/governance-control-plane.service.d.ts +66 -0
  275. package/dist/core/sdd/services/governance-control-plane.service.js +134 -0
  276. package/dist/core/sdd/services/ingest-deposito.service.js +1 -1
  277. package/dist/core/sdd/services/legacy-capability.service.d.ts +10 -7
  278. package/dist/core/sdd/services/legacy-capability.service.js +38 -21
  279. package/dist/core/sdd/services/mcp-runtime.service.d.ts +123 -8
  280. package/dist/core/sdd/services/mcp-runtime.service.js +1085 -33
  281. package/dist/core/sdd/services/onboard.service.js +2 -1
  282. package/dist/core/sdd/services/rebuild.service.js +6 -1
  283. package/dist/core/sdd/services/semantic-intent-classifier.service.d.ts +6 -0
  284. package/dist/core/sdd/services/semantic-intent-classifier.service.js +7 -0
  285. package/dist/core/sdd/services/skills-sync.service.d.ts +17 -5
  286. package/dist/core/sdd/services/skills-sync.service.js +55 -2
  287. package/dist/core/sdd/services/start.service.js +6 -4
  288. package/dist/core/sdd/skill-bundles-curation-schema.d.ts +66 -0
  289. package/dist/core/sdd/skill-bundles-curation-schema.js +52 -0
  290. package/dist/core/sdd/skill-evidence.d.ts +19 -0
  291. package/dist/core/sdd/skill-evidence.js +38 -0
  292. package/dist/core/sdd/skill-policy-pool.d.ts +46 -0
  293. package/dist/core/sdd/skill-policy-pool.js +185 -0
  294. package/dist/core/sdd/state.d.ts +23 -0
  295. package/dist/core/sdd/state.js +313 -66
  296. package/dist/core/sdd/store/sdd-stores.js +2 -2
  297. package/dist/core/sdd/structural-health.d.ts +55 -55
  298. package/dist/core/sdd/types.d.ts +60 -19
  299. package/dist/core/sdd/types.js +21 -0
  300. package/dist/core/sdd/upgrade-to-codesdd.d.ts +45 -0
  301. package/dist/core/sdd/upgrade-to-codesdd.js +179 -0
  302. package/dist/core/sdd/views.js +17 -0
  303. package/dist/core/sdd/workspace-schemas.d.ts +670 -19
  304. package/dist/core/sdd/workspace-schemas.js +285 -5
  305. package/dist/core/sdd/write-manifest.js +22 -4
  306. package/dist/core/shared/skill-generation.d.ts +1 -1
  307. package/dist/core/shared/skill-generation.js +15 -15
  308. package/dist/core/shared/tool-detection.d.ts +3 -3
  309. package/dist/core/shared/tool-detection.js +14 -14
  310. package/dist/core/specs-apply.js +6 -6
  311. package/dist/core/templates/index.d.ts +1 -1
  312. package/dist/core/templates/index.js +1 -1
  313. package/dist/core/templates/workflows/apply-change.js +14 -14
  314. package/dist/core/templates/workflows/archive-change.js +32 -32
  315. package/dist/core/templates/workflows/bulk-archive-change.js +25 -25
  316. package/dist/core/templates/workflows/continue-change.js +12 -12
  317. package/dist/core/templates/workflows/explore.js +29 -29
  318. package/dist/core/templates/workflows/feedback.js +6 -6
  319. package/dist/core/templates/workflows/ff-change.js +24 -24
  320. package/dist/core/templates/workflows/new-change.js +20 -20
  321. package/dist/core/templates/workflows/onboard.js +33 -33
  322. package/dist/core/templates/workflows/propose.js +23 -23
  323. package/dist/core/templates/workflows/sdd.js +8 -8
  324. package/dist/core/templates/workflows/sync-specs.js +19 -19
  325. package/dist/core/templates/workflows/verify-change.js +17 -17
  326. package/dist/core/update.d.ts +2 -2
  327. package/dist/core/update.js +16 -15
  328. package/dist/core/validation/constants.d.ts +1 -1
  329. package/dist/core/validation/constants.js +1 -1
  330. package/dist/core/view.js +11 -11
  331. package/dist/domains/sdd/index.d.ts +6 -0
  332. package/dist/domains/sdd/index.js +6 -0
  333. package/dist/infrastructures/sdd/index.d.ts +7 -0
  334. package/dist/infrastructures/sdd/index.js +6 -0
  335. package/dist/presentations/cli/sdd/index.d.ts +3 -0
  336. package/dist/presentations/cli/sdd/index.js +3 -0
  337. package/dist/shared/sdd/index.d.ts +3 -0
  338. package/dist/shared/sdd/index.js +2 -0
  339. package/dist/telemetry/config.d.ts +2 -1
  340. package/dist/telemetry/config.js +17 -8
  341. package/dist/telemetry/index.d.ts +10 -2
  342. package/dist/telemetry/index.js +40 -7
  343. package/dist/ui/ascii-patterns.d.ts +2 -2
  344. package/dist/ui/ascii-patterns.js +2 -2
  345. package/dist/ui/welcome-screen.js +2 -2
  346. package/dist/utils/change-metadata.d.ts +4 -4
  347. package/dist/utils/change-metadata.js +6 -6
  348. package/dist/utils/change-utils.d.ts +3 -3
  349. package/dist/utils/change-utils.js +5 -5
  350. package/dist/utils/file-system.js +1 -1
  351. package/dist/utils/interactive.js +1 -1
  352. package/dist/utils/item-discovery.js +4 -4
  353. package/dist/utils/legacy-spec-compat.d.ts +2 -0
  354. package/dist/utils/legacy-spec-compat.js +2 -0
  355. package/dist/utils/shell-detection.d.ts +1 -0
  356. package/dist/utils/shell-detection.js +16 -0
  357. package/package.json +34 -21
  358. package/schemas/sdd/1-spec.schema.json +1 -1
  359. package/schemas/sdd/2-plan.schema.json +280 -3
  360. package/schemas/sdd/3-tasks.schema.json +73 -1
  361. package/schemas/sdd/4-changelog.schema.json +1 -1
  362. package/schemas/sdd/5-quality.schema.json +701 -5
  363. package/schemas/sdd/adr.schema.json +148 -0
  364. package/schemas/sdd/agent-binding-adapter.schema.json +210 -0
  365. package/schemas/sdd/agent-binding-resolution.schema.json +338 -0
  366. package/schemas/sdd/agent-runtime-command-plan.schema.json +212 -0
  367. package/schemas/sdd/agent-runtime-opencode-run-evidence.schema.json +270 -0
  368. package/schemas/sdd/backlog-projection-plan.schema.json +180 -0
  369. package/schemas/sdd/backlog-provider-contract.schema.json +260 -0
  370. package/schemas/sdd/codesdd-plugin.schema.json +645 -0
  371. package/schemas/sdd/debate.schema.json +244 -0
  372. package/schemas/sdd/deepagent-decision-evidence.schema.json +58 -0
  373. package/schemas/sdd/deepagent-env-contract.schema.json +143 -0
  374. package/schemas/sdd/deepagent-quality-evidence.schema.json +108 -0
  375. package/schemas/sdd/deepagent-run-evidence.schema.json +192 -0
  376. package/schemas/sdd/deepagent-run-plan.schema.json +197 -0
  377. package/schemas/sdd/deepagent-run-request.schema.json +637 -0
  378. package/schemas/sdd/deepagent-subagent-evidence.schema.json +110 -0
  379. package/schemas/sdd/deepagent-tool-call-evidence.schema.json +78 -0
  380. package/schemas/sdd/discarded.schema.json +127 -0
  381. package/schemas/sdd/epic.schema.json +147 -0
  382. package/schemas/sdd/insight.schema.json +136 -0
  383. package/schemas/sdd/parallel-feat-automation-plan.schema.json +304 -0
  384. package/schemas/sdd/parallel-feat-automation-request.schema.json +109 -0
  385. package/schemas/sdd/parallel-feat-scheduler-request.schema.json +116 -0
  386. package/schemas/sdd/parallel-feat-scheduler-result.schema.json +404 -0
  387. package/schemas/sdd/plugin-artifact-manifest.schema.json +259 -0
  388. package/schemas/sdd/plugin-artifact-map.schema.json +223 -0
  389. package/schemas/sdd/plugin-compliance-index.schema.json +136 -0
  390. package/schemas/sdd/plugin-dry-run-plan.schema.json +260 -0
  391. package/schemas/sdd/plugin-evidence-manifest.schema.json +678 -0
  392. package/schemas/sdd/plugin-language-runtime.schema.json +103 -0
  393. package/schemas/sdd/plugin-package-governance.schema.json +74 -0
  394. package/schemas/sdd/plugin-policy-evaluation.schema.json +92 -0
  395. package/schemas/sdd/plugin-policy-pack-evaluation.schema.json +94 -0
  396. package/schemas/sdd/plugin-policy-pack.schema.json +196 -0
  397. package/schemas/sdd/plugin-registry.schema.json +729 -0
  398. package/schemas/sdd/plugin-rollback-manifest.schema.json +87 -0
  399. package/schemas/sdd/plugin-runtime-invocation-plan.schema.json +954 -0
  400. package/schemas/sdd/plugin-skill-binding-resolution.schema.json +305 -0
  401. package/schemas/sdd/plugin-skill-binding.schema.json +88 -0
  402. package/schemas/sdd/plugin-validation-manifest.schema.json +123 -0
  403. package/schemas/sdd/quality-architecture-schema.schema.json +216 -0
  404. package/schemas/sdd/quality-evidence-bundle.schema.json +1337 -0
  405. package/schemas/sdd/quality-run.schema.json +197 -0
  406. package/schemas/sdd/quality-scenario.schema.json +252 -0
  407. package/schemas/sdd/sdk-agent-plugin-quality-gate-input.schema.json +168 -0
  408. package/schemas/sdd/sdk-agent-plugin-quality-gate-report.schema.json +160 -0
  409. package/schemas/sdd/workspace-catalog.schema.json +13232 -35
  410. package/schemas/spec-driven/schema.yaml +4 -4
  411. package/schemas/spec-driven/templates/proposal.md +1 -1
  412. package/dist/utils/openspec-compat.d.ts +0 -2
  413. package/dist/utils/openspec-compat.js +0 -2
@@ -4,14 +4,14 @@ import path from 'node:path';
4
4
  import { parse as parseYaml } from 'yaml';
5
5
  import { CLI_NAME } from '../branding.js';
6
6
  import { ID_PATTERNS, } from './types.js';
7
- import { loadProjectSddConfig, loadStateSnapshot, resolveSddPaths, } from './state.js';
7
+ import { buildDefaultSkillRoutingState, loadProjectSddConfig, loadStateSnapshot, resolveSddPaths, } from './state.js';
8
8
  import { DEFAULT_CURATED_SKILL_CATALOG } from './default-skills.js';
9
9
  import { renderViews } from './views.js';
10
10
  import { syncSddGuideDocs, validateSddGuideDocs } from './docs-sync.js';
11
11
  import { evaluateWorkspaceTraceability } from './domain/traceability.js';
12
12
  import { detectArchiveArchivedLifecycleCollisions } from './domain/post-active-validation.js';
13
13
  import { parseWorkspaceYamlDocument, workspaceTasksSchema, } from './workspace-schemas.js';
14
- function checkUniqueIds(items, scope, errors) {
14
+ export function checkUniqueIds(items, scope, errors) {
15
15
  const seen = new Set();
16
16
  for (const item of items) {
17
17
  if (seen.has(item.id)) {
@@ -21,7 +21,7 @@ function checkUniqueIds(items, scope, errors) {
21
21
  }
22
22
  }
23
23
  const FORBIDDEN_TITLE_PATTERNS = ['debate:', 'insight:', '(preencher', '(placeholder'];
24
- function hasForbiddenTitleToken(title) {
24
+ export function hasForbiddenTitleToken(title) {
25
25
  const lowered = title.toLowerCase();
26
26
  for (const token of FORBIDDEN_TITLE_PATTERNS) {
27
27
  if (lowered.includes(token))
@@ -29,7 +29,7 @@ function hasForbiddenTitleToken(title) {
29
29
  }
30
30
  return null;
31
31
  }
32
- function validateDiscoveryRecords(records, errors) {
32
+ export function validateDiscoveryRecords(records, errors) {
33
33
  for (const record of records) {
34
34
  if (record.type === 'INS' && !ID_PATTERNS.insight.test(record.id)) {
35
35
  errors.push(`Discovery record ${record.id} is INS but does not follow INS-####`);
@@ -51,7 +51,7 @@ function validateDiscoveryRecords(records, errors) {
51
51
  }
52
52
  }
53
53
  }
54
- function validateBacklog(items, errors, warnings) {
54
+ export function validateBacklog(items, errors, warnings) {
55
55
  const ids = new Set(items.map((item) => item.id));
56
56
  const lockOwners = new Map();
57
57
  for (const item of items) {
@@ -79,7 +79,7 @@ function validateBacklog(items, errors, warnings) {
79
79
  }
80
80
  }
81
81
  }
82
- function validateReferentialIntegrity(snapshot, errors, warnings, isStrict) {
82
+ export function validateReferentialIntegrity(snapshot, errors, warnings, isStrict) {
83
83
  const discoveryIds = new Set(snapshot.discoveryIndex.records.map((record) => record.id));
84
84
  const backlogIds = new Set(snapshot.backlog.items.map((item) => item.id));
85
85
  const frontendGapIds = new Set(snapshot.frontendGaps?.items.map((gap) => gap.id) ?? []);
@@ -122,6 +122,13 @@ function validateReferentialIntegrity(snapshot, errors, warnings, isStrict) {
122
122
  }
123
123
  }
124
124
  }
125
+ if (snapshot.finalizeQueue?.history) {
126
+ for (const fq of snapshot.finalizeQueue.history) {
127
+ if (!backlogIds.has(fq.feature_id)) {
128
+ record(`Finalize history has entry for feature_id="${fq.feature_id}" blocked by an unknown feature.`);
129
+ }
130
+ }
131
+ }
125
132
  if (snapshot.unblockEvents?.events) {
126
133
  for (const ev of snapshot.unblockEvents.events) {
127
134
  if (!backlogIds.has(ev.feature_id)) {
@@ -133,7 +140,7 @@ function validateReferentialIntegrity(snapshot, errors, warnings, isStrict) {
133
140
  }
134
141
  }
135
142
  }
136
- function validateSkillOperationalIntegrity(snapshot, errors) {
143
+ export function validateSkillOperationalIntegrity(snapshot, errors) {
137
144
  const knownSkills = new Set((snapshot.skillCatalog?.skills || []).map((skill) => skill.id));
138
145
  const currentBundles = new Map((snapshot.skillCatalog?.bundles || []).map((bundle) => [bundle.id, bundle]));
139
146
  for (const defaultSkill of DEFAULT_CURATED_SKILL_CATALOG.skills) {
@@ -172,8 +179,28 @@ function validateSkillOperationalIntegrity(snapshot, errors) {
172
179
  }
173
180
  }
174
181
  }
182
+ const currentRoutes = new Map((snapshot.skillRouting?.routes || []).map((route) => [route.domain, route]));
183
+ for (const defaultRoute of buildDefaultSkillRoutingState().routes) {
184
+ const currentRoute = currentRoutes.get(defaultRoute.domain);
185
+ if (!currentRoute) {
186
+ errors.push(`Default skill route "${defaultRoute.domain}" is missing from skill-routing.yaml`);
187
+ continue;
188
+ }
189
+ const currentSkills = currentRoute.skills || [];
190
+ const currentBundles = currentRoute.bundles || [];
191
+ for (const skillId of defaultRoute.skills) {
192
+ if (!currentSkills.includes(skillId)) {
193
+ errors.push(`Default skill route "${defaultRoute.domain}" is missing skill "${skillId}"`);
194
+ }
195
+ }
196
+ for (const bundleId of defaultRoute.bundles) {
197
+ if (!currentBundles.includes(bundleId)) {
198
+ errors.push(`Default skill route "${defaultRoute.domain}" is missing bundle "${bundleId}"`);
199
+ }
200
+ }
201
+ }
175
202
  }
176
- function computeGraphSummary(items) {
203
+ export function computeGraphSummary(items) {
177
204
  const byId = new Map(items.map((item) => [item.id, item]));
178
205
  const runnable = items.filter((item) => {
179
206
  if (item.status === 'DONE' || item.status === 'ARCHIVED')
@@ -226,12 +253,12 @@ function computeGraphSummary(items) {
226
253
  lockConflicts: conflictingIds.size,
227
254
  };
228
255
  }
229
- function roundPercent(done, total) {
256
+ export function roundPercent(done, total) {
230
257
  if (total <= 0)
231
258
  return 0;
232
259
  return Math.round((done / total) * 100);
233
260
  }
234
- function computeProgress(items) {
261
+ export function computeProgress(items) {
235
262
  const activeItems = items.filter((item) => item.status !== 'ARCHIVED');
236
263
  const total = activeItems.length;
237
264
  const done = activeItems.filter((item) => item.status === 'DONE').length;
@@ -262,14 +289,14 @@ function computeProgress(items) {
262
289
  progressByRadar,
263
290
  };
264
291
  }
265
- function validateTechDebt(items, errors) {
292
+ export function validateTechDebt(items, errors) {
266
293
  for (const item of items) {
267
294
  if (!ID_PATTERNS.techDebt.test(item.id)) {
268
295
  errors.push(`Technical debt item ${item.id} does not follow TD-###`);
269
296
  }
270
297
  }
271
298
  }
272
- function validateFrontendReferences(gaps, backlog, errors, warnings) {
299
+ export function validateFrontendReferences(gaps, backlog, errors, warnings) {
273
300
  const gapIds = new Set(gaps.map((g) => g.id));
274
301
  for (const item of backlog) {
275
302
  for (const gapRef of item.frontend_gap_refs) {
@@ -285,7 +312,7 @@ function validateFrontendReferences(gaps, backlog, errors, warnings) {
285
312
  }
286
313
  }
287
314
  }
288
- async function validateActiveTaskChecklist(activeDir, items, warnings) {
315
+ export async function validateActiveTaskChecklist(activeDir, items, warnings) {
289
316
  for (const item of items) {
290
317
  if (item.status !== 'IN_PROGRESS')
291
318
  continue;
@@ -325,7 +352,7 @@ async function validateActiveTaskChecklist(activeDir, items, warnings) {
325
352
  }
326
353
  }
327
354
  }
328
- async function validateWorkspaceCoherence(activeDir, archivedDir, items, warnings) {
355
+ export async function validateWorkspaceCoherence(activeDir, archivedDir, items, warnings) {
329
356
  for (const item of items) {
330
357
  const activePath = path.join(activeDir, item.id);
331
358
  const archivedPath = path.join(archivedDir, item.id);
@@ -342,13 +369,13 @@ async function validateWorkspaceCoherence(activeDir, archivedDir, items, warning
342
369
  }
343
370
  }
344
371
  }
345
- function isPrivacyComplianceBacklogItem(item) {
372
+ export function isPrivacyComplianceBacklogItem(item) {
346
373
  if (item.origin_ref === 'EPIC-0020' || item.origin_ref === 'EPIC-0021')
347
374
  return true;
348
375
  const refs = new Set(item.acceptance_refs || []);
349
376
  return refs.has('EPIC-0020') || refs.has('EPIC-0021') || refs.has('DEB-0021') || refs.has('INS-0021');
350
377
  }
351
- function validatePrivacySourceRegistry(snapshot, warnings) {
378
+ export function validatePrivacySourceRegistry(snapshot, warnings) {
352
379
  const privacyItems = snapshot.backlog.items.filter((item) => item.status !== 'DONE' && item.status !== 'ARCHIVED' && isPrivacyComplianceBacklogItem(item));
353
380
  if (privacyItems.length === 0)
354
381
  return;
@@ -385,7 +412,7 @@ function validatePrivacySourceRegistry(snapshot, warnings) {
385
412
  warnings.push(`Privacy source registry metadata incomplete for: ${missingMetadata.slice(0, 12).join(', ')}${missingMetadata.length > 12 ? ' ...' : ''}`);
386
413
  }
387
414
  }
388
- async function validatePrivacyWorkspaceChecklist(activeDir, items, warnings) {
415
+ export async function validatePrivacyWorkspaceChecklist(activeDir, items, warnings) {
389
416
  const privacyItems = items.filter((item) => item.status === 'IN_PROGRESS' && isPrivacyComplianceBacklogItem(item));
390
417
  for (const item of privacyItems) {
391
418
  const specPath = path.join(activeDir, item.id, '1-spec.yaml');
@@ -433,7 +460,7 @@ async function validatePrivacyWorkspaceChecklist(activeDir, items, warnings) {
433
460
  }
434
461
  }
435
462
  }
436
- async function validateTraceabilityWorkspaceChecklist(projectRoot, activeDir, items, warnings) {
463
+ export async function validateTraceabilityWorkspaceChecklist(projectRoot, activeDir, items, warnings) {
437
464
  const traceabilityItems = items.filter((item) => item.status === 'IN_PROGRESS');
438
465
  for (const item of traceabilityItems) {
439
466
  const specPath = path.join(activeDir, item.id, '1-spec.yaml');
@@ -458,12 +485,12 @@ async function validateTraceabilityWorkspaceChecklist(projectRoot, activeDir, it
458
485
  }
459
486
  }
460
487
  }
461
- function featureRequiresQualityContract(item) {
488
+ export function featureRequiresQualityContract(item) {
462
489
  if (item.status === 'ARCHIVED' || item.status === 'DONE')
463
490
  return false;
464
491
  return Boolean(item.quality_contract) || item.status === 'IN_PROGRESS' || item.origin_ref === 'EPIC-0013';
465
492
  }
466
- async function detectMissingQualityArtifacts(activeDir, items) {
493
+ export async function detectMissingQualityArtifacts(activeDir, items) {
467
494
  const missing = [];
468
495
  for (const item of items) {
469
496
  if (item.status !== 'IN_PROGRESS')
@@ -477,7 +504,7 @@ async function detectMissingQualityArtifacts(activeDir, items) {
477
504
  }
478
505
  return missing;
479
506
  }
480
- function parseRouteToken(value) {
507
+ export function parseRouteToken(value) {
481
508
  const token = value.trim();
482
509
  if (!token)
483
510
  return null;
@@ -494,7 +521,7 @@ function parseRouteToken(value) {
494
521
  return inlineRoute[0];
495
522
  return null;
496
523
  }
497
- function featureHasMetadataFrontendEvidence(item) {
524
+ export function featureHasMetadataFrontendEvidence(item) {
498
525
  const routes = [
499
526
  ...item.produces.map(parseRouteToken),
500
527
  ...item.consumes.map(parseRouteToken),
@@ -506,7 +533,7 @@ function featureHasMetadataFrontendEvidence(item) {
506
533
  item.touches.includes('frontend') ||
507
534
  item.execution_kind === 'frontend_coverage');
508
535
  }
509
- async function validateCanonicalSddStructure(memoryRoot, errors) {
536
+ export async function validateCanonicalSddStructure(memoryRoot, errors) {
510
537
  const forbiddenTopLevelDirs = ['backlog', 'features', 'finalize', 'queue'];
511
538
  for (const dirName of forbiddenTopLevelDirs) {
512
539
  const candidate = path.join(memoryRoot, dirName);
@@ -541,6 +568,8 @@ export class SddCheckCommand {
541
568
  backlog: 0,
542
569
  techDebt: 0,
543
570
  finalizeQueue: 0,
571
+ finalizeQueuePending: 0,
572
+ finalizeQueueDone: 0,
544
573
  frontendEnabled: false,
545
574
  frontendGaps: 0,
546
575
  frontendRoutes: 0,
@@ -618,6 +647,8 @@ export class SddCheckCommand {
618
647
  backlog: 0,
619
648
  techDebt: 0,
620
649
  finalizeQueue: 0,
650
+ finalizeQueuePending: 0,
651
+ finalizeQueueDone: 0,
621
652
  frontendEnabled: config.frontend.enabled,
622
653
  frontendGaps: 0,
623
654
  frontendRoutes: 0,
@@ -658,6 +689,8 @@ export class SddCheckCommand {
658
689
  backlog: 0,
659
690
  techDebt: 0,
660
691
  finalizeQueue: 0,
692
+ finalizeQueuePending: 0,
693
+ finalizeQueueDone: 0,
661
694
  frontendEnabled: config.frontend.enabled,
662
695
  frontendGaps: 0,
663
696
  frontendRoutes: 0,
@@ -796,6 +829,9 @@ export class SddCheckCommand {
796
829
  featuresMissingFgapLink.length === 0;
797
830
  const qualityContractSync = featuresMissingQualityContract.length === 0 &&
798
831
  featuresMissingQualityArtifact.length === 0;
832
+ const finalizeQueuePending = snapshot.finalizeQueue.items.filter((item) => item.status === 'PENDING').length;
833
+ const finalizeQueueDone = snapshot.finalizeQueue.history.length +
834
+ snapshot.finalizeQueue.items.filter((item) => item.status === 'DONE').length;
799
835
  return {
800
836
  valid: errors.length === 0,
801
837
  errors,
@@ -804,7 +840,9 @@ export class SddCheckCommand {
804
840
  discovery: snapshot.discoveryIndex.records.length,
805
841
  backlog: snapshot.backlog.items.length,
806
842
  techDebt: snapshot.techDebt.items.length,
807
- finalizeQueue: snapshot.finalizeQueue.items.length,
843
+ finalizeQueue: finalizeQueuePending,
844
+ finalizeQueuePending,
845
+ finalizeQueueDone,
808
846
  frontendEnabled: config.frontend.enabled,
809
847
  frontendGaps: snapshot.frontendGaps?.items.length ?? 0,
810
848
  frontendRoutes: snapshot.frontendMap?.routes.length ?? 0,
@@ -0,0 +1,13 @@
1
+ export declare const CURRENT_SDD_STATE_VERSION = 3;
2
+ export declare const CURRENT_SDD_CONTRACT_NAME = "codesdd-sdd";
3
+ export declare const CURRENT_CODESDD_MIN_CLI_VERSION = "1.2.2";
4
+ export declare const CURRENT_SDD_LEGACY_COMPATIBILITY = "migration-only";
5
+ export interface SddContractConfig {
6
+ name: string;
7
+ version: number;
8
+ min_cli_version: string;
9
+ legacy_compatibility: string;
10
+ }
11
+ export declare function buildSddContractConfig(): SddContractConfig;
12
+ export declare function sddContractMismatchReasons(value: unknown): string[];
13
+ //# sourceMappingURL=contract.d.ts.map
@@ -0,0 +1,36 @@
1
+ export const CURRENT_SDD_STATE_VERSION = 3;
2
+ export const CURRENT_SDD_CONTRACT_NAME = 'codesdd-sdd';
3
+ export const CURRENT_CODESDD_MIN_CLI_VERSION = '1.2.2';
4
+ export const CURRENT_SDD_LEGACY_COMPATIBILITY = 'migration-only';
5
+ export function buildSddContractConfig() {
6
+ return {
7
+ name: CURRENT_SDD_CONTRACT_NAME,
8
+ version: CURRENT_SDD_STATE_VERSION,
9
+ min_cli_version: CURRENT_CODESDD_MIN_CLI_VERSION,
10
+ legacy_compatibility: CURRENT_SDD_LEGACY_COMPATIBILITY,
11
+ };
12
+ }
13
+ function isRecord(value) {
14
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
15
+ }
16
+ export function sddContractMismatchReasons(value) {
17
+ if (!isRecord(value)) {
18
+ return ['sdd_contract ausente'];
19
+ }
20
+ const expected = buildSddContractConfig();
21
+ const reasons = [];
22
+ if (value.name !== expected.name) {
23
+ reasons.push(`name=${String(value.name || '') || '<empty>'}`);
24
+ }
25
+ if (value.version !== expected.version) {
26
+ reasons.push(`version=${String(value.version || '') || '<empty>'}`);
27
+ }
28
+ if (value.min_cli_version !== expected.min_cli_version) {
29
+ reasons.push(`min_cli_version=${String(value.min_cli_version || '') || '<empty>'}`);
30
+ }
31
+ if (value.legacy_compatibility !== expected.legacy_compatibility) {
32
+ reasons.push(`legacy_compatibility=${String(value.legacy_compatibility || '') || '<empty>'}`);
33
+ }
34
+ return reasons;
35
+ }
36
+ //# sourceMappingURL=contract.js.map
@@ -1,4 +1,7 @@
1
1
  import { type AcquireOptions } from '../state-lock.js';
2
+ import { type GlobalConfig } from '../../global-config.js';
3
+ import { type RedisRuntimeConfig, type RedisRuntimeStatus } from './redis-runtime.js';
4
+ export { resolveRedisBoundaryConfig } from './redis-runtime.js';
2
5
  export interface CoordinationLockAdapter {
3
6
  withLock<T>(scope: string, fn: () => Promise<T>, options?: AcquireOptions): Promise<T>;
4
7
  }
@@ -24,15 +27,16 @@ export interface CoordinationEventBusAdapter {
24
27
  publish(event: CoordinationEvent): Promise<void>;
25
28
  drain(): Promise<CoordinationEvent[]>;
26
29
  }
27
- export interface RedisBoundaryConfig {
28
- requested: boolean;
29
- namespace: string;
30
- url?: string;
31
- }
30
+ export type RedisBoundaryConfig = RedisRuntimeConfig;
32
31
  export interface SddCoordinationAdapters {
33
- mode: 'filesystem';
32
+ mode: 'filesystem' | 'redis' | 'hybrid';
33
+ cacheTier: {
34
+ root: string;
35
+ projectFingerprint: string;
36
+ namespace: string;
37
+ };
34
38
  redis: RedisBoundaryConfig & {
35
- status: 'disabled' | 'requested-unavailable';
39
+ status: RedisRuntimeStatus;
36
40
  reason: string;
37
41
  };
38
42
  locks: CoordinationLockAdapter;
@@ -54,6 +58,36 @@ export declare class InMemoryCoordinationCache implements CoordinationCacheAdapt
54
58
  delete(key: string): Promise<void>;
55
59
  clear(): Promise<void>;
56
60
  }
61
+ export declare class MultiTierCoordinationCache implements CoordinationCacheAdapter {
62
+ private readonly l1Cache;
63
+ private readonly projectFingerprint;
64
+ private readonly configFingerprint;
65
+ private readonly namespace;
66
+ private readonly l2Root;
67
+ constructor(options: {
68
+ projectRoot: string;
69
+ namespace?: string;
70
+ configFingerprint?: string;
71
+ cacheRootDir?: string;
72
+ });
73
+ get<T>(key: string): Promise<T | undefined>;
74
+ set<T>(key: string, value: T, options?: {
75
+ ttlMs?: number;
76
+ }): Promise<void>;
77
+ delete(key: string): Promise<void>;
78
+ clear(): Promise<void>;
79
+ pruneExpired(): Promise<number>;
80
+ describeTierState(): {
81
+ root: string;
82
+ projectFingerprint: string;
83
+ namespace: string;
84
+ };
85
+ private toEntryPath;
86
+ private remainingTtlMs;
87
+ private listEntryFiles;
88
+ private readEntry;
89
+ private safeUnlink;
90
+ }
57
91
  export declare class InMemoryCoordinationQueue<T = unknown> implements CoordinationQueueAdapter<T> {
58
92
  private readonly topics;
59
93
  enqueue(topic: string, item: T): Promise<void>;
@@ -65,9 +99,20 @@ export declare class InMemoryCoordinationEventBus implements CoordinationEventBu
65
99
  publish(event: CoordinationEvent): Promise<void>;
66
100
  drain(): Promise<CoordinationEvent[]>;
67
101
  }
68
- export declare function resolveRedisBoundaryConfig(env?: NodeJS.ProcessEnv): RedisBoundaryConfig;
69
102
  export declare function createFilesystemFirstCoordinationAdapters(options: {
70
103
  stateDir: string;
104
+ projectRoot?: string;
105
+ configFingerprint?: string;
106
+ cacheRootDir?: string;
71
107
  env?: NodeJS.ProcessEnv;
108
+ globalConfig?: Partial<GlobalConfig>;
72
109
  }): SddCoordinationAdapters;
110
+ export declare function createSddCoordinationAdapters(options: {
111
+ stateDir: string;
112
+ projectRoot?: string;
113
+ configFingerprint?: string;
114
+ cacheRootDir?: string;
115
+ env?: NodeJS.ProcessEnv;
116
+ globalConfig?: Partial<GlobalConfig>;
117
+ }): Promise<SddCoordinationAdapters>;
73
118
  //# sourceMappingURL=coordination-adapters.d.ts.map
@@ -1,4 +1,10 @@
1
1
  import { withStateLock } from '../state-lock.js';
2
+ import { createHash } from 'node:crypto';
3
+ import path from 'node:path';
4
+ import { promises as fs } from 'node:fs';
5
+ import { createProjectFingerprint, ensureGlobalCacheLayout, getGlobalCacheDir } from '../../global-config.js';
6
+ import { buildRedisOperationalReport, RedisClientFactory, RedisCoordinationCache, RedisEventBusAdapter, RedisLockAdapter, RedisQueueAdapter, resolveRedisBoundaryConfig, } from './redis-runtime.js';
7
+ export { resolveRedisBoundaryConfig } from './redis-runtime.js';
2
8
  export class FileSystemLockAdapter {
3
9
  stateDir;
4
10
  constructor(stateDir) {
@@ -31,6 +37,131 @@ export class InMemoryCoordinationCache {
31
37
  this.entries.clear();
32
38
  }
33
39
  }
40
+ export class MultiTierCoordinationCache {
41
+ l1Cache = new InMemoryCoordinationCache();
42
+ projectFingerprint;
43
+ configFingerprint;
44
+ namespace;
45
+ l2Root;
46
+ constructor(options) {
47
+ this.projectFingerprint = createProjectFingerprint(options.projectRoot);
48
+ this.configFingerprint = options.configFingerprint ?? 'default';
49
+ this.namespace = options.namespace ?? 'coordination';
50
+ this.l2Root = path.join(options.cacheRootDir ?? getGlobalCacheDir(), 'projects', this.projectFingerprint, this.namespace);
51
+ }
52
+ async get(key) {
53
+ const l1Value = await this.l1Cache.get(key);
54
+ if (typeof l1Value !== 'undefined') {
55
+ return l1Value;
56
+ }
57
+ const filePath = this.toEntryPath(key);
58
+ const diskEntry = await this.readEntry(filePath);
59
+ if (!diskEntry) {
60
+ return undefined;
61
+ }
62
+ const ttlMs = this.remainingTtlMs(diskEntry.expires_at);
63
+ if (ttlMs === 0) {
64
+ await this.safeUnlink(filePath);
65
+ return undefined;
66
+ }
67
+ await this.l1Cache.set(key, diskEntry.value, ttlMs > 0 ? { ttlMs } : {});
68
+ return diskEntry.value;
69
+ }
70
+ async set(key, value, options = {}) {
71
+ await this.l1Cache.set(key, value, options);
72
+ await fs.mkdir(this.l2Root, { recursive: true });
73
+ const entry = {
74
+ schema_version: 1,
75
+ key,
76
+ value,
77
+ created_at: new Date().toISOString(),
78
+ expires_at: options.ttlMs ? new Date(Date.now() + options.ttlMs).toISOString() : undefined,
79
+ project_fingerprint: this.projectFingerprint,
80
+ config_fingerprint: this.configFingerprint,
81
+ namespace: this.namespace,
82
+ };
83
+ await fs.writeFile(this.toEntryPath(key), JSON.stringify(entry), 'utf-8');
84
+ }
85
+ async delete(key) {
86
+ await this.l1Cache.delete(key);
87
+ await this.safeUnlink(this.toEntryPath(key));
88
+ }
89
+ async clear() {
90
+ await this.l1Cache.clear();
91
+ await fs.rm(this.l2Root, { recursive: true, force: true });
92
+ }
93
+ async pruneExpired() {
94
+ const files = await this.listEntryFiles();
95
+ let pruned = 0;
96
+ for (const filePath of files) {
97
+ const entry = await this.readEntry(filePath);
98
+ if (!entry) {
99
+ continue;
100
+ }
101
+ if (this.remainingTtlMs(entry.expires_at) === 0) {
102
+ await this.safeUnlink(filePath);
103
+ pruned += 1;
104
+ }
105
+ }
106
+ return pruned;
107
+ }
108
+ describeTierState() {
109
+ return {
110
+ root: this.l2Root,
111
+ projectFingerprint: this.projectFingerprint,
112
+ namespace: this.namespace,
113
+ };
114
+ }
115
+ toEntryPath(key) {
116
+ const hashedKey = createHash('sha256').update(key).digest('hex');
117
+ return path.join(this.l2Root, `${hashedKey}.json`);
118
+ }
119
+ remainingTtlMs(expiresAtIso) {
120
+ if (!expiresAtIso) {
121
+ return -1;
122
+ }
123
+ const expiresAt = Date.parse(expiresAtIso);
124
+ if (Number.isNaN(expiresAt)) {
125
+ return 0;
126
+ }
127
+ const remaining = expiresAt - Date.now();
128
+ return remaining > 0 ? remaining : 0;
129
+ }
130
+ async listEntryFiles() {
131
+ try {
132
+ const files = await fs.readdir(this.l2Root);
133
+ return files
134
+ .filter((fileName) => fileName.endsWith('.json'))
135
+ .map((fileName) => path.join(this.l2Root, fileName));
136
+ }
137
+ catch {
138
+ return [];
139
+ }
140
+ }
141
+ async readEntry(filePath) {
142
+ try {
143
+ const raw = await fs.readFile(filePath, 'utf-8');
144
+ const parsed = JSON.parse(raw);
145
+ if (parsed.schema_version !== 1 ||
146
+ parsed.project_fingerprint !== this.projectFingerprint ||
147
+ parsed.config_fingerprint !== this.configFingerprint) {
148
+ return undefined;
149
+ }
150
+ return parsed;
151
+ }
152
+ catch {
153
+ return undefined;
154
+ }
155
+ }
156
+ async safeUnlink(filePath) {
157
+ try {
158
+ await fs.unlink(filePath);
159
+ }
160
+ catch {
161
+ // best effort cleanup
162
+ }
163
+ }
164
+ }
34
165
  export class InMemoryCoordinationQueue {
35
166
  topics = new Map();
36
167
  async enqueue(topic, item) {
@@ -57,31 +188,66 @@ export class InMemoryCoordinationEventBus {
57
188
  return this.events.splice(0, this.events.length);
58
189
  }
59
190
  }
60
- export function resolveRedisBoundaryConfig(env = process.env) {
61
- const url = env.CODESDD_REDIS_URL?.trim() || env.REDIS_URL?.trim() || undefined;
62
- const requestedByFlag = env.CODESDD_REDIS_ENABLED === 'true';
63
- const namespace = env.CODESDD_REDIS_NAMESPACE?.trim() || 'codesdd';
64
- return {
65
- requested: Boolean(url || requestedByFlag),
66
- namespace,
67
- url,
68
- };
69
- }
70
191
  export function createFilesystemFirstCoordinationAdapters(options) {
71
- const redis = resolveRedisBoundaryConfig(options.env);
192
+ if (!options.cacheRootDir) {
193
+ ensureGlobalCacheLayout();
194
+ }
195
+ const redis = resolveRedisBoundaryConfig(options.env, options.globalConfig);
196
+ const cache = new MultiTierCoordinationCache({
197
+ projectRoot: options.projectRoot ?? process.cwd(),
198
+ configFingerprint: options.configFingerprint,
199
+ cacheRootDir: options.cacheRootDir,
200
+ });
72
201
  return {
73
202
  mode: 'filesystem',
203
+ cacheTier: cache.describeTierState(),
74
204
  redis: {
75
205
  ...redis,
76
- status: redis.requested ? 'requested-unavailable' : 'disabled',
77
- reason: redis.requested
78
- ? 'Redis adapter boundary is configured but no Redis client adapter is installed; filesystem-first defaults remain authoritative.'
79
- : 'Redis is optional and disabled; filesystem-first defaults are authoritative.',
206
+ status: redis.validationErrors.length > 0 ? 'blocked' : redis.requested ? 'requested-unavailable' : 'disabled',
207
+ reason: redis.validationErrors.length > 0
208
+ ? 'Redis configuration is invalid and was blocked fail-closed.'
209
+ : redis.requested
210
+ ? 'Redis is requested but unavailable; filesystem-first defaults remain authoritative.'
211
+ : 'Redis is optional and disabled; filesystem-first defaults are authoritative.',
80
212
  },
81
213
  locks: new FileSystemLockAdapter(options.stateDir),
82
- cache: new InMemoryCoordinationCache(),
214
+ cache,
83
215
  queues: new InMemoryCoordinationQueue(),
84
216
  events: new InMemoryCoordinationEventBus(),
85
217
  };
86
218
  }
219
+ export async function createSddCoordinationAdapters(options) {
220
+ const filesystem = createFilesystemFirstCoordinationAdapters(options);
221
+ const projectRoot = options.projectRoot ?? process.cwd();
222
+ const redis = resolveRedisBoundaryConfig(options.env, options.globalConfig);
223
+ const report = await buildRedisOperationalReport({
224
+ env: options.env,
225
+ globalConfig: options.globalConfig,
226
+ });
227
+ if (report.status !== 'ready' || !redis.url) {
228
+ return {
229
+ ...filesystem,
230
+ redis: {
231
+ ...redis,
232
+ status: report.status,
233
+ reason: report.reason,
234
+ },
235
+ };
236
+ }
237
+ const projectFingerprint = createProjectFingerprint(projectRoot);
238
+ const factory = new RedisClientFactory(redis);
239
+ return {
240
+ ...filesystem,
241
+ mode: redis.fallback === 'filesystem' ? 'hybrid' : 'redis',
242
+ redis: {
243
+ ...redis,
244
+ status: 'ready',
245
+ reason: report.reason,
246
+ },
247
+ cache: new RedisCoordinationCache(factory, filesystem.cache, projectFingerprint),
248
+ locks: new RedisLockAdapter(factory, filesystem.locks, projectFingerprint),
249
+ queues: new RedisQueueAdapter(factory, filesystem.queues, projectFingerprint),
250
+ events: new RedisEventBusAdapter(factory, filesystem.events, projectFingerprint),
251
+ };
252
+ }
87
253
  //# sourceMappingURL=coordination-adapters.js.map
@@ -1,2 +1,3 @@
1
1
  export * from './coordination-adapters.js';
2
+ export * from './redis-runtime.js';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1,2 +1,3 @@
1
1
  export * from './coordination-adapters.js';
2
+ export * from './redis-runtime.js';
2
3
  //# sourceMappingURL=index.js.map