musubi-sdd 5.0.0 → 5.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) hide show
  1. package/README.ja.md +106 -48
  2. package/README.md +110 -32
  3. package/bin/musubi-analyze.js +74 -67
  4. package/bin/musubi-browser.js +27 -26
  5. package/bin/musubi-change.js +48 -47
  6. package/bin/musubi-checkpoint.js +10 -7
  7. package/bin/musubi-convert.js +25 -25
  8. package/bin/musubi-costs.js +27 -10
  9. package/bin/musubi-gui.js +52 -46
  10. package/bin/musubi-init.js +1952 -10
  11. package/bin/musubi-orchestrate.js +327 -239
  12. package/bin/musubi-remember.js +69 -56
  13. package/bin/musubi-resolve.js +53 -45
  14. package/bin/musubi-trace.js +51 -22
  15. package/bin/musubi-validate.js +39 -30
  16. package/bin/musubi-workflow.js +33 -34
  17. package/bin/musubi.js +39 -2
  18. package/package.json +1 -1
  19. package/src/agents/agent-loop.js +94 -95
  20. package/src/agents/agentic/code-generator.js +119 -109
  21. package/src/agents/agentic/code-reviewer.js +105 -108
  22. package/src/agents/agentic/index.js +4 -4
  23. package/src/agents/browser/action-executor.js +13 -13
  24. package/src/agents/browser/ai-comparator.js +11 -10
  25. package/src/agents/browser/context-manager.js +6 -6
  26. package/src/agents/browser/index.js +5 -5
  27. package/src/agents/browser/nl-parser.js +31 -46
  28. package/src/agents/browser/screenshot.js +2 -2
  29. package/src/agents/browser/test-generator.js +6 -4
  30. package/src/agents/function-tool.js +71 -65
  31. package/src/agents/index.js +7 -7
  32. package/src/agents/schema-generator.js +98 -94
  33. package/src/analyzers/ast-extractor.js +164 -145
  34. package/src/analyzers/codegraph-auto-update.js +858 -0
  35. package/src/analyzers/complexity-analyzer.js +536 -0
  36. package/src/analyzers/context-optimizer.js +247 -125
  37. package/src/analyzers/impact-analyzer.js +1 -1
  38. package/src/analyzers/large-project-analyzer.js +766 -0
  39. package/src/analyzers/repository-map.js +83 -80
  40. package/src/analyzers/security-analyzer.js +19 -11
  41. package/src/analyzers/stuck-detector.js +19 -17
  42. package/src/converters/index.js +78 -57
  43. package/src/converters/ir/types.js +12 -12
  44. package/src/converters/parsers/musubi-parser.js +134 -126
  45. package/src/converters/parsers/openapi-parser.js +70 -53
  46. package/src/converters/parsers/speckit-parser.js +239 -175
  47. package/src/converters/writers/musubi-writer.js +123 -118
  48. package/src/converters/writers/speckit-writer.js +124 -113
  49. package/src/generators/rust-migration-generator.js +512 -0
  50. package/src/gui/public/index.html +1365 -1211
  51. package/src/gui/server.js +41 -40
  52. package/src/gui/services/file-watcher.js +23 -8
  53. package/src/gui/services/project-scanner.js +26 -20
  54. package/src/gui/services/replanning-service.js +27 -23
  55. package/src/gui/services/traceability-service.js +8 -8
  56. package/src/gui/services/workflow-service.js +14 -7
  57. package/src/index.js +151 -0
  58. package/src/integrations/cicd.js +90 -104
  59. package/src/integrations/codegraph-mcp.js +643 -0
  60. package/src/integrations/documentation.js +142 -103
  61. package/src/integrations/examples.js +95 -80
  62. package/src/integrations/github-client.js +17 -17
  63. package/src/integrations/index.js +5 -5
  64. package/src/integrations/mcp/index.js +21 -21
  65. package/src/integrations/mcp/mcp-context-provider.js +76 -78
  66. package/src/integrations/mcp/mcp-discovery.js +74 -72
  67. package/src/integrations/mcp/mcp-tool-registry.js +99 -94
  68. package/src/integrations/mcp-connector.js +70 -66
  69. package/src/integrations/platforms.js +50 -49
  70. package/src/integrations/tool-discovery.js +37 -31
  71. package/src/llm-providers/anthropic-provider.js +11 -11
  72. package/src/llm-providers/base-provider.js +16 -18
  73. package/src/llm-providers/copilot-provider.js +22 -19
  74. package/src/llm-providers/index.js +26 -25
  75. package/src/llm-providers/ollama-provider.js +11 -11
  76. package/src/llm-providers/openai-provider.js +12 -12
  77. package/src/managers/agent-memory.js +36 -24
  78. package/src/managers/checkpoint-manager.js +4 -8
  79. package/src/managers/delta-spec.js +19 -19
  80. package/src/managers/index.js +13 -4
  81. package/src/managers/memory-condenser.js +35 -45
  82. package/src/managers/repo-skill-manager.js +57 -31
  83. package/src/managers/skill-loader.js +25 -22
  84. package/src/managers/skill-tools.js +36 -72
  85. package/src/managers/workflow.js +30 -22
  86. package/src/monitoring/cost-tracker.js +53 -44
  87. package/src/monitoring/incident-manager.js +123 -103
  88. package/src/monitoring/index.js +144 -134
  89. package/src/monitoring/observability.js +82 -59
  90. package/src/monitoring/quality-dashboard.js +51 -39
  91. package/src/monitoring/release-manager.js +70 -50
  92. package/src/orchestration/agent-skill-binding.js +39 -47
  93. package/src/orchestration/error-handler.js +65 -107
  94. package/src/orchestration/guardrails/base-guardrail.js +26 -24
  95. package/src/orchestration/guardrails/guardrail-rules.js +50 -64
  96. package/src/orchestration/guardrails/index.js +5 -5
  97. package/src/orchestration/guardrails/input-guardrail.js +58 -45
  98. package/src/orchestration/guardrails/output-guardrail.js +104 -81
  99. package/src/orchestration/guardrails/safety-check.js +79 -79
  100. package/src/orchestration/index.js +38 -55
  101. package/src/orchestration/mcp-tool-adapters.js +96 -99
  102. package/src/orchestration/orchestration-engine.js +21 -21
  103. package/src/orchestration/pattern-registry.js +60 -45
  104. package/src/orchestration/patterns/auto.js +34 -47
  105. package/src/orchestration/patterns/group-chat.js +59 -65
  106. package/src/orchestration/patterns/handoff.js +67 -65
  107. package/src/orchestration/patterns/human-in-loop.js +51 -72
  108. package/src/orchestration/patterns/nested.js +25 -40
  109. package/src/orchestration/patterns/sequential.js +35 -34
  110. package/src/orchestration/patterns/swarm.js +63 -56
  111. package/src/orchestration/patterns/triage.js +150 -109
  112. package/src/orchestration/reasoning/index.js +9 -9
  113. package/src/orchestration/reasoning/planning-engine.js +143 -140
  114. package/src/orchestration/reasoning/reasoning-engine.js +206 -144
  115. package/src/orchestration/reasoning/self-correction.js +121 -128
  116. package/src/orchestration/replanning/adaptive-goal-modifier.js +107 -112
  117. package/src/orchestration/replanning/alternative-generator.js +37 -42
  118. package/src/orchestration/replanning/config.js +63 -59
  119. package/src/orchestration/replanning/goal-progress-tracker.js +98 -100
  120. package/src/orchestration/replanning/index.js +24 -20
  121. package/src/orchestration/replanning/plan-evaluator.js +49 -50
  122. package/src/orchestration/replanning/plan-monitor.js +32 -28
  123. package/src/orchestration/replanning/proactive-path-optimizer.js +175 -178
  124. package/src/orchestration/replanning/replan-history.js +33 -26
  125. package/src/orchestration/replanning/replanning-engine.js +106 -108
  126. package/src/orchestration/skill-executor.js +107 -109
  127. package/src/orchestration/skill-registry.js +85 -89
  128. package/src/orchestration/workflow-examples.js +228 -231
  129. package/src/orchestration/workflow-executor.js +65 -68
  130. package/src/orchestration/workflow-orchestrator.js +72 -73
  131. package/src/phase4-integration.js +47 -40
  132. package/src/phase5-integration.js +89 -30
  133. package/src/reporters/coverage-report.js +82 -30
  134. package/src/reporters/hierarchical-reporter.js +498 -0
  135. package/src/reporters/traceability-matrix-report.js +29 -20
  136. package/src/resolvers/issue-resolver.js +43 -31
  137. package/src/steering/advanced-validation.js +133 -124
  138. package/src/steering/auto-updater.js +60 -73
  139. package/src/steering/index.js +6 -6
  140. package/src/steering/quality-metrics.js +41 -35
  141. package/src/steering/steering-auto-update.js +83 -86
  142. package/src/steering/steering-validator.js +98 -106
  143. package/src/steering/template-constraints.js +53 -54
  144. package/src/templates/agents/claude-code/CLAUDE.md +32 -32
  145. package/src/templates/agents/claude-code/skills/agent-assistant/SKILL.md +13 -5
  146. package/src/templates/agents/claude-code/skills/ai-ml-engineer/mlops-guide.md +23 -23
  147. package/src/templates/agents/claude-code/skills/ai-ml-engineer/model-card-template.md +60 -41
  148. package/src/templates/agents/claude-code/skills/api-designer/api-patterns.md +27 -19
  149. package/src/templates/agents/claude-code/skills/api-designer/openapi-template.md +11 -7
  150. package/src/templates/agents/claude-code/skills/bug-hunter/SKILL.md +4 -3
  151. package/src/templates/agents/claude-code/skills/bug-hunter/root-cause-analysis.md +37 -15
  152. package/src/templates/agents/claude-code/skills/change-impact-analyzer/dependency-graph-patterns.md +36 -42
  153. package/src/templates/agents/claude-code/skills/change-impact-analyzer/impact-analysis-template.md +69 -60
  154. package/src/templates/agents/claude-code/skills/cloud-architect/aws-patterns.md +31 -38
  155. package/src/templates/agents/claude-code/skills/cloud-architect/azure-patterns.md +28 -23
  156. package/src/templates/agents/claude-code/skills/code-reviewer/SKILL.md +61 -0
  157. package/src/templates/agents/claude-code/skills/code-reviewer/best-practices.md +27 -0
  158. package/src/templates/agents/claude-code/skills/code-reviewer/review-checklist.md +29 -10
  159. package/src/templates/agents/claude-code/skills/code-reviewer/review-standards.md +29 -24
  160. package/src/templates/agents/claude-code/skills/constitution-enforcer/SKILL.md +8 -6
  161. package/src/templates/agents/claude-code/skills/constitution-enforcer/constitutional-articles.md +62 -26
  162. package/src/templates/agents/claude-code/skills/constitution-enforcer/phase-minus-one-gates.md +35 -16
  163. package/src/templates/agents/claude-code/skills/database-administrator/backup-recovery.md +27 -17
  164. package/src/templates/agents/claude-code/skills/database-administrator/tuning-guide.md +25 -20
  165. package/src/templates/agents/claude-code/skills/database-schema-designer/schema-patterns.md +39 -22
  166. package/src/templates/agents/claude-code/skills/devops-engineer/ci-cd-templates.md +25 -22
  167. package/src/templates/agents/claude-code/skills/issue-resolver/SKILL.md +24 -21
  168. package/src/templates/agents/claude-code/skills/orchestrator/SKILL.md +148 -63
  169. package/src/templates/agents/claude-code/skills/orchestrator/patterns.md +35 -16
  170. package/src/templates/agents/claude-code/skills/orchestrator/selection-matrix.md +69 -64
  171. package/src/templates/agents/claude-code/skills/performance-engineer/optimization-playbook.md +47 -47
  172. package/src/templates/agents/claude-code/skills/performance-optimizer/SKILL.md +69 -0
  173. package/src/templates/agents/claude-code/skills/performance-optimizer/benchmark-template.md +63 -45
  174. package/src/templates/agents/claude-code/skills/performance-optimizer/optimization-patterns.md +33 -35
  175. package/src/templates/agents/claude-code/skills/project-manager/SKILL.md +7 -6
  176. package/src/templates/agents/claude-code/skills/project-manager/agile-ceremonies.md +47 -28
  177. package/src/templates/agents/claude-code/skills/project-manager/project-templates.md +94 -78
  178. package/src/templates/agents/claude-code/skills/quality-assurance/SKILL.md +20 -17
  179. package/src/templates/agents/claude-code/skills/quality-assurance/qa-plan-template.md +63 -49
  180. package/src/templates/agents/claude-code/skills/release-coordinator/SKILL.md +5 -5
  181. package/src/templates/agents/claude-code/skills/release-coordinator/feature-flag-guide.md +30 -26
  182. package/src/templates/agents/claude-code/skills/release-coordinator/release-plan-template.md +67 -35
  183. package/src/templates/agents/claude-code/skills/requirements-analyst/ears-format.md +54 -42
  184. package/src/templates/agents/claude-code/skills/requirements-analyst/validation-rules.md +36 -33
  185. package/src/templates/agents/claude-code/skills/security-auditor/SKILL.md +77 -19
  186. package/src/templates/agents/claude-code/skills/security-auditor/audit-checklists.md +24 -24
  187. package/src/templates/agents/claude-code/skills/security-auditor/owasp-top-10.md +61 -20
  188. package/src/templates/agents/claude-code/skills/security-auditor/vulnerability-patterns.md +43 -11
  189. package/src/templates/agents/claude-code/skills/site-reliability-engineer/SKILL.md +1 -0
  190. package/src/templates/agents/claude-code/skills/site-reliability-engineer/incident-response-template.md +55 -25
  191. package/src/templates/agents/claude-code/skills/site-reliability-engineer/observability-patterns.md +78 -68
  192. package/src/templates/agents/claude-code/skills/site-reliability-engineer/slo-sli-guide.md +73 -53
  193. package/src/templates/agents/claude-code/skills/software-developer/solid-principles.md +83 -37
  194. package/src/templates/agents/claude-code/skills/software-developer/test-first-workflow.md +38 -31
  195. package/src/templates/agents/claude-code/skills/steering/SKILL.md +1 -0
  196. package/src/templates/agents/claude-code/skills/steering/auto-update-rules.md +31 -0
  197. package/src/templates/agents/claude-code/skills/system-architect/adr-template.md +25 -7
  198. package/src/templates/agents/claude-code/skills/system-architect/c4-model-guide.md +74 -61
  199. package/src/templates/agents/claude-code/skills/technical-writer/doc-templates/documentation-templates.md +70 -52
  200. package/src/templates/agents/claude-code/skills/test-engineer/SKILL.md +2 -0
  201. package/src/templates/agents/claude-code/skills/test-engineer/ears-test-mapping.md +75 -71
  202. package/src/templates/agents/claude-code/skills/test-engineer/test-types.md +85 -63
  203. package/src/templates/agents/claude-code/skills/traceability-auditor/coverage-matrix-template.md +39 -36
  204. package/src/templates/agents/claude-code/skills/traceability-auditor/gap-detection-rules.md +22 -17
  205. package/src/templates/agents/claude-code/skills/ui-ux-designer/SKILL.md +1 -0
  206. package/src/templates/agents/claude-code/skills/ui-ux-designer/accessibility-guidelines.md +49 -75
  207. package/src/templates/agents/claude-code/skills/ui-ux-designer/design-system-components.md +71 -59
  208. package/src/templates/agents/codex/AGENTS.md +74 -42
  209. package/src/templates/agents/cursor/AGENTS.md +74 -42
  210. package/src/templates/agents/gemini-cli/GEMINI.md +74 -42
  211. package/src/templates/agents/github-copilot/AGENTS.md +83 -51
  212. package/src/templates/agents/qwen-code/QWEN.md +74 -42
  213. package/src/templates/agents/windsurf/AGENTS.md +74 -42
  214. package/src/templates/architectures/README.md +41 -0
  215. package/src/templates/architectures/clean-architecture/README.md +113 -0
  216. package/src/templates/architectures/event-driven/README.md +162 -0
  217. package/src/templates/architectures/hexagonal/README.md +130 -0
  218. package/src/templates/index.js +6 -1
  219. package/src/templates/locale-manager.js +16 -16
  220. package/src/templates/shared/delta-spec-template.md +20 -13
  221. package/src/templates/shared/github-actions/musubi-issue-resolver.yml +5 -5
  222. package/src/templates/shared/github-actions/musubi-security-check.yml +3 -3
  223. package/src/templates/shared/github-actions/musubi-validate.yml +4 -4
  224. package/src/templates/shared/steering/structure.md +95 -0
  225. package/src/templates/skills/browser-agent.md +21 -16
  226. package/src/templates/skills/web-gui.md +8 -0
  227. package/src/templates/template-constraints.js +50 -53
  228. package/src/validators/advanced-validation.js +30 -36
  229. package/src/validators/constitutional-validator.js +77 -73
  230. package/src/validators/critic-system.js +49 -59
  231. package/src/validators/delta-format.js +59 -55
  232. package/src/validators/traceability-validator.js +7 -11
@@ -1,11 +1,21 @@
1
1
  /**
2
2
  * Observability Module - Logs, Metrics, and Traces
3
- *
3
+ *
4
4
  * Provides unified observability capabilities:
5
5
  * - Structured logging
6
6
  * - Metrics collection
7
7
  * - Distributed tracing
8
8
  * - Correlation IDs
9
+ *
10
+ * Part of MUSUBI v5.0.0 - Production Readiness
11
+ *
12
+ * @module monitoring/observability
13
+ * @version 1.0.0
14
+ *
15
+ * @traceability
16
+ * - Requirement: REQ-P5-004 (Observability Integration)
17
+ * - Design: docs/design/tdd-musubi-v5.0.0.md#3.4
18
+ * - Test: tests/monitoring/observability.test.js
9
19
  */
10
20
 
11
21
  const { EventEmitter } = require('events');
@@ -19,7 +29,7 @@ const LogLevel = {
19
29
  INFO: 'info',
20
30
  WARN: 'warn',
21
31
  ERROR: 'error',
22
- FATAL: 'fatal'
32
+ FATAL: 'fatal',
23
33
  };
24
34
 
25
35
  /**
@@ -31,7 +41,7 @@ const LOG_PRIORITY = {
31
41
  [LogLevel.INFO]: 2,
32
42
  [LogLevel.WARN]: 3,
33
43
  [LogLevel.ERROR]: 4,
34
- [LogLevel.FATAL]: 5
44
+ [LogLevel.FATAL]: 5,
35
45
  };
36
46
 
37
47
  /**
@@ -40,7 +50,7 @@ const LOG_PRIORITY = {
40
50
  const TraceStatus = {
41
51
  OK: 'ok',
42
52
  ERROR: 'error',
43
- UNSET: 'unset'
53
+ UNSET: 'unset',
44
54
  };
45
55
 
46
56
  /**
@@ -51,7 +61,7 @@ const SpanKind = {
51
61
  SERVER: 'server',
52
62
  CLIENT: 'client',
53
63
  PRODUCER: 'producer',
54
- CONSUMER: 'consumer'
64
+ CONSUMER: 'consumer',
55
65
  };
56
66
 
57
67
  /**
@@ -88,7 +98,7 @@ class Logger extends EventEmitter {
88
98
  level: this.level,
89
99
  context: { ...this.context, ...context },
90
100
  outputs: this.outputs,
91
- parent: this
101
+ parent: this,
92
102
  });
93
103
  }
94
104
 
@@ -111,7 +121,7 @@ class Logger extends EventEmitter {
111
121
  logger: this.name,
112
122
  message,
113
123
  ...this.context,
114
- ...meta
124
+ ...meta,
115
125
  };
116
126
 
117
127
  for (const output of this.outputs) {
@@ -121,12 +131,24 @@ class Logger extends EventEmitter {
121
131
  this.emit('log', entry);
122
132
  }
123
133
 
124
- trace(message, meta) { this.log(LogLevel.TRACE, message, meta); }
125
- debug(message, meta) { this.log(LogLevel.DEBUG, message, meta); }
126
- info(message, meta) { this.log(LogLevel.INFO, message, meta); }
127
- warn(message, meta) { this.log(LogLevel.WARN, message, meta); }
128
- error(message, meta) { this.log(LogLevel.ERROR, message, meta); }
129
- fatal(message, meta) { this.log(LogLevel.FATAL, message, meta); }
134
+ trace(message, meta) {
135
+ this.log(LogLevel.TRACE, message, meta);
136
+ }
137
+ debug(message, meta) {
138
+ this.log(LogLevel.DEBUG, message, meta);
139
+ }
140
+ info(message, meta) {
141
+ this.log(LogLevel.INFO, message, meta);
142
+ }
143
+ warn(message, meta) {
144
+ this.log(LogLevel.WARN, message, meta);
145
+ }
146
+ error(message, meta) {
147
+ this.log(LogLevel.ERROR, message, meta);
148
+ }
149
+ fatal(message, meta) {
150
+ this.log(LogLevel.FATAL, message, meta);
151
+ }
130
152
 
131
153
  /**
132
154
  * Add an output
@@ -156,10 +178,8 @@ class ConsoleOutput {
156
178
 
157
179
  write(entry) {
158
180
  if (this.format === 'json') {
159
- const output = this.pretty
160
- ? JSON.stringify(entry, null, 2)
161
- : JSON.stringify(entry);
162
-
181
+ const output = this.pretty ? JSON.stringify(entry, null, 2) : JSON.stringify(entry);
182
+
163
183
  if (entry.level === LogLevel.ERROR || entry.level === LogLevel.FATAL) {
164
184
  console.error(output);
165
185
  } else if (entry.level === LogLevel.WARN) {
@@ -187,7 +207,7 @@ class FileOutput {
187
207
 
188
208
  write(entry) {
189
209
  this.buffer.push(JSON.stringify(entry) + '\n');
190
-
210
+
191
211
  if (this.buffer.length >= this.bufferSize) {
192
212
  this.flush();
193
213
  }
@@ -232,7 +252,7 @@ class MetricsCollector extends EventEmitter {
232
252
  type: 'counter',
233
253
  name: fullName,
234
254
  help,
235
- values: new Map()
255
+ values: new Map(),
236
256
  });
237
257
  }
238
258
  return new CounterMetric(this.metrics.get(fullName), this.labels);
@@ -248,7 +268,7 @@ class MetricsCollector extends EventEmitter {
248
268
  type: 'gauge',
249
269
  name: fullName,
250
270
  help,
251
- values: new Map()
271
+ values: new Map(),
252
272
  });
253
273
  }
254
274
  return new GaugeMetric(this.metrics.get(fullName), this.labels);
@@ -265,7 +285,7 @@ class MetricsCollector extends EventEmitter {
265
285
  name: fullName,
266
286
  help,
267
287
  buckets,
268
- values: new Map()
288
+ values: new Map(),
269
289
  });
270
290
  }
271
291
  return new HistogramMetric(this.metrics.get(fullName), this.labels);
@@ -313,13 +333,13 @@ class MetricsCollector extends EventEmitter {
313
333
  name: metric.name,
314
334
  type: metric.type,
315
335
  help: metric.help,
316
- values: []
336
+ values: [],
317
337
  };
318
338
 
319
339
  for (const [labelsKey, value] of metric.values) {
320
340
  metricData.values.push({
321
341
  labels: labelsKey,
322
- value: metric.type === 'histogram' ? { ...value } : value
342
+ value: metric.type === 'histogram' ? { ...value } : value,
323
343
  });
324
344
  }
325
345
 
@@ -420,12 +440,12 @@ class HistogramMetric {
420
440
  observe(value, labels = {}) {
421
441
  const key = this._labelKey(labels);
422
442
  let data = this.metric.values.get(key);
423
-
443
+
424
444
  if (!data) {
425
445
  data = {
426
446
  buckets: this.metric.buckets.map(() => 0),
427
447
  sum: 0,
428
- count: 0
448
+ count: 0,
429
449
  };
430
450
  this.metric.values.set(key, data);
431
451
  }
@@ -490,7 +510,7 @@ class Span {
490
510
  this.events.push({
491
511
  name,
492
512
  timestamp: Date.now(),
493
- attributes
513
+ attributes,
494
514
  });
495
515
  return this;
496
516
  }
@@ -526,7 +546,7 @@ class Span {
526
546
  getContext() {
527
547
  return {
528
548
  traceId: this.traceId,
529
- spanId: this.spanId
549
+ spanId: this.spanId,
530
550
  };
531
551
  }
532
552
 
@@ -544,7 +564,7 @@ class Span {
544
564
  statusMessage: this.statusMessage,
545
565
  attributes: this.attributes,
546
566
  events: this.events,
547
- links: this.links
567
+ links: this.links,
548
568
  };
549
569
  }
550
570
  }
@@ -573,9 +593,9 @@ class Tracer extends EventEmitter {
573
593
  attributes: {
574
594
  'service.name': this.serviceName,
575
595
  'service.version': this.version,
576
- ...options.attributes
596
+ ...options.attributes,
577
597
  },
578
- links: options.links
598
+ links: options.links,
579
599
  });
580
600
 
581
601
  this.spans.push(span);
@@ -590,7 +610,7 @@ class Tracer extends EventEmitter {
590
610
  return this.startSpan(name, {
591
611
  traceId: parent.traceId,
592
612
  parentSpanId: parent.spanId,
593
- ...options
613
+ ...options,
594
614
  });
595
615
  }
596
616
 
@@ -600,11 +620,11 @@ class Tracer extends EventEmitter {
600
620
  endSpan(span) {
601
621
  span.end();
602
622
  this.emit('spanEnded', span);
603
-
623
+
604
624
  for (const exporter of this.exporters) {
605
625
  exporter.export(span);
606
626
  }
607
-
627
+
608
628
  return span;
609
629
  }
610
630
 
@@ -712,7 +732,7 @@ class CorrelationContext {
712
732
  */
713
733
  toHeaders() {
714
734
  const headers = {};
715
-
735
+
716
736
  if (this.has('traceId')) {
717
737
  headers['x-trace-id'] = this.get('traceId');
718
738
  }
@@ -722,7 +742,7 @@ class CorrelationContext {
722
742
  if (this.has('correlationId')) {
723
743
  headers['x-correlation-id'] = this.get('correlationId');
724
744
  }
725
-
745
+
726
746
  return headers;
727
747
  }
728
748
 
@@ -731,7 +751,7 @@ class CorrelationContext {
731
751
  */
732
752
  static fromHeaders(headers) {
733
753
  const ctx = new CorrelationContext();
734
-
754
+
735
755
  if (headers['x-trace-id']) {
736
756
  ctx.set('traceId', headers['x-trace-id']);
737
757
  }
@@ -741,7 +761,7 @@ class CorrelationContext {
741
761
  if (headers['x-correlation-id']) {
742
762
  ctx.set('correlationId', headers['x-correlation-id']);
743
763
  }
744
-
764
+
745
765
  return ctx;
746
766
  }
747
767
  }
@@ -754,22 +774,22 @@ class ObservabilityProvider extends EventEmitter {
754
774
  super();
755
775
  this.serviceName = options.serviceName || 'musubi-service';
756
776
  this.version = options.version || '1.0.0';
757
-
777
+
758
778
  this.logger = new Logger({
759
779
  name: this.serviceName,
760
- level: options.logLevel || LogLevel.INFO
780
+ level: options.logLevel || LogLevel.INFO,
761
781
  });
762
-
782
+
763
783
  this.metrics = new MetricsCollector({
764
784
  name: this.serviceName,
765
- prefix: options.metricsPrefix || ''
785
+ prefix: options.metricsPrefix || '',
766
786
  });
767
-
787
+
768
788
  this.tracer = new Tracer({
769
789
  serviceName: this.serviceName,
770
- version: this.version
790
+ version: this.version,
771
791
  });
772
-
792
+
773
793
  // Standard metrics
774
794
  this._setupStandardMetrics();
775
795
  }
@@ -780,9 +800,12 @@ class ObservabilityProvider extends EventEmitter {
780
800
  _setupStandardMetrics() {
781
801
  // Request metrics
782
802
  this.requestCounter = this.metrics.counter('http_requests_total', 'Total HTTP requests');
783
- this.requestDuration = this.metrics.histogram('http_request_duration_seconds', 'HTTP request duration');
803
+ this.requestDuration = this.metrics.histogram(
804
+ 'http_request_duration_seconds',
805
+ 'HTTP request duration'
806
+ );
784
807
  this.requestErrors = this.metrics.counter('http_request_errors_total', 'Total HTTP errors');
785
-
808
+
786
809
  // Resource metrics
787
810
  this.activeConnections = this.metrics.gauge('active_connections', 'Active connections');
788
811
  }
@@ -813,10 +836,10 @@ class ObservabilityProvider extends EventEmitter {
813
836
  */
814
837
  trace(name, fn, options = {}) {
815
838
  const span = this.tracer.startSpan(name, options);
816
-
839
+
817
840
  try {
818
841
  const result = fn(span);
819
-
842
+
820
843
  if (result && typeof result.then === 'function') {
821
844
  return result
822
845
  .then(r => {
@@ -828,13 +851,13 @@ class ObservabilityProvider extends EventEmitter {
828
851
  span.setStatus(TraceStatus.ERROR, err.message);
829
852
  span.addEvent('exception', {
830
853
  'exception.type': err.name,
831
- 'exception.message': err.message
854
+ 'exception.message': err.message,
832
855
  });
833
856
  this.tracer.endSpan(span);
834
857
  throw err;
835
858
  });
836
859
  }
837
-
860
+
838
861
  span.setStatus(TraceStatus.OK);
839
862
  this.tracer.endSpan(span);
840
863
  return result;
@@ -842,7 +865,7 @@ class ObservabilityProvider extends EventEmitter {
842
865
  span.setStatus(TraceStatus.ERROR, err.message);
843
866
  span.addEvent('exception', {
844
867
  'exception.type': err.name,
845
- 'exception.message': err.message
868
+ 'exception.message': err.message,
846
869
  });
847
870
  this.tracer.endSpan(span);
848
871
  throw err;
@@ -854,10 +877,10 @@ class ObservabilityProvider extends EventEmitter {
854
877
  */
855
878
  recordRequest(method, path, statusCode, duration) {
856
879
  const labels = { method, path, status_code: statusCode.toString() };
857
-
880
+
858
881
  this.requestCounter.inc(labels);
859
882
  this.requestDuration.observe(duration / 1000, { method, path }); // Convert to seconds
860
-
883
+
861
884
  if (statusCode >= 400) {
862
885
  this.requestErrors.inc(labels);
863
886
  }
@@ -870,10 +893,10 @@ class ObservabilityProvider extends EventEmitter {
870
893
  return {
871
894
  service: {
872
895
  name: this.serviceName,
873
- version: this.version
896
+ version: this.version,
874
897
  },
875
898
  metrics: this.metrics.toJSON(),
876
- traces: this.tracer.getAllSpans()
899
+ traces: this.tracer.getAllSpans(),
877
900
  };
878
901
  }
879
902
  }
@@ -921,18 +944,18 @@ module.exports = {
921
944
  MemoryExporter,
922
945
  CorrelationContext,
923
946
  ObservabilityProvider,
924
-
947
+
925
948
  // Constants
926
949
  LogLevel,
927
950
  TraceStatus,
928
951
  SpanKind,
929
-
952
+
930
953
  // Factories
931
954
  createLogger,
932
955
  createMetricsCollector,
933
956
  createTracer,
934
957
  createObservability,
935
-
958
+
936
959
  // Utilities
937
- generateId
960
+ generateId,
938
961
  };
@@ -1,8 +1,16 @@
1
1
  /**
2
2
  * Quality Metrics Dashboard
3
3
  * カバレッジメトリクス、Constitutional準拠メトリクス、プロジェクトヘルス指標
4
- *
4
+ *
5
+ * Part of MUSUBI v5.0.0 - Production Readiness
6
+ *
5
7
  * @module monitoring/quality-dashboard
8
+ * @version 1.0.0
9
+ *
10
+ * @traceability
11
+ * - Requirement: REQ-P5-001 (Quality Dashboard)
12
+ * - Design: docs/design/tdd-musubi-v5.0.0.md#3.1
13
+ * - Test: tests/monitoring/quality-dashboard.test.js
6
14
  */
7
15
 
8
16
  const EventEmitter = require('events');
@@ -16,17 +24,17 @@ const METRIC_CATEGORY = {
16
24
  QUALITY: 'quality',
17
25
  HEALTH: 'health',
18
26
  PERFORMANCE: 'performance',
19
- CUSTOM: 'custom'
27
+ CUSTOM: 'custom',
20
28
  };
21
29
 
22
30
  /**
23
31
  * Health status levels
24
32
  */
25
33
  const HEALTH_STATUS = {
26
- HEALTHY: 'healthy', // 80-100%
27
- WARNING: 'warning', // 50-79%
28
- CRITICAL: 'critical', // 20-49%
29
- FAILING: 'failing' // <20%
34
+ HEALTHY: 'healthy', // 80-100%
35
+ WARNING: 'warning', // 50-79%
36
+ CRITICAL: 'critical', // 20-49%
37
+ FAILING: 'failing', // <20%
30
38
  };
31
39
 
32
40
  /**
@@ -41,7 +49,7 @@ const CONSTITUTIONAL_ARTICLES = {
41
49
  INCREMENTAL_ADOPTION: 'article-6',
42
50
  SEPARATION_OF_CONCERNS: 'article-7',
43
51
  FEEDBACK_LOOPS: 'article-8',
44
- GOVERNANCE: 'article-9'
52
+ GOVERNANCE: 'article-9',
45
53
  };
46
54
 
47
55
  /**
@@ -56,17 +64,17 @@ class QualityDashboard extends EventEmitter {
56
64
  */
57
65
  constructor(options = {}) {
58
66
  super();
59
-
67
+
60
68
  this.thresholds = {
61
69
  coverage: { healthy: 80, warning: 50, critical: 20 },
62
70
  constitutional: { healthy: 90, warning: 70, critical: 50 },
63
71
  quality: { healthy: 80, warning: 60, critical: 40 },
64
- ...options.thresholds
72
+ ...options.thresholds,
65
73
  };
66
74
 
67
75
  this.autoCollect = options.autoCollect ?? false;
68
76
  this.collectInterval = options.collectInterval ?? 60000;
69
-
77
+
70
78
  this.metrics = new Map();
71
79
  this.history = [];
72
80
  this.collectors = new Map();
@@ -85,25 +93,27 @@ class QualityDashboard extends EventEmitter {
85
93
  */
86
94
  initializeDefaultCollectors() {
87
95
  // Coverage metrics collector
88
- this.registerCollector('coverage', async (context) => ({
96
+ this.registerCollector('coverage', async context => ({
89
97
  lines: context?.coverage?.lines ?? 0,
90
98
  branches: context?.coverage?.branches ?? 0,
91
99
  functions: context?.coverage?.functions ?? 0,
92
100
  statements: context?.coverage?.statements ?? 0,
93
- overall: context?.coverage?.overall ??
94
- ((context?.coverage?.lines ?? 0) +
95
- (context?.coverage?.branches ?? 0) +
96
- (context?.coverage?.functions ?? 0) +
97
- (context?.coverage?.statements ?? 0)) / 4
101
+ overall:
102
+ context?.coverage?.overall ??
103
+ ((context?.coverage?.lines ?? 0) +
104
+ (context?.coverage?.branches ?? 0) +
105
+ (context?.coverage?.functions ?? 0) +
106
+ (context?.coverage?.statements ?? 0)) /
107
+ 4,
98
108
  }));
99
109
 
100
110
  // Constitutional compliance collector
101
- this.registerCollector('constitutional', async (context) => {
111
+ this.registerCollector('constitutional', async context => {
102
112
  const articles = context?.constitutional ?? {};
103
113
  const scores = Object.values(CONSTITUTIONAL_ARTICLES).map(id => ({
104
114
  id,
105
115
  score: articles[id]?.score ?? 0,
106
- compliant: articles[id]?.compliant ?? false
116
+ compliant: articles[id]?.compliant ?? false,
107
117
  }));
108
118
 
109
119
  const totalScore = scores.reduce((sum, s) => sum + s.score, 0) / scores.length;
@@ -114,25 +124,27 @@ class QualityDashboard extends EventEmitter {
114
124
  totalScore,
115
125
  compliantCount,
116
126
  totalArticles: scores.length,
117
- complianceRate: (compliantCount / scores.length) * 100
127
+ complianceRate: (compliantCount / scores.length) * 100,
118
128
  };
119
129
  });
120
130
 
121
131
  // Quality metrics collector
122
- this.registerCollector('quality', async (context) => ({
132
+ this.registerCollector('quality', async context => ({
123
133
  codeComplexity: context?.quality?.complexity ?? 0,
124
134
  maintainability: context?.quality?.maintainability ?? 0,
125
135
  documentation: context?.quality?.documentation ?? 0,
126
136
  testQuality: context?.quality?.testQuality ?? 0,
127
- overall: context?.quality?.overall ??
137
+ overall:
138
+ context?.quality?.overall ??
128
139
  ((context?.quality?.complexity ?? 0) +
129
- (context?.quality?.maintainability ?? 0) +
130
- (context?.quality?.documentation ?? 0) +
131
- (context?.quality?.testQuality ?? 0)) / 4
140
+ (context?.quality?.maintainability ?? 0) +
141
+ (context?.quality?.documentation ?? 0) +
142
+ (context?.quality?.testQuality ?? 0)) /
143
+ 4,
132
144
  }));
133
145
 
134
146
  // Health metrics collector
135
- this.registerCollector('health', async (context) => {
147
+ this.registerCollector('health', async _context => {
136
148
  const coverage = await this.getMetric('coverage');
137
149
  const constitutional = await this.getMetric('constitutional');
138
150
  const quality = await this.getMetric('quality');
@@ -149,7 +161,7 @@ class QualityDashboard extends EventEmitter {
149
161
  qualityScore,
150
162
  overall,
151
163
  status: this.calculateStatus(overall, 'quality'),
152
- timestamp: new Date().toISOString()
164
+ timestamp: new Date().toISOString(),
153
165
  };
154
166
  });
155
167
  }
@@ -189,20 +201,20 @@ class QualityDashboard extends EventEmitter {
189
201
  const data = await collector(context);
190
202
  results[name] = {
191
203
  ...data,
192
- collectedAt: timestamp
204
+ collectedAt: timestamp,
193
205
  };
194
206
  this.metrics.set(name, results[name]);
195
207
  } catch (error) {
196
208
  results[name] = {
197
209
  error: error.message,
198
- collectedAt: timestamp
210
+ collectedAt: timestamp,
199
211
  };
200
212
  }
201
213
  }
202
214
 
203
215
  const snapshot = {
204
216
  timestamp,
205
- metrics: { ...results }
217
+ metrics: { ...results },
206
218
  };
207
219
 
208
220
  this.history.push(snapshot);
@@ -263,20 +275,20 @@ class QualityDashboard extends EventEmitter {
263
275
  breakdown: {
264
276
  coverage: {
265
277
  score: coverage?.overall ?? 0,
266
- status: this.calculateStatus(coverage?.overall ?? 0, 'coverage')
278
+ status: this.calculateStatus(coverage?.overall ?? 0, 'coverage'),
267
279
  },
268
280
  constitutional: {
269
281
  score: constitutional?.totalScore ?? 0,
270
282
  status: this.calculateStatus(constitutional?.totalScore ?? 0, 'constitutional'),
271
283
  compliantArticles: constitutional?.compliantCount ?? 0,
272
- totalArticles: constitutional?.totalArticles ?? 9
284
+ totalArticles: constitutional?.totalArticles ?? 9,
273
285
  },
274
286
  quality: {
275
287
  score: quality?.overall ?? 0,
276
- status: this.calculateStatus(quality?.overall ?? 0, 'quality')
277
- }
288
+ status: this.calculateStatus(quality?.overall ?? 0, 'quality'),
289
+ },
278
290
  },
279
- lastUpdated: health?.timestamp ?? null
291
+ lastUpdated: health?.timestamp ?? null,
280
292
  };
281
293
  }
282
294
 
@@ -292,7 +304,7 @@ class QualityDashboard extends EventEmitter {
292
304
  .slice(-limit)
293
305
  .map(h => ({
294
306
  timestamp: h.timestamp,
295
- value: h.metrics[metricName]
307
+ value: h.metrics[metricName],
296
308
  }));
297
309
 
298
310
  if (data.length < 2) {
@@ -406,7 +418,7 @@ class QualityDashboard extends EventEmitter {
406
418
  [HEALTH_STATUS.HEALTHY]: '🟢',
407
419
  [HEALTH_STATUS.WARNING]: '🟡',
408
420
  [HEALTH_STATUS.CRITICAL]: '🟠',
409
- [HEALTH_STATUS.FAILING]: '🔴'
421
+ [HEALTH_STATUS.FAILING]: '🔴',
410
422
  };
411
423
  return emojis[status] || '⚪';
412
424
  }
@@ -448,7 +460,7 @@ class QualityDashboard extends EventEmitter {
448
460
  setThresholds(category, thresholds) {
449
461
  this.thresholds[category] = {
450
462
  ...this.thresholds[category],
451
- ...thresholds
463
+ ...thresholds,
452
464
  };
453
465
  }
454
466
 
@@ -462,7 +474,7 @@ class QualityDashboard extends EventEmitter {
462
474
  collectorsCount: this.collectors.size,
463
475
  historyCount: this.history.length,
464
476
  autoCollecting: this.intervalId !== null,
465
- thresholds: { ...this.thresholds }
477
+ thresholds: { ...this.thresholds },
466
478
  };
467
479
  }
468
480
  }
@@ -479,5 +491,5 @@ module.exports = {
479
491
  createQualityDashboard,
480
492
  METRIC_CATEGORY,
481
493
  HEALTH_STATUS,
482
- CONSTITUTIONAL_ARTICLES
494
+ CONSTITUTIONAL_ARTICLES,
483
495
  };