decision_agent 0.3.0 → 1.0.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 (115) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +272 -7
  3. data/lib/decision_agent/agent.rb +72 -1
  4. data/lib/decision_agent/context.rb +1 -0
  5. data/lib/decision_agent/data_enrichment/cache/memory_adapter.rb +86 -0
  6. data/lib/decision_agent/data_enrichment/cache_adapter.rb +49 -0
  7. data/lib/decision_agent/data_enrichment/circuit_breaker.rb +135 -0
  8. data/lib/decision_agent/data_enrichment/client.rb +220 -0
  9. data/lib/decision_agent/data_enrichment/config.rb +78 -0
  10. data/lib/decision_agent/data_enrichment/errors.rb +36 -0
  11. data/lib/decision_agent/decision.rb +102 -2
  12. data/lib/decision_agent/dmn/feel/evaluator.rb +28 -6
  13. data/lib/decision_agent/dsl/condition_evaluator.rb +982 -839
  14. data/lib/decision_agent/dsl/schema_validator.rb +51 -13
  15. data/lib/decision_agent/evaluators/dmn_evaluator.rb +106 -19
  16. data/lib/decision_agent/evaluators/json_rule_evaluator.rb +69 -9
  17. data/lib/decision_agent/explainability/condition_trace.rb +83 -0
  18. data/lib/decision_agent/explainability/explainability_result.rb +52 -0
  19. data/lib/decision_agent/explainability/rule_trace.rb +39 -0
  20. data/lib/decision_agent/explainability/trace_collector.rb +24 -0
  21. data/lib/decision_agent/monitoring/alert_manager.rb +5 -1
  22. data/lib/decision_agent/simulation/errors.rb +18 -0
  23. data/lib/decision_agent/simulation/impact_analyzer.rb +498 -0
  24. data/lib/decision_agent/simulation/monte_carlo_simulator.rb +635 -0
  25. data/lib/decision_agent/simulation/replay_engine.rb +486 -0
  26. data/lib/decision_agent/simulation/scenario_engine.rb +318 -0
  27. data/lib/decision_agent/simulation/scenario_library.rb +163 -0
  28. data/lib/decision_agent/simulation/shadow_test_engine.rb +287 -0
  29. data/lib/decision_agent/simulation/what_if_analyzer.rb +1002 -0
  30. data/lib/decision_agent/simulation.rb +17 -0
  31. data/lib/decision_agent/version.rb +1 -1
  32. data/lib/decision_agent/versioning/activerecord_adapter.rb +23 -8
  33. data/lib/decision_agent/web/public/app.js +119 -0
  34. data/lib/decision_agent/web/public/index.html +49 -0
  35. data/lib/decision_agent/web/public/simulation.html +130 -0
  36. data/lib/decision_agent/web/public/simulation_impact.html +478 -0
  37. data/lib/decision_agent/web/public/simulation_replay.html +551 -0
  38. data/lib/decision_agent/web/public/simulation_shadow.html +546 -0
  39. data/lib/decision_agent/web/public/simulation_whatif.html +532 -0
  40. data/lib/decision_agent/web/public/styles.css +65 -0
  41. data/lib/decision_agent/web/server.rb +594 -23
  42. data/lib/decision_agent.rb +60 -2
  43. metadata +53 -73
  44. data/spec/ab_testing/ab_test_assignment_spec.rb +0 -253
  45. data/spec/ab_testing/ab_test_manager_spec.rb +0 -612
  46. data/spec/ab_testing/ab_test_spec.rb +0 -270
  47. data/spec/ab_testing/ab_testing_agent_spec.rb +0 -655
  48. data/spec/ab_testing/storage/adapter_spec.rb +0 -64
  49. data/spec/ab_testing/storage/memory_adapter_spec.rb +0 -485
  50. data/spec/activerecord_thread_safety_spec.rb +0 -553
  51. data/spec/advanced_operators_spec.rb +0 -3150
  52. data/spec/agent_spec.rb +0 -289
  53. data/spec/api_contract_spec.rb +0 -430
  54. data/spec/audit_adapters_spec.rb +0 -92
  55. data/spec/auth/access_audit_logger_spec.rb +0 -394
  56. data/spec/auth/authenticator_spec.rb +0 -112
  57. data/spec/auth/password_reset_spec.rb +0 -294
  58. data/spec/auth/permission_checker_spec.rb +0 -207
  59. data/spec/auth/permission_spec.rb +0 -73
  60. data/spec/auth/rbac_adapter_spec.rb +0 -778
  61. data/spec/auth/rbac_config_spec.rb +0 -82
  62. data/spec/auth/role_spec.rb +0 -51
  63. data/spec/auth/session_manager_spec.rb +0 -172
  64. data/spec/auth/session_spec.rb +0 -112
  65. data/spec/auth/user_spec.rb +0 -130
  66. data/spec/comprehensive_edge_cases_spec.rb +0 -1777
  67. data/spec/context_spec.rb +0 -127
  68. data/spec/decision_agent_spec.rb +0 -96
  69. data/spec/decision_spec.rb +0 -423
  70. data/spec/dmn/decision_graph_spec.rb +0 -282
  71. data/spec/dmn/decision_tree_spec.rb +0 -203
  72. data/spec/dmn/feel/errors_spec.rb +0 -18
  73. data/spec/dmn/feel/functions_spec.rb +0 -400
  74. data/spec/dmn/feel/simple_parser_spec.rb +0 -274
  75. data/spec/dmn/feel/types_spec.rb +0 -176
  76. data/spec/dmn/feel_parser_spec.rb +0 -489
  77. data/spec/dmn/hit_policy_spec.rb +0 -202
  78. data/spec/dmn/integration_spec.rb +0 -226
  79. data/spec/dsl/condition_evaluator_spec.rb +0 -774
  80. data/spec/dsl_validation_spec.rb +0 -648
  81. data/spec/edge_cases_spec.rb +0 -353
  82. data/spec/evaluation_spec.rb +0 -364
  83. data/spec/evaluation_validator_spec.rb +0 -165
  84. data/spec/examples/feedback_aware_evaluator_spec.rb +0 -460
  85. data/spec/examples.txt +0 -1909
  86. data/spec/fixtures/dmn/complex_decision.dmn +0 -81
  87. data/spec/fixtures/dmn/invalid_structure.dmn +0 -31
  88. data/spec/fixtures/dmn/simple_decision.dmn +0 -40
  89. data/spec/issue_verification_spec.rb +0 -759
  90. data/spec/json_rule_evaluator_spec.rb +0 -587
  91. data/spec/monitoring/alert_manager_spec.rb +0 -378
  92. data/spec/monitoring/metrics_collector_spec.rb +0 -501
  93. data/spec/monitoring/monitored_agent_spec.rb +0 -225
  94. data/spec/monitoring/prometheus_exporter_spec.rb +0 -242
  95. data/spec/monitoring/storage/activerecord_adapter_spec.rb +0 -498
  96. data/spec/monitoring/storage/base_adapter_spec.rb +0 -61
  97. data/spec/monitoring/storage/memory_adapter_spec.rb +0 -247
  98. data/spec/performance_optimizations_spec.rb +0 -493
  99. data/spec/replay_edge_cases_spec.rb +0 -699
  100. data/spec/replay_spec.rb +0 -210
  101. data/spec/rfc8785_canonicalization_spec.rb +0 -215
  102. data/spec/scoring_spec.rb +0 -225
  103. data/spec/spec_helper.rb +0 -60
  104. data/spec/testing/batch_test_importer_spec.rb +0 -693
  105. data/spec/testing/batch_test_runner_spec.rb +0 -307
  106. data/spec/testing/test_coverage_analyzer_spec.rb +0 -292
  107. data/spec/testing/test_result_comparator_spec.rb +0 -392
  108. data/spec/testing/test_scenario_spec.rb +0 -113
  109. data/spec/thread_safety_spec.rb +0 -490
  110. data/spec/thread_safety_spec.rb.broken +0 -878
  111. data/spec/versioning/adapter_spec.rb +0 -156
  112. data/spec/versioning_spec.rb +0 -1030
  113. data/spec/web/middleware/auth_middleware_spec.rb +0 -133
  114. data/spec/web/middleware/permission_middleware_spec.rb +0 -247
  115. data/spec/web_ui_rack_spec.rb +0 -2134
@@ -1,156 +0,0 @@
1
- require "spec_helper"
2
- require "fileutils"
3
- require "tempfile"
4
- require "decision_agent/versioning/adapter"
5
- require "decision_agent/versioning/file_storage_adapter"
6
-
7
- RSpec.describe DecisionAgent::Versioning::Adapter do
8
- let(:temp_dir) { Dir.mktmpdir }
9
- let(:adapter) { DecisionAgent::Versioning::FileStorageAdapter.new(storage_path: temp_dir) }
10
- let(:rule_id) { "test_rule_001" }
11
- let(:rule_content) do
12
- {
13
- version: "1.0",
14
- ruleset: "test_ruleset",
15
- rules: [
16
- {
17
- id: "rule_1",
18
- if: { field: "amount", op: "gt", value: 100 },
19
- then: { decision: "approve", weight: 0.8, reason: "High value" }
20
- }
21
- ]
22
- }
23
- end
24
-
25
- after do
26
- FileUtils.rm_rf(temp_dir)
27
- end
28
-
29
- describe "#compare_versions" do
30
- it "returns nil when first version doesn't exist" do
31
- v2 = adapter.create_version(rule_id: rule_id, content: rule_content)
32
-
33
- comparison = adapter.compare_versions(version_id_1: "nonexistent", version_id_2: v2[:id])
34
- expect(comparison).to be_nil
35
- end
36
-
37
- it "returns nil when second version doesn't exist" do
38
- v1 = adapter.create_version(rule_id: rule_id, content: rule_content)
39
-
40
- comparison = adapter.compare_versions(version_id_1: v1[:id], version_id_2: "nonexistent")
41
- expect(comparison).to be_nil
42
- end
43
-
44
- it "calculates differences correctly with added keys" do
45
- content1 = { key1: "value1", key2: "value2" }
46
- content2 = { key1: "value1", key2: "value2", key3: "value3" }
47
-
48
- v1 = adapter.create_version(rule_id: rule_id, content: content1)
49
- v2 = adapter.create_version(rule_id: "rule_2", content: content2)
50
-
51
- comparison = adapter.compare_versions(version_id_1: v1[:id], version_id_2: v2[:id])
52
-
53
- expect(comparison[:differences][:added]).not_to be_empty
54
- end
55
-
56
- it "calculates differences correctly with removed keys" do
57
- content1 = { key1: "value1", key2: "value2", key3: "value3" }
58
- content2 = { key1: "value1", key2: "value2" }
59
-
60
- v1 = adapter.create_version(rule_id: rule_id, content: content1)
61
- v2 = adapter.create_version(rule_id: "rule_2", content: content2)
62
-
63
- comparison = adapter.compare_versions(version_id_1: v1[:id], version_id_2: v2[:id])
64
-
65
- expect(comparison[:differences][:removed]).not_to be_empty
66
- end
67
-
68
- it "calculates differences correctly with changed values" do
69
- content1 = { key1: "value1", key2: "value2" }
70
- content2 = { key1: "value1", key2: "value2_changed" }
71
-
72
- v1 = adapter.create_version(rule_id: rule_id, content: content1)
73
- v2 = adapter.create_version(rule_id: "rule_2", content: content2)
74
-
75
- comparison = adapter.compare_versions(version_id_1: v1[:id], version_id_2: v2[:id])
76
-
77
- expect(comparison[:differences][:changed]).to have_key(:key2)
78
- expect(comparison[:differences][:changed][:key2][:old]).to eq("value2")
79
- expect(comparison[:differences][:changed][:key2][:new]).to eq("value2_changed")
80
- end
81
-
82
- it "does not include nil values in changed differences" do
83
- content1 = { key1: "value1", key2: "value2" }
84
- content2 = { key1: "value1", key2: nil }
85
-
86
- v1 = adapter.create_version(rule_id: rule_id, content: content1)
87
- v2 = adapter.create_version(rule_id: "rule_2", content: content2)
88
-
89
- comparison = adapter.compare_versions(version_id_1: v1[:id], version_id_2: v2[:id])
90
-
91
- # key2 should not be in changed since new value is nil
92
- expect(comparison[:differences][:changed]).not_to have_key(:key2)
93
- end
94
-
95
- it "returns identical versions with empty differences" do
96
- v1 = adapter.create_version(rule_id: rule_id, content: rule_content)
97
- v2 = adapter.create_version(rule_id: "rule_2", content: rule_content)
98
-
99
- comparison = adapter.compare_versions(version_id_1: v1[:id], version_id_2: v2[:id])
100
-
101
- expect(comparison[:differences][:added]).to be_empty
102
- expect(comparison[:differences][:removed]).to be_empty
103
- expect(comparison[:differences][:changed]).to be_empty
104
- end
105
- end
106
-
107
- describe "abstract methods" do
108
- # Test that abstract methods raise NotImplementedError when called on base class
109
- # We use a minimal test adapter class for this
110
- let(:abstract_adapter) do
111
- Class.new(DecisionAgent::Versioning::Adapter).new
112
- end
113
-
114
- it "raises NotImplementedError for create_version" do
115
- expect do
116
- abstract_adapter.create_version(rule_id: "test", content: {})
117
- end.to raise_error(NotImplementedError)
118
- end
119
-
120
- it "raises NotImplementedError for list_versions" do
121
- expect do
122
- abstract_adapter.list_versions(rule_id: "test")
123
- end.to raise_error(NotImplementedError)
124
- end
125
-
126
- it "raises NotImplementedError for get_version" do
127
- expect do
128
- abstract_adapter.get_version(version_id: "test")
129
- end.to raise_error(NotImplementedError)
130
- end
131
-
132
- it "raises NotImplementedError for get_version_by_number" do
133
- expect do
134
- abstract_adapter.get_version_by_number(rule_id: "test", version_number: 1)
135
- end.to raise_error(NotImplementedError)
136
- end
137
-
138
- it "raises NotImplementedError for get_active_version" do
139
- expect do
140
- abstract_adapter.get_active_version(rule_id: "test")
141
- end.to raise_error(NotImplementedError)
142
- end
143
-
144
- it "raises NotImplementedError for activate_version" do
145
- expect do
146
- abstract_adapter.activate_version(version_id: "test")
147
- end.to raise_error(NotImplementedError)
148
- end
149
-
150
- it "raises NotImplementedError for delete_version" do
151
- expect do
152
- abstract_adapter.delete_version(version_id: "test")
153
- end.to raise_error(NotImplementedError)
154
- end
155
- end
156
- end