fluxrules 0.1.0__tar.gz

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 (538) hide show
  1. fluxrules-0.1.0/.github/CODEOWNERS +4 -0
  2. fluxrules-0.1.0/.github/workflows/ci.yml +72 -0
  3. fluxrules-0.1.0/.github/workflows/docs.yml +49 -0
  4. fluxrules-0.1.0/.github/workflows/package-artifacts.yml +59 -0
  5. fluxrules-0.1.0/.github/workflows/release.yml +190 -0
  6. fluxrules-0.1.0/.gitignore +74 -0
  7. fluxrules-0.1.0/CHANGELOG.md +121 -0
  8. fluxrules-0.1.0/CODE_OF_CONDUCT.md +133 -0
  9. fluxrules-0.1.0/CONTRIBUTING.md +126 -0
  10. fluxrules-0.1.0/LICENSE +21 -0
  11. fluxrules-0.1.0/Makefile +67 -0
  12. fluxrules-0.1.0/PKG-INFO +274 -0
  13. fluxrules-0.1.0/README.md +166 -0
  14. fluxrules-0.1.0/SECURITY.md +62 -0
  15. fluxrules-0.1.0/alembic/env.py +77 -0
  16. fluxrules-0.1.0/alembic/script.py.mako +28 -0
  17. fluxrules-0.1.0/alembic/versions/001_initial_schema.py +144 -0
  18. fluxrules-0.1.0/alembic.ini +66 -0
  19. fluxrules-0.1.0/docker-compose.yml +63 -0
  20. fluxrules-0.1.0/docs/action-registry.md +107 -0
  21. fluxrules-0.1.0/docs/algorithm-fidelity.md +53 -0
  22. fluxrules-0.1.0/docs/api.md +129 -0
  23. fluxrules-0.1.0/docs/architecture.md +292 -0
  24. fluxrules-0.1.0/docs/benchmarks.md +97 -0
  25. fluxrules-0.1.0/docs/changelog.md +46 -0
  26. fluxrules-0.1.0/docs/choosing-an-engine.md +52 -0
  27. fluxrules-0.1.0/docs/complex-conditions.md +584 -0
  28. fluxrules-0.1.0/docs/concepts.md +245 -0
  29. fluxrules-0.1.0/docs/conditions.md +240 -0
  30. fluxrules-0.1.0/docs/contributing.md +71 -0
  31. fluxrules-0.1.0/docs/cross-fact-rules.md +90 -0
  32. fluxrules-0.1.0/docs/custom-actions.md +180 -0
  33. fluxrules-0.1.0/docs/custom-engines.md +82 -0
  34. fluxrules-0.1.0/docs/custom-transforms-answered.md +543 -0
  35. fluxrules-0.1.0/docs/custom-transforms-cheatsheet.md +402 -0
  36. fluxrules-0.1.0/docs/custom-transforms.md +130 -0
  37. fluxrules-0.1.0/docs/decision-guide.md +122 -0
  38. fluxrules-0.1.0/docs/dependency-injection.md +61 -0
  39. fluxrules-0.1.0/docs/deployment.md +133 -0
  40. fluxrules-0.1.0/docs/development/index.md +87 -0
  41. fluxrules-0.1.0/docs/development/testing.md +42 -0
  42. fluxrules-0.1.0/docs/domains-and-tags.md +286 -0
  43. fluxrules-0.1.0/docs/engine-comparison.md +98 -0
  44. fluxrules-0.1.0/docs/engine-scope-and-limits.md +149 -0
  45. fluxrules-0.1.0/docs/examples.md +606 -0
  46. fluxrules-0.1.0/docs/extension-points.md +115 -0
  47. fluxrules-0.1.0/docs/fact-pipeline.md +115 -0
  48. fluxrules-0.1.0/docs/features.md +155 -0
  49. fluxrules-0.1.0/docs/getting-started.md +65 -0
  50. fluxrules-0.1.0/docs/id-generation.md +77 -0
  51. fluxrules-0.1.0/docs/index.md +44 -0
  52. fluxrules-0.1.0/docs/installation.md +123 -0
  53. fluxrules-0.1.0/docs/load-testing.md +518 -0
  54. fluxrules-0.1.0/docs/nested-facts.md +107 -0
  55. fluxrules-0.1.0/docs/observability-exporters.md +434 -0
  56. fluxrules-0.1.0/docs/observability.md +121 -0
  57. fluxrules-0.1.0/docs/persistence.md +150 -0
  58. fluxrules-0.1.0/docs/pydantic-rule-guide.md +161 -0
  59. fluxrules-0.1.0/docs/quickstart.md +148 -0
  60. fluxrules-0.1.0/docs/reference/http-endpoints.md +21 -0
  61. fluxrules-0.1.0/docs/reference/index.md +18 -0
  62. fluxrules-0.1.0/docs/reference/public-api.md +122 -0
  63. fluxrules-0.1.0/docs/rest-api.md +222 -0
  64. fluxrules-0.1.0/docs/rule-analysis.md +92 -0
  65. fluxrules-0.1.0/docs/rule-builder.md +153 -0
  66. fluxrules-0.1.0/docs/rule-lifecycle.md +184 -0
  67. fluxrules-0.1.0/docs/rule-types.md +112 -0
  68. fluxrules-0.1.0/docs/security.md +157 -0
  69. fluxrules-0.1.0/docs/sessions.md +124 -0
  70. fluxrules-0.1.0/docs/troubleshooting.md +95 -0
  71. fluxrules-0.1.0/docs/usage/advanced-capabilities.md +83 -0
  72. fluxrules-0.1.0/docs/usage/configuration.md +34 -0
  73. fluxrules-0.1.0/docs/usage/engines.md +36 -0
  74. fluxrules-0.1.0/docs/usage/examples.md +89 -0
  75. fluxrules-0.1.0/docs/usage/http-api.md +59 -0
  76. fluxrules-0.1.0/docs/usage/index.md +10 -0
  77. fluxrules-0.1.0/docs/usage/python-api.md +94 -0
  78. fluxrules-0.1.0/docs/usecases.md +71 -0
  79. fluxrules-0.1.0/docs/validation-framework.md +274 -0
  80. fluxrules-0.1.0/docs/working-memory.md +145 -0
  81. fluxrules-0.1.0/docs/yaml-rules.md +90 -0
  82. fluxrules-0.1.0/examples/00_getting_started.py +37 -0
  83. fluxrules-0.1.0/examples/01_conditions.py +110 -0
  84. fluxrules-0.1.0/examples/02_complex_conditions.py +38 -0
  85. fluxrules-0.1.0/examples/03_domains_and_tags.py +36 -0
  86. fluxrules-0.1.0/examples/04_validation.py +44 -0
  87. fluxrules-0.1.0/examples/05_persistence.py +39 -0
  88. fluxrules-0.1.0/examples/06_working_memory.py +37 -0
  89. fluxrules-0.1.0/examples/07_yaml_rules.py +50 -0
  90. fluxrules-0.1.0/examples/09_custom_engines.py +31 -0
  91. fluxrules-0.1.0/examples/10_pluggable_engines.py +49 -0
  92. fluxrules-0.1.0/examples/11_cli_usage.py +29 -0
  93. fluxrules-0.1.0/examples/12_api_usage.py +36 -0
  94. fluxrules-0.1.0/examples/13_complex_rules.py +34 -0
  95. fluxrules-0.1.0/examples/14_error_handling.py +43 -0
  96. fluxrules-0.1.0/examples/15_action_system.py +31 -0
  97. fluxrules-0.1.0/examples/16_fact_store.py +31 -0
  98. fluxrules-0.1.0/examples/17_id_generation.py +46 -0
  99. fluxrules-0.1.0/examples/18_unified_rule.py +41 -0
  100. fluxrules-0.1.0/examples/19_advanced_features.py +34 -0
  101. fluxrules-0.1.0/examples/20_streaming_mode.py +31 -0
  102. fluxrules-0.1.0/examples/21_action_registry.py +39 -0
  103. fluxrules-0.1.0/examples/22_real_world_workflow.py +36 -0
  104. fluxrules-0.1.0/examples/23_streaming_vs_stateless.py +27 -0
  105. fluxrules-0.1.0/examples/24_cross_fact_joins.py +29 -0
  106. fluxrules-0.1.0/examples/25_nested_facts.py +28 -0
  107. fluxrules-0.1.0/examples/26_fact_loader.py +30 -0
  108. fluxrules-0.1.0/examples/27_factpipeline.py +38 -0
  109. fluxrules-0.1.0/examples/28_factpipeline_tier1.py +30 -0
  110. fluxrules-0.1.0/examples/29_custom_transforms.py +37 -0
  111. fluxrules-0.1.0/examples/30_conflict_detection.py +42 -0
  112. fluxrules-0.1.0/examples/README.md +398 -0
  113. fluxrules-0.1.0/examples/rules.yaml +71 -0
  114. fluxrules-0.1.0/examples/shared_use_case.py +208 -0
  115. fluxrules-0.1.0/mkdocs.yml +104 -0
  116. fluxrules-0.1.0/pyproject.toml +179 -0
  117. fluxrules-0.1.0/scripts/artifact_smoke_test.py +36 -0
  118. fluxrules-0.1.0/scripts/check_uv.py +59 -0
  119. fluxrules-0.1.0/src/fluxrules/__init__.py +209 -0
  120. fluxrules-0.1.0/src/fluxrules/adapters/__init__.py +3 -0
  121. fluxrules-0.1.0/src/fluxrules/adapters/caches/__init__.py +100 -0
  122. fluxrules-0.1.0/src/fluxrules/adapters/loaders/__init__.py +5 -0
  123. fluxrules-0.1.0/src/fluxrules/adapters/loaders/yaml_loader.py +47 -0
  124. fluxrules-0.1.0/src/fluxrules/adapters/observability/__init__.py +3 -0
  125. fluxrules-0.1.0/src/fluxrules/adapters/observability/noop.py +27 -0
  126. fluxrules-0.1.0/src/fluxrules/adapters/persistence/__init__.py +7 -0
  127. fluxrules-0.1.0/src/fluxrules/adapters/persistence/sqlalchemy_adapter.py +168 -0
  128. fluxrules-0.1.0/src/fluxrules/adapters/queues/__init__.py +101 -0
  129. fluxrules-0.1.0/src/fluxrules/adapters/repository/__init__.py +15 -0
  130. fluxrules-0.1.0/src/fluxrules/adapters/repository/database.py +59 -0
  131. fluxrules-0.1.0/src/fluxrules/adapters/repository/in_memory.py +60 -0
  132. fluxrules-0.1.0/src/fluxrules/analytics/__init__.py +11 -0
  133. fluxrules-0.1.0/src/fluxrules/api/__init__.py +10 -0
  134. fluxrules-0.1.0/src/fluxrules/api/analytics/__init__.py +1 -0
  135. fluxrules-0.1.0/src/fluxrules/api/analytics/coverage_report.py +20 -0
  136. fluxrules-0.1.0/src/fluxrules/api/analytics/explanation_engine.py +21 -0
  137. fluxrules-0.1.0/src/fluxrules/api/analytics/metrics.py +23 -0
  138. fluxrules-0.1.0/src/fluxrules/api/analytics/store.py +149 -0
  139. fluxrules-0.1.0/src/fluxrules/api/app.py +108 -0
  140. fluxrules-0.1.0/src/fluxrules/api/config.py +136 -0
  141. fluxrules-0.1.0/src/fluxrules/api/database.py +172 -0
  142. fluxrules-0.1.0/src/fluxrules/api/deps.py +69 -0
  143. fluxrules-0.1.0/src/fluxrules/api/engines/__init__.py +16 -0
  144. fluxrules-0.1.0/src/fluxrules/api/engines/adapter.py +434 -0
  145. fluxrules-0.1.0/src/fluxrules/api/engines/engine_pool.py +229 -0
  146. fluxrules-0.1.0/src/fluxrules/api/engines/holder.py +0 -0
  147. fluxrules-0.1.0/src/fluxrules/api/handlers.py +110 -0
  148. fluxrules-0.1.0/src/fluxrules/api/models/__init__.py +7 -0
  149. fluxrules-0.1.0/src/fluxrules/api/models/audit.py +20 -0
  150. fluxrules-0.1.0/src/fluxrules/api/models/audit_policy.py +65 -0
  151. fluxrules-0.1.0/src/fluxrules/api/models/conflicted_rule.py +44 -0
  152. fluxrules-0.1.0/src/fluxrules/api/models/rule.py +72 -0
  153. fluxrules-0.1.0/src/fluxrules/api/models/user.py +24 -0
  154. fluxrules-0.1.0/src/fluxrules/api/routes/__init__.py +0 -0
  155. fluxrules-0.1.0/src/fluxrules/api/routes/admin.py +65 -0
  156. fluxrules-0.1.0/src/fluxrules/api/routes/analytics.py +53 -0
  157. fluxrules-0.1.0/src/fluxrules/api/routes/audit.py +56 -0
  158. fluxrules-0.1.0/src/fluxrules/api/routes/audit_policy.py +160 -0
  159. fluxrules-0.1.0/src/fluxrules/api/routes/auth.py +61 -0
  160. fluxrules-0.1.0/src/fluxrules/api/routes/brms_analyze.py +525 -0
  161. fluxrules-0.1.0/src/fluxrules/api/routes/dependency_graph.py +203 -0
  162. fluxrules-0.1.0/src/fluxrules/api/routes/engines.py +397 -0
  163. fluxrules-0.1.0/src/fluxrules/api/routes/evaluate.py +42 -0
  164. fluxrules-0.1.0/src/fluxrules/api/routes/evaluation.py +219 -0
  165. fluxrules-0.1.0/src/fluxrules/api/routes/events.py +97 -0
  166. fluxrules-0.1.0/src/fluxrules/api/routes/explain.py +25 -0
  167. fluxrules-0.1.0/src/fluxrules/api/routes/health.py +37 -0
  168. fluxrules-0.1.0/src/fluxrules/api/routes/metrics.py +49 -0
  169. fluxrules-0.1.0/src/fluxrules/api/routes/rules.py +1119 -0
  170. fluxrules-0.1.0/src/fluxrules/api/routes/rulesets.py +109 -0
  171. fluxrules-0.1.0/src/fluxrules/api/routes/sdk.py +109 -0
  172. fluxrules-0.1.0/src/fluxrules/api/routes/sessions.py +205 -0
  173. fluxrules-0.1.0/src/fluxrules/api/routes/simulate.py +28 -0
  174. fluxrules-0.1.0/src/fluxrules/api/routes/validate.py +34 -0
  175. fluxrules-0.1.0/src/fluxrules/api/schema_manager.py +98 -0
  176. fluxrules-0.1.0/src/fluxrules/api/schemas/__init__.py +30 -0
  177. fluxrules-0.1.0/src/fluxrules/api/schemas/analytics.py +57 -0
  178. fluxrules-0.1.0/src/fluxrules/api/schemas/audit_policy.py +79 -0
  179. fluxrules-0.1.0/src/fluxrules/api/schemas/event.py +15 -0
  180. fluxrules-0.1.0/src/fluxrules/api/schemas/rule.py +98 -0
  181. fluxrules-0.1.0/src/fluxrules/api/schemas/session.py +38 -0
  182. fluxrules-0.1.0/src/fluxrules/api/schemas/user.py +37 -0
  183. fluxrules-0.1.0/src/fluxrules/api/schemas.py +30 -0
  184. fluxrules-0.1.0/src/fluxrules/api/security.py +82 -0
  185. fluxrules-0.1.0/src/fluxrules/api/services/__init__.py +0 -0
  186. fluxrules-0.1.0/src/fluxrules/api/services/analytics_service.py +207 -0
  187. fluxrules-0.1.0/src/fluxrules/api/services/audit_runner.py +265 -0
  188. fluxrules-0.1.0/src/fluxrules/api/services/audit_scheduler.py +157 -0
  189. fluxrules-0.1.0/src/fluxrules/api/services/audit_service.py +118 -0
  190. fluxrules-0.1.0/src/fluxrules/api/services/auth_service.py +38 -0
  191. fluxrules-0.1.0/src/fluxrules/api/services/brms_service.py +135 -0
  192. fluxrules-0.1.0/src/fluxrules/api/services/rule_service.py +196 -0
  193. fluxrules-0.1.0/src/fluxrules/api/services/rule_validation_service.py +468 -0
  194. fluxrules-0.1.0/src/fluxrules/api/utils/__init__.py +0 -0
  195. fluxrules-0.1.0/src/fluxrules/api/utils/metrics.py +198 -0
  196. fluxrules-0.1.0/src/fluxrules/api/utils/redis_client.py +38 -0
  197. fluxrules-0.1.0/src/fluxrules/api/workers/__init__.py +0 -0
  198. fluxrules-0.1.0/src/fluxrules/api/workers/event_worker.py +83 -0
  199. fluxrules-0.1.0/src/fluxrules/api/workers/validation_worker.py +212 -0
  200. fluxrules-0.1.0/src/fluxrules/cli/__init__.py +0 -0
  201. fluxrules-0.1.0/src/fluxrules/cli/main.py +200 -0
  202. fluxrules-0.1.0/src/fluxrules/compat/__init__.py +3 -0
  203. fluxrules-0.1.0/src/fluxrules/compat/contracts.py +17 -0
  204. fluxrules-0.1.0/src/fluxrules/config/__init__.py +208 -0
  205. fluxrules-0.1.0/src/fluxrules/config/deployment.py +355 -0
  206. fluxrules-0.1.0/src/fluxrules/config/manager.py +77 -0
  207. fluxrules-0.1.0/src/fluxrules/core/__init__.py +11 -0
  208. fluxrules-0.1.0/src/fluxrules/di/__init__.py +334 -0
  209. fluxrules-0.1.0/src/fluxrules/domain/__init__.py +35 -0
  210. fluxrules-0.1.0/src/fluxrules/domain/actions.py +338 -0
  211. fluxrules-0.1.0/src/fluxrules/domain/dsl/__init__.py +179 -0
  212. fluxrules-0.1.0/src/fluxrules/domain/dsl/evaluator.py +180 -0
  213. fluxrules-0.1.0/src/fluxrules/domain/dsl/expression_parser.py +94 -0
  214. fluxrules-0.1.0/src/fluxrules/domain/dsl/parser.py +147 -0
  215. fluxrules-0.1.0/src/fluxrules/domain/dsl/validation.py +183 -0
  216. fluxrules-0.1.0/src/fluxrules/domain/errors.py +108 -0
  217. fluxrules-0.1.0/src/fluxrules/domain/factory.py +177 -0
  218. fluxrules-0.1.0/src/fluxrules/domain/models.py +236 -0
  219. fluxrules-0.1.0/src/fluxrules/domain/predicates.py +37 -0
  220. fluxrules-0.1.0/src/fluxrules/domain/rule_builder.py +462 -0
  221. fluxrules-0.1.0/src/fluxrules/domain/schemas.py +87 -0
  222. fluxrules-0.1.0/src/fluxrules/domain/unified_rule.py +456 -0
  223. fluxrules-0.1.0/src/fluxrules/engine/__init__.py +156 -0
  224. fluxrules-0.1.0/src/fluxrules/engine/base.py +339 -0
  225. fluxrules-0.1.0/src/fluxrules/engine/configuration.py +61 -0
  226. fluxrules-0.1.0/src/fluxrules/engine/cross_fact/__init__.py +48 -0
  227. fluxrules-0.1.0/src/fluxrules/engine/cross_fact/_engine.py +574 -0
  228. fluxrules-0.1.0/src/fluxrules/engine/cross_fact/models.py +324 -0
  229. fluxrules-0.1.0/src/fluxrules/engine/cross_fact/working_memory.py +133 -0
  230. fluxrules-0.1.0/src/fluxrules/engine/infrastructure/__init__.py +72 -0
  231. fluxrules-0.1.0/src/fluxrules/engine/infrastructure/agenda.py +111 -0
  232. fluxrules-0.1.0/src/fluxrules/engine/infrastructure/bitmask_linker.py +363 -0
  233. fluxrules-0.1.0/src/fluxrules/engine/infrastructure/engine_metrics.py +146 -0
  234. fluxrules-0.1.0/src/fluxrules/engine/infrastructure/evaluation_filter.py +26 -0
  235. fluxrules-0.1.0/src/fluxrules/engine/infrastructure/evaluation_result.py +15 -0
  236. fluxrules-0.1.0/src/fluxrules/engine/infrastructure/fact_store.py +184 -0
  237. fluxrules-0.1.0/src/fluxrules/engine/infrastructure/field_index.py +85 -0
  238. fluxrules-0.1.0/src/fluxrules/engine/infrastructure/global_rule_repository.py +329 -0
  239. fluxrules-0.1.0/src/fluxrules/engine/infrastructure/lazy_evaluation.py +173 -0
  240. fluxrules-0.1.0/src/fluxrules/engine/infrastructure/node_memory.py +178 -0
  241. fluxrules-0.1.0/src/fluxrules/engine/infrastructure/scope_guard.py +402 -0
  242. fluxrules-0.1.0/src/fluxrules/engine/infrastructure/segment_network.py +139 -0
  243. fluxrules-0.1.0/src/fluxrules/engine/infrastructure/token_propagator.py +62 -0
  244. fluxrules-0.1.0/src/fluxrules/engine/infrastructure/working_memory.py +141 -0
  245. fluxrules-0.1.0/src/fluxrules/engine/interfaces.py +13 -0
  246. fluxrules-0.1.0/src/fluxrules/engine/operator_registry.py +83 -0
  247. fluxrules-0.1.0/src/fluxrules/engine/operators.py +175 -0
  248. fluxrules-0.1.0/src/fluxrules/engine/phreak/__init__.py +34 -0
  249. fluxrules-0.1.0/src/fluxrules/engine/phreak/_engine.py +1333 -0
  250. fluxrules-0.1.0/src/fluxrules/engine/phreak/condition_compiler.py +204 -0
  251. fluxrules-0.1.0/src/fluxrules/engine/profiler.py +62 -0
  252. fluxrules-0.1.0/src/fluxrules/engine/runtime/__init__.py +43 -0
  253. fluxrules-0.1.0/src/fluxrules/engine/runtime/action_dispatcher.py +277 -0
  254. fluxrules-0.1.0/src/fluxrules/engine/runtime/dedup_cache.py +247 -0
  255. fluxrules-0.1.0/src/fluxrules/engine/runtime/worker_pool.py +120 -0
  256. fluxrules-0.1.0/src/fluxrules/exceptions.py +132 -0
  257. fluxrules-0.1.0/src/fluxrules/features.py +61 -0
  258. fluxrules-0.1.0/src/fluxrules/initialization.py +111 -0
  259. fluxrules-0.1.0/src/fluxrules/logging.py +70 -0
  260. fluxrules-0.1.0/src/fluxrules/persistence/__init__.py +27 -0
  261. fluxrules-0.1.0/src/fluxrules/persistence/database_config.py +141 -0
  262. fluxrules-0.1.0/src/fluxrules/persistence/db_connection_manager.py +201 -0
  263. fluxrules-0.1.0/src/fluxrules/persistence/execution_repository.py +67 -0
  264. fluxrules-0.1.0/src/fluxrules/persistence/mappers.py +178 -0
  265. fluxrules-0.1.0/src/fluxrules/persistence/persistence_manager.py +229 -0
  266. fluxrules-0.1.0/src/fluxrules/persistence/rule_repository.py +131 -0
  267. fluxrules-0.1.0/src/fluxrules/pipeline/__init__.py +156 -0
  268. fluxrules-0.1.0/src/fluxrules/pipeline/base.py +179 -0
  269. fluxrules-0.1.0/src/fluxrules/pipeline/core.py +410 -0
  270. fluxrules-0.1.0/src/fluxrules/pipeline/error_policy.py +106 -0
  271. fluxrules-0.1.0/src/fluxrules/pipeline/exporters.py +320 -0
  272. fluxrules-0.1.0/src/fluxrules/pipeline/loaders.py +173 -0
  273. fluxrules-0.1.0/src/fluxrules/pipeline/observability.py +206 -0
  274. fluxrules-0.1.0/src/fluxrules/pipeline/registry.py +96 -0
  275. fluxrules-0.1.0/src/fluxrules/pipeline/schema.py +118 -0
  276. fluxrules-0.1.0/src/fluxrules/pipeline/transforms/__init__.py +33 -0
  277. fluxrules-0.1.0/src/fluxrules/pipeline/transforms/builtin.py +240 -0
  278. fluxrules-0.1.0/src/fluxrules/pipeline/transforms/composed.py +196 -0
  279. fluxrules-0.1.0/src/fluxrules/pipeline/utils/__init__.py +13 -0
  280. fluxrules-0.1.0/src/fluxrules/pipeline/utils/dict_utils.py +189 -0
  281. fluxrules-0.1.0/src/fluxrules/pipeline/validators.py +128 -0
  282. fluxrules-0.1.0/src/fluxrules/pipeline/versioning.py +137 -0
  283. fluxrules-0.1.0/src/fluxrules/plugins/__init__.py +0 -0
  284. fluxrules-0.1.0/src/fluxrules/plugins/actions.py +446 -0
  285. fluxrules-0.1.0/src/fluxrules/plugins/discovery.py +106 -0
  286. fluxrules-0.1.0/src/fluxrules/plugins/operators.py +88 -0
  287. fluxrules-0.1.0/src/fluxrules/ports/__init__.py +19 -0
  288. fluxrules-0.1.0/src/fluxrules/ports/circuit_breaker.py +35 -0
  289. fluxrules-0.1.0/src/fluxrules/ports/execution_store.py +22 -0
  290. fluxrules-0.1.0/src/fluxrules/ports/health.py +33 -0
  291. fluxrules-0.1.0/src/fluxrules/ports/observability.py +30 -0
  292. fluxrules-0.1.0/src/fluxrules/ports/persistence.py +97 -0
  293. fluxrules-0.1.0/src/fluxrules/ports/queue.py +78 -0
  294. fluxrules-0.1.0/src/fluxrules/ports/repository.py +27 -0
  295. fluxrules-0.1.0/src/fluxrules/ports/rule.py +23 -0
  296. fluxrules-0.1.0/src/fluxrules/ports/rule_cache.py +69 -0
  297. fluxrules-0.1.0/src/fluxrules/ports/validation.py +44 -0
  298. fluxrules-0.1.0/src/fluxrules/prefilter/__init__.py +76 -0
  299. fluxrules-0.1.0/src/fluxrules/prefilter/pipeline.py +115 -0
  300. fluxrules-0.1.0/src/fluxrules/prefilter/predicate.py +304 -0
  301. fluxrules-0.1.0/src/fluxrules/prefilter/predicate_index.py +307 -0
  302. fluxrules-0.1.0/src/fluxrules/prefilter/sql_store.py +238 -0
  303. fluxrules-0.1.0/src/fluxrules/py.typed +0 -0
  304. fluxrules-0.1.0/src/fluxrules/services/__init__.py +4 -0
  305. fluxrules-0.1.0/src/fluxrules/services/audit_service.py +29 -0
  306. fluxrules-0.1.0/src/fluxrules/services/circuit_breaker.py +98 -0
  307. fluxrules-0.1.0/src/fluxrules/services/compilation/__init__.py +7 -0
  308. fluxrules-0.1.0/src/fluxrules/services/compilation/rule_compiler.py +81 -0
  309. fluxrules-0.1.0/src/fluxrules/services/evaluation_service.py +21 -0
  310. fluxrules-0.1.0/src/fluxrules/services/execution/__init__.py +25 -0
  311. fluxrules-0.1.0/src/fluxrules/services/execution/agenda.py +51 -0
  312. fluxrules-0.1.0/src/fluxrules/services/execution/scheduler.py +37 -0
  313. fluxrules-0.1.0/src/fluxrules/services/execution/session_context.py +187 -0
  314. fluxrules-0.1.0/src/fluxrules/services/execution/session_manager.py +242 -0
  315. fluxrules-0.1.0/src/fluxrules/services/execution/session_storage.py +227 -0
  316. fluxrules-0.1.0/src/fluxrules/services/execution/storage_backend.py +302 -0
  317. fluxrules-0.1.0/src/fluxrules/services/execution/working_memory.py +96 -0
  318. fluxrules-0.1.0/src/fluxrules/services/health.py +59 -0
  319. fluxrules-0.1.0/src/fluxrules/services/persistence_service.py +67 -0
  320. fluxrules-0.1.0/src/fluxrules/services/reference_evaluator.py +127 -0
  321. fluxrules-0.1.0/src/fluxrules/services/rule_loader.py +73 -0
  322. fluxrules-0.1.0/src/fluxrules/services/rule_service.py +229 -0
  323. fluxrules-0.1.0/src/fluxrules/services/session.py +105 -0
  324. fluxrules-0.1.0/src/fluxrules/services/validation/__init__.py +39 -0
  325. fluxrules-0.1.0/src/fluxrules/services/validation/_compiled_cache.py +230 -0
  326. fluxrules-0.1.0/src/fluxrules/services/validation/_interval_index.py +200 -0
  327. fluxrules-0.1.0/src/fluxrules/services/validation/_normalization.py +110 -0
  328. fluxrules-0.1.0/src/fluxrules/services/validation/conflict_detection.py +375 -0
  329. fluxrules-0.1.0/src/fluxrules/services/validation/coverage_analysis.py +55 -0
  330. fluxrules-0.1.0/src/fluxrules/services/validation/dead_rule_detection.py +75 -0
  331. fluxrules-0.1.0/src/fluxrules/services/validation/duplicate_detection.py +24 -0
  332. fluxrules-0.1.0/src/fluxrules/services/validation/gap_detection.py +40 -0
  333. fluxrules-0.1.0/src/fluxrules/services/validation/priority_collision_detection.py +26 -0
  334. fluxrules-0.1.0/src/fluxrules/services/validation/redundancy_detection.py +42 -0
  335. fluxrules-0.1.0/src/fluxrules/services/validation/sat_validation.py +281 -0
  336. fluxrules-0.1.0/src/fluxrules/services/validation_enforcer.py +142 -0
  337. fluxrules-0.1.0/src/fluxrules/services/validation_gateway.py +213 -0
  338. fluxrules-0.1.0/src/fluxrules/services/validation_service.py +115 -0
  339. fluxrules-0.1.0/src/fluxrules/services/validators/__init__.py +35 -0
  340. fluxrules-0.1.0/src/fluxrules/services/validators/action_validator.py +73 -0
  341. fluxrules-0.1.0/src/fluxrules/services/validators/base.py +207 -0
  342. fluxrules-0.1.0/src/fluxrules/services/validators/brms_validator.py +151 -0
  343. fluxrules-0.1.0/src/fluxrules/services/validators/duplicate_validator.py +139 -0
  344. fluxrules-0.1.0/src/fluxrules/services/validators/priority_validator.py +90 -0
  345. fluxrules-0.1.0/src/fluxrules/services/validators/referential_validator.py +83 -0
  346. fluxrules-0.1.0/src/fluxrules/services/validators/stateful_dsl_validator.py +195 -0
  347. fluxrules-0.1.0/src/fluxrules/services/validators/structural_validator.py +199 -0
  348. fluxrules-0.1.0/src/fluxrules/testing/__init__.py +193 -0
  349. fluxrules-0.1.0/src/fluxrules/utils/__init__.py +16 -0
  350. fluxrules-0.1.0/src/fluxrules/utils/dependency_graph.py +67 -0
  351. fluxrules-0.1.0/src/fluxrules/utils/dependency_graph_analyzer.py +114 -0
  352. fluxrules-0.1.0/src/fluxrules/utils/id_generators.py +379 -0
  353. fluxrules-0.1.0/src/fluxrules/utils/metrics.py +93 -0
  354. fluxrules-0.1.0/src/fluxrules/version.py +5 -0
  355. fluxrules-0.1.0/tests/__init__.py +0 -0
  356. fluxrules-0.1.0/tests/api/test_engine_adapter.py +223 -0
  357. fluxrules-0.1.0/tests/api/test_engine_holder.py +146 -0
  358. fluxrules-0.1.0/tests/api/test_routers_load.py +111 -0
  359. fluxrules-0.1.0/tests/conftest.py +273 -0
  360. fluxrules-0.1.0/tests/contract/test_engine_contract.py +13 -0
  361. fluxrules-0.1.0/tests/contract/test_engine_contract_battery.py +149 -0
  362. fluxrules-0.1.0/tests/contract/test_plugin_contract.py +142 -0
  363. fluxrules-0.1.0/tests/contract/test_public_api_contracts.py +90 -0
  364. fluxrules-0.1.0/tests/contract/test_quickstart_contract.py +142 -0
  365. fluxrules-0.1.0/tests/docs/__init__.py +0 -0
  366. fluxrules-0.1.0/tests/docs/_extract.py +156 -0
  367. fluxrules-0.1.0/tests/docs/test_doc_imports.py +75 -0
  368. fluxrules-0.1.0/tests/docs/test_doc_snippets.py +157 -0
  369. fluxrules-0.1.0/tests/docs/test_nav_completeness.py +58 -0
  370. fluxrules-0.1.0/tests/engine/test_action_dispatcher.py +160 -0
  371. fluxrules-0.1.0/tests/engine/test_agenda_cancellation.py +238 -0
  372. fluxrules-0.1.0/tests/engine/test_agenda_unscheduling.py +451 -0
  373. fluxrules-0.1.0/tests/engine/test_bitmask_linker.py +383 -0
  374. fluxrules-0.1.0/tests/engine/test_capability_matrix.py +85 -0
  375. fluxrules-0.1.0/tests/engine/test_concurrency_thread_safety.py +165 -0
  376. fluxrules-0.1.0/tests/engine/test_conflict_resolution_ordering.py +87 -0
  377. fluxrules-0.1.0/tests/engine/test_cross_fact_engine.py +859 -0
  378. fluxrules-0.1.0/tests/engine/test_cross_fact_oracle_differential.py +212 -0
  379. fluxrules-0.1.0/tests/engine/test_dedup.py +145 -0
  380. fluxrules-0.1.0/tests/engine/test_default_engine_wiring.py +19 -0
  381. fluxrules-0.1.0/tests/engine/test_differential_fuzz.py +309 -0
  382. fluxrules-0.1.0/tests/engine/test_explanation_contract.py +53 -0
  383. fluxrules-0.1.0/tests/engine/test_finding_unhashable_values.py +69 -0
  384. fluxrules-0.1.0/tests/engine/test_flat_evaluation.py +154 -0
  385. fluxrules-0.1.0/tests/engine/test_flat_segments.py +124 -0
  386. fluxrules-0.1.0/tests/engine/test_nested_fact_contract.py +53 -0
  387. fluxrules-0.1.0/tests/engine/test_node_memory.py +300 -0
  388. fluxrules-0.1.0/tests/engine/test_parallel_worker_pool.py +76 -0
  389. fluxrules-0.1.0/tests/engine/test_phreak_infrastructure_integration.py +531 -0
  390. fluxrules-0.1.0/tests/engine/test_realistic_rules_smoke.py +121 -0
  391. fluxrules-0.1.0/tests/engine/test_scope_guard.py +371 -0
  392. fluxrules-0.1.0/tests/engine/test_single_discovery_parity.py +211 -0
  393. fluxrules-0.1.0/tests/engine/test_stateless_streaming_equivalence.py +285 -0
  394. fluxrules-0.1.0/tests/engine/test_stateless_streaming_parity_strict.py +96 -0
  395. fluxrules-0.1.0/tests/engine/test_streaming_guardrail.py +122 -0
  396. fluxrules-0.1.0/tests/engine/test_streaming_mode_feature.py +749 -0
  397. fluxrules-0.1.0/tests/engine/test_strict_facts.py +33 -0
  398. fluxrules-0.1.0/tests/engine/test_working_memory_contract.py +58 -0
  399. fluxrules-0.1.0/tests/factories.py +38 -0
  400. fluxrules-0.1.0/tests/infrastructure/test_node_memory_lru.py +150 -0
  401. fluxrules-0.1.0/tests/infrastructure/test_working_memory_watchdog.py +89 -0
  402. fluxrules-0.1.0/tests/integration/__init__.py +0 -0
  403. fluxrules-0.1.0/tests/integration/api_endpoints_functional_test_script.py +253 -0
  404. fluxrules-0.1.0/tests/integration/conftest.py +15 -0
  405. fluxrules-0.1.0/tests/integration/test_alembic_migrations.py +143 -0
  406. fluxrules-0.1.0/tests/integration/test_analytics.py +132 -0
  407. fluxrules-0.1.0/tests/integration/test_api.py +160 -0
  408. fluxrules-0.1.0/tests/integration/test_api_evaluate.py +61 -0
  409. fluxrules-0.1.0/tests/integration/test_audit_policy.py +915 -0
  410. fluxrules-0.1.0/tests/integration/test_audit_policy_service.py +94 -0
  411. fluxrules-0.1.0/tests/integration/test_comprehensive_integration.py +1302 -0
  412. fluxrules-0.1.0/tests/integration/test_dependency_graph_api.py +122 -0
  413. fluxrules-0.1.0/tests/integration/test_e2e_admin_integration.py +448 -0
  414. fluxrules-0.1.0/tests/integration/test_engines_router.py +176 -0
  415. fluxrules-0.1.0/tests/integration/test_factpipeline_e2e.py +197 -0
  416. fluxrules-0.1.0/tests/integration/test_hybrid_validation_e2e.py +565 -0
  417. fluxrules-0.1.0/tests/integration/test_persistence_performance.py +177 -0
  418. fluxrules-0.1.0/tests/integration/test_redis_session_storage.py +136 -0
  419. fluxrules-0.1.0/tests/integration/test_rules_validate.py +677 -0
  420. fluxrules-0.1.0/tests/integration/test_session_api.py +119 -0
  421. fluxrules-0.1.0/tests/integration/test_session_storage_integration.py +144 -0
  422. fluxrules-0.1.0/tests/integration/test_unified_engine_e2e.py +190 -0
  423. fluxrules-0.1.0/tests/integration/test_validation_integration.py +263 -0
  424. fluxrules-0.1.0/tests/integration/test_validation_worker_db.py +63 -0
  425. fluxrules-0.1.0/tests/observability/test_engine_metrics.py +206 -0
  426. fluxrules-0.1.0/tests/performance/__init__.py +0 -0
  427. fluxrules-0.1.0/tests/performance/conftest.py +32 -0
  428. fluxrules-0.1.0/tests/performance/generators.py +448 -0
  429. fluxrules-0.1.0/tests/performance/perf_alpha_network.py +225 -0
  430. fluxrules-0.1.0/tests/performance/perf_and_heavy_rules.py +463 -0
  431. fluxrules-0.1.0/tests/performance/perf_baseline_vs_optimized.py +143 -0
  432. fluxrules-0.1.0/tests/performance/perf_condition_compiler.py +194 -0
  433. fluxrules-0.1.0/tests/performance/perf_dedup.py +98 -0
  434. fluxrules-0.1.0/tests/performance/perf_massive_scale.py +618 -0
  435. fluxrules-0.1.0/tests/performance/perf_parallel.py +115 -0
  436. fluxrules-0.1.0/tests/performance/perf_prefilter.py +165 -0
  437. fluxrules-0.1.0/tests/performance/perf_real_world_scenarios.py +294 -0
  438. fluxrules-0.1.0/tests/performance/perf_realistic_rules.py +730 -0
  439. fluxrules-0.1.0/tests/performance/perf_risk_areas.py +372 -0
  440. fluxrules-0.1.0/tests/performance/perf_scale_quick.py +233 -0
  441. fluxrules-0.1.0/tests/performance/perf_scale_validation.py +286 -0
  442. fluxrules-0.1.0/tests/performance/perf_streaming_validation.py +394 -0
  443. fluxrules-0.1.0/tests/performance/test_benchmark.py +179 -0
  444. fluxrules-0.1.0/tests/performance/test_load_scenarios.py +108 -0
  445. fluxrules-0.1.0/tests/performance/test_phreak_engine_perf.py +351 -0
  446. fluxrules-0.1.0/tests/performance/test_scale_readiness.py +261 -0
  447. fluxrules-0.1.0/tests/plugins/test_action_registry.py +395 -0
  448. fluxrules-0.1.0/tests/prefilter/__init__.py +1 -0
  449. fluxrules-0.1.0/tests/prefilter/test_alpha_adaptive_gate.py +137 -0
  450. fluxrules-0.1.0/tests/prefilter/test_alpha_primary_soundness.py +149 -0
  451. fluxrules-0.1.0/tests/prefilter/test_condition_compiler.py +214 -0
  452. fluxrules-0.1.0/tests/prefilter/test_engine_alpha_integration.py +76 -0
  453. fluxrules-0.1.0/tests/prefilter/test_predicate_index.py +150 -0
  454. fluxrules-0.1.0/tests/prefilter/test_soundness.py +177 -0
  455. fluxrules-0.1.0/tests/regression/__init__.py +1 -0
  456. fluxrules-0.1.0/tests/regression/test_condition_dsl_storage_shape.py +282 -0
  457. fluxrules-0.1.0/tests/regression/test_public_error_surface.py +125 -0
  458. fluxrules-0.1.0/tests/regression/test_rule_ingestion_matrix.py +639 -0
  459. fluxrules-0.1.0/tests/regression/test_validator_vocabulary.py +172 -0
  460. fluxrules-0.1.0/tests/security/__init__.py +0 -0
  461. fluxrules-0.1.0/tests/security/conftest.py +15 -0
  462. fluxrules-0.1.0/tests/security/test_reliability_hardening.py +633 -0
  463. fluxrules-0.1.0/tests/security/test_security_hardening.py +587 -0
  464. fluxrules-0.1.0/tests/unit/__init__.py +0 -0
  465. fluxrules-0.1.0/tests/unit/conftest.py +14 -0
  466. fluxrules-0.1.0/tests/unit/perf_results/full_benchmark_report.json +90 -0
  467. fluxrules-0.1.0/tests/unit/pipeline/__init__.py +0 -0
  468. fluxrules-0.1.0/tests/unit/pipeline/test_base.py +170 -0
  469. fluxrules-0.1.0/tests/unit/pipeline/test_builtin_transforms.py +155 -0
  470. fluxrules-0.1.0/tests/unit/pipeline/test_composed_transforms.py +117 -0
  471. fluxrules-0.1.0/tests/unit/pipeline/test_core.py +177 -0
  472. fluxrules-0.1.0/tests/unit/pipeline/test_dict_utils.py +84 -0
  473. fluxrules-0.1.0/tests/unit/pipeline/test_error_policy.py +110 -0
  474. fluxrules-0.1.0/tests/unit/pipeline/test_exporters.py +394 -0
  475. fluxrules-0.1.0/tests/unit/pipeline/test_loaders.py +169 -0
  476. fluxrules-0.1.0/tests/unit/pipeline/test_observability.py +140 -0
  477. fluxrules-0.1.0/tests/unit/pipeline/test_registry.py +110 -0
  478. fluxrules-0.1.0/tests/unit/pipeline/test_versioning.py +65 -0
  479. fluxrules-0.1.0/tests/unit/test_action_execution.py +168 -0
  480. fluxrules-0.1.0/tests/unit/test_api_handlers.py +23 -0
  481. fluxrules-0.1.0/tests/unit/test_api_routes_evaluation.py +263 -0
  482. fluxrules-0.1.0/tests/unit/test_api_routes_rules.py +88 -0
  483. fluxrules-0.1.0/tests/unit/test_brms_validation.py +296 -0
  484. fluxrules-0.1.0/tests/unit/test_brms_validation_edge_cases.py +241 -0
  485. fluxrules-0.1.0/tests/unit/test_candidate_rule_ids.py +109 -0
  486. fluxrules-0.1.0/tests/unit/test_circuit_breaker.py +116 -0
  487. fluxrules-0.1.0/tests/unit/test_cli_main.py +170 -0
  488. fluxrules-0.1.0/tests/unit/test_compiled_cache_invalidation.py +73 -0
  489. fluxrules-0.1.0/tests/unit/test_config_manager.py +77 -0
  490. fluxrules-0.1.0/tests/unit/test_conflict_detection.py +225 -0
  491. fluxrules-0.1.0/tests/unit/test_conflict_detection_categorical.py +230 -0
  492. fluxrules-0.1.0/tests/unit/test_cycle_detection.py +98 -0
  493. fluxrules-0.1.0/tests/unit/test_dependency_fallbacks.py +78 -0
  494. fluxrules-0.1.0/tests/unit/test_dependency_graph.py +46 -0
  495. fluxrules-0.1.0/tests/unit/test_domain_factory.py +119 -0
  496. fluxrules-0.1.0/tests/unit/test_domain_models.py +11 -0
  497. fluxrules-0.1.0/tests/unit/test_dsl_ast.py +305 -0
  498. fluxrules-0.1.0/tests/unit/test_dsl_parser.py +48 -0
  499. fluxrules-0.1.0/tests/unit/test_dsl_validation.py +133 -0
  500. fluxrules-0.1.0/tests/unit/test_event_worker.py +132 -0
  501. fluxrules-0.1.0/tests/unit/test_exceptions.py +80 -0
  502. fluxrules-0.1.0/tests/unit/test_fact_store.py +160 -0
  503. fluxrules-0.1.0/tests/unit/test_health_service.py +44 -0
  504. fluxrules-0.1.0/tests/unit/test_id_generator.py +499 -0
  505. fluxrules-0.1.0/tests/unit/test_mappers.py +225 -0
  506. fluxrules-0.1.0/tests/unit/test_memory_session_storage.py +92 -0
  507. fluxrules-0.1.0/tests/unit/test_null_handling_comprehensive.py +84 -0
  508. fluxrules-0.1.0/tests/unit/test_operator_edge_matrix.py +102 -0
  509. fluxrules-0.1.0/tests/unit/test_operator_parity.py +86 -0
  510. fluxrules-0.1.0/tests/unit/test_operator_registry.py +61 -0
  511. fluxrules-0.1.0/tests/unit/test_persistence.py +350 -0
  512. fluxrules-0.1.0/tests/unit/test_persistence_port.py +67 -0
  513. fluxrules-0.1.0/tests/unit/test_phreak_engine.py +304 -0
  514. fluxrules-0.1.0/tests/unit/test_public_api.py +80 -0
  515. fluxrules-0.1.0/tests/unit/test_reference_evaluator.py +45 -0
  516. fluxrules-0.1.0/tests/unit/test_rule_consolidation.py +449 -0
  517. fluxrules-0.1.0/tests/unit/test_rule_file_loaders.py +64 -0
  518. fluxrules-0.1.0/tests/unit/test_rule_loader.py +131 -0
  519. fluxrules-0.1.0/tests/unit/test_rule_repository.py +160 -0
  520. fluxrules-0.1.0/tests/unit/test_rule_service.py +34 -0
  521. fluxrules-0.1.0/tests/unit/test_rule_service_persistence.py +107 -0
  522. fluxrules-0.1.0/tests/unit/test_schemas.py +71 -0
  523. fluxrules-0.1.0/tests/unit/test_service_factory.py +426 -0
  524. fluxrules-0.1.0/tests/unit/test_services.py +65 -0
  525. fluxrules-0.1.0/tests/unit/test_session_context.py +77 -0
  526. fluxrules-0.1.0/tests/unit/test_session_manager.py +73 -0
  527. fluxrules-0.1.0/tests/unit/test_session_persistence.py +150 -0
  528. fluxrules-0.1.0/tests/unit/test_unified_engine_core.py +441 -0
  529. fluxrules-0.1.0/tests/unit/test_unified_rule.py +571 -0
  530. fluxrules-0.1.0/tests/unit/test_unified_validators.py +519 -0
  531. fluxrules-0.1.0/tests/unit/test_validation_enforcer.py +145 -0
  532. fluxrules-0.1.0/tests/unit/test_validation_gateway.py +175 -0
  533. fluxrules-0.1.0/tests/unit/test_validation_performance.py +73 -0
  534. fluxrules-0.1.0/tests/unit/test_validation_plugins.py +77 -0
  535. fluxrules-0.1.0/tests/unit/test_validation_worker.py +91 -0
  536. fluxrules-0.1.0/tests/unit/test_working_memory.py +64 -0
  537. fluxrules-0.1.0/tests/unit/validators/test_stateful_dsl_validator.py +333 -0
  538. fluxrules-0.1.0/uv.lock +2804 -0
@@ -0,0 +1,4 @@
1
+ # Every file in the repository requires review from the project owner.
2
+ # GitHub enforces this when "Require review from Code Owners" is enabled
3
+ # in the branch protection rule for main.
4
+ * @saurabh2mishra
@@ -0,0 +1,72 @@
1
+ name: CI
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - master
8
+ pull_request:
9
+ workflow_dispatch:
10
+
11
+ jobs:
12
+ quality:
13
+ name: Python ${{ matrix.python-version }}
14
+ runs-on: ubuntu-latest
15
+ timeout-minutes: 30
16
+ permissions:
17
+ contents: read
18
+ strategy:
19
+ fail-fast: false
20
+ matrix:
21
+ python-version: ["3.10", "3.11", "3.12"]
22
+
23
+ steps:
24
+ - name: Check out repository
25
+ uses: actions/checkout@v4
26
+
27
+ - name: Set up uv
28
+ uses: astral-sh/setup-uv@v4
29
+ with:
30
+ enable-cache: true
31
+ version: ">=0.8"
32
+
33
+ - name: Set up Python ${{ matrix.python-version }}
34
+ uses: actions/setup-python@v5
35
+ with:
36
+ python-version: ${{ matrix.python-version }}
37
+
38
+ - name: Install project dependencies
39
+ run: uv sync --extra dev --extra docs
40
+
41
+ - name: Ruff
42
+ run: uv run ruff check src/ tests/
43
+
44
+ - name: Mypy
45
+ run: uv run mypy src/fluxrules --ignore-missing-imports
46
+
47
+ - name: Quickstart contract (first-run experience)
48
+ run: uv run pytest tests/contract/test_quickstart_contract.py -q
49
+
50
+ - name: Non-performance test suite
51
+ run: uv run pytest tests/ -q -m "not performance"
52
+
53
+ - name: Docs snippet tests
54
+ run: uv run pytest tests/docs/test_doc_snippets.py -q
55
+
56
+ - name: MkDocs build
57
+ run: uv run mkdocs build
58
+
59
+ - name: Bandit security scan
60
+ run: uv run bandit -r src/fluxrules -c pyproject.toml
61
+
62
+ - name: Dependency audit
63
+ run: uv run pip-audit --skip-editable
64
+
65
+ - name: Fresh API-extra dependency audit
66
+ run: |
67
+ set -euo pipefail
68
+ api_env="$(mktemp -d)/venv"
69
+ uv venv --python "${{ matrix.python-version }}" "$api_env"
70
+ uv pip install --python "$api_env/bin/python" '.[api]'
71
+ api_site_packages="$("$api_env/bin/python" -c 'import sysconfig; print(sysconfig.get_paths()["purelib"])')"
72
+ uv run --no-sync pip-audit --path "$api_site_packages"
@@ -0,0 +1,49 @@
1
+ name: Docs
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ paths:
8
+ - "docs/**"
9
+ - "mkdocs.yml"
10
+ - "src/**" # API reference regenerates on source changes
11
+ - ".github/workflows/docs.yml"
12
+ workflow_dispatch: # allow manual deploys from the Actions tab
13
+
14
+ permissions:
15
+ contents: write # mkdocs gh-deploy pushes to the gh-pages branch
16
+
17
+ jobs:
18
+ deploy:
19
+ name: Build and deploy MkDocs site
20
+ runs-on: ubuntu-latest
21
+ timeout-minutes: 15
22
+
23
+ steps:
24
+ - name: Check out repository
25
+ uses: actions/checkout@v4
26
+ with:
27
+ fetch-depth: 0 # full history so git-revision-date plugins work
28
+
29
+ - name: Set up uv
30
+ uses: astral-sh/setup-uv@v4
31
+ with:
32
+ enable-cache: true
33
+ version: ">=0.8"
34
+
35
+ - name: Set up Python 3.12
36
+ uses: actions/setup-python@v5
37
+ with:
38
+ python-version: "3.12"
39
+
40
+ - name: Install project with docs extras
41
+ run: uv sync --extra docs
42
+
43
+ - name: Configure git for gh-deploy
44
+ run: |
45
+ git config user.name "github-actions[bot]"
46
+ git config user.email "github-actions[bot]@users.noreply.github.com"
47
+
48
+ - name: Build and deploy to gh-pages branch
49
+ run: uv run mkdocs gh-deploy --force --clean --verbose
@@ -0,0 +1,59 @@
1
+ name: Package artifact gate
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ - master
8
+ tags:
9
+ - "v*"
10
+ pull_request:
11
+ branches:
12
+ - main
13
+ - master
14
+ workflow_dispatch:
15
+
16
+ jobs:
17
+ package-smoke:
18
+ name: Build + install smoke test (Python ${{ matrix.python-version }})
19
+ runs-on: ubuntu-latest
20
+ timeout-minutes: 30
21
+ permissions:
22
+ contents: read
23
+ strategy:
24
+ fail-fast: false
25
+ matrix:
26
+ python-version: ["3.10", "3.11", "3.12"]
27
+
28
+ steps:
29
+ - name: Check out repository
30
+ uses: actions/checkout@v4
31
+
32
+ - name: Set up uv
33
+ uses: astral-sh/setup-uv@v4
34
+ with:
35
+ enable-cache: true
36
+ version: ">=0.8"
37
+
38
+ - name: Set up Python ${{ matrix.python-version }}
39
+ uses: actions/setup-python@v5
40
+ with:
41
+ python-version: ${{ matrix.python-version }}
42
+
43
+ - name: Build sdist and wheel
44
+ run: uv build
45
+
46
+ - name: Install each artifact in a clean venv and run a core smoke test
47
+ shell: bash
48
+ run: |
49
+ set -euo pipefail
50
+ for artifact in dist/*.tar.gz dist/*.whl; do
51
+ venv_dir=".artifact-venv-$(basename "$artifact" | tr -cs '[:alnum:]' '_')"
52
+ python -m venv "$venv_dir"
53
+ . "$venv_dir/bin/activate"
54
+ python -m pip install --upgrade pip --quiet
55
+ python -m pip install --force-reinstall "$artifact" --quiet
56
+ python scripts/artifact_smoke_test.py
57
+ deactivate
58
+ rm -rf "$venv_dir"
59
+ done
@@ -0,0 +1,190 @@
1
+ name: Release
2
+
3
+ # Triggers only on version tags — never on branch pushes.
4
+ # Pushing v0.1.0 starts build → smoke-test → (manual gate) → PyPI.
5
+ on:
6
+ push:
7
+ tags:
8
+ - "v*"
9
+
10
+ # No top-level permissions: every job declares its own minimal set.
11
+ permissions: {}
12
+
13
+ jobs:
14
+ # ── 1. Build ──────────────────────────────────────────────────────────────
15
+ build:
16
+ name: Build sdist + wheel
17
+ runs-on: ubuntu-latest
18
+ timeout-minutes: 15
19
+ permissions:
20
+ contents: read # checkout only
21
+
22
+ steps:
23
+ - name: Check out repository
24
+ uses: actions/checkout@v4
25
+ with:
26
+ fetch-depth: 0 # full history for SCM-based version tools
27
+
28
+ - name: Set up uv
29
+ uses: astral-sh/setup-uv@v4
30
+ with:
31
+ enable-cache: true
32
+ version: ">=0.8"
33
+
34
+ - name: Set up Python 3.12
35
+ uses: actions/setup-python@v5
36
+ with:
37
+ python-version: "3.12"
38
+
39
+ # Reject runs triggered by a tag that is not reachable from main.
40
+ # This prevents a tag pushed from a feature branch from publishing.
41
+ - name: Assert tag commit is on main
42
+ shell: bash
43
+ run: |
44
+ set -euo pipefail
45
+ git fetch origin main --depth=50
46
+ if ! git merge-base --is-ancestor "$GITHUB_SHA" origin/main; then
47
+ echo "::error::Tag $GITHUB_REF_NAME was pushed from a commit not on main."
48
+ echo "Only tags on main may trigger a release."
49
+ exit 1
50
+ fi
51
+ echo "tag-on-main-gate: $GITHUB_SHA is reachable from origin/main OK"
52
+
53
+ - name: Build sdist and wheel
54
+ run: uv build
55
+
56
+ # Verify the tag version matches pyproject.toml before uploading anything.
57
+ - name: Assert tag matches package version
58
+ shell: bash
59
+ run: |
60
+ set -euo pipefail
61
+ TAG="${GITHUB_REF_NAME}" # e.g. "v0.1.0"
62
+ PKG_VERSION="$(python3 -c "
63
+ import tomllib, pathlib
64
+ print(tomllib.loads(pathlib.Path('pyproject.toml').read_text())['project']['version'])
65
+ ")"
66
+ EXPECTED_TAG="v${PKG_VERSION}"
67
+ if [ "$TAG" != "$EXPECTED_TAG" ]; then
68
+ echo "::error::Tag '$TAG' does not match pyproject.toml version 'v${PKG_VERSION}'."
69
+ echo "Update pyproject.toml and src/fluxrules/version.py, then re-tag."
70
+ exit 1
71
+ fi
72
+ echo "tag-version-gate: $TAG == v$PKG_VERSION OK"
73
+
74
+ # Verify both version fields are in sync — read version.py with grep,
75
+ # no package import needed (avoids pydantic not being installed yet).
76
+ - name: Assert pyproject.toml and version.py agree
77
+ shell: bash
78
+ run: |
79
+ set -euo pipefail
80
+ PY_VERSION="$(grep -m1 '^__version__' src/fluxrules/version.py | sed 's/.*"\(.*\)".*/\1/')"
81
+ PKG_VERSION="$(python3 -c "
82
+ import tomllib, pathlib
83
+ print(tomllib.loads(pathlib.Path('pyproject.toml').read_text())['project']['version'])
84
+ ")"
85
+ if [ "$PY_VERSION" != "$PKG_VERSION" ]; then
86
+ echo "::error::src/fluxrules/version.py (__version__='$PY_VERSION') differs from pyproject.toml ('$PKG_VERSION')."
87
+ exit 1
88
+ fi
89
+ echo "version-sync-gate: $PY_VERSION OK"
90
+
91
+ - name: twine check
92
+ run: |
93
+ uv tool install twine
94
+ uv tool run twine check dist/* --strict
95
+
96
+ - name: Upload dist artifacts
97
+ uses: actions/upload-artifact@v4
98
+ with:
99
+ name: dist
100
+ path: dist/
101
+ if-no-files-found: error
102
+ retention-days: 7
103
+
104
+ # ── 2. Install smoke test (sdist + wheel, 3 Python versions) ─────────────
105
+ smoke-test:
106
+ name: Install smoke (${{ matrix.python-version }})
107
+ needs: build
108
+ runs-on: ubuntu-latest
109
+ timeout-minutes: 15
110
+ permissions:
111
+ contents: read
112
+ strategy:
113
+ fail-fast: true
114
+ matrix:
115
+ python-version: ["3.10", "3.11", "3.12"]
116
+
117
+ steps:
118
+ - name: Check out repository
119
+ uses: actions/checkout@v4
120
+
121
+ - name: Download dist artifacts
122
+ uses: actions/download-artifact@v4
123
+ with:
124
+ name: dist
125
+ path: dist/
126
+
127
+ - name: Set up Python ${{ matrix.python-version }}
128
+ uses: actions/setup-python@v5
129
+ with:
130
+ python-version: ${{ matrix.python-version }}
131
+
132
+ - name: Smoke-test each artifact
133
+ shell: bash
134
+ run: |
135
+ set -euo pipefail
136
+ for artifact in dist/*.tar.gz dist/*.whl; do
137
+ venv_dir="$(mktemp -d)/smoke-venv"
138
+ python -m venv "$venv_dir"
139
+ . "$venv_dir/bin/activate"
140
+ pip install --upgrade pip --quiet
141
+ pip install --force-reinstall "$artifact" --quiet
142
+ python scripts/artifact_smoke_test.py
143
+ deactivate
144
+ rm -rf "$venv_dir"
145
+ done
146
+
147
+ # ── 3. Publish to PyPI ───────────────────────────────────────────────────
148
+ #
149
+ # TestPyPI skipped: name is unavailable on test.pypi.org.
150
+ # Validation is covered by build gates + smoke-test on 3 Python versions.
151
+ #
152
+ # Requires secret PYPI_API_TOKEN set at:
153
+ # https://github.com/saurabh2mishra/fluxrules/settings/secrets/actions
154
+ #
155
+ # The pypi GitHub environment gate gives a manual confirmation click
156
+ # before the upload proceeds. Set up at:
157
+ # https://github.com/saurabh2mishra/fluxrules/settings/environments
158
+ #
159
+ publish-pypi:
160
+ name: Publish → PyPI
161
+ needs: [build, smoke-test]
162
+ runs-on: ubuntu-latest
163
+ timeout-minutes: 10
164
+ environment:
165
+ name: pypi
166
+ url: https://pypi.org/p/fluxrules
167
+ permissions:
168
+ contents: write # create GitHub release
169
+
170
+ steps:
171
+ - name: Download dist artifacts
172
+ uses: actions/download-artifact@v4
173
+ with:
174
+ name: dist
175
+ path: dist/
176
+
177
+ - name: Publish to PyPI
178
+ uses: pypa/gh-action-pypi-publish@release/v1
179
+ with:
180
+ password: ${{ secrets.PYPI_API_TOKEN }}
181
+ print-hash: true
182
+ verbose: true
183
+
184
+ # Create a GitHub release automatically on successful PyPI publish.
185
+ - name: Create GitHub Release
186
+ uses: softprops/action-gh-release@v2
187
+ with:
188
+ files: dist/*
189
+ generate_release_notes: true
190
+ fail_on_unmatched_files: true
@@ -0,0 +1,74 @@
1
+ # Python virtual environments
2
+ .venv/
3
+ venv/
4
+ env/
5
+ ENV/
6
+ .python-version
7
+
8
+ # Python bytecode and build artifacts
9
+ # Python creates these directories throughout the source and test trees.
10
+ **/__pycache__/
11
+ *.py[cod]
12
+ *.so
13
+ *.pyo
14
+ *.pyd
15
+ *.egg-info/
16
+ .eggs/
17
+ dist/
18
+ build/
19
+ site/
20
+ *.egg
21
+
22
+ # Test, coverage, and tooling caches
23
+ .pytest_cache/
24
+ .hypothesis/
25
+ .coverage
26
+ .coverage.*
27
+ htmlcov/
28
+ .tox/
29
+ .nox/
30
+ .mypy_cache/
31
+ .ruff_cache/
32
+ .pyre/
33
+ .pytype/
34
+
35
+ # Local environment and secrets
36
+ .env
37
+ .env.*
38
+ *.local
39
+ *.pem
40
+ credentials*.json
41
+
42
+ # Editors and OS files
43
+ .vscode/
44
+ .idea/
45
+ *.swp
46
+ *.swo
47
+ .DS_Store
48
+ Thumbs.db
49
+
50
+ # Project-specific generated files
51
+ logs/
52
+ *.log
53
+ /.github/agents/
54
+ /.github/skills/
55
+
56
+ # SQLite / database runtime artifacts
57
+ *.db
58
+ *.sqlite
59
+ *.sqlite3
60
+ *.db-wal
61
+ *.db-shm
62
+ *_wal
63
+ *_shm
64
+ rune_engine.db
65
+ fluxrules_dev.db
66
+ rule_engine.db
67
+ rule_engine.db-wal
68
+ rule_engine.db-shm
69
+
70
+ # Optional generated docs/assets
71
+ mkdocs_material/
72
+
73
+ # Claude Code — keep local only, do not publish to remote.
74
+ .claude/
@@ -0,0 +1,121 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ## [0.1.0] - 2026-10-06
11
+
12
+ First release intended for publication. The changes below tighten the public
13
+ API surface so that one concept has one name and one type. `0.0.1` was never
14
+ published, so these are breaking relative to an unreleased baseline only and
15
+ carry no deprecation shims — carrying a shim for `matched_rule_ids` was
16
+ rejected precisely because the name's meaning was the defect.
17
+
18
+ ### Changed — breaking
19
+
20
+ - **One `EvaluationResult`.** There were two classes of that name: the domain
21
+ one, whose `matched_rule_ids` meant *the rules that fired*, and the engine
22
+ one, whose `matched_rule_ids` meant *the rules discovery considered*. Both
23
+ were exported as `EvaluationResult`, so the same attribute answered a
24
+ different question depending on which function you called, and the engine's
25
+ answer was a superset that silently over-reported matches. They are now a
26
+ single class owned by `fluxrules.domain.models`;
27
+ `fluxrules.engine.infrastructure.EvaluationResult` re-exports it.
28
+ - **`fired_rules` is the only name for what matched.** `matched_rule_ids` is
29
+ removed from the attribute set, the constructor, and the persisted schema.
30
+ `candidate_rule_ids` remains the discovery prefilter's output and is
31
+ guaranteed to be a superset of `fired_rules` on every evaluation path,
32
+ including the reference evaluator.
33
+ - **`Rule(...)` no longer touches the database.** `persist` now defaults to
34
+ `False`, so constructing a rule is a pure in-memory operation; previously the
35
+ default `True` meant importing a module that defined rules opened a
36
+ connection and created a `.db` file, then swallowed any failure as a log
37
+ warning. Persist explicitly with the new `Rule.save()` or `persist=True`.
38
+ The redundant `except Exception` around persistence is gone —
39
+ `PersistenceManager.persist_rule` already degrades to a local ID, so anything
40
+ escaping it is a real fault.
41
+ - **`RuleBuilder.build()` returns `Rule`**, not the internal `EngineRule`, so a
42
+ built rule goes straight into `load_rules()` or `evaluate()`. Use the new
43
+ `build_engine_rule()` for the internal representation. `RuleBuilder`'s
44
+ `persist` default is now `False` to match `Rule`.
45
+ - **`evaluate()` and `validate()` take rules directly.** Both accept a single
46
+ `Rule`, any iterable of `Rule`, or a `Ruleset`; the first parameter is
47
+ renamed `ruleset` → `rules`. Building a `Ruleset` of `to_engine_rule()`
48
+ conversions is no longer required to evaluate a list of rules.
49
+ - **`explain()` returns `fired_rules`** instead of `matched_rules`, matching
50
+ `EvaluationResult`. The HTTP API's own `matched_rules` response field is a
51
+ separate wire contract and is unchanged.
52
+ - The `evaluation_results` table's `matched_rule_ids` column is now
53
+ `fired_rules`. The table is created by `create_all()` rather than Alembic, so
54
+ an existing development database needs to be recreated.
55
+
56
+ ### Fixed
57
+
58
+ - `RuleBuilder()` with no explicit ID allocated from a second, builder-local
59
+ sequential generator that also started at 1, so the first built rule and the
60
+ first directly-constructed rule were assigned the same ID and evaluating them
61
+ together failed with "Ruleset has duplicate rule ids". The builder now defers
62
+ to the same shared generator `Rule` uses.
63
+ - `docs/rule-builder.md` documented a `RuleBuilder` API that did not exist
64
+ (`.domain()`, `.tags()`, `.condition_dsl()`, and a snippet that was not valid
65
+ Python) while never demonstrating the real builder. Every block on the page
66
+ is now executable and covered by the documentation harness.
67
+
68
+ ### Added
69
+
70
+ - `Rule.save()` — explicit persistence for a rule built in memory.
71
+ - `RuleBuilder`, `ConditionBuilder`, and the `Rules` input alias are exported
72
+ from the top-level `fluxrules` namespace.
73
+ - `RuleBuilder.build_engine_rule()` for the internal `EngineRule` shape.
74
+ - A quickstart contract test (`tests/contract/test_quickstart_contract.py`) that
75
+ runs the documented ten-line example in a clean subprocess, asserts it emits
76
+ no warnings, and asserts it writes nothing to disk. CI runs it as its own step
77
+ ahead of the main suite so a broken first-run experience fails loudly.
78
+
79
+ ## [0.0.1] - 2026-09-14
80
+
81
+ Initial, unpublished development version. FluxRules is a Python rule-evaluation
82
+ library built on a single engine, PHREAK, with stateless (default) and streaming
83
+ evaluation modes.
84
+
85
+ ### Added
86
+
87
+ - Core evaluation API — `evaluate()`, `validate()`, `explain()` over a typed
88
+ `Ruleset` of rules, with a curated public `__all__` and a shipped `py.typed`
89
+ marker.
90
+ - PHREAK engine (`PhreakEngine`): lazy, agenda-driven evaluation in stateless
91
+ (default) and streaming modes. Correctness is checked against the
92
+ dependency-free `ReferenceEvaluator` oracle and by stateless/streaming parity.
93
+ - Condition operators — 13 distinct operators plus 6 word aliases: `==`/`eq`,
94
+ `!=`/`ne`, `>`/`gt`, `>=`/`gte`, `<`/`lt`, `<=`/`lte`, `in`, `not_in`,
95
+ `contains`, `not_contains`, `starts_with`, `ends_with`, `regex`; combined with
96
+ arbitrary AND/OR/NOT nesting.
97
+ - Extensibility — public `register_engine()` / `unregister_engine()` (a custom
98
+ `BaseEngine` becomes selectable via `get_engine()`, the HTTP API, and the CLI
99
+ `--engine` flag; the built-in engine is protected), registries for custom
100
+ operators/actions/transforms/validators, entry-point auto-discovery
101
+ (`fluxrules.plugins.discovery.load_plugins`), and a public conformance kit
102
+ (`fluxrules.testing.assert_engine_contract`).
103
+ - Fact pipeline — `Flatten`, `Rename`, `Defaults`, `Require`, `FieldType`, and
104
+ user-defined transforms.
105
+ - Validation framework (structure, conflicts, dead/redundant rules) and an audit
106
+ trail with integrity hashing.
107
+ - Optional adapters behind extras: FastAPI HTTP API (`api`), SQLAlchemy/Alembic
108
+ persistence (`sql`), Redis sessions (`redis`), OpenTelemetry (`otel`), YAML
109
+ rules (`yaml`), and a Typer CLI (`cli`).
110
+ - Documentation (MkDocs Material), 31 runnable examples, a suite of 2,000+ tests,
111
+ and a CI-gated scale test.
112
+
113
+ ### Security
114
+
115
+ - Scoped flake8-bandit (`S`) ruff rule set enforced in the lint gate
116
+ (exec/eval/pickle/marshal/weak-hash/SQL-injection/try-except-pass).
117
+ - CI security job (`bandit` + `pip-audit`) and a pull-request `dependency-review`
118
+ job; SPDX SBOM generation and Sigstore signing in the release workflow.
119
+ - `SECURITY.md` (supported versions, response targets, coordinated disclosure), a
120
+ threat model in `docs/security.md`, `CODEOWNERS`, and branch-protection
121
+ guidance in `CONTRIBUTING.md`.