@mcp-graph-workflow/mcp-graph 5.1.5 → 5.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (228) hide show
  1. package/dist/core/analyzer/ac-parser.d.ts +7 -0
  2. package/dist/core/analyzer/ac-parser.d.ts.map +1 -0
  3. package/dist/core/analyzer/ac-parser.js +67 -0
  4. package/dist/core/analyzer/ac-parser.js.map +1 -0
  5. package/dist/core/analyzer/ac-validator.d.ts +15 -0
  6. package/dist/core/analyzer/ac-validator.d.ts.map +1 -0
  7. package/dist/core/analyzer/ac-validator.js +142 -0
  8. package/dist/core/analyzer/ac-validator.js.map +1 -0
  9. package/dist/core/analyzer/definition-of-ready.d.ts +16 -0
  10. package/dist/core/analyzer/definition-of-ready.d.ts.map +1 -0
  11. package/dist/core/analyzer/definition-of-ready.js +107 -0
  12. package/dist/core/analyzer/definition-of-ready.js.map +1 -0
  13. package/dist/core/analyzer/prd-quality.d.ts +14 -0
  14. package/dist/core/analyzer/prd-quality.d.ts.map +1 -0
  15. package/dist/core/analyzer/prd-quality.js +156 -0
  16. package/dist/core/analyzer/prd-quality.js.map +1 -0
  17. package/dist/core/analyzer/risk-assessment.d.ts +11 -0
  18. package/dist/core/analyzer/risk-assessment.d.ts.map +1 -0
  19. package/dist/core/analyzer/risk-assessment.js +97 -0
  20. package/dist/core/analyzer/risk-assessment.js.map +1 -0
  21. package/dist/core/analyzer/scope-analyzer.d.ts +7 -0
  22. package/dist/core/analyzer/scope-analyzer.d.ts.map +1 -0
  23. package/dist/core/analyzer/scope-analyzer.js +99 -0
  24. package/dist/core/analyzer/scope-analyzer.js.map +1 -0
  25. package/dist/core/config/ai-memory-generator.d.ts.map +1 -1
  26. package/dist/core/config/ai-memory-generator.js +8 -11
  27. package/dist/core/config/ai-memory-generator.js.map +1 -1
  28. package/dist/core/context/context-assembler.d.ts +3 -0
  29. package/dist/core/context/context-assembler.d.ts.map +1 -1
  30. package/dist/core/context/context-assembler.js +5 -2
  31. package/dist/core/context/context-assembler.js.map +1 -1
  32. package/dist/core/context/rag-context.d.ts +4 -2
  33. package/dist/core/context/rag-context.d.ts.map +1 -1
  34. package/dist/core/context/rag-context.js +8 -5
  35. package/dist/core/context/rag-context.js.map +1 -1
  36. package/dist/core/designer/adr-validator.d.ts +8 -0
  37. package/dist/core/designer/adr-validator.d.ts.map +1 -0
  38. package/dist/core/designer/adr-validator.js +61 -0
  39. package/dist/core/designer/adr-validator.js.map +1 -0
  40. package/dist/core/designer/coupling-analyzer.d.ts +7 -0
  41. package/dist/core/designer/coupling-analyzer.d.ts.map +1 -0
  42. package/dist/core/designer/coupling-analyzer.js +59 -0
  43. package/dist/core/designer/coupling-analyzer.js.map +1 -0
  44. package/dist/core/designer/definition-of-ready.d.ts +8 -0
  45. package/dist/core/designer/definition-of-ready.d.ts.map +1 -0
  46. package/dist/core/designer/definition-of-ready.js +146 -0
  47. package/dist/core/designer/definition-of-ready.js.map +1 -0
  48. package/dist/core/designer/interface-checker.d.ts +7 -0
  49. package/dist/core/designer/interface-checker.d.ts.map +1 -0
  50. package/dist/core/designer/interface-checker.js +53 -0
  51. package/dist/core/designer/interface-checker.js.map +1 -0
  52. package/dist/core/designer/tech-risk-assessor.d.ts +7 -0
  53. package/dist/core/designer/tech-risk-assessor.d.ts.map +1 -0
  54. package/dist/core/designer/tech-risk-assessor.js +95 -0
  55. package/dist/core/designer/tech-risk-assessor.js.map +1 -0
  56. package/dist/core/designer/traceability-matrix.d.ts +8 -0
  57. package/dist/core/designer/traceability-matrix.d.ts.map +1 -0
  58. package/dist/core/designer/traceability-matrix.js +67 -0
  59. package/dist/core/designer/traceability-matrix.js.map +1 -0
  60. package/dist/core/events/event-types.d.ts +11 -1
  61. package/dist/core/events/event-types.d.ts.map +1 -1
  62. package/dist/core/handoff/delivery-checklist.d.ts +10 -0
  63. package/dist/core/handoff/delivery-checklist.d.ts.map +1 -0
  64. package/dist/core/handoff/delivery-checklist.js +148 -0
  65. package/dist/core/handoff/delivery-checklist.js.map +1 -0
  66. package/dist/core/handoff/doc-completeness.d.ts +7 -0
  67. package/dist/core/handoff/doc-completeness.d.ts.map +1 -0
  68. package/dist/core/handoff/doc-completeness.js +19 -0
  69. package/dist/core/handoff/doc-completeness.js.map +1 -0
  70. package/dist/core/implementer/definition-of-done.d.ts +11 -0
  71. package/dist/core/implementer/definition-of-done.d.ts.map +1 -0
  72. package/dist/core/implementer/definition-of-done.js +158 -0
  73. package/dist/core/implementer/definition-of-done.js.map +1 -0
  74. package/dist/core/implementer/sprint-progress.d.ts +11 -0
  75. package/dist/core/implementer/sprint-progress.d.ts.map +1 -0
  76. package/dist/core/implementer/sprint-progress.js +80 -0
  77. package/dist/core/implementer/sprint-progress.js.map +1 -0
  78. package/dist/core/implementer/tdd-checker.d.ts +15 -0
  79. package/dist/core/implementer/tdd-checker.d.ts.map +1 -0
  80. package/dist/core/implementer/tdd-checker.js +132 -0
  81. package/dist/core/implementer/tdd-checker.js.map +1 -0
  82. package/dist/core/listener/backlog-health.d.ts +7 -0
  83. package/dist/core/listener/backlog-health.d.ts.map +1 -0
  84. package/dist/core/listener/backlog-health.js +64 -0
  85. package/dist/core/listener/backlog-health.js.map +1 -0
  86. package/dist/core/listener/feedback-readiness.d.ts +11 -0
  87. package/dist/core/listener/feedback-readiness.d.ts.map +1 -0
  88. package/dist/core/listener/feedback-readiness.js +124 -0
  89. package/dist/core/listener/feedback-readiness.js.map +1 -0
  90. package/dist/core/planner/lifecycle-phase.d.ts.map +1 -1
  91. package/dist/core/planner/lifecycle-phase.js +78 -50
  92. package/dist/core/planner/lifecycle-phase.js.map +1 -1
  93. package/dist/core/rag/phase-metadata.d.ts +23 -0
  94. package/dist/core/rag/phase-metadata.d.ts.map +1 -0
  95. package/dist/core/rag/phase-metadata.js +72 -0
  96. package/dist/core/rag/phase-metadata.js.map +1 -0
  97. package/dist/core/rag/phase-summary.d.ts +17 -0
  98. package/dist/core/rag/phase-summary.d.ts.map +1 -0
  99. package/dist/core/rag/phase-summary.js +104 -0
  100. package/dist/core/rag/phase-summary.js.map +1 -0
  101. package/dist/core/rag/prd-indexer.d.ts +16 -0
  102. package/dist/core/rag/prd-indexer.d.ts.map +1 -0
  103. package/dist/core/rag/prd-indexer.js +37 -0
  104. package/dist/core/rag/prd-indexer.js.map +1 -0
  105. package/dist/core/reviewer/review-readiness.d.ts +8 -0
  106. package/dist/core/reviewer/review-readiness.d.ts.map +1 -0
  107. package/dist/core/reviewer/review-readiness.js +159 -0
  108. package/dist/core/reviewer/review-readiness.js.map +1 -0
  109. package/dist/core/store/knowledge-store.d.ts +9 -0
  110. package/dist/core/store/knowledge-store.d.ts.map +1 -1
  111. package/dist/core/store/knowledge-store.js +22 -0
  112. package/dist/core/store/knowledge-store.js.map +1 -1
  113. package/dist/core/validator/definition-of-ready.d.ts +8 -0
  114. package/dist/core/validator/definition-of-ready.d.ts.map +1 -0
  115. package/dist/core/validator/definition-of-ready.js +155 -0
  116. package/dist/core/validator/definition-of-ready.js.map +1 -0
  117. package/dist/core/validator/done-integrity-checker.d.ts +7 -0
  118. package/dist/core/validator/done-integrity-checker.d.ts.map +1 -0
  119. package/dist/core/validator/done-integrity-checker.js +38 -0
  120. package/dist/core/validator/done-integrity-checker.js.map +1 -0
  121. package/dist/core/validator/status-flow-checker.d.ts +7 -0
  122. package/dist/core/validator/status-flow-checker.d.ts.map +1 -0
  123. package/dist/core/validator/status-flow-checker.js +26 -0
  124. package/dist/core/validator/status-flow-checker.js.map +1 -0
  125. package/dist/mcp/lifecycle-wrapper.d.ts +9 -0
  126. package/dist/mcp/lifecycle-wrapper.d.ts.map +1 -1
  127. package/dist/mcp/lifecycle-wrapper.js +27 -2
  128. package/dist/mcp/lifecycle-wrapper.js.map +1 -1
  129. package/dist/mcp/tools/{stats.d.ts → analyze.d.ts} +2 -2
  130. package/dist/mcp/tools/analyze.d.ts.map +1 -0
  131. package/dist/mcp/tools/analyze.js +272 -0
  132. package/dist/mcp/tools/analyze.js.map +1 -0
  133. package/dist/mcp/tools/import-prd.d.ts.map +1 -1
  134. package/dist/mcp/tools/import-prd.js +15 -1
  135. package/dist/mcp/tools/import-prd.js.map +1 -1
  136. package/dist/mcp/tools/index.d.ts.map +1 -1
  137. package/dist/mcp/tools/index.js +6 -10
  138. package/dist/mcp/tools/index.js.map +1 -1
  139. package/dist/mcp/tools/{velocity.d.ts → metrics.d.ts} +2 -2
  140. package/dist/mcp/tools/metrics.d.ts.map +1 -0
  141. package/dist/mcp/tools/metrics.js +69 -0
  142. package/dist/mcp/tools/metrics.js.map +1 -0
  143. package/dist/mcp/tools/next.d.ts.map +1 -1
  144. package/dist/mcp/tools/next.js +19 -5
  145. package/dist/mcp/tools/next.js.map +1 -1
  146. package/dist/mcp/tools/plan-sprint.d.ts.map +1 -1
  147. package/dist/mcp/tools/plan-sprint.js +20 -0
  148. package/dist/mcp/tools/plan-sprint.js.map +1 -1
  149. package/dist/mcp/tools/rag-context.d.ts.map +1 -1
  150. package/dist/mcp/tools/rag-context.js +20 -5
  151. package/dist/mcp/tools/rag-context.js.map +1 -1
  152. package/dist/mcp/tools/set-phase.d.ts.map +1 -1
  153. package/dist/mcp/tools/set-phase.js +16 -1
  154. package/dist/mcp/tools/set-phase.js.map +1 -1
  155. package/dist/mcp/tools/update-status.d.ts.map +1 -1
  156. package/dist/mcp/tools/update-status.js +21 -6
  157. package/dist/mcp/tools/update-status.js.map +1 -1
  158. package/dist/mcp/tools/{decompose.d.ts → validate-ac.d.ts} +2 -2
  159. package/dist/mcp/tools/validate-ac.d.ts.map +1 -0
  160. package/dist/mcp/tools/validate-ac.js +23 -0
  161. package/dist/mcp/tools/validate-ac.js.map +1 -0
  162. package/dist/schemas/ac-quality-schema.d.ts +90 -0
  163. package/dist/schemas/ac-quality-schema.d.ts.map +1 -0
  164. package/dist/schemas/ac-quality-schema.js +34 -0
  165. package/dist/schemas/ac-quality-schema.js.map +1 -0
  166. package/dist/schemas/analyzer-schema.d.ts +160 -0
  167. package/dist/schemas/analyzer-schema.d.ts.map +1 -0
  168. package/dist/schemas/analyzer-schema.js +74 -0
  169. package/dist/schemas/analyzer-schema.js.map +1 -0
  170. package/dist/schemas/designer-schema.d.ts +259 -0
  171. package/dist/schemas/designer-schema.d.ts.map +1 -0
  172. package/dist/schemas/designer-schema.js +102 -0
  173. package/dist/schemas/designer-schema.js.map +1 -0
  174. package/dist/schemas/handoff-schema.d.ts +49 -0
  175. package/dist/schemas/handoff-schema.d.ts.map +1 -0
  176. package/dist/schemas/handoff-schema.js +28 -0
  177. package/dist/schemas/handoff-schema.js.map +1 -0
  178. package/dist/schemas/implementer-schema.d.ts +187 -0
  179. package/dist/schemas/implementer-schema.d.ts.map +1 -0
  180. package/dist/schemas/implementer-schema.js +80 -0
  181. package/dist/schemas/implementer-schema.js.map +1 -0
  182. package/dist/schemas/knowledge.schema.d.ts +8 -0
  183. package/dist/schemas/knowledge.schema.d.ts.map +1 -1
  184. package/dist/schemas/knowledge.schema.js +1 -1
  185. package/dist/schemas/knowledge.schema.js.map +1 -1
  186. package/dist/schemas/listener-schema.d.ts +62 -0
  187. package/dist/schemas/listener-schema.d.ts.map +1 -0
  188. package/dist/schemas/listener-schema.js +35 -0
  189. package/dist/schemas/listener-schema.js.map +1 -0
  190. package/dist/schemas/reviewer-schema.d.ts +34 -0
  191. package/dist/schemas/reviewer-schema.d.ts.map +1 -0
  192. package/dist/schemas/reviewer-schema.js +17 -0
  193. package/dist/schemas/reviewer-schema.js.map +1 -0
  194. package/dist/schemas/validator-schema.d.ts +79 -0
  195. package/dist/schemas/validator-schema.d.ts.map +1 -0
  196. package/dist/schemas/validator-schema.js +43 -0
  197. package/dist/schemas/validator-schema.js.map +1 -0
  198. package/dist/web/dashboard/dist/assets/{benchmark-tab-DzYj_lJO.js → benchmark-tab-DE6hAHVG.js} +1 -1
  199. package/dist/web/dashboard/dist/assets/{gitnexus-tab-B16kDpcc.js → gitnexus-tab-DsBjJHx8.js} +1 -1
  200. package/dist/web/dashboard/dist/assets/graph-tab-C09DzeZ_.js +1 -0
  201. package/dist/web/dashboard/dist/assets/{graph-utils-CETPf3Qj.js → graph-utils-D4LFspTf.js} +5 -5
  202. package/dist/web/dashboard/dist/assets/{index-DLehETrJ.js → index-B2fTJ4AS.js} +2 -2
  203. package/dist/web/dashboard/dist/assets/index-CkqEqKiH.css +1 -0
  204. package/dist/web/dashboard/dist/assets/{insights-tab-MkpvetqF.js → insights-tab-Bm7CDckb.js} +1 -1
  205. package/dist/web/dashboard/dist/assets/{logs-tab-BPDyVj2B.js → logs-tab-Cxpcv_ni.js} +1 -1
  206. package/dist/web/dashboard/dist/assets/{prd-backlog-tab-DbnFo6Ve.js → prd-backlog-tab-X84Rj-IB.js} +1 -1
  207. package/dist/web/dashboard/dist/assets/{serena-tab-CLJOpG5i.js → serena-tab-BunULNvw.js} +1 -1
  208. package/dist/web/dashboard/dist/index.html +2 -2
  209. package/package.json +1 -1
  210. package/dist/mcp/tools/bulk-update-status.d.ts +0 -4
  211. package/dist/mcp/tools/bulk-update-status.d.ts.map +0 -1
  212. package/dist/mcp/tools/bulk-update-status.js +0 -22
  213. package/dist/mcp/tools/bulk-update-status.js.map +0 -1
  214. package/dist/mcp/tools/decompose.d.ts.map +0 -1
  215. package/dist/mcp/tools/decompose.js +0 -25
  216. package/dist/mcp/tools/decompose.js.map +0 -1
  217. package/dist/mcp/tools/dependencies.d.ts +0 -4
  218. package/dist/mcp/tools/dependencies.d.ts.map +0 -1
  219. package/dist/mcp/tools/dependencies.js +0 -47
  220. package/dist/mcp/tools/dependencies.js.map +0 -1
  221. package/dist/mcp/tools/stats.d.ts.map +0 -1
  222. package/dist/mcp/tools/stats.js +0 -46
  223. package/dist/mcp/tools/stats.js.map +0 -1
  224. package/dist/mcp/tools/velocity.d.ts.map +0 -1
  225. package/dist/mcp/tools/velocity.js +0 -25
  226. package/dist/mcp/tools/velocity.js.map +0 -1
  227. package/dist/web/dashboard/dist/assets/graph-tab-bgRao3Qi.js +0 -1
  228. package/dist/web/dashboard/dist/assets/index-D4nxPvv8.css +0 -1
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Design Definition of Ready — composite gate for DESIGN→PLAN transition.
3
+ * Aggregates ADR, traceability, coupling, interface, and risk checks.
4
+ */
5
+ import { validateAdrs } from "./adr-validator.js";
6
+ import { buildTraceabilityMatrix } from "./traceability-matrix.js";
7
+ import { analyzeCoupling } from "./coupling-analyzer.js";
8
+ import { checkInterfaces } from "./interface-checker.js";
9
+ import { assessTechRisks } from "./tech-risk-assessor.js";
10
+ import { detectCycles } from "../planner/dependency-chain.js";
11
+ import { logger } from "../utils/logger.js";
12
+ const GRADE_ORDER = { A: 4, B: 3, C: 2, D: 1, F: 0 };
13
+ function scoreToGrade(score) {
14
+ if (score >= 90)
15
+ return "A";
16
+ if (score >= 75)
17
+ return "B";
18
+ if (score >= 60)
19
+ return "C";
20
+ if (score >= 40)
21
+ return "D";
22
+ return "F";
23
+ }
24
+ export function checkDesignReadiness(doc) {
25
+ const checks = [];
26
+ // ── Required checks (block ready: true) ──
27
+ // 1. Has at least 1 decision
28
+ const hasDecisions = doc.nodes.some((n) => n.type === "decision");
29
+ checks.push({
30
+ name: "has_decisions",
31
+ passed: hasDecisions,
32
+ details: hasDecisions
33
+ ? `${doc.nodes.filter((n) => n.type === "decision").length} decision(s) encontrada(s)`
34
+ : "Nenhum decision node encontrado",
35
+ severity: "required",
36
+ });
37
+ // 2. Has at least 1 constraint
38
+ const hasConstraints = doc.nodes.some((n) => n.type === "constraint");
39
+ checks.push({
40
+ name: "has_constraints",
41
+ passed: hasConstraints,
42
+ details: hasConstraints
43
+ ? `${doc.nodes.filter((n) => n.type === "constraint").length} constraint(s) encontrada(s)`
44
+ : "Nenhum constraint node encontrado",
45
+ severity: "required",
46
+ });
47
+ // 3. No orphan requirements (all requirements have at least 1 edge)
48
+ const requirements = doc.nodes.filter((n) => n.type === "requirement");
49
+ const reqsWithEdges = requirements.filter((req) => doc.edges.some((e) => e.from === req.id || e.to === req.id));
50
+ const noOrphans = requirements.length === 0 || reqsWithEdges.length === requirements.length;
51
+ checks.push({
52
+ name: "no_orphan_requirements",
53
+ passed: noOrphans,
54
+ details: noOrphans
55
+ ? "Todos requirements têm pelo menos 1 edge"
56
+ : `${requirements.length - reqsWithEdges.length} requirement(s) sem edges`,
57
+ severity: "required",
58
+ });
59
+ // 4. No cycles
60
+ const cycles = detectCycles(doc);
61
+ const noCycles = cycles.length === 0;
62
+ checks.push({
63
+ name: "no_cycles",
64
+ passed: noCycles,
65
+ details: noCycles
66
+ ? "Nenhum ciclo de dependência detectado"
67
+ : `${cycles.length} ciclo(s) detectado(s)`,
68
+ severity: "required",
69
+ });
70
+ // 5. ADR quality >= C
71
+ const adrReport = validateAdrs(doc);
72
+ const adrPass = hasDecisions && GRADE_ORDER[adrReport.overallGrade] >= GRADE_ORDER["C"];
73
+ checks.push({
74
+ name: "adr_quality",
75
+ passed: adrPass,
76
+ details: hasDecisions
77
+ ? `ADR grade: ${adrReport.overallGrade} (mínimo: C)`
78
+ : "Sem decisions para avaliar ADR",
79
+ severity: "required",
80
+ });
81
+ // ── Recommended checks (affect score but don't block) ──
82
+ // 6. Traceability coverage >= 80%
83
+ const traceReport = buildTraceabilityMatrix(doc);
84
+ const traceCoveragePass = traceReport.coverageRate >= 80;
85
+ checks.push({
86
+ name: "traceability_coverage",
87
+ passed: traceCoveragePass,
88
+ details: `Cobertura de rastreabilidade: ${traceReport.coverageRate}% (meta: 80%)`,
89
+ severity: "recommended",
90
+ });
91
+ // 7. No isolated nodes
92
+ const couplingReport = analyzeCoupling(doc);
93
+ const noIsolated = couplingReport.isolatedNodes.length === 0;
94
+ checks.push({
95
+ name: "no_isolated_nodes",
96
+ passed: noIsolated,
97
+ details: noIsolated
98
+ ? "Nenhum nó isolado"
99
+ : `${couplingReport.isolatedNodes.length} nó(s) isolado(s)`,
100
+ severity: "recommended",
101
+ });
102
+ // 8. Interface score >= 60
103
+ const ifReport = checkInterfaces(doc);
104
+ const ifPass = ifReport.overallScore >= 60;
105
+ checks.push({
106
+ name: "interface_quality",
107
+ passed: ifPass,
108
+ details: `Interface score: ${ifReport.overallScore} (meta: 60)`,
109
+ severity: "recommended",
110
+ });
111
+ // 9. High risks mitigated
112
+ const riskReport = assessTechRisks(doc);
113
+ const highUnmitigated = riskReport.risks.filter((r) => r.score >= 6 && !r.mitigated);
114
+ const risksPass = highUnmitigated.length === 0;
115
+ checks.push({
116
+ name: "risks_mitigated",
117
+ passed: risksPass,
118
+ details: risksPass
119
+ ? "Todos riscos altos estão mitigados"
120
+ : `${highUnmitigated.length} risco(s) alto(s) sem mitigação`,
121
+ severity: "recommended",
122
+ });
123
+ // 10. Has at least 1 milestone
124
+ const hasMilestones = doc.nodes.some((n) => n.type === "milestone");
125
+ checks.push({
126
+ name: "has_milestones",
127
+ passed: hasMilestones,
128
+ details: hasMilestones
129
+ ? `${doc.nodes.filter((n) => n.type === "milestone").length} milestone(s) encontrado(s)`
130
+ : "Nenhum milestone definido",
131
+ severity: "recommended",
132
+ });
133
+ // ── Scoring ──
134
+ const totalChecks = checks.length;
135
+ const passedChecks = checks.filter((c) => c.passed).length;
136
+ const score = Math.round((passedChecks / totalChecks) * 100);
137
+ const grade = scoreToGrade(score);
138
+ // Ready = all required checks passed
139
+ const ready = checks.filter((c) => c.severity === "required").every((c) => c.passed);
140
+ const summary = ready
141
+ ? `Design Ready (${grade}): ${passedChecks}/${totalChecks} checks passed, score ${score}`
142
+ : `Design Not Ready: ${checks.filter((c) => c.severity === "required" && !c.passed).map((c) => c.name).join(", ")} failed`;
143
+ logger.info("design-readiness", { ready, score, grade, passed: passedChecks, total: totalChecks });
144
+ return { checks, ready, score, grade, summary };
145
+ }
146
+ //# sourceMappingURL=definition-of-ready.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definition-of-ready.js","sourceRoot":"","sources":["../../../src/core/designer/definition-of-ready.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Interface-first checker: validates that contract nodes have description, AC, edges, and constraint links.
3
+ */
4
+ import type { GraphDocument } from "../graph/graph-types.js";
5
+ import type { InterfaceReport } from "../../schemas/designer-schema.js";
6
+ export declare function checkInterfaces(doc: GraphDocument): InterfaceReport;
7
+ //# sourceMappingURL=interface-checker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface-checker.d.ts","sourceRoot":"","sources":["../../../src/core/designer/interface-checker.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAwB,MAAM,kCAAkC,CAAC;AAK9F,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,eAAe,CAsDnE"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Interface-first checker: validates that contract nodes have description, AC, edges, and constraint links.
3
+ */
4
+ import { logger } from "../utils/logger.js";
5
+ const INTERFACE_NODE_TYPES = new Set(["epic", "requirement", "decision"]);
6
+ export function checkInterfaces(doc) {
7
+ const { nodes, edges } = doc;
8
+ const interfaceNodes = nodes.filter((n) => INTERFACE_NODE_TYPES.has(n.type));
9
+ if (interfaceNodes.length === 0) {
10
+ return { results: [], overallScore: 100, nodesWithoutContracts: [] };
11
+ }
12
+ const constraintIds = new Set(nodes.filter((n) => n.type === "constraint").map((n) => n.id));
13
+ // Build node-to-edges map
14
+ const nodeEdges = new Map();
15
+ const nodeConstraintLinks = new Map();
16
+ for (const edge of edges) {
17
+ // Track edges for both from and to
18
+ const fromSet = nodeEdges.get(edge.from) ?? new Set();
19
+ fromSet.add(edge.to);
20
+ nodeEdges.set(edge.from, fromSet);
21
+ const toSet = nodeEdges.get(edge.to) ?? new Set();
22
+ toSet.add(edge.from);
23
+ nodeEdges.set(edge.to, toSet);
24
+ // Track constraint links
25
+ if (constraintIds.has(edge.to)) {
26
+ nodeConstraintLinks.set(edge.from, true);
27
+ }
28
+ if (constraintIds.has(edge.from)) {
29
+ nodeConstraintLinks.set(edge.to, true);
30
+ }
31
+ }
32
+ const results = interfaceNodes.map((node) => {
33
+ const hasDescription = !!node.description && node.description.trim().length > 0;
34
+ const hasAC = !!node.acceptanceCriteria && node.acceptanceCriteria.length > 0;
35
+ const hasEdges = (nodeEdges.get(node.id)?.size ?? 0) > 0;
36
+ const hasConstraintLink = nodeConstraintLinks.get(node.id) ?? false;
37
+ let score = 0;
38
+ if (hasDescription)
39
+ score += 25;
40
+ if (hasAC)
41
+ score += 25;
42
+ if (hasEdges)
43
+ score += 25;
44
+ if (hasConstraintLink)
45
+ score += 25;
46
+ return { nodeId: node.id, hasDescription, hasAC, hasEdges, hasConstraintLink, score };
47
+ });
48
+ const overallScore = Math.round(results.reduce((sum, r) => sum + r.score, 0) / results.length);
49
+ const nodesWithoutContracts = results.filter((r) => r.score < 50).map((r) => r.nodeId);
50
+ logger.info("interface-checker", { evaluated: results.length, overallScore });
51
+ return { results, overallScore, nodesWithoutContracts };
52
+ }
53
+ //# sourceMappingURL=interface-checker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interface-checker.js","sourceRoot":"","sources":["../../../src/core/designer/interface-checker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Tech risk assessor: categorize, score, and infer technical risks from graph structure.
3
+ */
4
+ import type { GraphDocument } from "../graph/graph-types.js";
5
+ import type { TechRiskReport } from "../../schemas/designer-schema.js";
6
+ export declare function assessTechRisks(doc: GraphDocument): TechRiskReport;
7
+ //# sourceMappingURL=tech-risk-assessor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tech-risk-assessor.d.ts","sourceRoot":"","sources":["../../../src/core/designer/tech-risk-assessor.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAwD,MAAM,kCAAkC,CAAC;AAgD7H,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,cAAc,CA0DlE"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Tech risk assessor: categorize, score, and infer technical risks from graph structure.
3
+ */
4
+ import { logger } from "../utils/logger.js";
5
+ const CATEGORY_KEYWORDS = {
6
+ integration: ["integration", "api", "third-party", "external", "webhook", "endpoint"],
7
+ performance: ["performance", "latency", "throughput", "bottleneck", "slow", "cache"],
8
+ security: ["security", "auth", "vulnerability", "injection", "xss", "csrf", "encryption"],
9
+ maturity: ["maturity", "experimental", "beta", "unstable", "new technology", "prototype"],
10
+ complexity: ["complexity", "complex", "coupling", "monolith", "legacy", "refactor"],
11
+ dependency: ["dependency", "dependencies", "vendor", "lock-in", "upgrade", "breaking change"],
12
+ };
13
+ function categorizeRisk(description, tags) {
14
+ const text = `${description} ${tags.join(" ")}`.toLowerCase();
15
+ let bestCategory = "complexity";
16
+ let bestScore = 0;
17
+ for (const [category, keywords] of Object.entries(CATEGORY_KEYWORDS)) {
18
+ const matchCount = keywords.filter((kw) => text.includes(kw)).length;
19
+ if (matchCount > bestScore) {
20
+ bestScore = matchCount;
21
+ bestCategory = category;
22
+ }
23
+ }
24
+ return bestCategory;
25
+ }
26
+ function priorityToProbability(priority) {
27
+ if (priority <= 2)
28
+ return "high";
29
+ if (priority <= 3)
30
+ return "medium";
31
+ return "low";
32
+ }
33
+ const PROBABILITY_VALUE = { low: 1, medium: 2, high: 3 };
34
+ function isRiskMitigated(doc, riskId) {
35
+ const mitigationTypes = new Set(["decision", "constraint"]);
36
+ const nodeTypeMap = new Map(doc.nodes.map((n) => [n.id, n.type]));
37
+ return doc.edges.some((edge) => {
38
+ if (edge.from === riskId && mitigationTypes.has(nodeTypeMap.get(edge.to) ?? ""))
39
+ return true;
40
+ if (edge.to === riskId && mitigationTypes.has(nodeTypeMap.get(edge.from) ?? ""))
41
+ return true;
42
+ return false;
43
+ });
44
+ }
45
+ export function assessTechRisks(doc) {
46
+ const riskNodes = doc.nodes.filter((n) => n.type === "risk");
47
+ const risks = riskNodes.map((node) => {
48
+ const category = categorizeRisk(node.description ?? "", node.tags ?? []);
49
+ const probability = priorityToProbability(node.priority);
50
+ const impact = node.priority <= 2 ? "high" : node.priority <= 3 ? "medium" : "low";
51
+ const score = PROBABILITY_VALUE[probability] * PROBABILITY_VALUE[impact];
52
+ const mitigated = isRiskMitigated(doc, node.id);
53
+ return { nodeId: node.id, category, probability, impact, score, mitigated };
54
+ });
55
+ // Infer risks from graph structure
56
+ const inferredRisks = [];
57
+ // Count fan-out per node
58
+ const fanOutMap = new Map();
59
+ for (const edge of doc.edges) {
60
+ if (edge.relationType === "depends_on") {
61
+ fanOutMap.set(edge.from, (fanOutMap.get(edge.from) ?? 0) + 1);
62
+ }
63
+ }
64
+ const HIGH_FAN_OUT_THRESHOLD = 5;
65
+ for (const [nodeId, fanOut] of fanOutMap) {
66
+ if (fanOut > HIGH_FAN_OUT_THRESHOLD) {
67
+ // High fan-out → complexity risk
68
+ inferredRisks.push({
69
+ nodeId,
70
+ category: "complexity",
71
+ probability: "medium",
72
+ impact: "medium",
73
+ score: 4,
74
+ mitigated: false,
75
+ });
76
+ // High depends_on count → dependency risk
77
+ inferredRisks.push({
78
+ nodeId,
79
+ category: "dependency",
80
+ probability: "medium",
81
+ impact: "medium",
82
+ score: 4,
83
+ mitigated: false,
84
+ });
85
+ }
86
+ }
87
+ const riskScore = risks.reduce((sum, r) => sum + r.score, 0)
88
+ + inferredRisks.reduce((sum, r) => sum + r.score, 0);
89
+ const highRisks = risks
90
+ .filter((r) => r.score >= 6)
91
+ .map((r) => r.nodeId);
92
+ logger.info("tech-risk-assessor", { explicit: risks.length, inferred: inferredRisks.length, riskScore });
93
+ return { risks, inferredRisks, riskScore, highRisks };
94
+ }
95
+ //# sourceMappingURL=tech-risk-assessor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tech-risk-assessor.js","sourceRoot":"","sources":["../../../src/core/designer/tech-risk-assessor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Traceability matrix: requirement → decision → constraint coverage.
3
+ * Follows edges to determine coverage level per requirement.
4
+ */
5
+ import type { GraphDocument } from "../graph/graph-types.js";
6
+ import type { TraceabilityReport } from "../../schemas/designer-schema.js";
7
+ export declare function buildTraceabilityMatrix(doc: GraphDocument): TraceabilityReport;
8
+ //# sourceMappingURL=traceability-matrix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceability-matrix.d.ts","sourceRoot":"","sources":["../../../src/core/designer/traceability-matrix.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,kBAAkB,EAA2C,MAAM,kCAAkC,CAAC;AAmCpH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,aAAa,GAAG,kBAAkB,CAsC9E"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Traceability matrix: requirement → decision → constraint coverage.
3
+ * Follows edges to determine coverage level per requirement.
4
+ */
5
+ import { logger } from "../utils/logger.js";
6
+ const TRACEABILITY_EDGE_TYPES = new Set([
7
+ "implements", "derived_from", "related_to", "depends_on", "parent_of", "child_of",
8
+ ]);
9
+ /**
10
+ * Find all nodes of given types connected to nodeId via traceability edges (both directions).
11
+ */
12
+ function findLinked(doc, nodeId, targetTypes) {
13
+ const linked = new Set();
14
+ const nodeTypeMap = new Map(doc.nodes.map((n) => [n.id, n.type]));
15
+ for (const edge of doc.edges) {
16
+ if (!TRACEABILITY_EDGE_TYPES.has(edge.relationType))
17
+ continue;
18
+ let otherId = null;
19
+ if (edge.from === nodeId)
20
+ otherId = edge.to;
21
+ else if (edge.to === nodeId)
22
+ otherId = edge.from;
23
+ if (otherId && targetTypes.has(nodeTypeMap.get(otherId) ?? "")) {
24
+ linked.add(otherId);
25
+ }
26
+ }
27
+ return [...linked];
28
+ }
29
+ function determineCoverage(linkedDecisions, linkedConstraints) {
30
+ if (linkedDecisions.length > 0 && linkedConstraints.length > 0)
31
+ return "full";
32
+ if (linkedDecisions.length > 0 || linkedConstraints.length > 0)
33
+ return "partial";
34
+ return "none";
35
+ }
36
+ export function buildTraceabilityMatrix(doc) {
37
+ const requirements = doc.nodes.filter((n) => n.type === "requirement");
38
+ const decisions = doc.nodes.filter((n) => n.type === "decision");
39
+ const decisionTypes = new Set(["decision"]);
40
+ const constraintTypes = new Set(["constraint"]);
41
+ const matrix = requirements.map((req) => {
42
+ const linkedDecisions = findLinked(doc, req.id, decisionTypes);
43
+ const linkedConstraints = findLinked(doc, req.id, constraintTypes);
44
+ const coverage = determineCoverage(linkedDecisions, linkedConstraints);
45
+ return {
46
+ requirementId: req.id,
47
+ linkedDecisions,
48
+ linkedConstraints,
49
+ coverage,
50
+ };
51
+ });
52
+ const orphanRequirements = matrix
53
+ .filter((e) => e.coverage === "none")
54
+ .map((e) => e.requirementId);
55
+ const coveredCount = matrix.filter((e) => e.coverage !== "none").length;
56
+ const coverageRate = requirements.length > 0
57
+ ? Math.round((coveredCount / requirements.length) * 10000) / 100
58
+ : 100;
59
+ // Find orphan decisions: not linked to any requirement
60
+ const linkedDecisionIds = new Set(matrix.flatMap((e) => e.linkedDecisions));
61
+ const orphanDecisions = decisions
62
+ .filter((d) => !linkedDecisionIds.has(d.id))
63
+ .map((d) => d.id);
64
+ logger.info("traceability-matrix", { requirements: requirements.length, coverageRate });
65
+ return { matrix, coverageRate, orphanRequirements, orphanDecisions };
66
+ }
67
+ //# sourceMappingURL=traceability-matrix.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"traceability-matrix.js","sourceRoot":"","sources":["../../../src/core/designer/traceability-matrix.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAE5C,MAAM,uBAAuB,GAAG,IAAI,GAAG,CAAC;IACtC,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU;CAClF,CAAC,CAAC;AAEH;;GAEG;AACH,SAAS,UAAU,CAAC,GAAkB,EAAE,MAAc,EAAE,WAAwB;IAC9E,MAAM,MAAM,GAAG,IAAI,GAAG,EAAU,CAAC;IACjC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAElE,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;QAC7B,IAAI,CAAC,uBAAuB,CAAC,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC;YAAE,SAAS;QAE9D,IAAI,OAAO,GAAkB,IAAI,CAAC;QAClC,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM;YAAE,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC;aACvC,IAAI,IAAI,CAAC,EAAE,KAAK,MAAM;YAAE,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC;QAEjD,IAAI,OAAO,IAAI,WAAW,CAAC,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YAC/D,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,MAAM,CAAC,CAAC;AACrB,CAAC;AAED,SAAS,iBAAiB,CAAC,eAAyB,EAAE,iBAA2B;IAC/E,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,MAAM,CAAC;IAC9E,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,iBAAiB,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACjF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,GAAkB;IACxD,MAAM,YAAY,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,aAAa,CAAC,CAAC;IACvE,MAAM,SAAS,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;IAEjE,MAAM,aAAa,GAAG,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC;IAC5C,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;IAEhD,MAAM,MAAM,GAAwB,YAAY,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC3D,MAAM,eAAe,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,aAAa,CAAC,CAAC;QAC/D,MAAM,iBAAiB,GAAG,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;QACnE,MAAM,QAAQ,GAAG,iBAAiB,CAAC,eAAe,EAAE,iBAAiB,CAAC,CAAC;QAEvE,OAAO;YACL,aAAa,EAAE,GAAG,CAAC,EAAE;YACrB,eAAe;YACf,iBAAiB;YACjB,QAAQ;SACT,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,kBAAkB,GAAG,MAAM;SAC9B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC;SACpC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;IAE/B,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IACxE,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC;QAC1C,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,GAAG,KAAK,CAAC,GAAG,GAAG;QAChE,CAAC,CAAC,GAAG,CAAC;IAER,uDAAuD;IACvD,MAAM,iBAAiB,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC;IAC5E,MAAM,eAAe,GAAG,SAAS;SAC9B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,iBAAiB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SAC3C,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAEpB,MAAM,CAAC,IAAI,CAAC,qBAAqB,EAAE,EAAE,YAAY,EAAE,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,CAAC,CAAC;IAExF,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,kBAAkB,EAAE,eAAe,EAAE,CAAC;AACvE,CAAC"}
@@ -1,4 +1,4 @@
1
- export type GraphEventType = "node:created" | "node:updated" | "node:deleted" | "edge:created" | "edge:deleted" | "import:completed" | "bulk:updated" | "knowledge:indexed" | "knowledge:deleted" | "log:entry";
1
+ export type GraphEventType = "node:created" | "node:updated" | "node:deleted" | "edge:created" | "edge:deleted" | "import:completed" | "bulk:updated" | "knowledge:indexed" | "knowledge:deleted" | "phase:transitioned" | "log:entry";
2
2
  export interface GraphEvent {
3
3
  type: GraphEventType;
4
4
  timestamp: string;
@@ -68,6 +68,16 @@ export interface KnowledgeDeletedEvent extends GraphEvent {
68
68
  documentsDeleted: number;
69
69
  };
70
70
  }
71
+ export interface PhaseTransitionedEvent extends GraphEvent {
72
+ type: "phase:transitioned";
73
+ payload: {
74
+ fromPhase: string;
75
+ toPhase: string;
76
+ forced: boolean;
77
+ nodesCount: number;
78
+ doneTasksCount: number;
79
+ };
80
+ }
71
81
  export interface LogEntryEvent extends GraphEvent {
72
82
  type: "log:entry";
73
83
  payload: {
@@ -1 +1 @@
1
- {"version":3,"file":"event-types.d.ts","sourceRoot":"","sources":["../../../src/core/events/event-types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,cAAc,GACtB,cAAc,GACd,cAAc,GACd,cAAc,GACd,cAAc,GACd,cAAc,GACd,kBAAkB,GAClB,cAAc,GACd,mBAAmB,GACnB,mBAAmB,GACnB,WAAW,CAAC;AAEhB,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,cAAc,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;CAC9D;AAED,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAC/C;AAED,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7E;AAED,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7B;AAED,MAAM,WAAW,oBAAqB,SAAQ,UAAU;IACtD,IAAI,EAAE,kBAAkB,CAAC;IACzB,OAAO,EAAE;QAAE,YAAY,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,CAAC;CACzD;AAED,MAAM,WAAW,gBAAiB,SAAQ,UAAU;IAClD,IAAI,EAAE,cAAc,CAAC;IACrB,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED,MAAM,WAAW,qBAAsB,SAAQ,UAAU;IACvD,IAAI,EAAE,mBAAmB,CAAC;IAC1B,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;CACvD;AAED,MAAM,WAAW,qBAAsB,SAAQ,UAAU;IACvD,IAAI,EAAE,mBAAmB,CAAC;IAC1B,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,gBAAgB,EAAE,MAAM,CAAA;KAAE,CAAC;CACvD;AAED,MAAM,WAAW,aAAc,SAAQ,UAAU;IAC/C,IAAI,EAAE,WAAW,CAAC;IAClB,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC;CAC5F"}
1
+ {"version":3,"file":"event-types.d.ts","sourceRoot":"","sources":["../../../src/core/events/event-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Delivery Checklist — composite gate for REVIEW→HANDOFF transition.
3
+ */
4
+ import type { GraphDocument } from "../graph/graph-types.js";
5
+ import type { HandoffReadinessReport } from "../../schemas/handoff-schema.js";
6
+ export interface HandoffReadinessOptions {
7
+ knowledgeCount?: number;
8
+ }
9
+ export declare function checkHandoffReadiness(doc: GraphDocument, opts?: HandoffReadinessOptions): HandoffReadinessReport;
10
+ //# sourceMappingURL=delivery-checklist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delivery-checklist.d.ts","sourceRoot":"","sources":["../../../src/core/handoff/delivery-checklist.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,sBAAsB,EAAyB,MAAM,iCAAiC,CAAC;AAYrG,MAAM,WAAW,uBAAuB;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAUD,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,aAAa,EAClB,IAAI,CAAC,EAAE,uBAAuB,GAC7B,sBAAsB,CAkJxB"}
@@ -0,0 +1,148 @@
1
+ /**
2
+ * Delivery Checklist — composite gate for REVIEW→HANDOFF transition.
3
+ */
4
+ import { assessRisks } from "../analyzer/risk-assessment.js";
5
+ import { analyzeScope } from "../analyzer/scope-analyzer.js";
6
+ import { detectBottlenecks } from "../insights/bottleneck-detector.js";
7
+ import { calculateVelocity } from "../planner/velocity.js";
8
+ import { detectCycles } from "../planner/dependency-chain.js";
9
+ import { checkDocCompleteness } from "./doc-completeness.js";
10
+ import { logger } from "../utils/logger.js";
11
+ const TASK_TYPES = new Set(["task", "subtask"]);
12
+ function scoreToGrade(score) {
13
+ if (score >= 90)
14
+ return "A";
15
+ if (score >= 75)
16
+ return "B";
17
+ if (score >= 60)
18
+ return "C";
19
+ if (score >= 40)
20
+ return "D";
21
+ return "F";
22
+ }
23
+ export function checkHandoffReadiness(doc, opts) {
24
+ const checks = [];
25
+ const tasks = doc.nodes.filter((n) => TASK_TYPES.has(n.type));
26
+ const doneTasks = tasks.filter((n) => n.status === "done");
27
+ // ── Required checks ──
28
+ // 1. all_tasks_done — 100% tasks done
29
+ const allDone = tasks.length > 0 && tasks.every((n) => n.status === "done");
30
+ checks.push({
31
+ name: "all_tasks_done",
32
+ passed: allDone,
33
+ details: allDone
34
+ ? "Todas tasks done"
35
+ : `${doneTasks.length}/${tasks.length} tasks done (100% requerido)`,
36
+ severity: "required",
37
+ });
38
+ // 2. no_blocked_nodes — zero blocked nodes
39
+ const bottlenecks = detectBottlenecks(doc);
40
+ const noBlocked = bottlenecks.blockedTasks.length === 0;
41
+ checks.push({
42
+ name: "no_blocked_nodes",
43
+ passed: noBlocked,
44
+ details: noBlocked
45
+ ? "Nenhum node bloqueado"
46
+ : `${bottlenecks.blockedTasks.length} node(s) bloqueado(s)`,
47
+ severity: "required",
48
+ });
49
+ // 3. no_critical_risks — zero critical/high unmitigated risks
50
+ const riskMatrix = assessRisks(doc);
51
+ const unmitigated = riskMatrix.risks.filter((r) => (r.level === "critical" || r.level === "high") && r.mitigationStatus === "unmitigated");
52
+ const risksPass = unmitigated.length === 0;
53
+ checks.push({
54
+ name: "no_critical_risks",
55
+ passed: risksPass,
56
+ details: risksPass
57
+ ? "Nenhum risco critical/high sem mitigação"
58
+ : `${unmitigated.length} risco(s) critical/high sem mitigação`,
59
+ severity: "required",
60
+ });
61
+ // 4. ac_coverage — ≥80% tasks with AC
62
+ const tasksWithAC = tasks.filter((t) => t.acceptanceCriteria && t.acceptanceCriteria.length > 0);
63
+ const acCoverage = tasks.length > 0 ? Math.round((tasksWithAC.length / tasks.length) * 100) : 100;
64
+ const acPass = acCoverage >= 80;
65
+ checks.push({
66
+ name: "ac_coverage",
67
+ passed: acPass,
68
+ details: `${acCoverage}% tasks com AC (meta: 80%)`,
69
+ severity: "required",
70
+ });
71
+ // 5. no_cycles — no dependency cycles
72
+ const cycles = detectCycles(doc);
73
+ const noCycles = cycles.length === 0;
74
+ checks.push({
75
+ name: "no_cycles",
76
+ passed: noCycles,
77
+ details: noCycles
78
+ ? "Nenhum ciclo de dependência detectado"
79
+ : `${cycles.length} ciclo(s) detectado(s)`,
80
+ severity: "required",
81
+ });
82
+ // ── Recommended checks ──
83
+ // 6. knowledge_captured — knowledge count > 0
84
+ const knowledgeCount = opts?.knowledgeCount ?? 0;
85
+ const knowledgePass = knowledgeCount > 0;
86
+ checks.push({
87
+ name: "knowledge_captured",
88
+ passed: knowledgePass,
89
+ details: knowledgePass
90
+ ? `${knowledgeCount} conhecimento(s) capturado(s)`
91
+ : "Nenhum conhecimento capturado no knowledge store",
92
+ severity: "recommended",
93
+ });
94
+ // 7. milestones_done — ≥1 milestone done
95
+ const milestonesDone = doc.nodes.filter((n) => n.type === "milestone" && n.status === "done");
96
+ const milestonesPass = milestonesDone.length > 0;
97
+ checks.push({
98
+ name: "milestones_done",
99
+ passed: milestonesPass,
100
+ details: milestonesPass
101
+ ? `${milestonesDone.length} milestone(s) concluído(s)`
102
+ : "Nenhum milestone concluído",
103
+ severity: "recommended",
104
+ });
105
+ // 8. scope_clean — zero orphans
106
+ const scopeAnalysis = analyzeScope(doc);
107
+ const noOrphans = scopeAnalysis.orphans.length === 0;
108
+ checks.push({
109
+ name: "scope_clean",
110
+ passed: noOrphans,
111
+ details: noOrphans
112
+ ? "Sem nodes órfãos"
113
+ : `${scopeAnalysis.orphans.length} node(s) órfão(s)`,
114
+ severity: "recommended",
115
+ });
116
+ // 9. velocity_recorded — ≥1 sprint with data
117
+ const velocity = calculateVelocity(doc);
118
+ const velocityPass = velocity.sprints.length > 0;
119
+ checks.push({
120
+ name: "velocity_recorded",
121
+ passed: velocityPass,
122
+ details: velocityPass
123
+ ? `${velocity.sprints.length} sprint(s) com dados de velocidade`
124
+ : "Nenhum sprint com dados de velocidade",
125
+ severity: "recommended",
126
+ });
127
+ // 10. doc_completeness — ≥70% nodes with description
128
+ const docReport = checkDocCompleteness(doc);
129
+ const docPass = docReport.coverageRate >= 70;
130
+ checks.push({
131
+ name: "doc_completeness",
132
+ passed: docPass,
133
+ details: `${docReport.coverageRate}% nodes com description (meta: 70%)`,
134
+ severity: "recommended",
135
+ });
136
+ // ── Scoring ──
137
+ const totalChecks = checks.length;
138
+ const passedChecks = checks.filter((c) => c.passed).length;
139
+ const score = Math.round((passedChecks / totalChecks) * 100);
140
+ const grade = scoreToGrade(score);
141
+ const ready = checks.filter((c) => c.severity === "required").every((c) => c.passed);
142
+ const summary = ready
143
+ ? `Handoff Ready (${grade}): ${passedChecks}/${totalChecks} checks passed, score ${score}`
144
+ : `Handoff Not Ready: ${checks.filter((c) => c.severity === "required" && !c.passed).map((c) => c.name).join(", ")} failed`;
145
+ logger.info("handoff-readiness", { ready, score, grade, passed: passedChecks, total: totalChecks });
146
+ return { checks, ready, score, grade, summary };
147
+ }
148
+ //# sourceMappingURL=delivery-checklist.js.map