omnibase_infra 0.2.6__py3-none-any.whl

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 (833) hide show
  1. omnibase_infra/__init__.py +101 -0
  2. omnibase_infra/adapters/adapter_onex_tool_execution.py +451 -0
  3. omnibase_infra/capabilities/__init__.py +15 -0
  4. omnibase_infra/capabilities/capability_inference_rules.py +211 -0
  5. omnibase_infra/capabilities/contract_capability_extractor.py +221 -0
  6. omnibase_infra/capabilities/intent_type_extractor.py +160 -0
  7. omnibase_infra/cli/__init__.py +1 -0
  8. omnibase_infra/cli/commands.py +216 -0
  9. omnibase_infra/clients/__init__.py +0 -0
  10. omnibase_infra/configs/widget_mapping.yaml +176 -0
  11. omnibase_infra/constants_topic_patterns.py +26 -0
  12. omnibase_infra/contracts/handlers/filesystem/handler_contract.yaml +264 -0
  13. omnibase_infra/contracts/handlers/mcp/handler_contract.yaml +141 -0
  14. omnibase_infra/decorators/__init__.py +29 -0
  15. omnibase_infra/decorators/allow_any.py +109 -0
  16. omnibase_infra/dlq/__init__.py +90 -0
  17. omnibase_infra/dlq/constants_dlq.py +57 -0
  18. omnibase_infra/dlq/models/__init__.py +26 -0
  19. omnibase_infra/dlq/models/enum_replay_status.py +37 -0
  20. omnibase_infra/dlq/models/model_dlq_replay_record.py +135 -0
  21. omnibase_infra/dlq/models/model_dlq_tracking_config.py +184 -0
  22. omnibase_infra/dlq/service_dlq_tracking.py +611 -0
  23. omnibase_infra/enums/__init__.py +132 -0
  24. omnibase_infra/enums/enum_any_type_violation.py +104 -0
  25. omnibase_infra/enums/enum_backend_type.py +27 -0
  26. omnibase_infra/enums/enum_capture_outcome.py +42 -0
  27. omnibase_infra/enums/enum_capture_state.py +88 -0
  28. omnibase_infra/enums/enum_chain_violation_type.py +119 -0
  29. omnibase_infra/enums/enum_circuit_state.py +51 -0
  30. omnibase_infra/enums/enum_confirmation_event_type.py +27 -0
  31. omnibase_infra/enums/enum_consumer_group_purpose.py +92 -0
  32. omnibase_infra/enums/enum_contract_type.py +84 -0
  33. omnibase_infra/enums/enum_dedupe_strategy.py +46 -0
  34. omnibase_infra/enums/enum_dispatch_status.py +191 -0
  35. omnibase_infra/enums/enum_environment.py +46 -0
  36. omnibase_infra/enums/enum_execution_shape_violation.py +103 -0
  37. omnibase_infra/enums/enum_handler_error_type.py +111 -0
  38. omnibase_infra/enums/enum_handler_loader_error.py +178 -0
  39. omnibase_infra/enums/enum_handler_source_mode.py +86 -0
  40. omnibase_infra/enums/enum_handler_source_type.py +87 -0
  41. omnibase_infra/enums/enum_handler_type.py +77 -0
  42. omnibase_infra/enums/enum_handler_type_category.py +61 -0
  43. omnibase_infra/enums/enum_infra_transport_type.py +73 -0
  44. omnibase_infra/enums/enum_introspection_reason.py +154 -0
  45. omnibase_infra/enums/enum_kafka_acks.py +99 -0
  46. omnibase_infra/enums/enum_message_category.py +213 -0
  47. omnibase_infra/enums/enum_node_archetype.py +74 -0
  48. omnibase_infra/enums/enum_node_output_type.py +185 -0
  49. omnibase_infra/enums/enum_non_retryable_error_category.py +224 -0
  50. omnibase_infra/enums/enum_policy_type.py +32 -0
  51. omnibase_infra/enums/enum_registration_state.py +261 -0
  52. omnibase_infra/enums/enum_registration_status.py +33 -0
  53. omnibase_infra/enums/enum_registry_response_status.py +28 -0
  54. omnibase_infra/enums/enum_response_status.py +26 -0
  55. omnibase_infra/enums/enum_retry_error_category.py +98 -0
  56. omnibase_infra/enums/enum_security_rule_id.py +103 -0
  57. omnibase_infra/enums/enum_selection_strategy.py +91 -0
  58. omnibase_infra/enums/enum_topic_standard.py +42 -0
  59. omnibase_infra/enums/enum_validation_severity.py +78 -0
  60. omnibase_infra/errors/__init__.py +160 -0
  61. omnibase_infra/errors/error_architecture_violation.py +152 -0
  62. omnibase_infra/errors/error_binding_resolution.py +128 -0
  63. omnibase_infra/errors/error_chain_propagation.py +188 -0
  64. omnibase_infra/errors/error_compute_registry.py +95 -0
  65. omnibase_infra/errors/error_consul.py +132 -0
  66. omnibase_infra/errors/error_container_wiring.py +243 -0
  67. omnibase_infra/errors/error_event_bus_registry.py +105 -0
  68. omnibase_infra/errors/error_infra.py +610 -0
  69. omnibase_infra/errors/error_message_type_registry.py +101 -0
  70. omnibase_infra/errors/error_policy_registry.py +115 -0
  71. omnibase_infra/errors/error_vault.py +123 -0
  72. omnibase_infra/event_bus/__init__.py +72 -0
  73. omnibase_infra/event_bus/configs/kafka_event_bus_config.yaml +84 -0
  74. omnibase_infra/event_bus/event_bus_inmemory.py +797 -0
  75. omnibase_infra/event_bus/event_bus_kafka.py +1716 -0
  76. omnibase_infra/event_bus/mixin_kafka_broadcast.py +180 -0
  77. omnibase_infra/event_bus/mixin_kafka_dlq.py +771 -0
  78. omnibase_infra/event_bus/models/__init__.py +29 -0
  79. omnibase_infra/event_bus/models/config/__init__.py +20 -0
  80. omnibase_infra/event_bus/models/config/model_kafka_event_bus_config.py +693 -0
  81. omnibase_infra/event_bus/models/model_dlq_event.py +206 -0
  82. omnibase_infra/event_bus/models/model_dlq_metrics.py +304 -0
  83. omnibase_infra/event_bus/models/model_event_headers.py +115 -0
  84. omnibase_infra/event_bus/models/model_event_message.py +60 -0
  85. omnibase_infra/event_bus/testing/__init__.py +26 -0
  86. omnibase_infra/event_bus/testing/adapter_protocol_event_publisher_inmemory.py +418 -0
  87. omnibase_infra/event_bus/testing/model_publisher_metrics.py +64 -0
  88. omnibase_infra/event_bus/topic_constants.py +376 -0
  89. omnibase_infra/handlers/__init__.py +82 -0
  90. omnibase_infra/handlers/filesystem/__init__.py +48 -0
  91. omnibase_infra/handlers/filesystem/enum_file_system_operation.py +35 -0
  92. omnibase_infra/handlers/filesystem/model_file_system_request.py +298 -0
  93. omnibase_infra/handlers/filesystem/model_file_system_result.py +166 -0
  94. omnibase_infra/handlers/handler_consul.py +795 -0
  95. omnibase_infra/handlers/handler_db.py +1046 -0
  96. omnibase_infra/handlers/handler_filesystem.py +1478 -0
  97. omnibase_infra/handlers/handler_graph.py +2015 -0
  98. omnibase_infra/handlers/handler_http.py +926 -0
  99. omnibase_infra/handlers/handler_intent.py +387 -0
  100. omnibase_infra/handlers/handler_manifest_persistence.contract.yaml +184 -0
  101. omnibase_infra/handlers/handler_manifest_persistence.py +1539 -0
  102. omnibase_infra/handlers/handler_mcp.py +1430 -0
  103. omnibase_infra/handlers/handler_qdrant.py +1076 -0
  104. omnibase_infra/handlers/handler_vault.py +428 -0
  105. omnibase_infra/handlers/mcp/__init__.py +19 -0
  106. omnibase_infra/handlers/mcp/adapter_onex_to_mcp.py +446 -0
  107. omnibase_infra/handlers/mcp/protocols.py +178 -0
  108. omnibase_infra/handlers/mcp/transport_streamable_http.py +352 -0
  109. omnibase_infra/handlers/mixins/__init__.py +47 -0
  110. omnibase_infra/handlers/mixins/mixin_consul_initialization.py +349 -0
  111. omnibase_infra/handlers/mixins/mixin_consul_kv.py +338 -0
  112. omnibase_infra/handlers/mixins/mixin_consul_service.py +542 -0
  113. omnibase_infra/handlers/mixins/mixin_consul_topic_index.py +585 -0
  114. omnibase_infra/handlers/mixins/mixin_vault_initialization.py +338 -0
  115. omnibase_infra/handlers/mixins/mixin_vault_retry.py +412 -0
  116. omnibase_infra/handlers/mixins/mixin_vault_secrets.py +450 -0
  117. omnibase_infra/handlers/mixins/mixin_vault_token.py +365 -0
  118. omnibase_infra/handlers/models/__init__.py +286 -0
  119. omnibase_infra/handlers/models/consul/__init__.py +81 -0
  120. omnibase_infra/handlers/models/consul/enum_consul_operation_type.py +57 -0
  121. omnibase_infra/handlers/models/consul/model_consul_deregister_payload.py +51 -0
  122. omnibase_infra/handlers/models/consul/model_consul_handler_config.py +153 -0
  123. omnibase_infra/handlers/models/consul/model_consul_handler_payload.py +89 -0
  124. omnibase_infra/handlers/models/consul/model_consul_kv_get_found_payload.py +55 -0
  125. omnibase_infra/handlers/models/consul/model_consul_kv_get_not_found_payload.py +49 -0
  126. omnibase_infra/handlers/models/consul/model_consul_kv_get_recurse_payload.py +50 -0
  127. omnibase_infra/handlers/models/consul/model_consul_kv_item.py +33 -0
  128. omnibase_infra/handlers/models/consul/model_consul_kv_put_payload.py +41 -0
  129. omnibase_infra/handlers/models/consul/model_consul_register_payload.py +53 -0
  130. omnibase_infra/handlers/models/consul/model_consul_retry_config.py +66 -0
  131. omnibase_infra/handlers/models/consul/model_payload_consul.py +66 -0
  132. omnibase_infra/handlers/models/consul/registry_payload_consul.py +214 -0
  133. omnibase_infra/handlers/models/graph/__init__.py +35 -0
  134. omnibase_infra/handlers/models/graph/enum_graph_operation_type.py +20 -0
  135. omnibase_infra/handlers/models/graph/model_graph_execute_payload.py +38 -0
  136. omnibase_infra/handlers/models/graph/model_graph_handler_config.py +54 -0
  137. omnibase_infra/handlers/models/graph/model_graph_handler_payload.py +44 -0
  138. omnibase_infra/handlers/models/graph/model_graph_query_payload.py +40 -0
  139. omnibase_infra/handlers/models/graph/model_graph_record.py +22 -0
  140. omnibase_infra/handlers/models/http/__init__.py +50 -0
  141. omnibase_infra/handlers/models/http/enum_http_operation_type.py +29 -0
  142. omnibase_infra/handlers/models/http/model_http_body_content.py +45 -0
  143. omnibase_infra/handlers/models/http/model_http_get_payload.py +88 -0
  144. omnibase_infra/handlers/models/http/model_http_handler_payload.py +90 -0
  145. omnibase_infra/handlers/models/http/model_http_post_payload.py +88 -0
  146. omnibase_infra/handlers/models/http/model_payload_http.py +66 -0
  147. omnibase_infra/handlers/models/http/registry_payload_http.py +212 -0
  148. omnibase_infra/handlers/models/mcp/__init__.py +23 -0
  149. omnibase_infra/handlers/models/mcp/enum_mcp_operation_type.py +24 -0
  150. omnibase_infra/handlers/models/mcp/model_mcp_handler_config.py +40 -0
  151. omnibase_infra/handlers/models/mcp/model_mcp_tool_call.py +32 -0
  152. omnibase_infra/handlers/models/mcp/model_mcp_tool_result.py +45 -0
  153. omnibase_infra/handlers/models/model_consul_handler_response.py +96 -0
  154. omnibase_infra/handlers/models/model_db_describe_response.py +83 -0
  155. omnibase_infra/handlers/models/model_db_query_payload.py +95 -0
  156. omnibase_infra/handlers/models/model_db_query_response.py +60 -0
  157. omnibase_infra/handlers/models/model_filesystem_config.py +98 -0
  158. omnibase_infra/handlers/models/model_filesystem_delete_payload.py +54 -0
  159. omnibase_infra/handlers/models/model_filesystem_delete_result.py +77 -0
  160. omnibase_infra/handlers/models/model_filesystem_directory_entry.py +75 -0
  161. omnibase_infra/handlers/models/model_filesystem_ensure_directory_payload.py +54 -0
  162. omnibase_infra/handlers/models/model_filesystem_ensure_directory_result.py +60 -0
  163. omnibase_infra/handlers/models/model_filesystem_list_directory_payload.py +60 -0
  164. omnibase_infra/handlers/models/model_filesystem_list_directory_result.py +68 -0
  165. omnibase_infra/handlers/models/model_filesystem_read_payload.py +62 -0
  166. omnibase_infra/handlers/models/model_filesystem_read_result.py +61 -0
  167. omnibase_infra/handlers/models/model_filesystem_write_payload.py +70 -0
  168. omnibase_infra/handlers/models/model_filesystem_write_result.py +55 -0
  169. omnibase_infra/handlers/models/model_graph_handler_response.py +98 -0
  170. omnibase_infra/handlers/models/model_handler_response.py +103 -0
  171. omnibase_infra/handlers/models/model_http_handler_response.py +101 -0
  172. omnibase_infra/handlers/models/model_manifest_metadata.py +75 -0
  173. omnibase_infra/handlers/models/model_manifest_persistence_config.py +62 -0
  174. omnibase_infra/handlers/models/model_manifest_query_payload.py +90 -0
  175. omnibase_infra/handlers/models/model_manifest_query_result.py +97 -0
  176. omnibase_infra/handlers/models/model_manifest_retrieve_payload.py +44 -0
  177. omnibase_infra/handlers/models/model_manifest_retrieve_result.py +98 -0
  178. omnibase_infra/handlers/models/model_manifest_store_payload.py +47 -0
  179. omnibase_infra/handlers/models/model_manifest_store_result.py +67 -0
  180. omnibase_infra/handlers/models/model_operation_context.py +187 -0
  181. omnibase_infra/handlers/models/model_qdrant_handler_response.py +98 -0
  182. omnibase_infra/handlers/models/model_retry_state.py +162 -0
  183. omnibase_infra/handlers/models/model_vault_handler_response.py +98 -0
  184. omnibase_infra/handlers/models/qdrant/__init__.py +44 -0
  185. omnibase_infra/handlers/models/qdrant/enum_qdrant_operation_type.py +26 -0
  186. omnibase_infra/handlers/models/qdrant/model_qdrant_collection_payload.py +42 -0
  187. omnibase_infra/handlers/models/qdrant/model_qdrant_delete_payload.py +36 -0
  188. omnibase_infra/handlers/models/qdrant/model_qdrant_handler_config.py +42 -0
  189. omnibase_infra/handlers/models/qdrant/model_qdrant_handler_payload.py +54 -0
  190. omnibase_infra/handlers/models/qdrant/model_qdrant_search_payload.py +42 -0
  191. omnibase_infra/handlers/models/qdrant/model_qdrant_search_result.py +30 -0
  192. omnibase_infra/handlers/models/qdrant/model_qdrant_upsert_payload.py +36 -0
  193. omnibase_infra/handlers/models/vault/__init__.py +69 -0
  194. omnibase_infra/handlers/models/vault/enum_vault_operation_type.py +35 -0
  195. omnibase_infra/handlers/models/vault/model_payload_vault.py +66 -0
  196. omnibase_infra/handlers/models/vault/model_vault_delete_payload.py +57 -0
  197. omnibase_infra/handlers/models/vault/model_vault_handler_config.py +148 -0
  198. omnibase_infra/handlers/models/vault/model_vault_handler_payload.py +101 -0
  199. omnibase_infra/handlers/models/vault/model_vault_list_payload.py +58 -0
  200. omnibase_infra/handlers/models/vault/model_vault_renew_token_payload.py +67 -0
  201. omnibase_infra/handlers/models/vault/model_vault_retry_config.py +66 -0
  202. omnibase_infra/handlers/models/vault/model_vault_secret_payload.py +106 -0
  203. omnibase_infra/handlers/models/vault/model_vault_write_payload.py +66 -0
  204. omnibase_infra/handlers/models/vault/registry_payload_vault.py +213 -0
  205. omnibase_infra/handlers/registration_storage/__init__.py +43 -0
  206. omnibase_infra/handlers/registration_storage/handler_registration_storage_mock.py +392 -0
  207. omnibase_infra/handlers/registration_storage/handler_registration_storage_postgres.py +922 -0
  208. omnibase_infra/handlers/registration_storage/models/__init__.py +23 -0
  209. omnibase_infra/handlers/registration_storage/models/model_delete_registration_request.py +58 -0
  210. omnibase_infra/handlers/registration_storage/models/model_update_registration_request.py +73 -0
  211. omnibase_infra/handlers/registration_storage/protocol_registration_persistence.py +191 -0
  212. omnibase_infra/handlers/service_discovery/__init__.py +43 -0
  213. omnibase_infra/handlers/service_discovery/handler_service_discovery_consul.py +1051 -0
  214. omnibase_infra/handlers/service_discovery/handler_service_discovery_mock.py +258 -0
  215. omnibase_infra/handlers/service_discovery/models/__init__.py +22 -0
  216. omnibase_infra/handlers/service_discovery/models/model_discovery_result.py +64 -0
  217. omnibase_infra/handlers/service_discovery/models/model_registration_result.py +138 -0
  218. omnibase_infra/handlers/service_discovery/models/model_service_info.py +109 -0
  219. omnibase_infra/handlers/service_discovery/protocol_discovery_operations.py +170 -0
  220. omnibase_infra/idempotency/__init__.py +94 -0
  221. omnibase_infra/idempotency/models/__init__.py +43 -0
  222. omnibase_infra/idempotency/models/model_idempotency_check_result.py +85 -0
  223. omnibase_infra/idempotency/models/model_idempotency_guard_config.py +130 -0
  224. omnibase_infra/idempotency/models/model_idempotency_record.py +86 -0
  225. omnibase_infra/idempotency/models/model_idempotency_store_health_check_result.py +81 -0
  226. omnibase_infra/idempotency/models/model_idempotency_store_metrics.py +140 -0
  227. omnibase_infra/idempotency/models/model_postgres_idempotency_store_config.py +299 -0
  228. omnibase_infra/idempotency/protocol_idempotency_store.py +184 -0
  229. omnibase_infra/idempotency/store_inmemory.py +265 -0
  230. omnibase_infra/idempotency/store_postgres.py +923 -0
  231. omnibase_infra/infrastructure/__init__.py +0 -0
  232. omnibase_infra/migrations/001_create_event_ledger.sql +166 -0
  233. omnibase_infra/migrations/001_drop_event_ledger.sql +18 -0
  234. omnibase_infra/mixins/__init__.py +71 -0
  235. omnibase_infra/mixins/mixin_async_circuit_breaker.py +656 -0
  236. omnibase_infra/mixins/mixin_dict_like_accessors.py +146 -0
  237. omnibase_infra/mixins/mixin_envelope_extraction.py +119 -0
  238. omnibase_infra/mixins/mixin_node_introspection.py +2670 -0
  239. omnibase_infra/mixins/mixin_retry_execution.py +386 -0
  240. omnibase_infra/mixins/protocol_circuit_breaker_aware.py +133 -0
  241. omnibase_infra/models/__init__.py +144 -0
  242. omnibase_infra/models/bindings/__init__.py +59 -0
  243. omnibase_infra/models/bindings/constants.py +144 -0
  244. omnibase_infra/models/bindings/model_binding_resolution_result.py +103 -0
  245. omnibase_infra/models/bindings/model_operation_binding.py +44 -0
  246. omnibase_infra/models/bindings/model_operation_bindings_subcontract.py +152 -0
  247. omnibase_infra/models/bindings/model_parsed_binding.py +52 -0
  248. omnibase_infra/models/corpus/__init__.py +17 -0
  249. omnibase_infra/models/corpus/model_capture_config.py +133 -0
  250. omnibase_infra/models/corpus/model_capture_result.py +86 -0
  251. omnibase_infra/models/discovery/__init__.py +42 -0
  252. omnibase_infra/models/discovery/model_dependency_spec.py +319 -0
  253. omnibase_infra/models/discovery/model_discovered_capabilities.py +50 -0
  254. omnibase_infra/models/discovery/model_introspection_config.py +330 -0
  255. omnibase_infra/models/discovery/model_introspection_performance_metrics.py +169 -0
  256. omnibase_infra/models/discovery/model_introspection_task_config.py +116 -0
  257. omnibase_infra/models/dispatch/__init__.py +155 -0
  258. omnibase_infra/models/dispatch/model_debug_trace_snapshot.py +114 -0
  259. omnibase_infra/models/dispatch/model_dispatch_context.py +439 -0
  260. omnibase_infra/models/dispatch/model_dispatch_error.py +336 -0
  261. omnibase_infra/models/dispatch/model_dispatch_log_context.py +400 -0
  262. omnibase_infra/models/dispatch/model_dispatch_metadata.py +228 -0
  263. omnibase_infra/models/dispatch/model_dispatch_metrics.py +496 -0
  264. omnibase_infra/models/dispatch/model_dispatch_outcome.py +317 -0
  265. omnibase_infra/models/dispatch/model_dispatch_outputs.py +231 -0
  266. omnibase_infra/models/dispatch/model_dispatch_result.py +436 -0
  267. omnibase_infra/models/dispatch/model_dispatch_route.py +279 -0
  268. omnibase_infra/models/dispatch/model_dispatcher_metrics.py +275 -0
  269. omnibase_infra/models/dispatch/model_dispatcher_registration.py +352 -0
  270. omnibase_infra/models/dispatch/model_materialized_dispatch.py +141 -0
  271. omnibase_infra/models/dispatch/model_parsed_topic.py +135 -0
  272. omnibase_infra/models/dispatch/model_topic_parser.py +725 -0
  273. omnibase_infra/models/dispatch/model_tracing_context.py +285 -0
  274. omnibase_infra/models/errors/__init__.py +45 -0
  275. omnibase_infra/models/errors/model_handler_validation_error.py +594 -0
  276. omnibase_infra/models/errors/model_infra_error_context.py +99 -0
  277. omnibase_infra/models/errors/model_message_type_registry_error_context.py +71 -0
  278. omnibase_infra/models/errors/model_timeout_error_context.py +110 -0
  279. omnibase_infra/models/handlers/__init__.py +80 -0
  280. omnibase_infra/models/handlers/model_bootstrap_handler_descriptor.py +162 -0
  281. omnibase_infra/models/handlers/model_contract_discovery_result.py +82 -0
  282. omnibase_infra/models/handlers/model_handler_descriptor.py +200 -0
  283. omnibase_infra/models/handlers/model_handler_identifier.py +215 -0
  284. omnibase_infra/models/handlers/model_handler_source_config.py +220 -0
  285. omnibase_infra/models/health/__init__.py +9 -0
  286. omnibase_infra/models/health/model_health_check_result.py +40 -0
  287. omnibase_infra/models/lifecycle/__init__.py +39 -0
  288. omnibase_infra/models/logging/__init__.py +51 -0
  289. omnibase_infra/models/logging/model_log_context.py +756 -0
  290. omnibase_infra/models/mcp/__init__.py +15 -0
  291. omnibase_infra/models/mcp/model_mcp_contract_config.py +80 -0
  292. omnibase_infra/models/mcp/model_mcp_server_config.py +67 -0
  293. omnibase_infra/models/mcp/model_mcp_tool_definition.py +73 -0
  294. omnibase_infra/models/mcp/model_mcp_tool_parameter.py +35 -0
  295. omnibase_infra/models/model_node_identity.py +126 -0
  296. omnibase_infra/models/model_retry_error_classification.py +78 -0
  297. omnibase_infra/models/projection/__init__.py +43 -0
  298. omnibase_infra/models/projection/model_capability_fields.py +112 -0
  299. omnibase_infra/models/projection/model_registration_projection.py +434 -0
  300. omnibase_infra/models/projection/model_registration_snapshot.py +322 -0
  301. omnibase_infra/models/projection/model_sequence_info.py +182 -0
  302. omnibase_infra/models/projection/model_snapshot_topic_config.py +591 -0
  303. omnibase_infra/models/projectors/__init__.py +41 -0
  304. omnibase_infra/models/projectors/model_projector_column.py +289 -0
  305. omnibase_infra/models/projectors/model_projector_discovery_result.py +65 -0
  306. omnibase_infra/models/projectors/model_projector_index.py +270 -0
  307. omnibase_infra/models/projectors/model_projector_schema.py +415 -0
  308. omnibase_infra/models/projectors/model_projector_validation_error.py +63 -0
  309. omnibase_infra/models/projectors/util_sql_identifiers.py +115 -0
  310. omnibase_infra/models/registration/__init__.py +68 -0
  311. omnibase_infra/models/registration/commands/__init__.py +15 -0
  312. omnibase_infra/models/registration/commands/model_node_registration_acked.py +108 -0
  313. omnibase_infra/models/registration/events/__init__.py +56 -0
  314. omnibase_infra/models/registration/events/model_node_became_active.py +103 -0
  315. omnibase_infra/models/registration/events/model_node_liveness_expired.py +103 -0
  316. omnibase_infra/models/registration/events/model_node_registration_accepted.py +98 -0
  317. omnibase_infra/models/registration/events/model_node_registration_ack_received.py +98 -0
  318. omnibase_infra/models/registration/events/model_node_registration_ack_timed_out.py +112 -0
  319. omnibase_infra/models/registration/events/model_node_registration_initiated.py +107 -0
  320. omnibase_infra/models/registration/events/model_node_registration_rejected.py +104 -0
  321. omnibase_infra/models/registration/model_event_bus_topic_entry.py +59 -0
  322. omnibase_infra/models/registration/model_introspection_metrics.py +253 -0
  323. omnibase_infra/models/registration/model_node_capabilities.py +190 -0
  324. omnibase_infra/models/registration/model_node_event_bus_config.py +99 -0
  325. omnibase_infra/models/registration/model_node_heartbeat_event.py +126 -0
  326. omnibase_infra/models/registration/model_node_introspection_event.py +195 -0
  327. omnibase_infra/models/registration/model_node_metadata.py +79 -0
  328. omnibase_infra/models/registration/model_node_registration.py +162 -0
  329. omnibase_infra/models/registration/model_node_registration_record.py +162 -0
  330. omnibase_infra/models/registry/__init__.py +29 -0
  331. omnibase_infra/models/registry/model_domain_constraint.py +202 -0
  332. omnibase_infra/models/registry/model_message_type_entry.py +271 -0
  333. omnibase_infra/models/resilience/__init__.py +9 -0
  334. omnibase_infra/models/resilience/model_circuit_breaker_config.py +227 -0
  335. omnibase_infra/models/routing/__init__.py +25 -0
  336. omnibase_infra/models/routing/model_routing_entry.py +52 -0
  337. omnibase_infra/models/routing/model_routing_subcontract.py +70 -0
  338. omnibase_infra/models/runtime/__init__.py +49 -0
  339. omnibase_infra/models/runtime/model_contract_security_config.py +41 -0
  340. omnibase_infra/models/runtime/model_discovery_error.py +81 -0
  341. omnibase_infra/models/runtime/model_discovery_result.py +162 -0
  342. omnibase_infra/models/runtime/model_discovery_warning.py +74 -0
  343. omnibase_infra/models/runtime/model_failed_plugin_load.py +63 -0
  344. omnibase_infra/models/runtime/model_handler_contract.py +296 -0
  345. omnibase_infra/models/runtime/model_loaded_handler.py +129 -0
  346. omnibase_infra/models/runtime/model_plugin_load_context.py +93 -0
  347. omnibase_infra/models/runtime/model_plugin_load_summary.py +124 -0
  348. omnibase_infra/models/security/__init__.py +50 -0
  349. omnibase_infra/models/security/classification_levels.py +99 -0
  350. omnibase_infra/models/security/model_environment_policy.py +145 -0
  351. omnibase_infra/models/security/model_handler_security_policy.py +107 -0
  352. omnibase_infra/models/security/model_security_error.py +81 -0
  353. omnibase_infra/models/security/model_security_validation_result.py +328 -0
  354. omnibase_infra/models/security/model_security_warning.py +67 -0
  355. omnibase_infra/models/snapshot/__init__.py +27 -0
  356. omnibase_infra/models/snapshot/model_field_change.py +65 -0
  357. omnibase_infra/models/snapshot/model_snapshot.py +270 -0
  358. omnibase_infra/models/snapshot/model_snapshot_diff.py +203 -0
  359. omnibase_infra/models/snapshot/model_subject_ref.py +81 -0
  360. omnibase_infra/models/types/__init__.py +71 -0
  361. omnibase_infra/models/validation/__init__.py +89 -0
  362. omnibase_infra/models/validation/model_any_type_validation_result.py +118 -0
  363. omnibase_infra/models/validation/model_any_type_violation.py +141 -0
  364. omnibase_infra/models/validation/model_category_match_result.py +345 -0
  365. omnibase_infra/models/validation/model_chain_violation.py +166 -0
  366. omnibase_infra/models/validation/model_coverage_metrics.py +316 -0
  367. omnibase_infra/models/validation/model_execution_shape_rule.py +159 -0
  368. omnibase_infra/models/validation/model_execution_shape_validation.py +208 -0
  369. omnibase_infra/models/validation/model_execution_shape_validation_result.py +294 -0
  370. omnibase_infra/models/validation/model_execution_shape_violation.py +122 -0
  371. omnibase_infra/models/validation/model_localhandler_validation_result.py +139 -0
  372. omnibase_infra/models/validation/model_localhandler_violation.py +100 -0
  373. omnibase_infra/models/validation/model_output_validation_params.py +74 -0
  374. omnibase_infra/models/validation/model_validate_and_raise_params.py +84 -0
  375. omnibase_infra/models/validation/model_validation_error_params.py +84 -0
  376. omnibase_infra/models/validation/model_validation_outcome.py +287 -0
  377. omnibase_infra/nodes/__init__.py +57 -0
  378. omnibase_infra/nodes/architecture_validator/__init__.py +79 -0
  379. omnibase_infra/nodes/architecture_validator/contract.yaml +252 -0
  380. omnibase_infra/nodes/architecture_validator/contract_architecture_validator.yaml +203 -0
  381. omnibase_infra/nodes/architecture_validator/mixins/__init__.py +16 -0
  382. omnibase_infra/nodes/architecture_validator/mixins/mixin_file_path_rule.py +92 -0
  383. omnibase_infra/nodes/architecture_validator/models/__init__.py +36 -0
  384. omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_request.py +56 -0
  385. omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_result.py +311 -0
  386. omnibase_infra/nodes/architecture_validator/models/model_architecture_violation.py +163 -0
  387. omnibase_infra/nodes/architecture_validator/models/model_rule_check_result.py +265 -0
  388. omnibase_infra/nodes/architecture_validator/models/model_validation_request.py +105 -0
  389. omnibase_infra/nodes/architecture_validator/models/model_validation_result.py +314 -0
  390. omnibase_infra/nodes/architecture_validator/node.py +262 -0
  391. omnibase_infra/nodes/architecture_validator/node_architecture_validator.py +383 -0
  392. omnibase_infra/nodes/architecture_validator/protocols/__init__.py +9 -0
  393. omnibase_infra/nodes/architecture_validator/protocols/protocol_architecture_rule.py +225 -0
  394. omnibase_infra/nodes/architecture_validator/registry/__init__.py +28 -0
  395. omnibase_infra/nodes/architecture_validator/registry/registry_infra_architecture_validator.py +106 -0
  396. omnibase_infra/nodes/architecture_validator/validators/__init__.py +104 -0
  397. omnibase_infra/nodes/architecture_validator/validators/validator_no_direct_dispatch.py +422 -0
  398. omnibase_infra/nodes/architecture_validator/validators/validator_no_handler_publishing.py +481 -0
  399. omnibase_infra/nodes/architecture_validator/validators/validator_no_orchestrator_fsm.py +491 -0
  400. omnibase_infra/nodes/contract_registry_reducer/__init__.py +29 -0
  401. omnibase_infra/nodes/contract_registry_reducer/contract.yaml +255 -0
  402. omnibase_infra/nodes/contract_registry_reducer/models/__init__.py +38 -0
  403. omnibase_infra/nodes/contract_registry_reducer/models/model_contract_registry_state.py +266 -0
  404. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_cleanup_topic_references.py +55 -0
  405. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_deactivate_contract.py +58 -0
  406. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_mark_stale.py +49 -0
  407. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_update_heartbeat.py +71 -0
  408. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_update_topic.py +66 -0
  409. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_upsert_contract.py +92 -0
  410. omnibase_infra/nodes/contract_registry_reducer/node.py +121 -0
  411. omnibase_infra/nodes/contract_registry_reducer/reducer.py +784 -0
  412. omnibase_infra/nodes/contract_registry_reducer/registry/__init__.py +9 -0
  413. omnibase_infra/nodes/contract_registry_reducer/registry/registry_infra_contract_registry_reducer.py +101 -0
  414. omnibase_infra/nodes/effects/README.md +358 -0
  415. omnibase_infra/nodes/effects/__init__.py +26 -0
  416. omnibase_infra/nodes/effects/contract.yaml +167 -0
  417. omnibase_infra/nodes/effects/models/__init__.py +32 -0
  418. omnibase_infra/nodes/effects/models/model_backend_result.py +190 -0
  419. omnibase_infra/nodes/effects/models/model_effect_idempotency_config.py +92 -0
  420. omnibase_infra/nodes/effects/models/model_registry_request.py +132 -0
  421. omnibase_infra/nodes/effects/models/model_registry_response.py +263 -0
  422. omnibase_infra/nodes/effects/protocol_consul_client.py +89 -0
  423. omnibase_infra/nodes/effects/protocol_effect_idempotency_store.py +143 -0
  424. omnibase_infra/nodes/effects/protocol_postgres_adapter.py +96 -0
  425. omnibase_infra/nodes/effects/registry_effect.py +525 -0
  426. omnibase_infra/nodes/effects/store_effect_idempotency_inmemory.py +425 -0
  427. omnibase_infra/nodes/handlers/consul/contract.yaml +85 -0
  428. omnibase_infra/nodes/handlers/db/contract.yaml +72 -0
  429. omnibase_infra/nodes/handlers/graph/contract.yaml +127 -0
  430. omnibase_infra/nodes/handlers/http/contract.yaml +74 -0
  431. omnibase_infra/nodes/handlers/intent/contract.yaml +66 -0
  432. omnibase_infra/nodes/handlers/mcp/contract.yaml +69 -0
  433. omnibase_infra/nodes/handlers/vault/contract.yaml +91 -0
  434. omnibase_infra/nodes/node_intent_storage_effect/__init__.py +50 -0
  435. omnibase_infra/nodes/node_intent_storage_effect/contract.yaml +194 -0
  436. omnibase_infra/nodes/node_intent_storage_effect/models/__init__.py +24 -0
  437. omnibase_infra/nodes/node_intent_storage_effect/models/model_intent_storage_input.py +141 -0
  438. omnibase_infra/nodes/node_intent_storage_effect/models/model_intent_storage_output.py +130 -0
  439. omnibase_infra/nodes/node_intent_storage_effect/node.py +94 -0
  440. omnibase_infra/nodes/node_intent_storage_effect/registry/__init__.py +35 -0
  441. omnibase_infra/nodes/node_intent_storage_effect/registry/registry_infra_intent_storage.py +294 -0
  442. omnibase_infra/nodes/node_ledger_projection_compute/__init__.py +50 -0
  443. omnibase_infra/nodes/node_ledger_projection_compute/contract.yaml +104 -0
  444. omnibase_infra/nodes/node_ledger_projection_compute/node.py +284 -0
  445. omnibase_infra/nodes/node_ledger_projection_compute/registry/__init__.py +29 -0
  446. omnibase_infra/nodes/node_ledger_projection_compute/registry/registry_infra_ledger_projection.py +118 -0
  447. omnibase_infra/nodes/node_ledger_write_effect/__init__.py +82 -0
  448. omnibase_infra/nodes/node_ledger_write_effect/contract.yaml +200 -0
  449. omnibase_infra/nodes/node_ledger_write_effect/handlers/__init__.py +22 -0
  450. omnibase_infra/nodes/node_ledger_write_effect/handlers/handler_ledger_append.py +372 -0
  451. omnibase_infra/nodes/node_ledger_write_effect/handlers/handler_ledger_query.py +597 -0
  452. omnibase_infra/nodes/node_ledger_write_effect/models/__init__.py +31 -0
  453. omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_append_result.py +54 -0
  454. omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_entry.py +92 -0
  455. omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_query.py +53 -0
  456. omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_query_result.py +41 -0
  457. omnibase_infra/nodes/node_ledger_write_effect/node.py +89 -0
  458. omnibase_infra/nodes/node_ledger_write_effect/protocols/__init__.py +13 -0
  459. omnibase_infra/nodes/node_ledger_write_effect/protocols/protocol_ledger_persistence.py +127 -0
  460. omnibase_infra/nodes/node_ledger_write_effect/registry/__init__.py +9 -0
  461. omnibase_infra/nodes/node_ledger_write_effect/registry/registry_infra_ledger_write.py +121 -0
  462. omnibase_infra/nodes/node_registration_orchestrator/README.md +542 -0
  463. omnibase_infra/nodes/node_registration_orchestrator/__init__.py +120 -0
  464. omnibase_infra/nodes/node_registration_orchestrator/contract.yaml +482 -0
  465. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/__init__.py +53 -0
  466. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_introspected.py +376 -0
  467. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_registration_acked.py +376 -0
  468. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_runtime_tick.py +373 -0
  469. omnibase_infra/nodes/node_registration_orchestrator/handlers/__init__.py +62 -0
  470. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_heartbeat.py +376 -0
  471. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_introspected.py +694 -0
  472. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_registration_acked.py +458 -0
  473. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_runtime_tick.py +364 -0
  474. omnibase_infra/nodes/node_registration_orchestrator/introspection_event_router.py +544 -0
  475. omnibase_infra/nodes/node_registration_orchestrator/models/__init__.py +75 -0
  476. omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_intent_payload.py +194 -0
  477. omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_registration_intent.py +67 -0
  478. omnibase_infra/nodes/node_registration_orchestrator/models/model_intent_execution_result.py +50 -0
  479. omnibase_infra/nodes/node_registration_orchestrator/models/model_node_liveness_expired.py +107 -0
  480. omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_config.py +67 -0
  481. omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_input.py +41 -0
  482. omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_output.py +166 -0
  483. omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_intent_payload.py +235 -0
  484. omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_upsert_intent.py +68 -0
  485. omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_execution_result.py +384 -0
  486. omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_state.py +60 -0
  487. omnibase_infra/nodes/node_registration_orchestrator/models/model_registration_intent.py +177 -0
  488. omnibase_infra/nodes/node_registration_orchestrator/models/model_registry_intent.py +247 -0
  489. omnibase_infra/nodes/node_registration_orchestrator/node.py +195 -0
  490. omnibase_infra/nodes/node_registration_orchestrator/plugin.py +909 -0
  491. omnibase_infra/nodes/node_registration_orchestrator/protocols.py +439 -0
  492. omnibase_infra/nodes/node_registration_orchestrator/registry/__init__.py +41 -0
  493. omnibase_infra/nodes/node_registration_orchestrator/registry/registry_infra_node_registration_orchestrator.py +528 -0
  494. omnibase_infra/nodes/node_registration_orchestrator/timeout_coordinator.py +393 -0
  495. omnibase_infra/nodes/node_registration_orchestrator/wiring.py +743 -0
  496. omnibase_infra/nodes/node_registration_reducer/__init__.py +15 -0
  497. omnibase_infra/nodes/node_registration_reducer/contract.yaml +301 -0
  498. omnibase_infra/nodes/node_registration_reducer/models/__init__.py +38 -0
  499. omnibase_infra/nodes/node_registration_reducer/models/model_validation_result.py +113 -0
  500. omnibase_infra/nodes/node_registration_reducer/node.py +139 -0
  501. omnibase_infra/nodes/node_registration_reducer/registry/__init__.py +9 -0
  502. omnibase_infra/nodes/node_registration_reducer/registry/registry_infra_node_registration_reducer.py +79 -0
  503. omnibase_infra/nodes/node_registration_storage_effect/__init__.py +41 -0
  504. omnibase_infra/nodes/node_registration_storage_effect/contract.yaml +220 -0
  505. omnibase_infra/nodes/node_registration_storage_effect/models/__init__.py +44 -0
  506. omnibase_infra/nodes/node_registration_storage_effect/models/model_delete_result.py +132 -0
  507. omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_record.py +199 -0
  508. omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_update.py +155 -0
  509. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_details.py +123 -0
  510. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_result.py +117 -0
  511. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_query.py +100 -0
  512. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_result.py +136 -0
  513. omnibase_infra/nodes/node_registration_storage_effect/models/model_upsert_result.py +127 -0
  514. omnibase_infra/nodes/node_registration_storage_effect/node.py +112 -0
  515. omnibase_infra/nodes/node_registration_storage_effect/protocols/__init__.py +22 -0
  516. omnibase_infra/nodes/node_registration_storage_effect/protocols/protocol_registration_persistence.py +333 -0
  517. omnibase_infra/nodes/node_registration_storage_effect/registry/__init__.py +23 -0
  518. omnibase_infra/nodes/node_registration_storage_effect/registry/registry_infra_registration_storage.py +215 -0
  519. omnibase_infra/nodes/node_registry_effect/__init__.py +85 -0
  520. omnibase_infra/nodes/node_registry_effect/contract.yaml +677 -0
  521. omnibase_infra/nodes/node_registry_effect/handlers/__init__.py +70 -0
  522. omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_deregister.py +211 -0
  523. omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_register.py +212 -0
  524. omnibase_infra/nodes/node_registry_effect/handlers/handler_partial_retry.py +417 -0
  525. omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_deactivate.py +215 -0
  526. omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_upsert.py +208 -0
  527. omnibase_infra/nodes/node_registry_effect/models/__init__.py +43 -0
  528. omnibase_infra/nodes/node_registry_effect/models/model_partial_retry_request.py +92 -0
  529. omnibase_infra/nodes/node_registry_effect/node.py +165 -0
  530. omnibase_infra/nodes/node_registry_effect/registry/__init__.py +27 -0
  531. omnibase_infra/nodes/node_registry_effect/registry/registry_infra_registry_effect.py +196 -0
  532. omnibase_infra/nodes/node_service_discovery_effect/__init__.py +111 -0
  533. omnibase_infra/nodes/node_service_discovery_effect/contract.yaml +246 -0
  534. omnibase_infra/nodes/node_service_discovery_effect/models/__init__.py +67 -0
  535. omnibase_infra/nodes/node_service_discovery_effect/models/enum_health_status.py +72 -0
  536. omnibase_infra/nodes/node_service_discovery_effect/models/enum_service_discovery_operation.py +58 -0
  537. omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_query.py +99 -0
  538. omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_result.py +98 -0
  539. omnibase_infra/nodes/node_service_discovery_effect/models/model_health_check_config.py +121 -0
  540. omnibase_infra/nodes/node_service_discovery_effect/models/model_query_metadata.py +63 -0
  541. omnibase_infra/nodes/node_service_discovery_effect/models/model_registration_result.py +130 -0
  542. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_details.py +111 -0
  543. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_result.py +119 -0
  544. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_info.py +106 -0
  545. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_registration.py +121 -0
  546. omnibase_infra/nodes/node_service_discovery_effect/node.py +111 -0
  547. omnibase_infra/nodes/node_service_discovery_effect/protocols/__init__.py +14 -0
  548. omnibase_infra/nodes/node_service_discovery_effect/protocols/protocol_discovery_operations.py +279 -0
  549. omnibase_infra/nodes/node_service_discovery_effect/registry/__init__.py +13 -0
  550. omnibase_infra/nodes/node_service_discovery_effect/registry/registry_infra_service_discovery.py +222 -0
  551. omnibase_infra/nodes/reducers/__init__.py +30 -0
  552. omnibase_infra/nodes/reducers/models/__init__.py +37 -0
  553. omnibase_infra/nodes/reducers/models/model_payload_consul_register.py +87 -0
  554. omnibase_infra/nodes/reducers/models/model_payload_ledger_append.py +133 -0
  555. omnibase_infra/nodes/reducers/models/model_payload_postgres_upsert_registration.py +60 -0
  556. omnibase_infra/nodes/reducers/models/model_registration_confirmation.py +166 -0
  557. omnibase_infra/nodes/reducers/models/model_registration_state.py +433 -0
  558. omnibase_infra/nodes/reducers/registration_reducer.py +1138 -0
  559. omnibase_infra/observability/__init__.py +143 -0
  560. omnibase_infra/observability/constants_metrics.py +91 -0
  561. omnibase_infra/observability/factory_observability_sink.py +525 -0
  562. omnibase_infra/observability/handlers/__init__.py +118 -0
  563. omnibase_infra/observability/handlers/handler_logging_structured.py +967 -0
  564. omnibase_infra/observability/handlers/handler_metrics_prometheus.py +1120 -0
  565. omnibase_infra/observability/handlers/model_logging_handler_config.py +71 -0
  566. omnibase_infra/observability/handlers/model_logging_handler_response.py +77 -0
  567. omnibase_infra/observability/handlers/model_metrics_handler_config.py +172 -0
  568. omnibase_infra/observability/handlers/model_metrics_handler_payload.py +135 -0
  569. omnibase_infra/observability/handlers/model_metrics_handler_response.py +101 -0
  570. omnibase_infra/observability/hooks/__init__.py +74 -0
  571. omnibase_infra/observability/hooks/hook_observability.py +1223 -0
  572. omnibase_infra/observability/models/__init__.py +30 -0
  573. omnibase_infra/observability/models/enum_required_log_context_key.py +77 -0
  574. omnibase_infra/observability/models/model_buffered_log_entry.py +117 -0
  575. omnibase_infra/observability/models/model_logging_sink_config.py +73 -0
  576. omnibase_infra/observability/models/model_metrics_sink_config.py +156 -0
  577. omnibase_infra/observability/sinks/__init__.py +69 -0
  578. omnibase_infra/observability/sinks/sink_logging_structured.py +809 -0
  579. omnibase_infra/observability/sinks/sink_metrics_prometheus.py +710 -0
  580. omnibase_infra/plugins/__init__.py +27 -0
  581. omnibase_infra/plugins/examples/__init__.py +28 -0
  582. omnibase_infra/plugins/examples/plugin_json_normalizer.py +271 -0
  583. omnibase_infra/plugins/examples/plugin_json_normalizer_error_handling.py +210 -0
  584. omnibase_infra/plugins/models/__init__.py +21 -0
  585. omnibase_infra/plugins/models/model_plugin_context.py +76 -0
  586. omnibase_infra/plugins/models/model_plugin_input_data.py +58 -0
  587. omnibase_infra/plugins/models/model_plugin_output_data.py +62 -0
  588. omnibase_infra/plugins/plugin_compute_base.py +449 -0
  589. omnibase_infra/projectors/__init__.py +30 -0
  590. omnibase_infra/projectors/contracts/__init__.py +63 -0
  591. omnibase_infra/projectors/contracts/registration_projector.yaml +370 -0
  592. omnibase_infra/projectors/projection_reader_registration.py +1559 -0
  593. omnibase_infra/projectors/snapshot_publisher_registration.py +1329 -0
  594. omnibase_infra/protocols/__init__.py +104 -0
  595. omnibase_infra/protocols/protocol_capability_projection.py +253 -0
  596. omnibase_infra/protocols/protocol_capability_query.py +251 -0
  597. omnibase_infra/protocols/protocol_container_aware.py +200 -0
  598. omnibase_infra/protocols/protocol_dispatch_engine.py +152 -0
  599. omnibase_infra/protocols/protocol_event_bus_like.py +127 -0
  600. omnibase_infra/protocols/protocol_event_projector.py +96 -0
  601. omnibase_infra/protocols/protocol_idempotency_store.py +142 -0
  602. omnibase_infra/protocols/protocol_message_dispatcher.py +247 -0
  603. omnibase_infra/protocols/protocol_message_type_registry.py +306 -0
  604. omnibase_infra/protocols/protocol_plugin_compute.py +368 -0
  605. omnibase_infra/protocols/protocol_projector_schema_validator.py +82 -0
  606. omnibase_infra/protocols/protocol_registry_metrics.py +215 -0
  607. omnibase_infra/protocols/protocol_snapshot_publisher.py +396 -0
  608. omnibase_infra/protocols/protocol_snapshot_store.py +567 -0
  609. omnibase_infra/runtime/__init__.py +445 -0
  610. omnibase_infra/runtime/binding_config_resolver.py +2771 -0
  611. omnibase_infra/runtime/binding_resolver.py +753 -0
  612. omnibase_infra/runtime/chain_aware_dispatch.py +467 -0
  613. omnibase_infra/runtime/constants_notification.py +75 -0
  614. omnibase_infra/runtime/constants_security.py +70 -0
  615. omnibase_infra/runtime/contract_handler_discovery.py +587 -0
  616. omnibase_infra/runtime/contract_loaders/__init__.py +51 -0
  617. omnibase_infra/runtime/contract_loaders/handler_routing_loader.py +464 -0
  618. omnibase_infra/runtime/contract_loaders/operation_bindings_loader.py +789 -0
  619. omnibase_infra/runtime/dispatch_context_enforcer.py +427 -0
  620. omnibase_infra/runtime/emit_daemon/__init__.py +97 -0
  621. omnibase_infra/runtime/emit_daemon/cli.py +844 -0
  622. omnibase_infra/runtime/emit_daemon/client.py +811 -0
  623. omnibase_infra/runtime/emit_daemon/config.py +535 -0
  624. omnibase_infra/runtime/emit_daemon/daemon.py +812 -0
  625. omnibase_infra/runtime/emit_daemon/event_registry.py +477 -0
  626. omnibase_infra/runtime/emit_daemon/model_daemon_request.py +139 -0
  627. omnibase_infra/runtime/emit_daemon/model_daemon_response.py +191 -0
  628. omnibase_infra/runtime/emit_daemon/queue.py +618 -0
  629. omnibase_infra/runtime/enums/__init__.py +18 -0
  630. omnibase_infra/runtime/enums/enum_config_ref_scheme.py +33 -0
  631. omnibase_infra/runtime/enums/enum_scheduler_status.py +170 -0
  632. omnibase_infra/runtime/envelope_validator.py +179 -0
  633. omnibase_infra/runtime/event_bus_subcontract_wiring.py +466 -0
  634. omnibase_infra/runtime/handler_bootstrap_source.py +507 -0
  635. omnibase_infra/runtime/handler_contract_config_loader.py +603 -0
  636. omnibase_infra/runtime/handler_contract_source.py +750 -0
  637. omnibase_infra/runtime/handler_identity.py +81 -0
  638. omnibase_infra/runtime/handler_plugin_loader.py +2046 -0
  639. omnibase_infra/runtime/handler_registry.py +329 -0
  640. omnibase_infra/runtime/handler_source_resolver.py +367 -0
  641. omnibase_infra/runtime/invocation_security_enforcer.py +427 -0
  642. omnibase_infra/runtime/kafka_contract_source.py +984 -0
  643. omnibase_infra/runtime/kernel.py +40 -0
  644. omnibase_infra/runtime/mixin_policy_validation.py +522 -0
  645. omnibase_infra/runtime/mixin_semver_cache.py +402 -0
  646. omnibase_infra/runtime/mixins/__init__.py +24 -0
  647. omnibase_infra/runtime/mixins/mixin_projector_notification_publishing.py +566 -0
  648. omnibase_infra/runtime/mixins/mixin_projector_sql_operations.py +778 -0
  649. omnibase_infra/runtime/models/__init__.py +229 -0
  650. omnibase_infra/runtime/models/model_batch_lifecycle_result.py +217 -0
  651. omnibase_infra/runtime/models/model_binding_config.py +168 -0
  652. omnibase_infra/runtime/models/model_binding_config_cache_stats.py +135 -0
  653. omnibase_infra/runtime/models/model_binding_config_resolver_config.py +329 -0
  654. omnibase_infra/runtime/models/model_cached_secret.py +138 -0
  655. omnibase_infra/runtime/models/model_compute_key.py +138 -0
  656. omnibase_infra/runtime/models/model_compute_registration.py +97 -0
  657. omnibase_infra/runtime/models/model_config_cache_entry.py +61 -0
  658. omnibase_infra/runtime/models/model_config_ref.py +331 -0
  659. omnibase_infra/runtime/models/model_config_ref_parse_result.py +125 -0
  660. omnibase_infra/runtime/models/model_contract_load_result.py +224 -0
  661. omnibase_infra/runtime/models/model_domain_plugin_config.py +92 -0
  662. omnibase_infra/runtime/models/model_domain_plugin_result.py +270 -0
  663. omnibase_infra/runtime/models/model_duplicate_response.py +54 -0
  664. omnibase_infra/runtime/models/model_enabled_protocols_config.py +61 -0
  665. omnibase_infra/runtime/models/model_event_bus_config.py +54 -0
  666. omnibase_infra/runtime/models/model_failed_component.py +55 -0
  667. omnibase_infra/runtime/models/model_health_check_response.py +168 -0
  668. omnibase_infra/runtime/models/model_health_check_result.py +229 -0
  669. omnibase_infra/runtime/models/model_lifecycle_result.py +245 -0
  670. omnibase_infra/runtime/models/model_logging_config.py +42 -0
  671. omnibase_infra/runtime/models/model_optional_correlation_id.py +167 -0
  672. omnibase_infra/runtime/models/model_optional_string.py +94 -0
  673. omnibase_infra/runtime/models/model_optional_uuid.py +110 -0
  674. omnibase_infra/runtime/models/model_policy_context.py +100 -0
  675. omnibase_infra/runtime/models/model_policy_key.py +138 -0
  676. omnibase_infra/runtime/models/model_policy_registration.py +139 -0
  677. omnibase_infra/runtime/models/model_policy_result.py +103 -0
  678. omnibase_infra/runtime/models/model_policy_type_filter.py +157 -0
  679. omnibase_infra/runtime/models/model_projector_notification_config.py +171 -0
  680. omnibase_infra/runtime/models/model_projector_plugin_loader_config.py +47 -0
  681. omnibase_infra/runtime/models/model_protocol_registration_config.py +65 -0
  682. omnibase_infra/runtime/models/model_retry_policy.py +105 -0
  683. omnibase_infra/runtime/models/model_runtime_config.py +150 -0
  684. omnibase_infra/runtime/models/model_runtime_contract_config.py +268 -0
  685. omnibase_infra/runtime/models/model_runtime_scheduler_config.py +625 -0
  686. omnibase_infra/runtime/models/model_runtime_scheduler_metrics.py +233 -0
  687. omnibase_infra/runtime/models/model_runtime_tick.py +193 -0
  688. omnibase_infra/runtime/models/model_secret_cache_stats.py +82 -0
  689. omnibase_infra/runtime/models/model_secret_mapping.py +63 -0
  690. omnibase_infra/runtime/models/model_secret_resolver_config.py +107 -0
  691. omnibase_infra/runtime/models/model_secret_resolver_metrics.py +111 -0
  692. omnibase_infra/runtime/models/model_secret_source_info.py +72 -0
  693. omnibase_infra/runtime/models/model_secret_source_spec.py +66 -0
  694. omnibase_infra/runtime/models/model_security_config.py +109 -0
  695. omnibase_infra/runtime/models/model_shutdown_batch_result.py +75 -0
  696. omnibase_infra/runtime/models/model_shutdown_config.py +94 -0
  697. omnibase_infra/runtime/models/model_transition_notification_outbox_config.py +112 -0
  698. omnibase_infra/runtime/models/model_transition_notification_outbox_metrics.py +140 -0
  699. omnibase_infra/runtime/models/model_transition_notification_publisher_metrics.py +357 -0
  700. omnibase_infra/runtime/projector_plugin_loader.py +1462 -0
  701. omnibase_infra/runtime/projector_schema_manager.py +565 -0
  702. omnibase_infra/runtime/projector_shell.py +1330 -0
  703. omnibase_infra/runtime/protocol_contract_descriptor.py +92 -0
  704. omnibase_infra/runtime/protocol_contract_source.py +92 -0
  705. omnibase_infra/runtime/protocol_domain_plugin.py +474 -0
  706. omnibase_infra/runtime/protocol_handler_discovery.py +221 -0
  707. omnibase_infra/runtime/protocol_handler_plugin_loader.py +327 -0
  708. omnibase_infra/runtime/protocol_lifecycle_executor.py +435 -0
  709. omnibase_infra/runtime/protocol_policy.py +366 -0
  710. omnibase_infra/runtime/protocols/__init__.py +37 -0
  711. omnibase_infra/runtime/protocols/protocol_runtime_scheduler.py +468 -0
  712. omnibase_infra/runtime/publisher_topic_scoped.py +294 -0
  713. omnibase_infra/runtime/registry/__init__.py +93 -0
  714. omnibase_infra/runtime/registry/mixin_message_type_query.py +326 -0
  715. omnibase_infra/runtime/registry/mixin_message_type_registration.py +354 -0
  716. omnibase_infra/runtime/registry/registry_event_bus_binding.py +268 -0
  717. omnibase_infra/runtime/registry/registry_message_type.py +542 -0
  718. omnibase_infra/runtime/registry/registry_protocol_binding.py +445 -0
  719. omnibase_infra/runtime/registry_compute.py +1143 -0
  720. omnibase_infra/runtime/registry_contract_source.py +693 -0
  721. omnibase_infra/runtime/registry_dispatcher.py +678 -0
  722. omnibase_infra/runtime/registry_policy.py +1185 -0
  723. omnibase_infra/runtime/runtime_contract_config_loader.py +406 -0
  724. omnibase_infra/runtime/runtime_scheduler.py +1070 -0
  725. omnibase_infra/runtime/secret_resolver.py +2112 -0
  726. omnibase_infra/runtime/security_metadata_validator.py +776 -0
  727. omnibase_infra/runtime/service_kernel.py +1651 -0
  728. omnibase_infra/runtime/service_message_dispatch_engine.py +2350 -0
  729. omnibase_infra/runtime/service_runtime_host_process.py +3493 -0
  730. omnibase_infra/runtime/transition_notification_outbox.py +1190 -0
  731. omnibase_infra/runtime/transition_notification_publisher.py +765 -0
  732. omnibase_infra/runtime/util_container_wiring.py +1124 -0
  733. omnibase_infra/runtime/util_validation.py +314 -0
  734. omnibase_infra/runtime/util_version.py +98 -0
  735. omnibase_infra/runtime/util_wiring.py +723 -0
  736. omnibase_infra/schemas/schema_registration_projection.sql +320 -0
  737. omnibase_infra/schemas/schema_transition_notification_outbox.sql +245 -0
  738. omnibase_infra/services/__init__.py +89 -0
  739. omnibase_infra/services/corpus_capture.py +684 -0
  740. omnibase_infra/services/mcp/__init__.py +31 -0
  741. omnibase_infra/services/mcp/mcp_server_lifecycle.py +449 -0
  742. omnibase_infra/services/mcp/service_mcp_tool_discovery.py +411 -0
  743. omnibase_infra/services/mcp/service_mcp_tool_registry.py +329 -0
  744. omnibase_infra/services/mcp/service_mcp_tool_sync.py +565 -0
  745. omnibase_infra/services/registry_api/__init__.py +40 -0
  746. omnibase_infra/services/registry_api/main.py +261 -0
  747. omnibase_infra/services/registry_api/models/__init__.py +66 -0
  748. omnibase_infra/services/registry_api/models/model_capability_widget_mapping.py +38 -0
  749. omnibase_infra/services/registry_api/models/model_pagination_info.py +48 -0
  750. omnibase_infra/services/registry_api/models/model_registry_discovery_response.py +73 -0
  751. omnibase_infra/services/registry_api/models/model_registry_health_response.py +49 -0
  752. omnibase_infra/services/registry_api/models/model_registry_instance_view.py +88 -0
  753. omnibase_infra/services/registry_api/models/model_registry_node_view.py +88 -0
  754. omnibase_infra/services/registry_api/models/model_registry_summary.py +60 -0
  755. omnibase_infra/services/registry_api/models/model_response_list_instances.py +43 -0
  756. omnibase_infra/services/registry_api/models/model_response_list_nodes.py +51 -0
  757. omnibase_infra/services/registry_api/models/model_warning.py +49 -0
  758. omnibase_infra/services/registry_api/models/model_widget_defaults.py +28 -0
  759. omnibase_infra/services/registry_api/models/model_widget_mapping.py +51 -0
  760. omnibase_infra/services/registry_api/routes.py +371 -0
  761. omnibase_infra/services/registry_api/service.py +837 -0
  762. omnibase_infra/services/service_capability_query.py +945 -0
  763. omnibase_infra/services/service_health.py +898 -0
  764. omnibase_infra/services/service_node_selector.py +530 -0
  765. omnibase_infra/services/service_timeout_emitter.py +699 -0
  766. omnibase_infra/services/service_timeout_scanner.py +394 -0
  767. omnibase_infra/services/session/__init__.py +56 -0
  768. omnibase_infra/services/session/config_consumer.py +137 -0
  769. omnibase_infra/services/session/config_store.py +139 -0
  770. omnibase_infra/services/session/consumer.py +1007 -0
  771. omnibase_infra/services/session/protocol_session_aggregator.py +117 -0
  772. omnibase_infra/services/session/store.py +997 -0
  773. omnibase_infra/services/snapshot/__init__.py +31 -0
  774. omnibase_infra/services/snapshot/service_snapshot.py +647 -0
  775. omnibase_infra/services/snapshot/store_inmemory.py +637 -0
  776. omnibase_infra/services/snapshot/store_postgres.py +1279 -0
  777. omnibase_infra/shared/__init__.py +8 -0
  778. omnibase_infra/testing/__init__.py +10 -0
  779. omnibase_infra/testing/utils.py +23 -0
  780. omnibase_infra/topics/__init__.py +45 -0
  781. omnibase_infra/topics/platform_topic_suffixes.py +140 -0
  782. omnibase_infra/topics/util_topic_composition.py +95 -0
  783. omnibase_infra/types/__init__.py +48 -0
  784. omnibase_infra/types/type_cache_info.py +49 -0
  785. omnibase_infra/types/type_dsn.py +173 -0
  786. omnibase_infra/types/type_infra_aliases.py +60 -0
  787. omnibase_infra/types/typed_dict/__init__.py +29 -0
  788. omnibase_infra/types/typed_dict/typed_dict_envelope_build_params.py +115 -0
  789. omnibase_infra/types/typed_dict/typed_dict_introspection_cache.py +128 -0
  790. omnibase_infra/types/typed_dict/typed_dict_performance_metrics_cache.py +140 -0
  791. omnibase_infra/types/typed_dict_capabilities.py +64 -0
  792. omnibase_infra/utils/__init__.py +117 -0
  793. omnibase_infra/utils/correlation.py +208 -0
  794. omnibase_infra/utils/util_atomic_file.py +261 -0
  795. omnibase_infra/utils/util_consumer_group.py +232 -0
  796. omnibase_infra/utils/util_datetime.py +372 -0
  797. omnibase_infra/utils/util_db_transaction.py +239 -0
  798. omnibase_infra/utils/util_dsn_validation.py +333 -0
  799. omnibase_infra/utils/util_env_parsing.py +264 -0
  800. omnibase_infra/utils/util_error_sanitization.py +457 -0
  801. omnibase_infra/utils/util_pydantic_validators.py +477 -0
  802. omnibase_infra/utils/util_retry_optimistic.py +281 -0
  803. omnibase_infra/utils/util_semver.py +233 -0
  804. omnibase_infra/validation/__init__.py +307 -0
  805. omnibase_infra/validation/contracts/security.validation.yaml +114 -0
  806. omnibase_infra/validation/enums/__init__.py +11 -0
  807. omnibase_infra/validation/enums/enum_contract_violation_severity.py +13 -0
  808. omnibase_infra/validation/infra_validators.py +1514 -0
  809. omnibase_infra/validation/linter_contract.py +907 -0
  810. omnibase_infra/validation/mixin_any_type_classification.py +120 -0
  811. omnibase_infra/validation/mixin_any_type_exemption.py +580 -0
  812. omnibase_infra/validation/mixin_any_type_reporting.py +106 -0
  813. omnibase_infra/validation/mixin_execution_shape_violation_checks.py +596 -0
  814. omnibase_infra/validation/mixin_node_archetype_detection.py +254 -0
  815. omnibase_infra/validation/models/__init__.py +15 -0
  816. omnibase_infra/validation/models/model_contract_lint_result.py +101 -0
  817. omnibase_infra/validation/models/model_contract_violation.py +41 -0
  818. omnibase_infra/validation/service_validation_aggregator.py +395 -0
  819. omnibase_infra/validation/validation_exemptions.yaml +2033 -0
  820. omnibase_infra/validation/validator_any_type.py +715 -0
  821. omnibase_infra/validation/validator_chain_propagation.py +839 -0
  822. omnibase_infra/validation/validator_execution_shape.py +465 -0
  823. omnibase_infra/validation/validator_localhandler.py +261 -0
  824. omnibase_infra/validation/validator_registration_security.py +410 -0
  825. omnibase_infra/validation/validator_routing_coverage.py +1020 -0
  826. omnibase_infra/validation/validator_runtime_shape.py +915 -0
  827. omnibase_infra/validation/validator_security.py +513 -0
  828. omnibase_infra/validation/validator_topic_category.py +1152 -0
  829. omnibase_infra-0.2.6.dist-info/METADATA +197 -0
  830. omnibase_infra-0.2.6.dist-info/RECORD +833 -0
  831. omnibase_infra-0.2.6.dist-info/WHEEL +4 -0
  832. omnibase_infra-0.2.6.dist-info/entry_points.txt +5 -0
  833. omnibase_infra-0.2.6.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,1185 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Policy Registry - SINGLE SOURCE OF TRUTH for policy plugin registration.
4
+
5
+ This module provides the RegistryPolicy class for registering and resolving
6
+ pure decision policy plugins in the ONEX infrastructure layer.
7
+
8
+ The registry is responsible for:
9
+ - Registering policy plugins by (policy_id, policy_type, version) tuple
10
+ - Resolving policy classes for specific policy configurations
11
+ - Thread-safe registration operations
12
+ - Listing all registered policies
13
+ - Enforcing synchronous-by-default policy execution
14
+
15
+ Design Principles:
16
+ - Single source of truth: All policy registrations go through this registry
17
+ - Sync enforcement: Async policies must be explicitly flagged
18
+ - Type-safe: Full typing for policy registrations (no Any types)
19
+ - Thread-safe: Registration operations protected by lock
20
+ - Testable: Easy to mock and test policy configurations
21
+
22
+ Policy Categories (by policy type):
23
+ - Orchestrator policies: Workflow coordination, retry strategies, routing
24
+ - Reducer policies: State aggregation, conflict resolution, projections
25
+
26
+ CRITICAL: Policy plugins are PURE decision logic only.
27
+
28
+ Policy plugins MUST NOT:
29
+ - Perform I/O operations (file, network, database)
30
+ - Have side effects (state mutation outside return values)
31
+ - Make external service calls
32
+ - Log at runtime
33
+ - Depend on mutable global state
34
+
35
+ Example Usage:
36
+ ```python
37
+ from omnibase_core.container import ModelONEXContainer
38
+ from omnibase_infra.runtime.registry_policy import RegistryPolicy, ModelPolicyRegistration
39
+ from omnibase_infra.runtime.util_container_wiring import wire_infrastructure_services
40
+ from omnibase_infra.enums import EnumPolicyType
41
+
42
+ # Container-based DI (preferred)
43
+ container = ModelONEXContainer()
44
+ await wire_infrastructure_services(container)
45
+ registry = await container.service_registry.resolve_service(RegistryPolicy)
46
+
47
+ # Register a synchronous policy using the model (PREFERRED API)
48
+ registration = ModelPolicyRegistration(
49
+ policy_id="exponential_backoff",
50
+ policy_class=ExponentialBackoffPolicy,
51
+ policy_type=EnumPolicyType.ORCHESTRATOR,
52
+ version="1.0.0",
53
+ )
54
+ registry.register(registration)
55
+
56
+ # Register using convenience method (preserves original API)
57
+ # Note: For new code, prefer register(ModelPolicyRegistration(...)) instead
58
+ registry.register_policy(
59
+ policy_id="async_merge",
60
+ policy_class=AsyncMergePolicy,
61
+ policy_type=EnumPolicyType.REDUCER,
62
+ version="1.0.0",
63
+ allow_async=True, # MUST be explicit for async policies
64
+ )
65
+
66
+ # Retrieve a policy
67
+ policy_cls = registry.get("exponential_backoff")
68
+ policy = policy_cls()
69
+ result = policy.evaluate(context)
70
+
71
+ # List all policies
72
+ policies = registry.list_keys() # [(id, type, version), ...]
73
+ ```
74
+
75
+ Integration Points:
76
+ - RuntimeHostProcess uses this registry to discover and instantiate policies
77
+ - Policies are loaded based on contract definitions
78
+ - Supports hot-reload patterns for development
79
+ """
80
+
81
+ from __future__ import annotations
82
+
83
+ import threading
84
+ import warnings
85
+ from typing import TYPE_CHECKING
86
+
87
+ from pydantic import ValidationError
88
+
89
+ from omnibase_core.models.primitives import ModelSemVer
90
+ from omnibase_infra.enums import EnumInfraTransportType, EnumPolicyType
91
+ from omnibase_infra.errors import PolicyRegistryError, ProtocolConfigurationError
92
+ from omnibase_infra.models.errors.model_infra_error_context import (
93
+ ModelInfraErrorContext,
94
+ )
95
+ from omnibase_infra.runtime.mixin_policy_validation import MixinPolicyValidation
96
+ from omnibase_infra.runtime.mixin_semver_cache import MixinSemverCache
97
+ from omnibase_infra.runtime.models import ModelPolicyKey, ModelPolicyRegistration
98
+ from omnibase_infra.runtime.util_version import normalize_version
99
+ from omnibase_infra.types import PolicyTypeInput
100
+
101
+ if TYPE_CHECKING:
102
+ from omnibase_infra.runtime.protocol_policy import ProtocolPolicy
103
+
104
+
105
+ # =============================================================================
106
+ # Policy Registry
107
+ # =============================================================================
108
+
109
+
110
+ class RegistryPolicy(MixinPolicyValidation, MixinSemverCache):
111
+ """SINGLE SOURCE OF TRUTH for policy plugin registration in omnibase_infra.
112
+
113
+ Thread-safe registry for policy plugins. Manages pure decision logic plugins
114
+ that can be used by orchestrator and reducer nodes.
115
+
116
+ The registry maintains a mapping from ModelPolicyKey instances to policy classes
117
+ that implement the ProtocolPolicy protocol. ModelPolicyKey provides strong typing
118
+ and replaces the legacy tuple[str, str, str] pattern.
119
+
120
+ Container Integration:
121
+ RegistryPolicy is designed to be managed by ModelONEXContainer from omnibase_core.
122
+ Use container_wiring.wire_infrastructure_services() to register RegistryPolicy
123
+ in the container, then resolve it via:
124
+
125
+ ```python
126
+ from omnibase_core.container import ModelONEXContainer
127
+ from omnibase_infra.runtime.registry_policy import RegistryPolicy
128
+
129
+ # Resolve from container (preferred) - async in omnibase_core v0.5.6+
130
+ registry = await container.service_registry.resolve_service(RegistryPolicy)
131
+
132
+ # Or use helper function (also async)
133
+ from omnibase_infra.runtime.util_container_wiring import get_policy_registry_from_container
134
+ registry = await get_policy_registry_from_container(container)
135
+ ```
136
+
137
+ Thread Safety:
138
+ All registration operations are protected by a threading.Lock to ensure
139
+ thread-safe access in concurrent environments.
140
+
141
+ Sync Enforcement:
142
+ By default, policies must be synchronous. If a policy has async methods
143
+ (evaluate, decide, reduce), registration will fail unless
144
+ allow_async=True is explicitly specified.
145
+
146
+ Scale and Performance Characteristics:
147
+
148
+ Expected Registry Scale:
149
+ - Typical ONEX system: 20-50 unique policies across 2-5 versions each
150
+ - Medium deployment: 50-100 policies across 3-8 versions each
151
+ - Large deployment: 100-200 policies across 5-10 versions each
152
+ - Stress tested: 500+ total registrations (100 policies x 5 versions)
153
+
154
+ Policy categories (by policy_type):
155
+ - Orchestrator policies: Workflow coordination, retry strategies, routing
156
+ - Reducer policies: State aggregation, conflict resolution, projections
157
+
158
+ Typical distribution: 60% orchestrator policies, 40% reducer policies
159
+
160
+ Performance Characteristics:
161
+
162
+ Primary Operations:
163
+ - register(): O(1) - Direct dictionary insert with secondary index update
164
+ - get(policy_id): O(1) best case, O(k) average, O(k*log k) filtered worst case
165
+ where k = number of matching versions after filtering
166
+ - Uses secondary index (_policy_id_index) for O(1) policy_id lookup
167
+ - Fast path (no filters, single version): O(1) direct lookup
168
+ - Multi-version (no filters): O(k) to find max version via comparison
169
+ - Filtered path (policy_type + multi-version): O(k*log k) for filter + semver sort
170
+ - Deferred error generation: Expensive _list_internal() only on error
171
+ - Cached semver parsing: LRU cache (128 entries) avoids re-parsing
172
+
173
+ - is_registered(): O(k) where k = versions for policy_id
174
+ - list_keys(): O(n*log n) where n = total registrations (full scan + sort)
175
+ - list_versions(): O(k) where k = versions for policy_id
176
+ - unregister(): O(k) where k = versions for policy_id
177
+
178
+ Benchmark Results (500 policy registrations):
179
+ - 1000 sequential get() calls: < 100ms (< 0.1ms per lookup)
180
+ - 1000 concurrent get() calls (10 threads): < 500ms
181
+ - 100 failed lookups (missing policy_id): < 500ms (early exit optimization)
182
+ - Fast path speedup vs filtered path: > 1.1x
183
+
184
+ Lock Contention:
185
+ - Read operations (get, is_registered): Hold lock during lookup only
186
+ - Write operations (register, unregister): Hold lock for full operation
187
+ - Critical sections minimized to reduce contention
188
+ - Expected concurrent throughput: > 2000 reads/sec under 10-thread load
189
+
190
+ Memory Footprint:
191
+
192
+ Per Policy Registration:
193
+ - ModelPolicyKey: ~200 bytes (3 strings: policy_id, policy_type, version)
194
+ - Policy class reference: 8 bytes (Python object pointer)
195
+ - Secondary index entry: ~50 bytes (list entry + key reference)
196
+ - Total per registration: ~260 bytes
197
+
198
+ Estimated Registry Memory:
199
+ - 50 registrations: ~13 KB
200
+ - 100 registrations: ~26 KB
201
+ - 500 registrations: ~130 KB
202
+ - 1000 registrations: ~260 KB
203
+
204
+ Cache Overhead:
205
+ - Semver LRU cache: 128 entries x ~100 bytes = ~12.8 KB
206
+ - Total with cache: Registry memory + 12.8 KB
207
+
208
+ Note: Memory footprint is negligible compared to typical ONEX process memory
209
+ (100-500 MB). Registry memory is not a bottleneck in production systems.
210
+
211
+ Secondary Indexes (Performance Optimization):
212
+
213
+ Current Indexes:
214
+ - _policy_id_index: Maps policy_id -> list[ModelPolicyKey]
215
+ - Purpose: O(1) lookup by policy_id (avoids O(n) scan of all registrations)
216
+ - Updated on: register(), unregister()
217
+ - Memory: ~50 bytes per policy_id + 8 bytes per version
218
+ - Hit rate: 100% for all get() operations
219
+
220
+ When to Add Additional Indexes:
221
+
222
+ Consider _policy_type_index if:
223
+ - Frequent list_keys(policy_type=...) calls (currently O(n))
224
+ - Deployment has > 500 total registrations
225
+ - Profiling shows list_keys filtering as bottleneck
226
+
227
+ Consider _version_index if:
228
+ - Frequent cross-policy version queries
229
+ - Complex version-based policy routing logic
230
+ - Deployment has > 10 versions per policy on average
231
+
232
+ Trade-off Analysis:
233
+ - Each index adds ~50-100 bytes per entry
234
+ - Benefits: O(n) -> O(1) for filtered queries
235
+ - Costs: Write amplification (update multiple indexes per register/unregister)
236
+ - Recommendation: Profile first, optimize only if proven bottleneck
237
+
238
+ Monitoring Recommendations:
239
+
240
+ Key Metrics to Track:
241
+ 1. Registry size: len(registry) - Track growth over time
242
+ 2. Lookup latency: Time for get() operations (p50, p95, p99)
243
+ 3. Lookup errors: PolicyRegistryError frequency (indicates config issues)
244
+ 4. Cache hit rate: LRU cache effectiveness (_parse_semver cache)
245
+ 5. Lock contention: Concurrent access patterns and throughput
246
+
247
+ Performance Thresholds (alert if exceeded):
248
+ - Average get() latency: > 1ms (indicates potential lock contention)
249
+ - P99 get() latency: > 10ms (indicates blocking on write operations)
250
+ - Registry size: > 1000 registrations (may need index optimization)
251
+ - Cache miss rate: > 10% (indicates cache size insufficient)
252
+ - Concurrent throughput: < 1000 reads/sec (indicates lock bottleneck)
253
+
254
+ Recommended Instrumentation:
255
+ ```python
256
+ import time
257
+ from omnibase_core.metrics import histogram, counter
258
+
259
+ # In production RegistryPolicy wrapper:
260
+ start = time.perf_counter()
261
+ policy_cls = registry.get(policy_id)
262
+ histogram("policy_registry.get_latency_ms", (time.perf_counter() - start) * 1000)
263
+ counter("policy_registry.get_total")
264
+
265
+ # Track registry growth:
266
+ histogram("policy_registry.size", len(registry))
267
+ ```
268
+
269
+ Health Check Integration:
270
+ - Include len(registry) in health check response
271
+ - Alert if registry empty (indicates bootstrap failure)
272
+ - Alert if registry size changes unexpectedly (> 20% delta)
273
+
274
+ Trust Model and Security Considerations:
275
+
276
+ RegistryPolicy performs LIMITED validation on registered policy classes.
277
+ This section documents what guarantees exist and what the caller is
278
+ responsible for.
279
+
280
+ VALIDATED (by RegistryPolicy):
281
+ - Async method detection: Policies with async methods (reduce, decide,
282
+ evaluate) must explicitly set allow_async=True. This prevents
283
+ accidental async policy registration that could cause runtime issues.
284
+ - Policy type validation: policy_type must be a valid EnumPolicyType
285
+ value ("orchestrator" or "reducer"). Invalid types raise PolicyRegistryError.
286
+ - Version format validation: version must be valid semver format
287
+ (e.g., "1.0.0", "1.2.3-beta"). Invalid formats raise ProtocolConfigurationError.
288
+ - Non-empty policy_id: Validated via ModelPolicyRegistration Pydantic model.
289
+ - Thread-safe registration: Registration operations are protected by lock.
290
+
291
+ NOT VALIDATED (caller's responsibility):
292
+ - Policy class correctness: The registry does not verify that a policy
293
+ class correctly implements ProtocolPolicy methods. A class missing
294
+ required methods will only fail at runtime when invoked.
295
+ - Policy class safety: No static analysis, sandboxing, or security
296
+ scanning is performed. Malicious code in a policy class will execute
297
+ with the same privileges as the host process.
298
+ - Policy behavior: The registry cannot validate that policy decision
299
+ logic is correct, deterministic, or free of bugs.
300
+ - Policy dependencies: Import-time side effects, malicious dependencies,
301
+ or resource-intensive imports are not prevented.
302
+ - Runtime behavior: Policies that hang, exhaust memory, raise unexpected
303
+ exceptions, or violate timeouts are not sandboxed.
304
+ - Idempotency: The registry does not verify that policies are idempotent
305
+ or safe to retry.
306
+
307
+ Trust Assumptions:
308
+ 1. Policy classes come from TRUSTED sources only:
309
+ - Internal codebase modules
310
+ - Vetted first-party packages
311
+ - Audited third-party packages
312
+ 2. Policy classes do not execute arbitrary code on registration:
313
+ - No __init_subclass__ side effects
314
+ - No metaclass execution during class reference
315
+ - No import-time network calls or file I/O
316
+ 3. Policy instances are created and used within the same trust boundary:
317
+ - No cross-tenant policy sharing
318
+ - No user-provided policy classes at runtime
319
+ 4. Policy implementers follow the purity contract:
320
+ - No I/O operations (file, network, database)
321
+ - No side effects (state mutation outside return values)
322
+ - No external service calls
323
+ - No runtime logging (use structured outputs only)
324
+
325
+ For High-Security Environments:
326
+ If deploying RegistryPolicy in environments with stricter security
327
+ requirements, consider implementing additional safeguards:
328
+
329
+ - Code Review: Mandatory review for all policy implementations before
330
+ registration approval.
331
+
332
+ - Static Analysis: Run linters and security scanners on policy modules
333
+ before allowing registration:
334
+ ```python
335
+ # Example: Pre-registration validation hook
336
+ def validate_policy_module(module_path: str) -> bool:
337
+ # Run bandit, semgrep, or custom security checks
338
+ result = run_security_scan(module_path)
339
+ return result.passed
340
+ ```
341
+
342
+ - Allowlist Pattern: Maintain an explicit allowlist of approved policy_ids
343
+ and reject registration attempts for unlisted policies:
344
+ ```python
345
+ APPROVED_POLICIES = {"exponential_backoff", "rate_limiter", "retry_strategy"}
346
+
347
+ def register_with_allowlist(registration: ModelPolicyRegistration) -> None:
348
+ if registration.policy_id not in APPROVED_POLICIES:
349
+ raise PolicyRegistryError(
350
+ f"Policy '{registration.policy_id}' not in approved list",
351
+ policy_id=registration.policy_id,
352
+ )
353
+ registry.register(registration)
354
+ ```
355
+
356
+ - Sandboxing: Execute policy code in isolated environments (not built
357
+ into RegistryPolicy, requires external infrastructure):
358
+ - Process isolation (subprocess with resource limits)
359
+ - Container isolation (Docker with security profiles)
360
+ - WASM isolation (for extreme security requirements)
361
+
362
+ - Runtime Monitoring: Instrument policy execution with timeouts and
363
+ resource monitoring:
364
+ ```python
365
+ async def execute_policy_with_limits(
366
+ policy: ProtocolPolicy,
367
+ context: dict,
368
+ timeout_seconds: float = 1.0,
369
+ ) -> PolicyResult:
370
+ try:
371
+ return await asyncio.wait_for(
372
+ policy.evaluate(context),
373
+ timeout=timeout_seconds,
374
+ )
375
+ except asyncio.TimeoutError:
376
+ raise PolicyRegistryError(
377
+ f"Policy '{policy.policy_id}' exceeded timeout",
378
+ policy_id=policy.policy_id,
379
+ )
380
+ ```
381
+
382
+ Safe Usage Patterns:
383
+
384
+ DO:
385
+ - Register policies from known, reviewed source modules
386
+ - Use container-based DI for better lifecycle management
387
+ - Document policy dependencies and requirements
388
+ - Test policies in isolation before registration
389
+ - Monitor policy execution metrics (latency, error rates)
390
+
391
+ DON'T:
392
+ - Register policy classes provided by untrusted users
393
+ - Allow dynamic policy class construction from user input
394
+ - Skip code review for new policy implementations
395
+ - Assume policies are safe because they're in the registry
396
+ - Share registries across trust boundaries
397
+
398
+ See Also:
399
+ - docs/patterns/policy_registry_trust_model.md for detailed security guide
400
+ - ProtocolPolicy for interface requirements
401
+ - ModelPolicyRegistration for registration model validation
402
+
403
+ Attributes:
404
+ _registry: Internal dictionary mapping ModelPolicyKey instances to policy classes
405
+ _lock: Threading lock for thread-safe registration operations
406
+ _policy_id_index: Secondary index for O(1) policy_id lookup
407
+
408
+ Inherited from MixinSemverCache:
409
+ SEMVER_CACHE_SIZE: Class variable for configuring LRU cache size (default: 128)
410
+
411
+ Class-Level Configuration:
412
+ The semver parsing cache size can be configured for large deployments:
413
+
414
+ ```python
415
+ # Option 1: Set class attribute before first use
416
+ RegistryPolicy.SEMVER_CACHE_SIZE = 256
417
+
418
+ # Option 2: Use configure method (recommended)
419
+ RegistryPolicy.configure_semver_cache(maxsize=256)
420
+
421
+ # Must be done BEFORE any registry operations
422
+ registry = RegistryPolicy()
423
+ ```
424
+
425
+ For testing, use _reset_semver_cache() to clear and reconfigure.
426
+
427
+ Example:
428
+ >>> from omnibase_infra.runtime.models import ModelPolicyRegistration
429
+ >>> registry = RegistryPolicy()
430
+ >>> registration = ModelPolicyRegistration(
431
+ ... policy_id="retry_backoff",
432
+ ... policy_class=RetryBackoffPolicy,
433
+ ... policy_type=EnumPolicyType.ORCHESTRATOR,
434
+ ... )
435
+ >>> registry.register(registration)
436
+ >>> policy_cls = registry.get("retry_backoff")
437
+ >>> print(registry.list_keys())
438
+ [('retry_backoff', 'orchestrator', '1.0.0')]
439
+ """
440
+
441
+ def __init__(self) -> None:
442
+ """Initialize an empty policy registry with thread lock."""
443
+ # Key: ModelPolicyKey -> policy_class (strong typing replaces tuple pattern)
444
+ self._registry: dict[ModelPolicyKey, type[ProtocolPolicy]] = {}
445
+ self._lock: threading.Lock = threading.Lock()
446
+
447
+ # Performance optimization: Secondary indexes for O(1) lookups
448
+ # Maps policy_id -> list of ModelPolicyKey instances
449
+ self._policy_id_index: dict[str, list[ModelPolicyKey]] = {}
450
+
451
+ # Note: _validate_protocol_implementation and _validate_sync_enforcement
452
+ # are inherited from MixinPolicyValidation with the correct signatures.
453
+ # Do not override them here.
454
+
455
+ def _normalize_policy_type(
456
+ self,
457
+ policy_type: PolicyTypeInput,
458
+ ) -> str:
459
+ """Normalize policy type to string value and validate against EnumPolicyType.
460
+
461
+ This method provides centralized policy type validation logic used by all
462
+ registration and query methods. It accepts both EnumPolicyType enum values
463
+ and string literals, normalizing them to their string representation while
464
+ ensuring they match valid EnumPolicyType values.
465
+
466
+ Validation Process:
467
+ 1. If policy_type is EnumPolicyType instance, extract .value
468
+ 2. If policy_type is string, validate against EnumPolicyType values
469
+ 3. Raise PolicyRegistryError if string doesn't match any enum value
470
+ 4. Return normalized string value
471
+
472
+ This centralized validation ensures consistent policy type handling across
473
+ all registry operations (register, get, list_keys, is_registered, unregister).
474
+
475
+ Args:
476
+ policy_type: Policy type as EnumPolicyType enum or string literal.
477
+ Valid values: "orchestrator", "reducer"
478
+
479
+ Returns:
480
+ Normalized string value for the policy type (e.g., "orchestrator", "reducer")
481
+
482
+ Raises:
483
+ PolicyRegistryError: If policy_type is a string that doesn't match any
484
+ EnumPolicyType value. Error includes the invalid value
485
+ and list of valid options.
486
+
487
+ Example:
488
+ >>> from omnibase_infra.enums import EnumPolicyType
489
+ >>> registry = RegistryPolicy()
490
+ >>> # Enum to string
491
+ >>> registry._normalize_policy_type(EnumPolicyType.ORCHESTRATOR)
492
+ 'orchestrator'
493
+ >>> # Valid string passthrough
494
+ >>> registry._normalize_policy_type("reducer")
495
+ 'reducer'
496
+ >>> # Invalid string raises error
497
+ >>> registry._normalize_policy_type("invalid")
498
+ PolicyRegistryError: Invalid policy_type: 'invalid'.
499
+ Must be one of: ['orchestrator', 'reducer']
500
+ """
501
+ if isinstance(policy_type, EnumPolicyType):
502
+ return policy_type.value
503
+
504
+ # Validate string against enum values
505
+ valid_types = {e.value for e in EnumPolicyType}
506
+ if policy_type not in valid_types:
507
+ context = ModelInfraErrorContext.with_correlation(
508
+ transport_type=EnumInfraTransportType.RUNTIME,
509
+ operation="normalize_policy_type",
510
+ )
511
+ raise PolicyRegistryError(
512
+ f"Invalid policy_type: {policy_type!r}. "
513
+ f"Must be one of: {sorted(valid_types)}",
514
+ policy_id=None,
515
+ policy_type=policy_type,
516
+ context=context,
517
+ )
518
+
519
+ return policy_type
520
+
521
+ @staticmethod
522
+ def _normalize_version(version: str) -> str:
523
+ """Normalize version string for consistent lookups.
524
+
525
+ Delegates to the shared normalize_version utility which is the
526
+ SINGLE SOURCE OF TRUTH for version normalization in omnibase_infra.
527
+
528
+ This method wraps the shared utility to convert ValueError to
529
+ ProtocolConfigurationError for RegistryPolicy's error contract.
530
+
531
+ Normalization rules:
532
+ 1. Strip leading/trailing whitespace
533
+ 2. Strip leading 'v' or 'V' prefix
534
+ 3. Expand partial versions (1 -> 1.0.0, 1.0 -> 1.0.0)
535
+ 4. Parse with ModelSemVer.parse() for validation
536
+ 5. Preserve prerelease suffix if present
537
+
538
+ Args:
539
+ version: The version string to normalize
540
+
541
+ Returns:
542
+ Normalized version string in "x.y.z" or "x.y.z-prerelease" format
543
+
544
+ Raises:
545
+ ProtocolConfigurationError: If the version format is invalid
546
+
547
+ Example:
548
+ >>> RegistryPolicy._normalize_version("1.0")
549
+ '1.0.0'
550
+ >>> RegistryPolicy._normalize_version("v2.1")
551
+ '2.1.0'
552
+ """
553
+ try:
554
+ return normalize_version(version)
555
+ except ValueError as e:
556
+ context = ModelInfraErrorContext.with_correlation(
557
+ transport_type=EnumInfraTransportType.RUNTIME,
558
+ operation="normalize_version",
559
+ )
560
+ raise ProtocolConfigurationError(
561
+ str(e),
562
+ version=version,
563
+ context=context,
564
+ ) from e
565
+
566
+ def register(
567
+ self,
568
+ registration: ModelPolicyRegistration,
569
+ ) -> None:
570
+ """Register a policy plugin using a registration model.
571
+
572
+ Associates a (policy_id, policy_type, version) tuple with a policy class.
573
+ If the combination is already registered, the existing registration is
574
+ overwritten.
575
+
576
+ This is the PREFERRED API for registering policies. For new code, use this
577
+ method with ModelPolicyRegistration instead of register_policy().
578
+
579
+ Args:
580
+ registration: ModelPolicyRegistration containing all registration parameters:
581
+ - policy_id: Unique identifier for the policy
582
+ - policy_class: The policy class to register (must implement ProtocolPolicy)
583
+ - policy_type: Whether this is orchestrator or reducer policy
584
+ - version: Semantic version string (default: "1.0.0")
585
+ - allow_async: If True, allows async interface
586
+
587
+ Raises:
588
+ PolicyRegistryError: If policy has async methods and
589
+ allow_async=False, or if policy_type is invalid
590
+
591
+ Example:
592
+ >>> from omnibase_infra.runtime.models import ModelPolicyRegistration
593
+ >>> registry = RegistryPolicy()
594
+ >>> registration = ModelPolicyRegistration(
595
+ ... policy_id="retry_backoff",
596
+ ... policy_class=RetryBackoffPolicy,
597
+ ... policy_type=EnumPolicyType.ORCHESTRATOR,
598
+ ... version="1.0.0",
599
+ ... )
600
+ >>> registry.register(registration)
601
+ """
602
+ # Extract fields from model
603
+ policy_id = registration.policy_id
604
+ policy_class = registration.policy_class
605
+ policy_type = registration.policy_type
606
+ version = registration.version
607
+ allow_async = registration.allow_async
608
+
609
+ # Validate protocol implementation (evaluate() method exists and is callable)
610
+ # Pass policy_type for complete parameter validation and error context
611
+ self._validate_protocol_implementation(policy_id, policy_class, policy_type)
612
+
613
+ # Validate sync enforcement (pass policy_type for better error context)
614
+ self._validate_sync_enforcement(
615
+ policy_id, policy_class, allow_async, policy_type
616
+ )
617
+
618
+ # Normalize policy type
619
+ normalized_type = self._normalize_policy_type(policy_type)
620
+
621
+ # Normalize version string before storing to prevent lookup mismatches
622
+ # This ensures "1.0", "1.0.0", and "v1.0.0" all resolve to "1.0.0"
623
+ # Note: ModelPolicyRegistration already normalizes, but we normalize again
624
+ # here to guarantee consistency with lookup operations
625
+ normalized_version = self._normalize_version(version)
626
+
627
+ # Validate version format (ensures semantic versioning compliance)
628
+ # This calls _parse_semver which will raise ProtocolConfigurationError if invalid
629
+ self._parse_semver(normalized_version)
630
+
631
+ # Register the policy using ModelPolicyKey with normalized version
632
+ key = ModelPolicyKey(
633
+ policy_id=policy_id,
634
+ policy_type=normalized_type,
635
+ version=normalized_version,
636
+ )
637
+ with self._lock:
638
+ self._registry[key] = policy_class
639
+ # Update secondary index for performance optimization
640
+ if policy_id not in self._policy_id_index:
641
+ self._policy_id_index[policy_id] = []
642
+ if key not in self._policy_id_index[policy_id]:
643
+ self._policy_id_index[policy_id].append(key)
644
+
645
+ def register_policy(
646
+ self,
647
+ policy_id: str,
648
+ policy_class: type[ProtocolPolicy],
649
+ policy_type: PolicyTypeInput,
650
+ version: str = "1.0.0",
651
+ allow_async: bool = False,
652
+ ) -> None:
653
+ """Convenience method to register a policy with individual parameters.
654
+
655
+ Wraps parameters in ModelPolicyRegistration and calls register().
656
+ Partial version strings (e.g., "1", "1.0") are auto-normalized to
657
+ "x.y.z" format by ModelPolicyRegistration.
658
+
659
+ Note:
660
+ For new code, prefer using register(ModelPolicyRegistration(...))
661
+ directly. This is a convenience method for simple registrations.
662
+
663
+ Args:
664
+ policy_id: Unique identifier for the policy (e.g., 'exponential_backoff')
665
+ policy_class: The policy class to register. Must implement ProtocolPolicy.
666
+ policy_type: Whether this is orchestrator or reducer policy.
667
+ Can be EnumPolicyType or string literal.
668
+ version: Semantic version string (default: "1.0.0"). Partial versions
669
+ like "1" or "1.0" are auto-normalized to "1.0.0" or "1.0.0".
670
+ allow_async: If True, allows async interface. MUST be explicitly
671
+ flagged for policies with async methods.
672
+
673
+ Raises:
674
+ PolicyRegistryError: If policy has async methods and
675
+ allow_async=False, or if policy_type is invalid
676
+ ProtocolConfigurationError: If version format is invalid
677
+
678
+ Example:
679
+ >>> registry = RegistryPolicy()
680
+ >>> registry.register_policy(
681
+ ... policy_id="retry_backoff",
682
+ ... policy_class=RetryBackoffPolicy,
683
+ ... policy_type=EnumPolicyType.ORCHESTRATOR,
684
+ ... version="1.0.0",
685
+ ... )
686
+ """
687
+ # Version normalization is handled by ModelPolicyRegistration validator
688
+ # which normalizes partial versions and v-prefixed versions automatically
689
+ try:
690
+ registration = ModelPolicyRegistration(
691
+ policy_id=policy_id,
692
+ policy_class=policy_class,
693
+ policy_type=policy_type,
694
+ version=version,
695
+ allow_async=allow_async,
696
+ )
697
+ except ValidationError as e:
698
+ # Convert all validation errors to ProtocolConfigurationError for consistency
699
+ # This ensures uniform error handling across all validation failures
700
+ context = ModelInfraErrorContext.with_correlation(
701
+ transport_type=EnumInfraTransportType.RUNTIME,
702
+ operation="register_policy",
703
+ )
704
+ for error in e.errors():
705
+ field_loc = error.get("loc", ())
706
+ field_name = field_loc[0] if field_loc else "unknown"
707
+ error_msg = error.get("msg", str(e))
708
+
709
+ if field_name == "version":
710
+ raise ProtocolConfigurationError(
711
+ f"Invalid version format: {error_msg}",
712
+ version=version,
713
+ context=context,
714
+ ) from e
715
+ if field_name == "policy_id":
716
+ raise ProtocolConfigurationError(
717
+ f"Invalid policy_id: {error_msg}",
718
+ policy_id=policy_id,
719
+ context=context,
720
+ ) from e
721
+ if field_name == "policy_type":
722
+ raise ProtocolConfigurationError(
723
+ f"Invalid policy_type: {error_msg}",
724
+ policy_type=str(policy_type),
725
+ context=context,
726
+ ) from e
727
+ if field_name == "policy_class":
728
+ raise ProtocolConfigurationError(
729
+ f"Invalid policy_class: {error_msg}",
730
+ context=context,
731
+ ) from e
732
+ # Fallback for any unhandled validation errors
733
+ raise ProtocolConfigurationError(
734
+ f"Validation error in policy registration: {e}",
735
+ context=context,
736
+ ) from e
737
+
738
+ self.register(registration)
739
+
740
+ def get(
741
+ self,
742
+ policy_id: str,
743
+ policy_type: PolicyTypeInput | None = None,
744
+ version: str | None = None,
745
+ ) -> type[ProtocolPolicy]:
746
+ """Get policy class by ID, type, and optional version.
747
+
748
+ Resolves the policy class registered for the given policy configuration.
749
+ If policy_type is not specified, returns the first matching policy_id.
750
+ If version is not specified, returns the latest version (by semantic version).
751
+
752
+ Performance Characteristics:
753
+ - Best case: O(1) - Direct lookup with policy_id only (single version, no filters)
754
+ - Average case: O(k) where k = number of matching versions (multi-version, no filters)
755
+ - Worst case: O(k*log(k)) when policy_type filter applied with multiple versions
756
+ (requires both filtering candidates and sorting by semver to find latest)
757
+ - Uses secondary index for O(1) policy_id lookup instead of O(n) scan
758
+ - Defers expensive error message generation until actually needed
759
+ - Fast path optimization when no filters applied (common case)
760
+
761
+ Args:
762
+ policy_id: Policy identifier.
763
+ policy_type: Optional policy type filter (orchestrator or reducer).
764
+ version: Optional version filter. If None, returns latest version.
765
+
766
+ Returns:
767
+ Policy class registered for the configuration.
768
+
769
+ Raises:
770
+ PolicyRegistryError: If no matching policy is found.
771
+
772
+ Example:
773
+ >>> registry = RegistryPolicy()
774
+ >>> registry.register("retry", RetryPolicy, EnumPolicyType.ORCHESTRATOR)
775
+ >>> policy_cls = registry.get("retry")
776
+ >>> policy_cls = registry.get("retry", policy_type="orchestrator")
777
+ >>> policy_cls = registry.get("retry", version="1.0.0")
778
+ """
779
+ # Normalize policy_type if provided (outside lock for minimal critical section)
780
+ # Use empty string as sentinel for "no filter" to reduce union types
781
+ normalized_type: str = (
782
+ self._normalize_policy_type(policy_type) if policy_type is not None else ""
783
+ )
784
+
785
+ # Normalize version for consistent lookup (e.g., "1.0" matches "1.0.0")
786
+ normalized_version: str | None = None
787
+ if version is not None:
788
+ normalized_version = self._normalize_version(version)
789
+
790
+ with self._lock:
791
+ # Performance optimization: Use secondary index for O(1) lookup by policy_id
792
+ # This avoids iterating through all registry entries (O(n) -> O(1))
793
+ candidate_keys = self._policy_id_index.get(policy_id, [])
794
+
795
+ # Early exit if policy_id not found - avoid building matches list
796
+ if not candidate_keys:
797
+ # Defer expensive _list_internal() call until actually raising error
798
+ filters = [f"policy_id={policy_id!r}"]
799
+ if policy_type is not None:
800
+ filters.append(f"policy_type={policy_type!r}")
801
+ if version is not None:
802
+ filters.append(f"version={version!r}")
803
+
804
+ # Inline list generation for error message (avoids separate method)
805
+ registered = [
806
+ k.to_tuple()
807
+ for k in sorted(
808
+ self._registry.keys(),
809
+ key=lambda k: (k.policy_id, k.policy_type, k.version),
810
+ )
811
+ ]
812
+ context = ModelInfraErrorContext.with_correlation(
813
+ transport_type=EnumInfraTransportType.RUNTIME,
814
+ operation="get_policy",
815
+ )
816
+ raise PolicyRegistryError(
817
+ f"No policy registered matching: {', '.join(filters)}. "
818
+ f"Registered policies: {registered}",
819
+ policy_id=policy_id,
820
+ policy_type=str(policy_type) if policy_type else None,
821
+ context=context,
822
+ )
823
+
824
+ # Find matching entries from candidates (optimized to reduce allocations)
825
+ # Fast path: no filtering needed (common case - just get latest version)
826
+ if not normalized_type and normalized_version is None:
827
+ # Fast path optimization: avoid tuple allocation and batch dict lookups
828
+ # Only build the matches list if we have multiple versions
829
+ if len(candidate_keys) == 1:
830
+ # Single version - direct return without any allocations
831
+ return self._registry[candidate_keys[0]]
832
+ else:
833
+ # Multiple versions - need to find latest
834
+ # Use direct key comparison instead of building tuples
835
+ latest_key = max(
836
+ candidate_keys,
837
+ key=lambda k: self._parse_semver(k.version),
838
+ )
839
+ return self._registry[latest_key]
840
+ else:
841
+ # Filtered path: apply type and version filters
842
+ matches = []
843
+ for key in candidate_keys:
844
+ if normalized_type and key.policy_type != normalized_type:
845
+ continue
846
+ if (
847
+ normalized_version is not None
848
+ and key.version != normalized_version
849
+ ):
850
+ continue
851
+ matches.append((key, self._registry[key]))
852
+
853
+ if not matches:
854
+ # Filters eliminated all candidates - build error message
855
+ filters = [f"policy_id={policy_id!r}"]
856
+ if policy_type is not None:
857
+ filters.append(f"policy_type={policy_type!r}")
858
+ if version is not None:
859
+ filters.append(f"version={version!r}")
860
+
861
+ # Inline list generation for error message (avoids separate method)
862
+ registered = [
863
+ k.to_tuple()
864
+ for k in sorted(
865
+ self._registry.keys(),
866
+ key=lambda k: (k.policy_id, k.policy_type, k.version),
867
+ )
868
+ ]
869
+ context = ModelInfraErrorContext.with_correlation(
870
+ transport_type=EnumInfraTransportType.RUNTIME,
871
+ operation="get_policy",
872
+ )
873
+ raise PolicyRegistryError(
874
+ f"No policy registered matching: {', '.join(filters)}. "
875
+ f"Registered policies: {registered}",
876
+ policy_id=policy_id,
877
+ policy_type=str(policy_type) if policy_type else None,
878
+ context=context,
879
+ )
880
+
881
+ # If version not specified and multiple matches, return latest
882
+ # (using cached semantic version comparison)
883
+ if normalized_version is None and len(matches) > 1:
884
+ # Sort in-place to avoid allocating a new list
885
+ matches.sort(
886
+ key=lambda x: self._parse_semver(x[0].version), reverse=True
887
+ )
888
+
889
+ return matches[0][1]
890
+
891
+ # ==========================================================================
892
+ # Semver Methods (inherited from MixinSemverCache)
893
+ # ==========================================================================
894
+ # The following methods are inherited from MixinSemverCache:
895
+ # - configure_semver_cache(maxsize: int) -> None
896
+ # - _reset_semver_cache() -> None
897
+ # - _get_semver_parser() -> Callable[[str], ModelSemVer]
898
+ # - _parse_semver(version: str) -> ModelSemVer
899
+ # - _get_semver_cache_info() -> functools._CacheInfo | None
900
+ #
901
+ # See MixinSemverCache for full documentation of these methods.
902
+
903
+ def _list_internal(self) -> list[tuple[str, str, str]]:
904
+ """Internal list method (assumes lock is held).
905
+
906
+ Returns:
907
+ List of (policy_id, policy_type, version) tuples.
908
+ """
909
+ return [
910
+ k.to_tuple()
911
+ for k in sorted(
912
+ self._registry.keys(),
913
+ key=lambda k: (k.policy_id, k.policy_type, k.version),
914
+ )
915
+ ]
916
+
917
+ def list_keys(
918
+ self,
919
+ policy_type: PolicyTypeInput | None = None,
920
+ ) -> list[tuple[str, str, str]]:
921
+ """List registered policy keys as (id, type, version) tuples.
922
+
923
+ Args:
924
+ policy_type: Optional filter to list only policies of a specific type.
925
+
926
+ Returns:
927
+ List of (policy_id, policy_type, version) tuples, sorted alphabetically.
928
+
929
+ Example:
930
+ >>> registry = RegistryPolicy()
931
+ >>> registry.register("retry", RetryPolicy, EnumPolicyType.ORCHESTRATOR)
932
+ >>> registry.register("merge", MergePolicy, EnumPolicyType.REDUCER)
933
+ >>> print(registry.list_keys())
934
+ [('merge', 'reducer', '1.0.0'), ('retry', 'orchestrator', '1.0.0')]
935
+ >>> print(registry.list_keys(policy_type="orchestrator"))
936
+ [('retry', 'orchestrator', '1.0.0')]
937
+ """
938
+ # Normalize policy_type if provided
939
+ # Use empty string as sentinel for "no filter" to reduce union types
940
+ normalized_type: str = (
941
+ self._normalize_policy_type(policy_type) if policy_type is not None else ""
942
+ )
943
+
944
+ with self._lock:
945
+ results: list[tuple[str, str, str]] = []
946
+ for key in sorted(
947
+ self._registry.keys(),
948
+ key=lambda k: (k.policy_id, k.policy_type, k.version),
949
+ ):
950
+ if normalized_type and key.policy_type != normalized_type:
951
+ continue
952
+ results.append(key.to_tuple())
953
+ return results
954
+
955
+ def list_policy_types(self) -> list[str]:
956
+ """List registered policy types.
957
+
958
+ Returns:
959
+ List of unique policy type strings that have registered policies.
960
+
961
+ Example:
962
+ >>> registry = RegistryPolicy()
963
+ >>> registry.register("retry", RetryPolicy, EnumPolicyType.ORCHESTRATOR)
964
+ >>> print(registry.list_policy_types())
965
+ ['orchestrator']
966
+ """
967
+ with self._lock:
968
+ types = {key.policy_type for key in self._registry}
969
+ return sorted(types)
970
+
971
+ def list_versions(self, policy_id: str) -> list[str]:
972
+ """List registered versions for a policy ID.
973
+
974
+ Args:
975
+ policy_id: The policy ID to list versions for.
976
+
977
+ Returns:
978
+ List of version strings registered for the policy ID, sorted.
979
+
980
+ Example:
981
+ >>> registry = RegistryPolicy()
982
+ >>> registry.register("retry", RetryPolicyV1, "orchestrator", "1.0.0")
983
+ >>> registry.register("retry", RetryPolicyV2, "orchestrator", "2.0.0")
984
+ >>> print(registry.list_versions("retry"))
985
+ ['1.0.0', '2.0.0']
986
+ """
987
+ with self._lock:
988
+ # Performance optimization: Use secondary index
989
+ candidate_keys = self._policy_id_index.get(policy_id, [])
990
+ versions = {key.version for key in candidate_keys}
991
+ return sorted(versions)
992
+
993
+ def is_registered(
994
+ self,
995
+ policy_id: str,
996
+ policy_type: PolicyTypeInput | None = None,
997
+ version: str | None = None,
998
+ ) -> bool:
999
+ """Check if a policy is registered.
1000
+
1001
+ Args:
1002
+ policy_id: Policy identifier.
1003
+ policy_type: Optional policy type filter.
1004
+ version: Optional version filter.
1005
+
1006
+ Returns:
1007
+ True if a matching policy is registered, False otherwise.
1008
+
1009
+ Example:
1010
+ >>> registry = RegistryPolicy()
1011
+ >>> registry.register("retry", RetryPolicy, EnumPolicyType.ORCHESTRATOR)
1012
+ >>> registry.is_registered("retry")
1013
+ True
1014
+ >>> registry.is_registered("unknown")
1015
+ False
1016
+ """
1017
+ # Normalize policy_type if provided
1018
+ # Use empty string as sentinel for "no filter" to reduce union types
1019
+ normalized_type: str = ""
1020
+ if policy_type is not None:
1021
+ try:
1022
+ normalized_type = self._normalize_policy_type(policy_type)
1023
+ except PolicyRegistryError:
1024
+ return False
1025
+
1026
+ # Normalize version for consistent lookup (e.g., "1.0" matches "1.0.0")
1027
+ normalized_version: str | None = None
1028
+ if version is not None:
1029
+ normalized_version = self._normalize_version(version)
1030
+
1031
+ with self._lock:
1032
+ # Performance optimization: Use secondary index
1033
+ candidate_keys = self._policy_id_index.get(policy_id, [])
1034
+ for key in candidate_keys:
1035
+ if normalized_type and key.policy_type != normalized_type:
1036
+ continue
1037
+ if normalized_version is not None and key.version != normalized_version:
1038
+ continue
1039
+ return True
1040
+ return False
1041
+
1042
+ def unregister(
1043
+ self,
1044
+ policy_id: str,
1045
+ policy_type: PolicyTypeInput | None = None,
1046
+ version: str | None = None,
1047
+ ) -> int:
1048
+ """Unregister policy plugins.
1049
+
1050
+ Removes policy registrations matching the given criteria.
1051
+ This is useful for testing and hot-reload scenarios.
1052
+
1053
+ Args:
1054
+ policy_id: Policy identifier to unregister.
1055
+ policy_type: Optional policy type filter.
1056
+ version: Optional version filter.
1057
+
1058
+ Returns:
1059
+ Number of policies unregistered.
1060
+
1061
+ Example:
1062
+ >>> registry = RegistryPolicy()
1063
+ >>> registry.register("retry", RetryPolicyV1, "orchestrator", "1.0.0")
1064
+ >>> registry.register("retry", RetryPolicyV2, "orchestrator", "2.0.0")
1065
+ >>> registry.unregister("retry") # Removes all versions
1066
+ 2
1067
+ >>> registry.unregister("retry", version="1.0.0") # Remove specific version
1068
+ 1
1069
+ """
1070
+ # Normalize policy_type if provided
1071
+ # Use empty string as sentinel for "no filter" to reduce union types
1072
+ normalized_type: str = ""
1073
+ if policy_type is not None:
1074
+ try:
1075
+ normalized_type = self._normalize_policy_type(policy_type)
1076
+ except PolicyRegistryError:
1077
+ return 0
1078
+
1079
+ # Normalize version for consistent lookup (e.g., "1.0" matches "1.0.0")
1080
+ normalized_version: str | None = None
1081
+ if version is not None:
1082
+ normalized_version = self._normalize_version(version)
1083
+
1084
+ # Thread safety: Lock held during full unregister operation (write operation)
1085
+ with self._lock:
1086
+ # Performance optimization: Use secondary index
1087
+ candidate_keys = self._policy_id_index.get(policy_id, [])
1088
+ keys_to_remove: list[ModelPolicyKey] = []
1089
+
1090
+ for key in candidate_keys:
1091
+ if normalized_type and key.policy_type != normalized_type:
1092
+ continue
1093
+ if normalized_version is not None and key.version != normalized_version:
1094
+ continue
1095
+ keys_to_remove.append(key)
1096
+
1097
+ for key in keys_to_remove:
1098
+ del self._registry[key]
1099
+ # Update secondary index
1100
+ self._policy_id_index[policy_id].remove(key)
1101
+
1102
+ # Clean up empty index entries
1103
+ if (
1104
+ policy_id in self._policy_id_index
1105
+ and not self._policy_id_index[policy_id]
1106
+ ):
1107
+ del self._policy_id_index[policy_id]
1108
+
1109
+ return len(keys_to_remove)
1110
+
1111
+ def clear(self) -> None:
1112
+ """Clear all policy registrations.
1113
+
1114
+ Removes all registered policies from the registry.
1115
+
1116
+ Warning:
1117
+ This method is intended for **testing purposes only**.
1118
+ Calling it in production code will emit a warning.
1119
+ It breaks the immutability guarantee after startup.
1120
+
1121
+ Example:
1122
+ >>> registry = RegistryPolicy()
1123
+ >>> registry.register("retry", RetryPolicy, EnumPolicyType.ORCHESTRATOR)
1124
+ >>> registry.clear()
1125
+ >>> registry.list_keys()
1126
+ []
1127
+ """
1128
+ warnings.warn(
1129
+ "RegistryPolicy.clear() is intended for testing only. "
1130
+ "Do not use in production code.",
1131
+ UserWarning,
1132
+ stacklevel=2,
1133
+ )
1134
+ with self._lock:
1135
+ self._registry.clear()
1136
+ self._policy_id_index.clear()
1137
+
1138
+ def __len__(self) -> int:
1139
+ """Return the number of registered policies.
1140
+
1141
+ Returns:
1142
+ Number of registered policy (id, type, version) combinations.
1143
+
1144
+ Example:
1145
+ >>> registry = RegistryPolicy()
1146
+ >>> len(registry)
1147
+ 0
1148
+ >>> registry.register("retry", RetryPolicy, EnumPolicyType.ORCHESTRATOR)
1149
+ >>> len(registry)
1150
+ 1
1151
+ """
1152
+ with self._lock:
1153
+ return len(self._registry)
1154
+
1155
+ def __contains__(self, policy_id: str) -> bool:
1156
+ """Check if policy ID is registered using 'in' operator.
1157
+
1158
+ Args:
1159
+ policy_id: Policy identifier.
1160
+
1161
+ Returns:
1162
+ True if policy ID is registered (any type/version), False otherwise.
1163
+
1164
+ Example:
1165
+ >>> registry = RegistryPolicy()
1166
+ >>> registry.register("retry", RetryPolicy, EnumPolicyType.ORCHESTRATOR)
1167
+ >>> "retry" in registry
1168
+ True
1169
+ >>> "unknown" in registry
1170
+ False
1171
+ """
1172
+ return self.is_registered(policy_id)
1173
+
1174
+
1175
+ # =============================================================================
1176
+ # Module Exports
1177
+ # =============================================================================
1178
+
1179
+ __all__: list[str] = [
1180
+ "ModelPolicyKey",
1181
+ # Models
1182
+ "ModelPolicyRegistration",
1183
+ # Registry class
1184
+ "RegistryPolicy",
1185
+ ]