@nahisaho/musubix-core 1.1.16 → 1.3.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 (98) hide show
  1. package/AGENTS.md +53 -10
  2. package/dist/index.d.ts +4 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +8 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/symbolic/__tests__/ears-to-formal.test.d.ts +9 -0
  7. package/dist/symbolic/__tests__/ears-to-formal.test.d.ts.map +1 -0
  8. package/dist/symbolic/__tests__/ears-to-formal.test.js +187 -0
  9. package/dist/symbolic/__tests__/ears-to-formal.test.js.map +1 -0
  10. package/dist/symbolic/__tests__/quality-gate.test.d.ts +9 -0
  11. package/dist/symbolic/__tests__/quality-gate.test.d.ts.map +1 -0
  12. package/dist/symbolic/__tests__/quality-gate.test.js +230 -0
  13. package/dist/symbolic/__tests__/quality-gate.test.js.map +1 -0
  14. package/dist/symbolic/__tests__/security-scanner.test.d.ts +9 -0
  15. package/dist/symbolic/__tests__/security-scanner.test.d.ts.map +1 -0
  16. package/dist/symbolic/__tests__/security-scanner.test.js +336 -0
  17. package/dist/symbolic/__tests__/security-scanner.test.js.map +1 -0
  18. package/dist/symbolic/__tests__/vc-generator.test.d.ts +9 -0
  19. package/dist/symbolic/__tests__/vc-generator.test.d.ts.map +1 -0
  20. package/dist/symbolic/__tests__/vc-generator.test.js +301 -0
  21. package/dist/symbolic/__tests__/vc-generator.test.js.map +1 -0
  22. package/dist/symbolic/__tests__/z3-adapter.test.d.ts +10 -0
  23. package/dist/symbolic/__tests__/z3-adapter.test.d.ts.map +1 -0
  24. package/dist/symbolic/__tests__/z3-adapter.test.js +260 -0
  25. package/dist/symbolic/__tests__/z3-adapter.test.js.map +1 -0
  26. package/dist/symbolic/audit-logger.d.ts +233 -0
  27. package/dist/symbolic/audit-logger.d.ts.map +1 -0
  28. package/dist/symbolic/audit-logger.js +438 -0
  29. package/dist/symbolic/audit-logger.js.map +1 -0
  30. package/dist/symbolic/candidate-ranker.d.ts +133 -0
  31. package/dist/symbolic/candidate-ranker.d.ts.map +1 -0
  32. package/dist/symbolic/candidate-ranker.js +223 -0
  33. package/dist/symbolic/candidate-ranker.js.map +1 -0
  34. package/dist/symbolic/confidence-estimator.d.ts +57 -0
  35. package/dist/symbolic/confidence-estimator.d.ts.map +1 -0
  36. package/dist/symbolic/confidence-estimator.js +185 -0
  37. package/dist/symbolic/confidence-estimator.js.map +1 -0
  38. package/dist/symbolic/confidence-router.d.ts +55 -0
  39. package/dist/symbolic/confidence-router.d.ts.map +1 -0
  40. package/dist/symbolic/confidence-router.js +186 -0
  41. package/dist/symbolic/confidence-router.js.map +1 -0
  42. package/dist/symbolic/constitution-registry.d.ts +100 -0
  43. package/dist/symbolic/constitution-registry.d.ts.map +1 -0
  44. package/dist/symbolic/constitution-registry.js +324 -0
  45. package/dist/symbolic/constitution-registry.js.map +1 -0
  46. package/dist/symbolic/ears-to-formal.d.ts +156 -0
  47. package/dist/symbolic/ears-to-formal.d.ts.map +1 -0
  48. package/dist/symbolic/ears-to-formal.js +419 -0
  49. package/dist/symbolic/ears-to-formal.js.map +1 -0
  50. package/dist/symbolic/error-handler.d.ts +88 -0
  51. package/dist/symbolic/error-handler.d.ts.map +1 -0
  52. package/dist/symbolic/error-handler.js +239 -0
  53. package/dist/symbolic/error-handler.js.map +1 -0
  54. package/dist/symbolic/hallucination-detector.d.ts +100 -0
  55. package/dist/symbolic/hallucination-detector.d.ts.map +1 -0
  56. package/dist/symbolic/hallucination-detector.js +327 -0
  57. package/dist/symbolic/hallucination-detector.js.map +1 -0
  58. package/dist/symbolic/index.d.ts +75 -0
  59. package/dist/symbolic/index.d.ts.map +1 -0
  60. package/dist/symbolic/index.js +95 -0
  61. package/dist/symbolic/index.js.map +1 -0
  62. package/dist/symbolic/performance-budget.d.ts +208 -0
  63. package/dist/symbolic/performance-budget.d.ts.map +1 -0
  64. package/dist/symbolic/performance-budget.js +356 -0
  65. package/dist/symbolic/performance-budget.js.map +1 -0
  66. package/dist/symbolic/quality-gate.d.ts +170 -0
  67. package/dist/symbolic/quality-gate.d.ts.map +1 -0
  68. package/dist/symbolic/quality-gate.js +484 -0
  69. package/dist/symbolic/quality-gate.js.map +1 -0
  70. package/dist/symbolic/result-blender.d.ts +150 -0
  71. package/dist/symbolic/result-blender.d.ts.map +1 -0
  72. package/dist/symbolic/result-blender.js +246 -0
  73. package/dist/symbolic/result-blender.js.map +1 -0
  74. package/dist/symbolic/rule-config.d.ts +223 -0
  75. package/dist/symbolic/rule-config.d.ts.map +1 -0
  76. package/dist/symbolic/rule-config.js +569 -0
  77. package/dist/symbolic/rule-config.js.map +1 -0
  78. package/dist/symbolic/security-scanner.d.ts +332 -0
  79. package/dist/symbolic/security-scanner.d.ts.map +1 -0
  80. package/dist/symbolic/security-scanner.js +727 -0
  81. package/dist/symbolic/security-scanner.js.map +1 -0
  82. package/dist/symbolic/semantic-filter.d.ts +57 -0
  83. package/dist/symbolic/semantic-filter.d.ts.map +1 -0
  84. package/dist/symbolic/semantic-filter.js +136 -0
  85. package/dist/symbolic/semantic-filter.js.map +1 -0
  86. package/dist/symbolic/types.d.ts +265 -0
  87. package/dist/symbolic/types.d.ts.map +1 -0
  88. package/dist/symbolic/types.js +16 -0
  89. package/dist/symbolic/types.js.map +1 -0
  90. package/dist/symbolic/vc-generator.d.ts +177 -0
  91. package/dist/symbolic/vc-generator.d.ts.map +1 -0
  92. package/dist/symbolic/vc-generator.js +400 -0
  93. package/dist/symbolic/vc-generator.js.map +1 -0
  94. package/dist/symbolic/z3-adapter.d.ts +219 -0
  95. package/dist/symbolic/z3-adapter.d.ts.map +1 -0
  96. package/dist/symbolic/z3-adapter.js +528 -0
  97. package/dist/symbolic/z3-adapter.js.map +1 -0
  98. package/package.json +1 -1
package/AGENTS.md CHANGED
@@ -8,14 +8,14 @@
8
8
 
9
9
  | 項目 | 詳細 |
10
10
  |------|------|
11
- | **バージョン** | 1.1.15 |
11
+ | **バージョン** | 1.3.0 |
12
12
  | **言語** | TypeScript |
13
13
  | **ランタイム** | Node.js >= 20.0.0 |
14
14
  | **パッケージマネージャ** | npm >= 10.0.0 |
15
15
  | **ビルドシステム** | モノレポ(npm workspaces) |
16
16
  | **テストフレームワーク** | Vitest |
17
- | **テスト数** | 459 (全合格) |
18
- | **コンポーネント数** | 224 (62ドメイン対応) |
17
+ | **テスト数** | 752 (全合格) |
18
+ | **コンポーネント数** | 243 (62ドメイン対応) |
19
19
  | **Agent Skills** | 12 (Claude Code対応) |
20
20
 
21
21
  ---
@@ -28,14 +28,22 @@
28
28
  packages/
29
29
  ├── core/ # @nahisaho/musubix-core
30
30
  ├── mcp-server/ # @nahisaho/musubix-mcp-server
31
- └── yata-client/ # @nahisaho/musubix-yata-client
31
+ ├── yata-client/ # @nahisaho/musubix-yata-client
32
+ ├── pattern-mcp/ # @nahisaho/musubix-pattern-mcp (NEW!)
33
+ ├── ontology-mcp/ # @nahisaho/musubix-ontology-mcp (NEW!)
34
+ ├── wake-sleep/ # @nahisaho/musubix-wake-sleep (NEW!)
35
+ └── sdd-ontology/ # @nahisaho/musubix-sdd-ontology (NEW!)
32
36
  ```
33
37
 
34
38
  | パッケージ | npm | 役割 |
35
39
  |-----------|-----|------|
36
40
  | `packages/core/` | `@nahisaho/musubix-core` | コアライブラリ - CLI、EARS検証、コード生成、設計パターン |
37
- | `packages/mcp-server/` | `@nahisaho/musubix-mcp-server` | MCPサーバー - 9ツール、3プロンプト |
41
+ | `packages/mcp-server/` | `@nahisaho/musubix-mcp-server` | MCPサーバー - 16ツール、3プロンプト |
38
42
  | `packages/yata-client/` | `@nahisaho/musubix-yata-client` | YATAクライアント - 知識グラフ連携 |
43
+ | `packages/pattern-mcp/` | `@nahisaho/musubix-pattern-mcp` | パターン学習 - 抽出・圧縮・ライブラリ |
44
+ | `packages/ontology-mcp/` | `@nahisaho/musubix-ontology-mcp` | オントロジー - N3Store・推論エンジン |
45
+ | `packages/wake-sleep/` | `@nahisaho/musubix-wake-sleep` | Wake-Sleep学習サイクル |
46
+ | `packages/sdd-ontology/` | `@nahisaho/musubix-sdd-ontology` | SDD方法論オントロジー |
39
47
 
40
48
  ### Core パッケージモジュール
41
49
 
@@ -47,8 +55,9 @@ packages/core/src/
47
55
  ├── design/ # 設計パターン・C4モデル
48
56
  ├── error/ # エラーハンドリング
49
57
  ├── explanation/ # 説明生成・可視化
50
- ├── learning/ # 自己学習システム(NEW!)
58
+ ├── learning/ # 自己学習システム
51
59
  ├── requirements/ # 要件分析・分解
60
+ ├── symbolic/ # シンボリック推論(v1.2.0 NEW!)
52
61
  ├── traceability/ # トレーサビリティ
53
62
  ├── types/ # 型定義
54
63
  ├── utils/ # ユーティリティ
@@ -121,7 +130,9 @@ npx @nahisaho/musubix-mcp-server
121
130
  npx musubix-mcp --transport stdio
122
131
  ```
123
132
 
124
- ### ツール一覧(9ツール)
133
+ ### ツール一覧(16ツール)
134
+
135
+ #### SDD基本ツール(9ツール)
125
136
 
126
137
  | ツール名 | 説明 |
127
138
  |---------|------|
@@ -135,6 +146,18 @@ npx musubix-mcp --transport stdio
135
146
  | `sdd_validate_constitution` | 9憲法条項への準拠検証 |
136
147
  | `sdd_validate_traceability` | 要件↔設計↔タスクのトレーサビリティ検証 |
137
148
 
149
+ #### パターン統合ツール(7ツール)- v1.3.0 NEW!
150
+
151
+ | ツール名 | 説明 |
152
+ |---------|------|
153
+ | `pattern_extract` | コードからパターンを抽出 |
154
+ | `pattern_compress` | パターンの抽象化・圧縮 |
155
+ | `pattern_store` | パターンライブラリへの保存 |
156
+ | `pattern_query` | パターンの検索・取得 |
157
+ | `pattern_consolidate` | 類似パターンの統合 |
158
+ | `ontology_query` | オントロジーグラフへのクエリ |
159
+ | `ontology_infer` | オントロジーによる推論実行 |
160
+
138
161
  ### プロンプト一覧(3プロンプト)
139
162
 
140
163
  | プロンプト名 | 説明 |
@@ -275,9 +298,29 @@ npx musubix codegen generate <design.md> --output src/
275
298
  フィードバック → パターン候補 → 閾値超過 → パターン登録 → 推論に適用
276
299
  ```
277
300
 
301
+ ### 6. Wake-Sleep学習サイクル(v1.3.0 NEW!)
302
+
303
+ Wake-Sleepアルゴリズムに基づいた継続的学習システム:
304
+
305
+ | フェーズ | 処理内容 |
306
+ |---------|----------|
307
+ | **Wake** | コード観察 → パターン抽出 → 知識グラフ更新 |
308
+ | **Sleep** | パターン統合 → 類似パターン圧縮 → メモリ最適化 |
309
+
310
+ ```
311
+ Wake Phase: observe() → extractPatterns() → updateKnowledge()
312
+ Sleep Phase: consolidate() → compress() → optimize()
313
+ ```
314
+
315
+ **主要コンポーネント**:
316
+ - `WakeSleepCycle`: 学習サイクル全体の制御
317
+ - `PatternLibrary`: 学習済みパターンの永続化管理
318
+ - `PatternOntologyBridge`: パターン↔オントロジー相互変換
319
+ - `N3Store`: RDF/OWLベースの知識グラフストレージ
320
+
278
321
  ---
279
322
 
280
- ## 学習済みベストプラクティス(v1.1.10 Updated!)
323
+ ## 📚 学習済みベストプラクティス(v1.1.10 Updated!)
281
324
 
282
325
  Project-07〜14の実装から学習したパターンです。
283
326
 
@@ -424,6 +467,6 @@ npx musubix learn best-practices --format markdown
424
467
  ---
425
468
 
426
469
  **Agent**: GitHub Copilot / Claude
427
- **Last Updated**: 2026-01-04
428
- **Version**: 1.1.15
470
+ **Last Updated**: 2025-01-10
471
+ **Version**: 1.3.0
429
472
  **Repository**: https://github.com/nahisaho/MUSUBIX
package/dist/index.d.ts CHANGED
@@ -20,6 +20,10 @@ export * from './codegen/index.js';
20
20
  export * from './explanation/index.js';
21
21
  export * from './error/index.js';
22
22
  export * from './learning/index.js';
23
+ import * as symbolic from './symbolic/index.js';
24
+ export { symbolic };
25
+ export { createSymbolicPipeline, processSymbolic, SemanticCodeFilterPipeline, HallucinationDetector, ProjectSymbolIndex, ConstitutionRuleRegistry, ConfidenceEstimator, ConfidenceBasedRouter, ErrorHandler, DEFAULT_CONSTITUTION_RULES, checkArticleI, checkArticleII, checkArticleIII, checkArticleIV, checkArticleV, checkArticleVI, checkArticleVII, checkArticleVIII, checkArticleIX, EarsToFormalSpecConverter, VerificationConditionGenerator, Z3Adapter, PreconditionVerifier, PostconditionVerifier, InvariantVerifier, } from './symbolic/index.js';
26
+ export type { FilterInput, FilterOutput, CodeCandidate, ProjectContext, SymbolInfo, HallucinationItem, HallucinationResult, ConstitutionRule, ConstitutionCheckInput, ConstitutionCheckResult, ConstitutionReport, ConfidenceEstimation, ConfidenceBreakdown, RiskFactor, RoutingResult, RoutingDecision, VerificationRequirement, RecoveryResult, ErrorClassification, FallbackAction, AuditLogEntry, EarsRequirement, EarsPatternType, EarsAstNode, SmtLibOutput, FormalSpecification, VerificationCondition, VcGenerationResult, Z3Result, FormalVerificationResult, } from './symbolic/index.js';
23
27
  /**
24
28
  * Core Library Entry Point
25
29
  *
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,gBAAgB,CAAC;AAG/B,cAAc,uBAAuB,CAAC;AAGtC,cAAc,yBAAyB,CAAC;AAGxC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,qBAAqB,CAAC;AAOpC;;;;;;;;;;GAUG"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAGvC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,gBAAgB,CAAC;AAG/B,cAAc,uBAAuB,CAAC;AAGtC,cAAc,yBAAyB,CAAC;AAGxC,cAAc,mBAAmB,CAAC;AAGlC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,kBAAkB,CAAC;AAGjC,cAAc,qBAAqB,CAAC;AAIpC,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,CAAC;AAGpB,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,0BAA0B,EAC1B,qBAAqB,EACrB,kBAAkB,EAClB,wBAAwB,EACxB,mBAAmB,EACnB,qBAAqB,EACrB,YAAY,EACZ,0BAA0B,EAC1B,aAAa,EACb,cAAc,EACd,eAAe,EACf,cAAc,EACd,aAAa,EACb,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EAEd,yBAAyB,EACzB,8BAA8B,EAC9B,SAAS,EACT,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAG7B,YAAY,EACV,WAAW,EACX,YAAY,EACZ,aAAa,EACb,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,mBAAmB,EACnB,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACvB,kBAAkB,EAClB,oBAAoB,EACpB,mBAAmB,EACnB,UAAU,EACV,aAAa,EACb,eAAe,EACf,uBAAuB,EACvB,cAAc,EACd,mBAAmB,EACnB,cAAc,EACd,aAAa,EAEb,eAAe,EACf,eAAe,EACf,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,qBAAqB,EACrB,kBAAkB,EAClB,QAAQ,EACR,wBAAwB,GACzB,MAAM,qBAAqB,CAAC;AAO7B;;;;;;;;;;GAUG"}
package/dist/index.js CHANGED
@@ -31,6 +31,14 @@ export * from './explanation/index.js';
31
31
  export * from './error/index.js';
32
32
  // Export learning system
33
33
  export * from './learning/index.js';
34
+ // Export symbolic reasoning (Neuro-Symbolic Integration)
35
+ // Use namespace import to avoid name collisions with existing types
36
+ import * as symbolic from './symbolic/index.js';
37
+ export { symbolic };
38
+ // Re-export key symbolic functions at top level for convenience
39
+ export { createSymbolicPipeline, processSymbolic, SemanticCodeFilterPipeline, HallucinationDetector, ProjectSymbolIndex, ConstitutionRuleRegistry, ConfidenceEstimator, ConfidenceBasedRouter, ErrorHandler, DEFAULT_CONSTITUTION_RULES, checkArticleI, checkArticleII, checkArticleIII, checkArticleIV, checkArticleV, checkArticleVI, checkArticleVII, checkArticleVIII, checkArticleIX,
40
+ // Phase 2: Formal Verification
41
+ EarsToFormalSpecConverter, VerificationConditionGenerator, Z3Adapter, PreconditionVerifier, PostconditionVerifier, InvariantVerifier, } from './symbolic/index.js';
34
42
  // Re-export modules (will be implemented in subsequent tasks)
35
43
  // export * from './integrator/index.js';
36
44
  // export * from './requirements/index.js';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,UAAU;AACV,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,eAAe;AACf,cAAc,kBAAkB,CAAC;AAEjC,mBAAmB;AACnB,cAAc,kBAAkB,CAAC;AAEjC,aAAa;AACb,cAAc,gBAAgB,CAAC;AAE/B,oBAAoB;AACpB,cAAc,uBAAuB,CAAC;AAEtC,sBAAsB;AACtB,cAAc,yBAAyB,CAAC;AAExC,gBAAgB;AAChB,cAAc,mBAAmB,CAAC;AAElC,yBAAyB;AACzB,cAAc,oBAAoB,CAAC;AAEnC,qBAAqB;AACrB,cAAc,wBAAwB,CAAC;AAEvC,wBAAwB;AACxB,cAAc,kBAAkB,CAAC;AAEjC,yBAAyB;AACzB,cAAc,qBAAqB,CAAC;AAEpC,8DAA8D;AAC9D,yCAAyC;AACzC,2CAA2C;AAC3C,sCAAsC;AAEtC;;;;;;;;;;GAUG"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,UAAU;AACV,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,eAAe;AACf,cAAc,kBAAkB,CAAC;AAEjC,mBAAmB;AACnB,cAAc,kBAAkB,CAAC;AAEjC,aAAa;AACb,cAAc,gBAAgB,CAAC;AAE/B,oBAAoB;AACpB,cAAc,uBAAuB,CAAC;AAEtC,sBAAsB;AACtB,cAAc,yBAAyB,CAAC;AAExC,gBAAgB;AAChB,cAAc,mBAAmB,CAAC;AAElC,yBAAyB;AACzB,cAAc,oBAAoB,CAAC;AAEnC,qBAAqB;AACrB,cAAc,wBAAwB,CAAC;AAEvC,wBAAwB;AACxB,cAAc,kBAAkB,CAAC;AAEjC,yBAAyB;AACzB,cAAc,qBAAqB,CAAC;AAEpC,yDAAyD;AACzD,oEAAoE;AACpE,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAE,CAAC;AAEpB,gEAAgE;AAChE,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,0BAA0B,EAC1B,qBAAqB,EACrB,kBAAkB,EAClB,wBAAwB,EACxB,mBAAmB,EACnB,qBAAqB,EACrB,YAAY,EACZ,0BAA0B,EAC1B,aAAa,EACb,cAAc,EACd,eAAe,EACf,cAAc,EACd,aAAa,EACb,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc;AACd,+BAA+B;AAC/B,yBAAyB,EACzB,8BAA8B,EAC9B,SAAS,EACT,oBAAoB,EACpB,qBAAqB,EACrB,iBAAiB,GAClB,MAAM,qBAAqB,CAAC;AAqC7B,8DAA8D;AAC9D,yCAAyC;AACzC,2CAA2C;AAC3C,sCAAsC;AAEtC;;;;;;;;;;GAUG"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * EARS to Formal Spec Converter Tests
3
+ *
4
+ * Tests for EARS requirement parsing and SMT-LIB generation.
5
+ *
6
+ * @see TSK-SYMB-009
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=ears-to-formal.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ears-to-formal.test.d.ts","sourceRoot":"","sources":["../../../src/symbolic/__tests__/ears-to-formal.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,187 @@
1
+ /**
2
+ * EARS to Formal Spec Converter Tests
3
+ *
4
+ * Tests for EARS requirement parsing and SMT-LIB generation.
5
+ *
6
+ * @see TSK-SYMB-009
7
+ */
8
+ import { describe, it, expect, beforeEach } from 'vitest';
9
+ import { EarsToFormalSpecConverter, parseEarsRequirement, generateSmtLib, } from '../ears-to-formal.js';
10
+ describe('EarsToFormalSpecConverter', () => {
11
+ let converter;
12
+ beforeEach(() => {
13
+ converter = new EarsToFormalSpecConverter();
14
+ });
15
+ describe('parseEarsRequirement', () => {
16
+ it('should parse ubiquitous pattern (THE system SHALL requirement)', () => {
17
+ const result = parseEarsRequirement('REQ-001', 'THE system SHALL validate all user inputs');
18
+ expect(result.success).toBe(true);
19
+ if (result.success) {
20
+ expect(result.ast.pattern).toBe('ubiquitous');
21
+ expect(result.ast.system).toBe('system');
22
+ expect(result.ast.requirement).toBe('validate all user inputs');
23
+ expect(result.ast.requirementId).toBe('REQ-001');
24
+ }
25
+ });
26
+ it('should parse event-driven pattern (WHEN event, THE system SHALL response)', () => {
27
+ const result = parseEarsRequirement('REQ-002', 'WHEN user clicks submit, THE system SHALL save the form data');
28
+ expect(result.success).toBe(true);
29
+ if (result.success) {
30
+ expect(result.ast.pattern).toBe('event-driven');
31
+ expect(result.ast.event).toBe('user clicks submit');
32
+ expect(result.ast.system).toBe('system');
33
+ expect(result.ast.requirement).toBe('save the form data');
34
+ }
35
+ });
36
+ it('should parse state-driven pattern (WHILE state, THE system SHALL response)', () => {
37
+ const result = parseEarsRequirement('REQ-003', 'WHILE system is in maintenance mode, THE API SHALL return 503 status');
38
+ expect(result.success).toBe(true);
39
+ if (result.success) {
40
+ expect(result.ast.pattern).toBe('state-driven');
41
+ expect(result.ast.state).toBe('system is in maintenance mode');
42
+ expect(result.ast.system).toBe('API');
43
+ expect(result.ast.requirement).toBe('return 503 status');
44
+ }
45
+ });
46
+ it('should parse unwanted pattern (THE system SHALL NOT behavior)', () => {
47
+ const result = parseEarsRequirement('REQ-004', 'THE system SHALL NOT store passwords in plain text');
48
+ expect(result.success).toBe(true);
49
+ if (result.success) {
50
+ expect(result.ast.pattern).toBe('unwanted');
51
+ expect(result.ast.system).toBe('system');
52
+ expect(result.ast.unwantedBehavior).toBe('store passwords in plain text');
53
+ }
54
+ });
55
+ it('should parse optional pattern (IF condition, THEN THE system SHALL response)', () => {
56
+ const result = parseEarsRequirement('REQ-005', 'IF user is premium, THEN THE system SHALL provide advanced features');
57
+ expect(result.success).toBe(true);
58
+ if (result.success) {
59
+ expect(result.ast.pattern).toBe('optional');
60
+ expect(result.ast.condition).toBe('user is premium');
61
+ expect(result.ast.system).toBe('system');
62
+ expect(result.ast.requirement).toBe('provide advanced features');
63
+ }
64
+ });
65
+ it('should return error for non-EARS format', () => {
66
+ const result = parseEarsRequirement('REQ-006', 'The system should work properly');
67
+ expect(result.success).toBe(false);
68
+ if (!result.success) {
69
+ expect(result.error).toContain('EARS pattern');
70
+ }
71
+ });
72
+ it('should be case-insensitive for keywords', () => {
73
+ const result = parseEarsRequirement('REQ-007', 'the System shall Process all requests');
74
+ expect(result.success).toBe(true);
75
+ if (result.success) {
76
+ expect(result.ast.pattern).toBe('ubiquitous');
77
+ }
78
+ });
79
+ });
80
+ describe('generateSmtLib', () => {
81
+ it('should generate SMT-LIB for ubiquitous pattern', () => {
82
+ const ast = {
83
+ requirementId: 'REQ-001',
84
+ pattern: 'ubiquitous',
85
+ system: 'system',
86
+ requirement: 'validate inputs',
87
+ originalText: 'THE system SHALL validate inputs',
88
+ parsedAt: new Date().toISOString(),
89
+ };
90
+ const result = generateSmtLib(ast);
91
+ expect(result.smtLib).toContain('REQ-001');
92
+ expect(result.smtLib).toContain('declare-const');
93
+ expect(result.requirementId).toBe('REQ-001');
94
+ expect(result.variables.length).toBeGreaterThan(0);
95
+ expect(result.assertions.length).toBeGreaterThan(0);
96
+ });
97
+ it('should generate SMT-LIB for event-driven pattern with implication', () => {
98
+ const ast = {
99
+ requirementId: 'REQ-002',
100
+ pattern: 'event-driven',
101
+ system: 'system',
102
+ requirement: 'respond quickly',
103
+ event: 'user clicks',
104
+ originalText: 'WHEN user clicks, THE system SHALL respond quickly',
105
+ parsedAt: new Date().toISOString(),
106
+ };
107
+ const result = generateSmtLib(ast);
108
+ expect(result.smtLib).toContain('user_clicks');
109
+ // Event-driven pattern should have implication logic
110
+ expect(result.assertions.length).toBeGreaterThan(0);
111
+ });
112
+ it('should generate SMT-LIB for unwanted pattern with negation', () => {
113
+ const ast = {
114
+ requirementId: 'REQ-003',
115
+ pattern: 'unwanted',
116
+ system: 'system',
117
+ requirement: 'NOT store plaintext',
118
+ unwantedBehavior: 'store plaintext',
119
+ originalText: 'THE system SHALL NOT store plaintext',
120
+ parsedAt: new Date().toISOString(),
121
+ };
122
+ const result = generateSmtLib(ast);
123
+ expect(result.smtLib).toContain('not');
124
+ });
125
+ it('should include explanation with reasoning', () => {
126
+ const ast = {
127
+ requirementId: 'REQ-004',
128
+ pattern: 'ubiquitous',
129
+ system: 'API',
130
+ requirement: 'return JSON',
131
+ originalText: 'THE API SHALL return JSON',
132
+ parsedAt: new Date().toISOString(),
133
+ };
134
+ const result = generateSmtLib(ast);
135
+ expect(result.explanation.summary).toContain('SMT-LIB');
136
+ expect(result.explanation.reasoning.length).toBeGreaterThan(0);
137
+ expect(result.explanation.relatedRequirements).toContain('REQ-004');
138
+ });
139
+ });
140
+ describe('EarsToFormalSpecConverter class', () => {
141
+ it('should parse requirements using parse method', () => {
142
+ const result = converter.parse('REQ-001', 'THE system SHALL work');
143
+ expect(result.success).toBe(true);
144
+ });
145
+ it('should convert single requirement to SMT-LIB', () => {
146
+ const result = converter.convert({
147
+ id: 'REQ-001',
148
+ text: 'THE system SHALL validate inputs',
149
+ type: 'ubiquitous',
150
+ });
151
+ expect(result.smtLib).toBeTruthy();
152
+ expect(result.requirementId).toBe('REQ-001');
153
+ });
154
+ it('should handle parse errors gracefully in convert', () => {
155
+ const result = converter.convert({
156
+ id: 'REQ-INVALID',
157
+ text: 'This is not EARS format',
158
+ type: 'ubiquitous',
159
+ });
160
+ expect(result.smtLib).toContain('Error');
161
+ expect(result.explanation.summary).toContain('Failed');
162
+ });
163
+ it('should convert multiple requirements', () => {
164
+ const requirements = [
165
+ { id: 'REQ-001', text: 'THE system SHALL validate inputs', type: 'ubiquitous' },
166
+ { id: 'REQ-002', text: 'WHEN error occurs, THE system SHALL log it', type: 'event-driven' },
167
+ ];
168
+ const result = converter.convertAll(requirements);
169
+ expect(result.astNodes.length).toBe(2);
170
+ expect(result.smtOutputs.length).toBe(2);
171
+ expect(result.combinedSmtLib).toContain('REQ-001');
172
+ expect(result.combinedSmtLib).toContain('REQ-002');
173
+ });
174
+ it('should generate combined SMT-LIB with all requirements', () => {
175
+ const requirements = [
176
+ { id: 'REQ-001', text: 'THE API SHALL return JSON', type: 'ubiquitous' },
177
+ { id: 'REQ-002', text: 'THE API SHALL NOT leak secrets', type: 'unwanted' },
178
+ ];
179
+ const result = converter.convertAll(requirements);
180
+ expect(result.combinedSmtLib).toContain('Combined');
181
+ expect(result.combinedSmtLib).toContain('check-sat');
182
+ expect(result.explanation.relatedRequirements).toContain('REQ-001');
183
+ expect(result.explanation.relatedRequirements).toContain('REQ-002');
184
+ });
185
+ });
186
+ });
187
+ //# sourceMappingURL=ears-to-formal.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ears-to-formal.test.js","sourceRoot":"","sources":["../../../src/symbolic/__tests__/ears-to-formal.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Quality Gate Validator Tests
3
+ *
4
+ * Tests for TSK-SYMB-019: Quality Gate validation
5
+ *
6
+ * @module quality-gate.test
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=quality-gate.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"quality-gate.test.d.ts","sourceRoot":"","sources":["../../../src/symbolic/__tests__/quality-gate.test.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG"}
@@ -0,0 +1,230 @@
1
+ /**
2
+ * Quality Gate Validator Tests
3
+ *
4
+ * Tests for TSK-SYMB-019: Quality Gate validation
5
+ *
6
+ * @module quality-gate.test
7
+ */
8
+ import { describe, it, expect, beforeEach } from 'vitest';
9
+ import { QualityGateValidator, createComponentValidation, } from '../quality-gate.js';
10
+ describe('QualityGateValidator', () => {
11
+ let validator;
12
+ let fullTraceability;
13
+ let fullComponents;
14
+ beforeEach(() => {
15
+ validator = new QualityGateValidator();
16
+ // Create full traceability for 27 requirements
17
+ fullTraceability = [
18
+ // Semantic Filter requirements
19
+ { requirementId: 'REQ-SF-001', designIds: ['DES-001'], taskIds: ['TSK-001'], testIds: ['TEST-001'], coveragePercent: 100 },
20
+ { requirementId: 'REQ-SF-002', designIds: ['DES-001'], taskIds: ['TSK-001'], testIds: ['TEST-002'], coveragePercent: 100 },
21
+ { requirementId: 'REQ-SF-003', designIds: ['DES-001'], taskIds: ['TSK-002'], testIds: ['TEST-003'], coveragePercent: 100 },
22
+ // Formal Verification requirements
23
+ { requirementId: 'REQ-FV-001', designIds: ['DES-002'], taskIds: ['TSK-003'], testIds: ['TEST-004'], coveragePercent: 100 },
24
+ { requirementId: 'REQ-FV-002', designIds: ['DES-002'], taskIds: ['TSK-003'], testIds: ['TEST-005'], coveragePercent: 100 },
25
+ { requirementId: 'REQ-FV-003', designIds: ['DES-002'], taskIds: ['TSK-004'], testIds: ['TEST-006'], coveragePercent: 100 },
26
+ { requirementId: 'REQ-FV-004', designIds: ['DES-002'], taskIds: ['TSK-004'], testIds: ['TEST-007'], coveragePercent: 100 },
27
+ { requirementId: 'REQ-FV-005', designIds: ['DES-002'], taskIds: ['TSK-005'], testIds: ['TEST-008'], coveragePercent: 100 },
28
+ // Constitution requirements
29
+ { requirementId: 'REQ-CONST-001', designIds: ['DES-003'], taskIds: ['TSK-006'], testIds: ['TEST-009'], coveragePercent: 100 },
30
+ { requirementId: 'REQ-CONST-002', designIds: ['DES-003'], taskIds: ['TSK-006'], testIds: ['TEST-010'], coveragePercent: 100 },
31
+ { requirementId: 'REQ-CONST-003', designIds: ['DES-003'], taskIds: ['TSK-007'], testIds: ['TEST-011'], coveragePercent: 100 },
32
+ { requirementId: 'REQ-CONST-004', designIds: ['DES-003'], taskIds: ['TSK-007'], testIds: ['TEST-012'], coveragePercent: 100 },
33
+ { requirementId: 'REQ-CONST-005', designIds: ['DES-003'], taskIds: ['TSK-008'], testIds: ['TEST-013'], coveragePercent: 100 },
34
+ { requirementId: 'REQ-CONST-006', designIds: ['DES-003'], taskIds: ['TSK-008'], testIds: ['TEST-014'], coveragePercent: 100 },
35
+ { requirementId: 'REQ-CONST-007', designIds: ['DES-003'], taskIds: ['TSK-009'], testIds: ['TEST-015'], coveragePercent: 100 },
36
+ { requirementId: 'REQ-CONST-008', designIds: ['DES-003'], taskIds: ['TSK-009'], testIds: ['TEST-016'], coveragePercent: 100 },
37
+ { requirementId: 'REQ-CONST-009', designIds: ['DES-003'], taskIds: ['TSK-010'], testIds: ['TEST-017'], coveragePercent: 100 },
38
+ { requirementId: 'REQ-CONST-010', designIds: ['DES-003'], taskIds: ['TSK-010'], testIds: ['TEST-018'], coveragePercent: 100 },
39
+ // Routing requirements
40
+ { requirementId: 'REQ-ROUTE-001', designIds: ['DES-004'], taskIds: ['TSK-011'], testIds: ['TEST-019'], coveragePercent: 100 },
41
+ { requirementId: 'REQ-ROUTE-002', designIds: ['DES-004'], taskIds: ['TSK-011'], testIds: ['TEST-020'], coveragePercent: 100 },
42
+ { requirementId: 'REQ-ROUTE-003', designIds: ['DES-004'], taskIds: ['TSK-012'], testIds: ['TEST-021'], coveragePercent: 100 },
43
+ // Non-functional requirements
44
+ { requirementId: 'REQ-NFR-001', designIds: ['DES-005'], taskIds: ['TSK-013'], testIds: ['TEST-022'], coveragePercent: 100 },
45
+ { requirementId: 'REQ-NFR-002', designIds: ['DES-005'], taskIds: ['TSK-013'], testIds: ['TEST-023'], coveragePercent: 100 },
46
+ { requirementId: 'REQ-NFR-003', designIds: ['DES-005'], taskIds: ['TSK-014'], testIds: ['TEST-024'], coveragePercent: 100 },
47
+ { requirementId: 'REQ-NFR-004', designIds: ['DES-005'], taskIds: ['TSK-014'], testIds: ['TEST-025'], coveragePercent: 100 },
48
+ { requirementId: 'REQ-NFR-005', designIds: ['DES-005'], taskIds: ['TSK-015'], testIds: ['TEST-026'], coveragePercent: 100 },
49
+ { requirementId: 'REQ-NFR-006', designIds: ['DES-005'], taskIds: ['TSK-015'], testIds: ['TEST-027'], coveragePercent: 100 },
50
+ ];
51
+ // Create fully compliant component validation
52
+ fullComponents = createComponentValidation({
53
+ performanceBudgetDefined: true,
54
+ extensibleConfigDefined: true,
55
+ explanationGeneratorDefined: true,
56
+ securityMaskingDefined: true,
57
+ auditLoggingDefined: true,
58
+ libraryFirstCompliant: true,
59
+ cliInterfaceDefined: true,
60
+ testFirstCompliant: true,
61
+ earsFormatCompliant: true,
62
+ traceabilityCompliant: true,
63
+ projectMemoryCompliant: true,
64
+ designPatternsDocumented: true,
65
+ adrCompliant: true,
66
+ qualityGatesConfigured: true,
67
+ });
68
+ });
69
+ describe('validate', () => {
70
+ it('should pass when all criteria are met', () => {
71
+ const result = validator.validate(fullTraceability, fullComponents);
72
+ expect(result.passed).toBe(true);
73
+ expect(result.gateName).toBe('DES-SYMB-001 Implementation Gate');
74
+ expect(result.phase).toBe('design');
75
+ expect(result.summary.blockerCount).toBe(0);
76
+ expect(result.summary.criticalCount).toBe(0);
77
+ });
78
+ it('should fail when design coverage is incomplete', () => {
79
+ // Remove design IDs from some requirements
80
+ const incompleteTraceability = fullTraceability.map((t, i) => i < 3 ? { ...t, designIds: [] } : t);
81
+ const result = validator.validate(incompleteTraceability, fullComponents);
82
+ expect(result.passed).toBe(false);
83
+ expect(result.summary.blockerCount).toBeGreaterThan(0);
84
+ const designCheck = result.checks.find(c => c.checkId === 'QG-TRACE-001');
85
+ expect(designCheck?.passed).toBe(false);
86
+ });
87
+ it('should fail when performance budget is not defined', () => {
88
+ const incompleteComponents = createComponentValidation({
89
+ ...fullComponents,
90
+ performanceBudgetDefined: false,
91
+ });
92
+ const result = validator.validate(fullTraceability, incompleteComponents);
93
+ expect(result.passed).toBe(false);
94
+ const perfCheck = result.checks.find(c => c.checkId === 'QG-NFR-001');
95
+ expect(perfCheck?.passed).toBe(false);
96
+ expect(perfCheck?.severity).toBe('blocker');
97
+ });
98
+ it('should fail when audit logging is not defined', () => {
99
+ const incompleteComponents = createComponentValidation({
100
+ ...fullComponents,
101
+ auditLoggingDefined: false,
102
+ });
103
+ const result = validator.validate(fullTraceability, incompleteComponents);
104
+ expect(result.passed).toBe(false);
105
+ const auditCheck = result.checks.find(c => c.checkId === 'QG-SEC-002');
106
+ expect(auditCheck?.passed).toBe(false);
107
+ expect(auditCheck?.severity).toBe('blocker');
108
+ });
109
+ it('should check all 9 Constitution articles', () => {
110
+ const result = validator.validate(fullTraceability, fullComponents);
111
+ const constitutionChecks = result.checks.filter(c => c.category === 'constitution');
112
+ expect(constitutionChecks.length).toBe(9);
113
+ // All should pass
114
+ for (const check of constitutionChecks) {
115
+ expect(check.passed).toBe(true);
116
+ }
117
+ });
118
+ it('should fail for non-compliant Constitution articles', () => {
119
+ const incompleteComponents = createComponentValidation({
120
+ ...fullComponents,
121
+ traceabilityCompliant: false, // Article V
122
+ });
123
+ const result = validator.validate(fullTraceability, incompleteComponents);
124
+ expect(result.passed).toBe(false);
125
+ const articleVCheck = result.checks.find(c => c.checkId === 'QG-CONST-V');
126
+ expect(articleVCheck?.passed).toBe(false);
127
+ expect(articleVCheck?.severity).toBe('blocker'); // Article V is blocker
128
+ });
129
+ it('should include explanation with reasoning', () => {
130
+ const result = validator.validate(fullTraceability, fullComponents);
131
+ expect(result.explanation).toBeDefined();
132
+ expect(result.explanation.summary).toContain('PASSED');
133
+ expect(result.explanation.reasoning.length).toBeGreaterThan(0);
134
+ expect(result.explanation.evidence.length).toBeGreaterThan(0);
135
+ });
136
+ });
137
+ describe('custom configuration', () => {
138
+ it('should use custom min design coverage', () => {
139
+ const customConfig = {
140
+ minDesignCoverage: 90,
141
+ };
142
+ const customValidator = new QualityGateValidator(customConfig);
143
+ // Remove design from ~5% of requirements (2 out of 27)
144
+ const partialTraceability = fullTraceability.map((t, i) => i < 2 ? { ...t, designIds: [] } : t);
145
+ const result = customValidator.validate(partialTraceability, fullComponents);
146
+ // 25/27 = 92.6% > 90%, should pass
147
+ const designCheck = result.checks.find(c => c.checkId === 'QG-TRACE-001');
148
+ expect(designCheck?.passed).toBe(true);
149
+ });
150
+ });
151
+ describe('generateApprovalReport', () => {
152
+ it('should generate markdown report for passed gate', () => {
153
+ const result = validator.validate(fullTraceability, fullComponents);
154
+ const report = validator.generateApprovalReport(result);
155
+ expect(report).toContain('# Quality Gate Approval Report');
156
+ expect(report).toContain('✅ PASSED');
157
+ expect(report).toContain('## Summary');
158
+ expect(report).toContain('## Traceability Checks');
159
+ expect(report).toContain('## Non-Functional Checks');
160
+ expect(report).toContain('## Security & Audit Checks');
161
+ expect(report).toContain('## Constitution Checks');
162
+ expect(report).toContain('## Approval Record');
163
+ });
164
+ it('should generate markdown report for failed gate', () => {
165
+ const incompleteComponents = createComponentValidation({
166
+ ...fullComponents,
167
+ performanceBudgetDefined: false,
168
+ auditLoggingDefined: false,
169
+ });
170
+ const result = validator.validate(fullTraceability, incompleteComponents);
171
+ const report = validator.generateApprovalReport(result);
172
+ expect(report).toContain('❌ FAILED');
173
+ expect(report).toContain('🚫'); // Blocker icon
174
+ });
175
+ });
176
+ describe('createComponentValidation', () => {
177
+ it('should create validation with defaults', () => {
178
+ const validation = createComponentValidation({});
179
+ expect(validation.performanceBudgetDefined).toBe(false);
180
+ expect(validation.auditLoggingDefined).toBe(false);
181
+ expect(validation.libraryFirstCompliant).toBe(false);
182
+ });
183
+ it('should create validation with partial overrides', () => {
184
+ const validation = createComponentValidation({
185
+ performanceBudgetDefined: true,
186
+ auditLoggingDefined: true,
187
+ });
188
+ expect(validation.performanceBudgetDefined).toBe(true);
189
+ expect(validation.auditLoggingDefined).toBe(true);
190
+ expect(validation.extensibleConfigDefined).toBe(false);
191
+ });
192
+ });
193
+ describe('traceability checks', () => {
194
+ it('should detect coverage gaps', () => {
195
+ // Create traceability with gaps
196
+ const gappyTraceability = fullTraceability.map((t, i) => i % 3 === 0 ? { ...t, coveragePercent: 50 } : t);
197
+ const result = validator.validate(gappyTraceability, fullComponents);
198
+ const gapCheck = result.checks.find(c => c.checkId === 'QG-TRACE-003');
199
+ expect(gapCheck?.passed).toBe(false);
200
+ expect(gapCheck?.message).toContain('coverage gaps');
201
+ });
202
+ it('should report task coverage', () => {
203
+ const result = validator.validate(fullTraceability, fullComponents);
204
+ const taskCheck = result.checks.find(c => c.checkId === 'QG-TRACE-002');
205
+ expect(taskCheck?.passed).toBe(true);
206
+ expect(taskCheck?.message).toContain('100');
207
+ });
208
+ });
209
+ describe('edge cases', () => {
210
+ it('should handle empty traceability', () => {
211
+ const result = validator.validate([], fullComponents);
212
+ expect(result.checks.length).toBeGreaterThan(0);
213
+ // Design coverage should be 0% which fails
214
+ const designCheck = result.checks.find(c => c.checkId === 'QG-TRACE-001');
215
+ expect(designCheck?.passed).toBe(false);
216
+ });
217
+ it('should handle partial component validation', () => {
218
+ const partialComponents = createComponentValidation({
219
+ performanceBudgetDefined: true,
220
+ auditLoggingDefined: true,
221
+ // Everything else defaults to false
222
+ });
223
+ const result = validator.validate(fullTraceability, partialComponents);
224
+ // Should fail due to missing components
225
+ expect(result.passed).toBe(false);
226
+ expect(result.summary.criticalCount).toBeGreaterThan(0);
227
+ });
228
+ });
229
+ });
230
+ //# sourceMappingURL=quality-gate.test.js.map