@devtrack-solution/codesdd 1.2.2 → 1.2.3

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 (345) hide show
  1. package/.sdd/skills/curated/api-clean-flask-langgraph/SKILL.md +17 -17
  2. package/.sdd/skills/curated/devtrack-api/SKILL.md +160 -28
  3. package/.sdd/skills/curated/devtrack-api/agents/openai.yaml +1 -1
  4. package/.sdd/skills/curated/devtrack-api/references/architecture-governance.md +8 -7
  5. package/.sdd/skills/curated/devtrack-api/references/consumer-sync-policy.md +93 -0
  6. package/.sdd/skills/curated/devtrack-api/references/contract-pack.yaml +317 -0
  7. package/.sdd/skills/curated/devtrack-api/references/field-validation-protocol.md +95 -0
  8. package/.sdd/skills/curated/devtrack-api/references/foundation-layout.md +295 -0
  9. package/.sdd/skills/curated/devtrack-api/references/implementation-checklist.md +4 -4
  10. package/.sdd/skills/curated/devtrack-api/references/imports-lint.md +4 -0
  11. package/.sdd/skills/curated/devtrack-api/references/testing-validation.md +2 -2
  12. package/LICENSE +1 -1
  13. package/README.md +243 -51
  14. package/bin/codesdd.js +3 -2
  15. package/dist/cli/index.d.ts +2 -2
  16. package/dist/cli/index.js +11 -558
  17. package/dist/cli/program.d.ts +14 -0
  18. package/dist/cli/program.js +645 -0
  19. package/dist/commands/change.js +5 -5
  20. package/dist/commands/completion.d.ts +1 -1
  21. package/dist/commands/completion.js +9 -2
  22. package/dist/commands/config.js +159 -20
  23. package/dist/commands/feedback.js +1 -1
  24. package/dist/commands/schema.d.ts +63 -0
  25. package/dist/commands/schema.js +12 -12
  26. package/dist/commands/sdd/backlog.d.ts +3 -0
  27. package/dist/commands/sdd/backlog.js +54 -0
  28. package/dist/commands/sdd/execution.js +147 -16
  29. package/dist/commands/sdd/plugin.d.ts +3 -0
  30. package/dist/commands/sdd/plugin.js +153 -0
  31. package/dist/commands/sdd/shared.js +2 -23
  32. package/dist/commands/sdd/skills.js +7 -0
  33. package/dist/commands/sdd.js +69 -12
  34. package/dist/commands/spec.js +9 -9
  35. package/dist/commands/validate.js +6 -6
  36. package/dist/commands/workflow/instructions.js +6 -6
  37. package/dist/commands/workflow/new-change.js +3 -3
  38. package/dist/commands/workflow/shared.d.ts +1 -1
  39. package/dist/commands/workflow/shared.js +4 -4
  40. package/dist/core/archive.js +15 -5
  41. package/dist/core/artifact-graph/instruction-loader.d.ts +1 -1
  42. package/dist/core/artifact-graph/instruction-loader.js +3 -3
  43. package/dist/core/artifact-graph/resolver.d.ts +4 -4
  44. package/dist/core/artifact-graph/resolver.js +6 -6
  45. package/dist/core/branding.js +3 -3
  46. package/dist/core/cli/command-matrix.js +10 -1
  47. package/dist/core/cli-command-quality.d.ts +27 -0
  48. package/dist/core/cli-command-quality.js +171 -0
  49. package/dist/core/command-generation/adapters/costrict.d.ts +1 -1
  50. package/dist/core/command-generation/adapters/costrict.js +2 -2
  51. package/dist/core/command-generation/types.d.ts +1 -1
  52. package/dist/core/completions/command-registry.d.ts +1 -1
  53. package/dist/core/completions/command-registry.js +155 -12
  54. package/dist/core/completions/completion-provider.d.ts +14 -1
  55. package/dist/core/completions/completion-provider.js +29 -1
  56. package/dist/core/completions/generators/bash-generator.d.ts +1 -1
  57. package/dist/core/completions/generators/bash-generator.js +20 -12
  58. package/dist/core/completions/generators/fish-generator.d.ts +9 -1
  59. package/dist/core/completions/generators/fish-generator.js +39 -25
  60. package/dist/core/completions/generators/powershell-generator.d.ts +1 -1
  61. package/dist/core/completions/generators/powershell-generator.js +21 -11
  62. package/dist/core/completions/generators/zsh-generator.d.ts +3 -6
  63. package/dist/core/completions/generators/zsh-generator.js +21 -42
  64. package/dist/core/completions/installers/bash-installer.js +6 -6
  65. package/dist/core/completions/installers/fish-installer.js +1 -1
  66. package/dist/core/completions/installers/powershell-installer.js +14 -14
  67. package/dist/core/completions/installers/zsh-installer.d.ts +7 -1
  68. package/dist/core/completions/installers/zsh-installer.js +36 -8
  69. package/dist/core/completions/templates/bash-templates.d.ts +1 -1
  70. package/dist/core/completions/templates/bash-templates.js +12 -6
  71. package/dist/core/completions/templates/fish-templates.d.ts +2 -2
  72. package/dist/core/completions/templates/fish-templates.js +20 -9
  73. package/dist/core/completions/templates/powershell-templates.d.ts +1 -1
  74. package/dist/core/completions/templates/powershell-templates.js +13 -4
  75. package/dist/core/completions/templates/zsh-templates.d.ts +1 -1
  76. package/dist/core/completions/templates/zsh-templates.js +18 -9
  77. package/dist/core/config-schema.d.ts +3 -1
  78. package/dist/core/config-schema.js +26 -1
  79. package/dist/core/config.d.ts +3 -3
  80. package/dist/core/config.js +4 -4
  81. package/dist/core/global-config.d.ts +41 -12
  82. package/dist/core/global-config.js +344 -27
  83. package/dist/core/index.d.ts +1 -1
  84. package/dist/core/index.js +2 -2
  85. package/dist/core/init.d.ts +6 -1
  86. package/dist/core/init.js +99 -77
  87. package/dist/core/legacy-cleanup.d.ts +17 -17
  88. package/dist/core/legacy-cleanup.js +96 -79
  89. package/dist/core/list.js +18 -4
  90. package/dist/core/migration.d.ts +3 -1
  91. package/dist/core/migration.js +7 -8
  92. package/dist/core/parsers/change-parser.js +1 -1
  93. package/dist/core/parsers/markdown-parser.js +2 -2
  94. package/dist/core/profile-sync-drift.d.ts +1 -1
  95. package/dist/core/profile-sync-drift.js +13 -13
  96. package/dist/core/project-config.d.ts +4 -4
  97. package/dist/core/project-config.js +11 -11
  98. package/dist/core/schemas/change.schema.d.ts +1 -1
  99. package/dist/core/schemas/change.schema.js +1 -1
  100. package/dist/core/schemas/spec.schema.d.ts +1 -1
  101. package/dist/core/schemas/spec.schema.js +1 -1
  102. package/dist/core/sdd/adr.js +23 -1
  103. package/dist/core/sdd/agent-binding.d.ts +346 -0
  104. package/dist/core/sdd/agent-binding.js +343 -0
  105. package/dist/core/sdd/backlog-cli.d.ts +16 -0
  106. package/dist/core/sdd/backlog-cli.js +146 -0
  107. package/dist/core/sdd/backlog-conflict-policy.d.ts +58 -0
  108. package/dist/core/sdd/backlog-conflict-policy.js +230 -0
  109. package/dist/core/sdd/backlog-projection.d.ts +8 -0
  110. package/dist/core/sdd/backlog-projection.js +89 -0
  111. package/dist/core/sdd/backlog-provider-contract.d.ts +252 -0
  112. package/dist/core/sdd/backlog-provider-contract.js +158 -0
  113. package/dist/core/sdd/bootstrap.js +2 -2
  114. package/dist/core/sdd/check.d.ts +42 -0
  115. package/dist/core/sdd/check.js +22 -22
  116. package/dist/core/sdd/contract.d.ts +13 -0
  117. package/dist/core/sdd/contract.js +36 -0
  118. package/dist/core/sdd/coordination/coordination-adapters.d.ts +38 -0
  119. package/dist/core/sdd/coordination/coordination-adapters.js +139 -1
  120. package/dist/core/sdd/deepagent-contracts.d.ts +276 -0
  121. package/dist/core/sdd/deepagent-contracts.js +173 -0
  122. package/dist/core/sdd/deepagents/adr-governor.d.ts +2 -0
  123. package/dist/core/sdd/deepagents/adr-governor.js +30 -0
  124. package/dist/core/sdd/deepagents/backend.d.ts +63 -0
  125. package/dist/core/sdd/deepagents/backend.js +174 -0
  126. package/dist/core/sdd/deepagents/codesdd-tools.d.ts +39 -0
  127. package/dist/core/sdd/deepagents/codesdd-tools.js +83 -0
  128. package/dist/core/sdd/deepagents/evidence-mapper.d.ts +86 -0
  129. package/dist/core/sdd/deepagents/evidence-mapper.js +178 -0
  130. package/dist/core/sdd/deepagents/model-provider.d.ts +53 -0
  131. package/dist/core/sdd/deepagents/model-provider.js +379 -0
  132. package/dist/core/sdd/deepagents/policy-enforcement.d.ts +30 -0
  133. package/dist/core/sdd/deepagents/policy-enforcement.js +90 -0
  134. package/dist/core/sdd/deepagents/policy.d.ts +75 -0
  135. package/dist/core/sdd/deepagents/policy.js +358 -0
  136. package/dist/core/sdd/deepagents/quality-witness.d.ts +3 -0
  137. package/dist/core/sdd/deepagents/quality-witness.js +77 -0
  138. package/dist/core/sdd/deepagents/reversa-subagents.d.ts +75 -0
  139. package/dist/core/sdd/deepagents/reversa-subagents.js +182 -0
  140. package/dist/core/sdd/deepagents/runtime-factory.d.ts +90 -0
  141. package/dist/core/sdd/deepagents/runtime-factory.js +231 -0
  142. package/dist/core/sdd/deepagents/runtime-loader.d.ts +16 -0
  143. package/dist/core/sdd/deepagents/runtime-loader.js +65 -0
  144. package/dist/core/sdd/default-bootstrap-files.d.ts +2 -2
  145. package/dist/core/sdd/default-bootstrap-files.js +36 -2
  146. package/dist/core/sdd/default-skills.d.ts +30 -0
  147. package/dist/core/sdd/default-skills.js +181 -5
  148. package/dist/core/sdd/devtrack-api-appliance.d.ts +84 -0
  149. package/dist/core/sdd/devtrack-api-appliance.js +257 -0
  150. package/dist/core/sdd/devtrack-api-architecture.d.ts +31 -0
  151. package/dist/core/sdd/devtrack-api-architecture.js +608 -0
  152. package/dist/core/sdd/devtrack-api-import-boundary.d.ts +19 -0
  153. package/dist/core/sdd/devtrack-api-import-boundary.js +32 -0
  154. package/dist/core/sdd/diagnose.d.ts +59 -0
  155. package/dist/core/sdd/diagnose.js +37 -37
  156. package/dist/core/sdd/docs-sync.js +33 -5
  157. package/dist/core/sdd/domain/post-active-validation.d.ts +7 -0
  158. package/dist/core/sdd/domain/post-active-validation.js +61 -0
  159. package/dist/core/sdd/domain/transition-engine.js +1 -0
  160. package/dist/core/sdd/entity-reference.d.ts +5 -0
  161. package/dist/core/sdd/entity-reference.js +22 -0
  162. package/dist/core/sdd/governance-backfill.d.ts +31 -0
  163. package/dist/core/sdd/governance-backfill.js +359 -0
  164. package/dist/core/sdd/governance-parser.d.ts +21 -0
  165. package/dist/core/sdd/governance-parser.js +91 -0
  166. package/dist/core/sdd/governance-schemas.d.ts +245 -0
  167. package/dist/core/sdd/governance-schemas.js +143 -0
  168. package/dist/core/sdd/{import-openspec.d.ts → import-legacy-spec.d.ts} +7 -7
  169. package/dist/core/sdd/{import-openspec.js → import-legacy-spec.js} +21 -29
  170. package/dist/core/sdd/init.d.ts +3 -0
  171. package/dist/core/sdd/init.js +6 -3
  172. package/dist/core/sdd/json-schema.js +100 -6
  173. package/dist/core/sdd/knowledge-graph.d.ts +45 -0
  174. package/dist/core/sdd/knowledge-graph.js +288 -0
  175. package/dist/core/sdd/legacy-operations.js +431 -43
  176. package/dist/core/sdd/lenses.d.ts +1 -0
  177. package/dist/core/sdd/lenses.js +29 -1
  178. package/dist/core/sdd/migrate-workspace.js +56 -2
  179. package/dist/core/sdd/migrate.d.ts +1 -1
  180. package/dist/core/sdd/migrate.js +36 -2
  181. package/dist/core/sdd/package-structure-gate.d.ts +83 -0
  182. package/dist/core/sdd/package-structure-gate.js +362 -0
  183. package/dist/core/sdd/parallel-feat-automation.d.ts +152 -0
  184. package/dist/core/sdd/parallel-feat-automation.js +212 -0
  185. package/dist/core/sdd/plugin-broker.d.ts +558 -0
  186. package/dist/core/sdd/plugin-broker.js +482 -0
  187. package/dist/core/sdd/plugin-certification.d.ts +79 -0
  188. package/dist/core/sdd/plugin-certification.js +453 -0
  189. package/dist/core/sdd/plugin-cli.d.ts +109 -0
  190. package/dist/core/sdd/plugin-cli.js +198 -0
  191. package/dist/core/sdd/plugin-evidence.d.ts +275 -0
  192. package/dist/core/sdd/plugin-evidence.js +307 -0
  193. package/dist/core/sdd/plugin-manifest.d.ts +164 -0
  194. package/dist/core/sdd/plugin-manifest.js +215 -0
  195. package/dist/core/sdd/plugin-policy-pack.d.ts +88 -0
  196. package/dist/core/sdd/plugin-policy-pack.js +236 -0
  197. package/dist/core/sdd/plugin-policy.d.ts +68 -0
  198. package/dist/core/sdd/plugin-policy.js +212 -0
  199. package/dist/core/sdd/plugin-registry.d.ts +311 -0
  200. package/dist/core/sdd/plugin-registry.js +138 -0
  201. package/dist/core/sdd/plugin-skill-binding.d.ts +151 -0
  202. package/dist/core/sdd/plugin-skill-binding.js +339 -0
  203. package/dist/core/sdd/quality-artifact-manifest-validator.d.ts +28 -0
  204. package/dist/core/sdd/quality-artifact-manifest-validator.js +167 -0
  205. package/dist/core/sdd/quality-evidence-renderer.d.ts +65 -0
  206. package/dist/core/sdd/quality-evidence-renderer.js +218 -0
  207. package/dist/core/sdd/quality-scenario-runner.d.ts +42 -0
  208. package/dist/core/sdd/quality-scenario-runner.js +613 -0
  209. package/dist/core/sdd/quality-validation.d.ts +547 -0
  210. package/dist/core/sdd/quality-validation.js +239 -0
  211. package/dist/core/sdd/resolve-project-root.d.ts +2 -2
  212. package/dist/core/sdd/resolve-project-root.js +11 -5
  213. package/dist/core/sdd/sanitize.d.ts +30 -1
  214. package/dist/core/sdd/sanitize.js +23 -23
  215. package/dist/core/sdd/services/agent-run.service.d.ts +65 -0
  216. package/dist/core/sdd/services/agent-run.service.js +189 -0
  217. package/dist/core/sdd/services/breakdown.service.js +2 -1
  218. package/dist/core/sdd/services/context.service.js +18 -16
  219. package/dist/core/sdd/services/debate.service.js +15 -2
  220. package/dist/core/sdd/services/feature-lint.service.d.ts +22 -0
  221. package/dist/core/sdd/services/feature-lint.service.js +105 -5
  222. package/dist/core/sdd/services/finalize.service.d.ts +80 -0
  223. package/dist/core/sdd/services/finalize.service.js +323 -24
  224. package/dist/core/sdd/services/frontend-gap.service.js +22 -7
  225. package/dist/core/sdd/services/governance-control-plane-runtime-adapters.d.ts +17 -0
  226. package/dist/core/sdd/services/governance-control-plane-runtime-adapters.js +38 -0
  227. package/dist/core/sdd/services/governance-control-plane.service.d.ts +66 -0
  228. package/dist/core/sdd/services/governance-control-plane.service.js +134 -0
  229. package/dist/core/sdd/services/ingest-deposito.service.js +1 -1
  230. package/dist/core/sdd/services/legacy-capability.service.d.ts +10 -7
  231. package/dist/core/sdd/services/legacy-capability.service.js +38 -21
  232. package/dist/core/sdd/services/mcp-runtime.service.d.ts +123 -8
  233. package/dist/core/sdd/services/mcp-runtime.service.js +1085 -33
  234. package/dist/core/sdd/services/onboard.service.js +2 -1
  235. package/dist/core/sdd/services/rebuild.service.js +6 -1
  236. package/dist/core/sdd/services/skills-sync.service.d.ts +17 -5
  237. package/dist/core/sdd/services/skills-sync.service.js +55 -2
  238. package/dist/core/sdd/services/start.service.js +6 -4
  239. package/dist/core/sdd/skill-bundles-curation-schema.d.ts +66 -0
  240. package/dist/core/sdd/skill-bundles-curation-schema.js +52 -0
  241. package/dist/core/sdd/skill-evidence.d.ts +19 -0
  242. package/dist/core/sdd/skill-evidence.js +38 -0
  243. package/dist/core/sdd/skill-policy-pool.d.ts +46 -0
  244. package/dist/core/sdd/skill-policy-pool.js +185 -0
  245. package/dist/core/sdd/state.d.ts +22 -0
  246. package/dist/core/sdd/state.js +66 -41
  247. package/dist/core/sdd/structural-health.d.ts +42 -42
  248. package/dist/core/sdd/types.d.ts +33 -7
  249. package/dist/core/sdd/types.js +17 -0
  250. package/dist/core/sdd/upgrade-to-codesdd.d.ts +45 -0
  251. package/dist/core/sdd/upgrade-to-codesdd.js +179 -0
  252. package/dist/core/sdd/workspace-schemas.d.ts +285 -14
  253. package/dist/core/sdd/workspace-schemas.js +148 -0
  254. package/dist/core/sdd/write-manifest.js +22 -4
  255. package/dist/core/shared/skill-generation.d.ts +1 -1
  256. package/dist/core/shared/skill-generation.js +15 -15
  257. package/dist/core/shared/tool-detection.d.ts +3 -3
  258. package/dist/core/shared/tool-detection.js +14 -14
  259. package/dist/core/specs-apply.js +6 -6
  260. package/dist/core/templates/index.d.ts +1 -1
  261. package/dist/core/templates/index.js +1 -1
  262. package/dist/core/templates/workflows/apply-change.js +14 -14
  263. package/dist/core/templates/workflows/archive-change.js +32 -32
  264. package/dist/core/templates/workflows/bulk-archive-change.js +25 -25
  265. package/dist/core/templates/workflows/continue-change.js +12 -12
  266. package/dist/core/templates/workflows/explore.js +29 -29
  267. package/dist/core/templates/workflows/feedback.js +6 -6
  268. package/dist/core/templates/workflows/ff-change.js +24 -24
  269. package/dist/core/templates/workflows/new-change.js +20 -20
  270. package/dist/core/templates/workflows/onboard.js +33 -33
  271. package/dist/core/templates/workflows/propose.js +23 -23
  272. package/dist/core/templates/workflows/sdd.js +8 -8
  273. package/dist/core/templates/workflows/sync-specs.js +19 -19
  274. package/dist/core/templates/workflows/verify-change.js +17 -17
  275. package/dist/core/update.d.ts +2 -2
  276. package/dist/core/update.js +16 -15
  277. package/dist/core/validation/constants.d.ts +1 -1
  278. package/dist/core/validation/constants.js +1 -1
  279. package/dist/core/view.js +11 -11
  280. package/dist/telemetry/config.d.ts +2 -1
  281. package/dist/telemetry/config.js +17 -8
  282. package/dist/telemetry/index.d.ts +10 -2
  283. package/dist/telemetry/index.js +40 -7
  284. package/dist/ui/ascii-patterns.d.ts +2 -2
  285. package/dist/ui/ascii-patterns.js +2 -2
  286. package/dist/ui/welcome-screen.js +2 -2
  287. package/dist/utils/change-metadata.d.ts +4 -4
  288. package/dist/utils/change-metadata.js +6 -6
  289. package/dist/utils/change-utils.d.ts +3 -3
  290. package/dist/utils/change-utils.js +5 -5
  291. package/dist/utils/file-system.js +1 -1
  292. package/dist/utils/interactive.js +1 -1
  293. package/dist/utils/item-discovery.js +4 -4
  294. package/dist/utils/legacy-spec-compat.d.ts +2 -0
  295. package/dist/utils/legacy-spec-compat.js +2 -0
  296. package/dist/utils/shell-detection.d.ts +1 -0
  297. package/dist/utils/shell-detection.js +16 -0
  298. package/package.json +27 -17
  299. package/schemas/sdd/1-spec.schema.json +1 -1
  300. package/schemas/sdd/2-plan.schema.json +73 -1
  301. package/schemas/sdd/3-tasks.schema.json +73 -1
  302. package/schemas/sdd/4-changelog.schema.json +1 -1
  303. package/schemas/sdd/5-quality.schema.json +442 -2
  304. package/schemas/sdd/adr.schema.json +148 -0
  305. package/schemas/sdd/agent-binding-adapter.schema.json +210 -0
  306. package/schemas/sdd/agent-binding-resolution.schema.json +338 -0
  307. package/schemas/sdd/backlog-projection-plan.schema.json +180 -0
  308. package/schemas/sdd/backlog-provider-contract.schema.json +260 -0
  309. package/schemas/sdd/codesdd-plugin.schema.json +474 -0
  310. package/schemas/sdd/debate.schema.json +244 -0
  311. package/schemas/sdd/deepagent-decision-evidence.schema.json +58 -0
  312. package/schemas/sdd/deepagent-env-contract.schema.json +143 -0
  313. package/schemas/sdd/deepagent-quality-evidence.schema.json +108 -0
  314. package/schemas/sdd/deepagent-run-evidence.schema.json +192 -0
  315. package/schemas/sdd/deepagent-run-plan.schema.json +197 -0
  316. package/schemas/sdd/deepagent-run-request.schema.json +321 -0
  317. package/schemas/sdd/deepagent-subagent-evidence.schema.json +110 -0
  318. package/schemas/sdd/deepagent-tool-call-evidence.schema.json +78 -0
  319. package/schemas/sdd/discarded.schema.json +127 -0
  320. package/schemas/sdd/epic.schema.json +147 -0
  321. package/schemas/sdd/insight.schema.json +136 -0
  322. package/schemas/sdd/parallel-feat-automation-plan.schema.json +215 -0
  323. package/schemas/sdd/parallel-feat-automation-request.schema.json +109 -0
  324. package/schemas/sdd/plugin-artifact-manifest.schema.json +150 -0
  325. package/schemas/sdd/plugin-compliance-index.schema.json +136 -0
  326. package/schemas/sdd/plugin-dry-run-plan.schema.json +260 -0
  327. package/schemas/sdd/plugin-evidence-manifest.schema.json +569 -0
  328. package/schemas/sdd/plugin-policy-evaluation.schema.json +92 -0
  329. package/schemas/sdd/plugin-policy-pack-evaluation.schema.json +94 -0
  330. package/schemas/sdd/plugin-policy-pack.schema.json +196 -0
  331. package/schemas/sdd/plugin-registry.schema.json +558 -0
  332. package/schemas/sdd/plugin-rollback-manifest.schema.json +87 -0
  333. package/schemas/sdd/plugin-runtime-invocation-plan.schema.json +845 -0
  334. package/schemas/sdd/plugin-skill-binding-resolution.schema.json +305 -0
  335. package/schemas/sdd/plugin-skill-binding.schema.json +88 -0
  336. package/schemas/sdd/plugin-validation-manifest.schema.json +123 -0
  337. package/schemas/sdd/quality-architecture-schema.schema.json +216 -0
  338. package/schemas/sdd/quality-evidence-bundle.schema.json +1228 -0
  339. package/schemas/sdd/quality-run.schema.json +197 -0
  340. package/schemas/sdd/quality-scenario.schema.json +252 -0
  341. package/schemas/sdd/workspace-catalog.schema.json +9841 -22
  342. package/schemas/spec-driven/schema.yaml +4 -4
  343. package/schemas/spec-driven/templates/proposal.md +1 -1
  344. package/dist/utils/openspec-compat.d.ts +0 -2
  345. package/dist/utils/openspec-compat.js +0 -2
@@ -0,0 +1,613 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { pluginArtifactManifestSchema, } from './plugin-broker.js';
3
+ import { pluginComplianceIndexSchema, pluginValidationManifestSchema, } from './plugin-evidence.js';
4
+ import { parseQualityArchitectureSchema, parseQualityEvidenceBundle, parseQualityRun, parseQualityScenario, } from './quality-validation.js';
5
+ const KNOWN_EVIDENCE_KEYS = new Set([
6
+ 'artifact_manifest',
7
+ 'validation_manifest',
8
+ 'compliance_index',
9
+ 'architecture_schema',
10
+ 'filesystem_snapshot',
11
+ 'import_graph',
12
+ 'command_log',
13
+ 'checksums',
14
+ ]);
15
+ const WARNING_ONLY_PLUGIN_REF = {
16
+ id: 'codesdd-warning-only-runner',
17
+ version: '0.0.0',
18
+ };
19
+ export function runQualityScenarioWarningOnly(input) {
20
+ const scenario = parseQualityScenario(input.scenario);
21
+ const startedAt = toIsoTimestamp(input.startedAt ?? new Date());
22
+ const finishedAt = toIsoTimestamp(input.finishedAt ?? input.startedAt ?? new Date(startedAt));
23
+ const runId = input.runId ?? buildRunId(startedAt, scenario.id);
24
+ const featureRef = input.featureRef ?? scenario.feature_ref;
25
+ if (!featureRef) {
26
+ throw new Error(`Quality scenario ${scenario.id} must declare feature_ref or receive featureRef.`);
27
+ }
28
+ const artifactManifest = input.artifactManifest
29
+ ? pluginArtifactManifestSchema.parse(input.artifactManifest)
30
+ : undefined;
31
+ const validationManifest = input.validationManifest
32
+ ? pluginValidationManifestSchema.parse(input.validationManifest)
33
+ : undefined;
34
+ const complianceIndex = input.complianceIndex
35
+ ? pluginComplianceIndexSchema.parse(input.complianceIndex)
36
+ : undefined;
37
+ const architectureSchema = input.architectureResult?.schema
38
+ ? parseQualityArchitectureSchema(input.architectureResult.schema)
39
+ : undefined;
40
+ const reportRoot = `.sdd/reports/quality-runs/${runId}`;
41
+ const commandLogRef = `${reportRoot}/command-log.txt`;
42
+ const commandArgv = input.commandArgv ?? [
43
+ 'codesdd',
44
+ 'sdd',
45
+ 'validate-quality',
46
+ '--scenario',
47
+ scenario.id,
48
+ '--warning-only',
49
+ ];
50
+ const findings = [
51
+ warningFinding({
52
+ code: 'QUALITY_WARNING_ONLY_RUNNER',
53
+ message: `Scenario ${scenario.id} was evaluated by the warning-only runner without plugin spawn, apply, or filesystem writes.`,
54
+ remediation: 'Review warnings and promote checks to enforced validation only after the baseline is accepted.',
55
+ }),
56
+ ];
57
+ collectArtifactManifestFindings({
58
+ scenario,
59
+ featureRef,
60
+ artifactManifest,
61
+ findings,
62
+ });
63
+ collectArchitectureFindings({
64
+ scenario,
65
+ architectureResult: input.architectureResult,
66
+ architectureSchema,
67
+ findings,
68
+ });
69
+ collectValidationFindings(validationManifest, findings);
70
+ collectComplianceFindings(complianceIndex, findings);
71
+ const syntheticEvidence = collectSyntheticEvidenceNeeds({
72
+ scenario,
73
+ artifactManifest,
74
+ validationManifest,
75
+ complianceIndex,
76
+ architectureSchema,
77
+ architectureResult: input.architectureResult,
78
+ findings,
79
+ });
80
+ const effectiveArtifactManifest = artifactManifest ?? (syntheticEvidence.artifact_manifest
81
+ ? buildSyntheticArtifactManifest({ scenario, featureRef, generatedAt: startedAt })
82
+ : undefined);
83
+ const effectiveValidationManifest = validationManifest ?? (syntheticEvidence.validation_manifest
84
+ ? buildSyntheticValidationManifest({
85
+ scenario,
86
+ featureRef,
87
+ generatedAt: startedAt,
88
+ artifactManifest: effectiveArtifactManifest,
89
+ })
90
+ : undefined);
91
+ const effectiveComplianceIndex = complianceIndex ?? (syntheticEvidence.compliance_index
92
+ ? buildSyntheticComplianceIndex({ scenario, featureRef, generatedAt: startedAt })
93
+ : undefined);
94
+ const effectiveArchitectureSchema = architectureSchema ?? (syntheticEvidence.architecture_schema
95
+ ? buildSyntheticArchitectureSchema(scenario)
96
+ : undefined);
97
+ const artifacts = buildRunArtifactRefs({
98
+ reportRoot,
99
+ scenario,
100
+ artifactManifest: effectiveArtifactManifest,
101
+ architectureResult: input.architectureResult,
102
+ });
103
+ const filesystemSnapshot = buildEvidenceFilesystemSnapshot({
104
+ reportRoot,
105
+ artifactManifest: effectiveArtifactManifest,
106
+ architectureResult: input.architectureResult,
107
+ });
108
+ const importGraph = buildEvidenceImportGraph({
109
+ architectureResult: input.architectureResult,
110
+ filesystemSnapshot,
111
+ scenario,
112
+ });
113
+ const checksums = buildEvidenceChecksums({
114
+ commandLogRef,
115
+ commandArgv,
116
+ artifactManifest: effectiveArtifactManifest,
117
+ });
118
+ const run = parseQualityRun({
119
+ schema_version: 1,
120
+ run_id: runId,
121
+ scenario_ref: scenario.id,
122
+ feature_ref: featureRef,
123
+ started_at: startedAt,
124
+ finished_at: finishedAt,
125
+ mode: scenario.mode,
126
+ status: 'warning',
127
+ plugin_ref: effectiveArtifactManifest
128
+ ? {
129
+ id: effectiveArtifactManifest.plugin_ref.id,
130
+ version: effectiveArtifactManifest.plugin_ref.version,
131
+ capability: effectiveArtifactManifest.capability,
132
+ }
133
+ : undefined,
134
+ command: {
135
+ argv: commandArgv,
136
+ cwd: input.cwd ?? '.',
137
+ env_keys: [],
138
+ },
139
+ schema_versions: {
140
+ scenario: String(scenario.schema_version),
141
+ run: '1',
142
+ evidence_bundle: '1',
143
+ artifact_manifest: effectiveArtifactManifest ? String(effectiveArtifactManifest.schema_version) : 'absent',
144
+ architecture_schema: effectiveArchitectureSchema ? String(effectiveArchitectureSchema.schema_version) : 'absent',
145
+ },
146
+ artifacts,
147
+ findings,
148
+ evidence_bundle_path: `${reportRoot}/evidence-bundle.yaml`,
149
+ metadata: {
150
+ warning_only: true,
151
+ spawned_process: false,
152
+ applied_changes: false,
153
+ synthetic_evidence: syntheticEvidence,
154
+ ...input.metadata,
155
+ },
156
+ });
157
+ const evidenceBundle = parseQualityEvidenceBundle({
158
+ schema_version: 1,
159
+ run,
160
+ scenario,
161
+ architecture_schema: effectiveArchitectureSchema,
162
+ artifact_manifest: effectiveArtifactManifest,
163
+ validation_manifest: effectiveValidationManifest,
164
+ compliance_index: effectiveComplianceIndex,
165
+ filesystem_snapshot: filesystemSnapshot,
166
+ import_graph: importGraph,
167
+ command_log_ref: commandLogRef,
168
+ exceptions: [],
169
+ checksums,
170
+ });
171
+ return {
172
+ run,
173
+ evidence_bundle: evidenceBundle,
174
+ };
175
+ }
176
+ function collectArtifactManifestFindings(input) {
177
+ const { scenario, featureRef, artifactManifest, findings } = input;
178
+ if (!artifactManifest) {
179
+ if (scenario.expected_artifacts.some((artifact) => artifact.required)) {
180
+ findings.push(warningFinding({
181
+ code: 'QUALITY_ARTIFACT_MANIFEST_MISSING',
182
+ message: `Scenario ${scenario.id} declares expected artifacts but no artifact manifest was provided.`,
183
+ remediation: 'Attach an artifact manifest from the dry-run/apply planning path before enforcing artifact gates.',
184
+ }));
185
+ }
186
+ return;
187
+ }
188
+ if (artifactManifest.feature_ref !== featureRef) {
189
+ findings.push(warningFinding({
190
+ code: 'QUALITY_ARTIFACT_FEATURE_MISMATCH',
191
+ message: `Artifact manifest feature_ref ${artifactManifest.feature_ref} does not match run feature_ref ${featureRef}.`,
192
+ remediation: 'Regenerate the artifact manifest for the same feature as the quality scenario.',
193
+ }));
194
+ }
195
+ if (artifactManifest.mode !== 'dry-run') {
196
+ findings.push(warningFinding({
197
+ code: 'QUALITY_ARTIFACT_MODE_NOT_DRY_RUN',
198
+ message: `Artifact manifest mode is ${artifactManifest.mode}; the warning-only runner did not execute apply.`,
199
+ remediation: 'Use dry-run artifact evidence for warning-only baselines, or review external apply evidence separately.',
200
+ }));
201
+ }
202
+ for (const validation of artifactManifest.validation_evidence) {
203
+ if (validation.status === 'passed')
204
+ continue;
205
+ findings.push(warningFinding({
206
+ code: `QUALITY_ARTIFACT_VALIDATION_${validation.status.toUpperCase().replace(/-/gu, '_')}`,
207
+ message: `Artifact manifest validation "${validation.command}" is ${validation.status}.`,
208
+ remediation: 'Run or replace pending/skipped/failed validation evidence before enabling hard gates.',
209
+ }));
210
+ }
211
+ const artifactPaths = artifactManifest.artifacts.map((artifact) => artifact.path);
212
+ for (const expectedArtifact of scenario.expected_artifacts) {
213
+ if (!expectedArtifact.required)
214
+ continue;
215
+ const matchingArtifacts = artifactManifest.artifacts.filter((artifact) => globToRegExp(expectedArtifact.path_pattern).test(normalizeRelativePath(artifact.path)));
216
+ if (matchingArtifacts.length === 0) {
217
+ findings.push(warningFinding({
218
+ code: 'QUALITY_EXPECTED_ARTIFACT_UNVERIFIED',
219
+ message: `No artifact manifest entry matched required pattern "${expectedArtifact.path_pattern}".`,
220
+ remediation: 'Add the generated artifact to the manifest or update the scenario expectation.',
221
+ path: expectedArtifact.path_pattern,
222
+ }));
223
+ continue;
224
+ }
225
+ if (expectedArtifact.checksum_required) {
226
+ for (const artifact of matchingArtifacts) {
227
+ if (!artifact.checksum_after) {
228
+ findings.push(warningFinding({
229
+ code: 'QUALITY_EXPECTED_CHECKSUM_MISSING',
230
+ message: `Artifact "${artifact.path}" matched ${expectedArtifact.path_pattern} but has no checksum_after.`,
231
+ remediation: 'Regenerate the artifact manifest with checksums before enforcing checksum gates.',
232
+ path: artifact.path,
233
+ }));
234
+ }
235
+ }
236
+ }
237
+ }
238
+ for (const artifactPath of artifactPaths) {
239
+ if (!isSafeRelativePath(normalizeRelativePath(artifactPath))) {
240
+ findings.push(warningFinding({
241
+ code: 'QUALITY_ARTIFACT_PATH_UNSAFE',
242
+ message: `Artifact path "${artifactPath}" is unsafe for project-relative evidence.`,
243
+ remediation: 'Use a project-relative artifact path without absolute roots or traversal segments.',
244
+ path: artifactPath,
245
+ }));
246
+ }
247
+ }
248
+ }
249
+ function collectArchitectureFindings(input) {
250
+ const { scenario, architectureResult, architectureSchema, findings } = input;
251
+ if (!architectureResult) {
252
+ if (scenario.required_evidence.includes('architecture_schema')) {
253
+ findings.push(warningFinding({
254
+ code: 'QUALITY_ARCHITECTURE_RESULT_MISSING',
255
+ message: `Scenario ${scenario.id} requires architecture evidence but no architecture result was provided.`,
256
+ remediation: 'Attach an architecture result before promoting the scenario to enforced validation.',
257
+ }));
258
+ }
259
+ return;
260
+ }
261
+ if (!architectureSchema && scenario.required_evidence.includes('architecture_schema')) {
262
+ findings.push(warningFinding({
263
+ code: 'QUALITY_ARCHITECTURE_SCHEMA_MISSING',
264
+ message: `Architecture result for ${scenario.id} did not include a schema.`,
265
+ remediation: 'Attach the architecture gateway schema used to evaluate this scenario.',
266
+ }));
267
+ }
268
+ if (architectureResult.status && architectureResult.status !== 'passed') {
269
+ findings.push(warningFinding({
270
+ code: 'QUALITY_ARCHITECTURE_RESULT_WARNING',
271
+ message: `Architecture result status is ${architectureResult.status}; warning-only mode recorded it without blocking.`,
272
+ remediation: 'Resolve architecture findings before switching this scenario to an enforced gate.',
273
+ }));
274
+ }
275
+ for (const finding of architectureResult.findings ?? []) {
276
+ findings.push(warningFinding({
277
+ code: normalizeIssueCode(finding.code),
278
+ message: finding.message,
279
+ remediation: finding.remediation ?? 'Resolve this architecture finding before enabling hard gates.',
280
+ path: finding.path,
281
+ gate_id: finding.gate_id,
282
+ }));
283
+ }
284
+ }
285
+ function collectValidationFindings(validationManifest, findings) {
286
+ if (!validationManifest)
287
+ return;
288
+ if (validationManifest.status !== 'passed') {
289
+ findings.push(warningFinding({
290
+ code: 'QUALITY_VALIDATION_MANIFEST_WARNING',
291
+ message: `Validation manifest status is ${validationManifest.status}.`,
292
+ remediation: 'Complete validation evidence before promoting the scenario to enforced gates.',
293
+ }));
294
+ }
295
+ for (const validation of validationManifest.validations) {
296
+ if (validation.status === 'passed')
297
+ continue;
298
+ findings.push(warningFinding({
299
+ code: `QUALITY_VALIDATION_${validation.status.toUpperCase().replace(/-/gu, '_')}`,
300
+ message: `Validation "${validation.command}" is ${validation.status}.`,
301
+ remediation: 'Run or replace pending/skipped/failed validation evidence before enabling hard gates.',
302
+ }));
303
+ }
304
+ }
305
+ function collectComplianceFindings(complianceIndex, findings) {
306
+ if (!complianceIndex)
307
+ return;
308
+ if (complianceIndex.decision !== 'compliant') {
309
+ findings.push(warningFinding({
310
+ code: 'QUALITY_COMPLIANCE_INDEX_WARNING',
311
+ message: `Compliance index decision is ${complianceIndex.decision} with score ${complianceIndex.score}.`,
312
+ remediation: 'Resolve compliance criteria before promoting the scenario to enforced gates.',
313
+ }));
314
+ }
315
+ for (const criterion of complianceIndex.criteria) {
316
+ if (criterion.status === 'pass')
317
+ continue;
318
+ findings.push(warningFinding({
319
+ code: normalizeIssueCode(`QUALITY_COMPLIANCE_${criterion.id}`),
320
+ message: `Compliance criterion "${criterion.label}" is ${criterion.status}.`,
321
+ remediation: 'Resolve this compliance criterion before enabling hard gates.',
322
+ }));
323
+ }
324
+ }
325
+ function collectSyntheticEvidenceNeeds(input) {
326
+ const syntheticEvidence = {};
327
+ for (const evidenceKey of input.scenario.required_evidence) {
328
+ if (!KNOWN_EVIDENCE_KEYS.has(evidenceKey))
329
+ continue;
330
+ const missing = evidenceKey === 'artifact_manifest' ? !input.artifactManifest
331
+ : evidenceKey === 'validation_manifest' ? !input.validationManifest
332
+ : evidenceKey === 'compliance_index' ? !input.complianceIndex
333
+ : evidenceKey === 'architecture_schema' ? !input.architectureSchema
334
+ : false;
335
+ if (!missing)
336
+ continue;
337
+ syntheticEvidence[evidenceKey] = true;
338
+ input.findings.push(warningFinding({
339
+ code: normalizeIssueCode(`QUALITY_${evidenceKey}_SYNTHETIC`),
340
+ message: `Required evidence "${evidenceKey}" was not supplied; warning-only mode attached a synthetic placeholder.`,
341
+ remediation: `Provide real ${evidenceKey} evidence before enforcing this quality scenario.`,
342
+ }));
343
+ }
344
+ if (input.scenario.required_evidence.includes('import_graph')) {
345
+ const graph = input.architectureResult?.import_graph;
346
+ if (!graph || (graph.nodes.length === 0 && graph.edges.length === 0)) {
347
+ syntheticEvidence.import_graph = true;
348
+ input.findings.push(warningFinding({
349
+ code: 'QUALITY_IMPORT_GRAPH_SYNTHETIC',
350
+ message: 'Required import_graph evidence was not supplied; warning-only mode derived a minimal graph.',
351
+ remediation: 'Provide a real import graph before enforcing architecture or dependency gates.',
352
+ }));
353
+ }
354
+ }
355
+ if (input.scenario.required_evidence.includes('checksums')) {
356
+ const hasManifestChecksum = input.artifactManifest?.artifacts.some((artifact) => Boolean(artifact.checksum_after));
357
+ if (!hasManifestChecksum) {
358
+ syntheticEvidence.checksums = true;
359
+ input.findings.push(warningFinding({
360
+ code: 'QUALITY_CHECKSUMS_SYNTHETIC',
361
+ message: 'Required checksum evidence was not supplied; warning-only mode checksummed the command log reference.',
362
+ remediation: 'Provide artifact checksums before enforcing checksum gates.',
363
+ }));
364
+ }
365
+ }
366
+ return syntheticEvidence;
367
+ }
368
+ function buildRunArtifactRefs(input) {
369
+ const refs = new Set([
370
+ `${input.reportRoot}/run.json`,
371
+ `${input.reportRoot}/evidence-bundle.yaml`,
372
+ `${input.reportRoot}/command-log.txt`,
373
+ ]);
374
+ for (const artifact of input.artifactManifest?.artifacts ?? []) {
375
+ const normalized = normalizeRelativePath(artifact.path);
376
+ if (isSafeRelativePath(normalized))
377
+ refs.add(normalized);
378
+ }
379
+ for (const artifact of input.architectureResult?.artifacts ?? []) {
380
+ const normalized = normalizeRelativePath(artifact);
381
+ if (isSafeRelativePath(normalized))
382
+ refs.add(normalized);
383
+ }
384
+ for (const evidenceKey of input.scenario.required_evidence) {
385
+ if (!KNOWN_EVIDENCE_KEYS.has(evidenceKey)) {
386
+ refs.add(`${input.reportRoot}/${slugify(evidenceKey)}.txt`);
387
+ }
388
+ }
389
+ return [...refs];
390
+ }
391
+ function buildEvidenceFilesystemSnapshot(input) {
392
+ const byPath = new Map();
393
+ for (const file of input.architectureResult?.filesystem_snapshot?.files ?? []) {
394
+ const normalized = normalizeRelativePath(file.path);
395
+ if (isSafeRelativePath(normalized)) {
396
+ byPath.set(normalized, {
397
+ ...file,
398
+ path: normalized,
399
+ });
400
+ }
401
+ }
402
+ for (const artifact of input.artifactManifest?.artifacts ?? []) {
403
+ const normalized = normalizeRelativePath(artifact.path);
404
+ if (isSafeRelativePath(normalized) && artifact.operation !== 'deleted') {
405
+ byPath.set(normalized, {
406
+ path: normalized,
407
+ size_bytes: 0,
408
+ sha256: artifact.checksum_after,
409
+ });
410
+ }
411
+ }
412
+ for (const reportPath of [
413
+ `${input.reportRoot}/run.json`,
414
+ `${input.reportRoot}/evidence-bundle.yaml`,
415
+ `${input.reportRoot}/command-log.txt`,
416
+ ]) {
417
+ byPath.set(reportPath, {
418
+ path: reportPath,
419
+ size_bytes: 0,
420
+ });
421
+ }
422
+ return {
423
+ root: '.',
424
+ files: [...byPath.values()],
425
+ };
426
+ }
427
+ function buildEvidenceImportGraph(input) {
428
+ const graph = input.architectureResult?.import_graph;
429
+ if (graph && (graph.nodes.length > 0 || graph.edges.length > 0)) {
430
+ return graph;
431
+ }
432
+ const nodes = new Set();
433
+ if (input.scenario.input.fixture_path) {
434
+ nodes.add(input.scenario.input.fixture_path);
435
+ }
436
+ for (const file of input.filesystemSnapshot.files.slice(0, 10)) {
437
+ nodes.add(file.path);
438
+ }
439
+ return {
440
+ nodes: [...nodes],
441
+ edges: [],
442
+ };
443
+ }
444
+ function buildEvidenceChecksums(input) {
445
+ const checksums = new Map();
446
+ checksums.set(input.commandLogRef, sha256(input.commandArgv.join('\n')));
447
+ for (const artifact of input.artifactManifest?.artifacts ?? []) {
448
+ const normalized = normalizeRelativePath(artifact.path);
449
+ if (artifact.checksum_after && isSafeRelativePath(normalized)) {
450
+ checksums.set(normalized, artifact.checksum_after);
451
+ }
452
+ }
453
+ return [...checksums.entries()].map(([path, checksum]) => ({
454
+ path,
455
+ sha256: checksum,
456
+ }));
457
+ }
458
+ function buildSyntheticArtifactManifest(input) {
459
+ return pluginArtifactManifestSchema.parse({
460
+ schema_version: 1,
461
+ operation_id: syntheticOperationId(input.scenario),
462
+ generated_at: input.generatedAt,
463
+ feature_ref: input.featureRef,
464
+ plugin_ref: WARNING_ONLY_PLUGIN_REF,
465
+ capability: 'quality.scenario.warning-only',
466
+ mode: 'dry-run',
467
+ status: 'planned',
468
+ artifacts: [],
469
+ validation_evidence: [],
470
+ });
471
+ }
472
+ function buildSyntheticValidationManifest(input) {
473
+ return pluginValidationManifestSchema.parse({
474
+ schema_version: 1,
475
+ operation_id: input.artifactManifest?.operation_id ?? syntheticOperationId(input.scenario),
476
+ generated_at: input.generatedAt,
477
+ feature_ref: input.featureRef,
478
+ plugin_ref: input.artifactManifest?.plugin_ref ?? WARNING_ONLY_PLUGIN_REF,
479
+ capability: input.artifactManifest?.capability ?? 'quality.scenario.warning-only',
480
+ status: 'partial',
481
+ validations: [],
482
+ });
483
+ }
484
+ function buildSyntheticComplianceIndex(input) {
485
+ return pluginComplianceIndexSchema.parse({
486
+ schema_version: 1,
487
+ generated_at: input.generatedAt,
488
+ feature_ref: input.featureRef,
489
+ operation_id: syntheticOperationId(input.scenario),
490
+ plugin_ref: WARNING_ONLY_PLUGIN_REF,
491
+ capability: 'quality.scenario.warning-only',
492
+ score: 0,
493
+ decision: 'warning',
494
+ criteria: [
495
+ {
496
+ id: 'warning-only-baseline',
497
+ label: 'Warning-only baseline',
498
+ status: 'warn',
499
+ score: 0,
500
+ max_score: 1,
501
+ evidence: 'Synthetic compliance evidence recorded by warning-only quality scenario runner.',
502
+ issues: ['QUALITY_COMPLIANCE_INDEX_SYNTHETIC'],
503
+ },
504
+ ],
505
+ evidence_refs: [`quality:${input.scenario.id}`],
506
+ });
507
+ }
508
+ function buildSyntheticArchitectureSchema(scenario) {
509
+ return parseQualityArchitectureSchema({
510
+ schema_version: 1,
511
+ id: `ARCH-GATE-${slugify(scenario.id)}`,
512
+ title: `${scenario.title} warning-only architecture baseline`,
513
+ stack: 'warning-only',
514
+ authority: scenario.authority,
515
+ applies_to: {},
516
+ layers: {
517
+ baseline: {
518
+ path_patterns: ['**/*'],
519
+ allowed_file_patterns: [],
520
+ forbidden_file_patterns: [],
521
+ allowed_imports: [],
522
+ forbidden_imports: [],
523
+ required_evidence: ['warning-only'],
524
+ },
525
+ },
526
+ exceptions: {
527
+ require_adr: false,
528
+ require_expiration: false,
529
+ allowed_refs: [],
530
+ },
531
+ update_policy: {
532
+ owner: 'codesdd-quality-runner',
533
+ review_trigger: 'Replace synthetic warning-only architecture evidence before enforcing gates.',
534
+ },
535
+ });
536
+ }
537
+ function warningFinding(input) {
538
+ return {
539
+ code: normalizeIssueCode(input.code),
540
+ severity: 'warn',
541
+ message: input.message,
542
+ remediation: input.remediation,
543
+ path: input.path && isSafeRelativePath(normalizeRelativePath(input.path))
544
+ ? normalizeRelativePath(input.path)
545
+ : undefined,
546
+ gate_id: input.gate_id,
547
+ };
548
+ }
549
+ function buildRunId(startedAt, scenarioId) {
550
+ const timestamp = startedAt
551
+ .replace(/[-:]/gu, '')
552
+ .replace(/\.\d{3}Z$/u, 'z')
553
+ .replace('T', 't');
554
+ return `qrun-${timestamp}-${slugify(scenarioId)}`;
555
+ }
556
+ function toIsoTimestamp(value) {
557
+ return value instanceof Date ? value.toISOString() : new Date(value).toISOString();
558
+ }
559
+ function syntheticOperationId(scenario) {
560
+ return `quality-${slugify(scenario.id)}`;
561
+ }
562
+ function normalizeIssueCode(value) {
563
+ const normalized = value
564
+ .trim()
565
+ .replace(/[^A-Za-z0-9]+/gu, '_')
566
+ .replace(/^_+|_+$/gu, '')
567
+ .toUpperCase();
568
+ return normalized || 'QUALITY_WARNING';
569
+ }
570
+ function normalizeRelativePath(value) {
571
+ return value.replace(/\\/gu, '/').replace(/^\.\//u, '');
572
+ }
573
+ function isSafeRelativePath(value) {
574
+ return Boolean(value)
575
+ && !value.startsWith('/')
576
+ && !/^[A-Za-z]:[\\/]/u.test(value)
577
+ && !value.split('/').some((segment) => segment === '..');
578
+ }
579
+ function globToRegExp(pattern) {
580
+ const normalized = normalizeRelativePath(pattern);
581
+ let source = '';
582
+ for (let index = 0; index < normalized.length; index += 1) {
583
+ const char = normalized[index];
584
+ const next = normalized[index + 1];
585
+ if (char === '*' && next === '*') {
586
+ source += '.*';
587
+ index += 1;
588
+ continue;
589
+ }
590
+ if (char === '*') {
591
+ source += '[^/]*';
592
+ continue;
593
+ }
594
+ source += escapeRegExp(char);
595
+ }
596
+ return new RegExp(`^${source}$`, 'u');
597
+ }
598
+ function escapeRegExp(value) {
599
+ return value.replace(/[|\\{}()[\]^$+?.]/gu, '\\$&');
600
+ }
601
+ function slugify(value) {
602
+ const slug = value
603
+ .toLowerCase()
604
+ .replace(/[^a-z0-9]+/gu, '-')
605
+ .replace(/^-+|-+$/gu, '');
606
+ return slug || 'quality';
607
+ }
608
+ function sha256(value) {
609
+ const hash = createHash('sha256');
610
+ hash.update(value);
611
+ return hash.digest('hex');
612
+ }
613
+ //# sourceMappingURL=quality-scenario-runner.js.map