omnibase_infra 0.2.1__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 (675) hide show
  1. omnibase_infra/__init__.py +101 -0
  2. omnibase_infra/cli/__init__.py +1 -0
  3. omnibase_infra/cli/commands.py +216 -0
  4. omnibase_infra/clients/__init__.py +0 -0
  5. omnibase_infra/contracts/handlers/filesystem/handler_contract.yaml +261 -0
  6. omnibase_infra/contracts/handlers/mcp/handler_contract.yaml +138 -0
  7. omnibase_infra/decorators/__init__.py +29 -0
  8. omnibase_infra/decorators/allow_any.py +109 -0
  9. omnibase_infra/dlq/__init__.py +90 -0
  10. omnibase_infra/dlq/constants_dlq.py +57 -0
  11. omnibase_infra/dlq/models/__init__.py +26 -0
  12. omnibase_infra/dlq/models/enum_replay_status.py +37 -0
  13. omnibase_infra/dlq/models/model_dlq_replay_record.py +135 -0
  14. omnibase_infra/dlq/models/model_dlq_tracking_config.py +184 -0
  15. omnibase_infra/dlq/service_dlq_tracking.py +611 -0
  16. omnibase_infra/enums/__init__.py +123 -0
  17. omnibase_infra/enums/enum_any_type_violation.py +104 -0
  18. omnibase_infra/enums/enum_backend_type.py +27 -0
  19. omnibase_infra/enums/enum_capture_outcome.py +42 -0
  20. omnibase_infra/enums/enum_capture_state.py +88 -0
  21. omnibase_infra/enums/enum_chain_violation_type.py +119 -0
  22. omnibase_infra/enums/enum_circuit_state.py +51 -0
  23. omnibase_infra/enums/enum_confirmation_event_type.py +27 -0
  24. omnibase_infra/enums/enum_contract_type.py +84 -0
  25. omnibase_infra/enums/enum_dedupe_strategy.py +46 -0
  26. omnibase_infra/enums/enum_dispatch_status.py +191 -0
  27. omnibase_infra/enums/enum_environment.py +46 -0
  28. omnibase_infra/enums/enum_execution_shape_violation.py +103 -0
  29. omnibase_infra/enums/enum_handler_error_type.py +101 -0
  30. omnibase_infra/enums/enum_handler_loader_error.py +178 -0
  31. omnibase_infra/enums/enum_handler_source_type.py +87 -0
  32. omnibase_infra/enums/enum_handler_type.py +77 -0
  33. omnibase_infra/enums/enum_handler_type_category.py +61 -0
  34. omnibase_infra/enums/enum_infra_transport_type.py +73 -0
  35. omnibase_infra/enums/enum_introspection_reason.py +154 -0
  36. omnibase_infra/enums/enum_message_category.py +213 -0
  37. omnibase_infra/enums/enum_node_archetype.py +74 -0
  38. omnibase_infra/enums/enum_node_output_type.py +185 -0
  39. omnibase_infra/enums/enum_non_retryable_error_category.py +224 -0
  40. omnibase_infra/enums/enum_policy_type.py +32 -0
  41. omnibase_infra/enums/enum_registration_state.py +261 -0
  42. omnibase_infra/enums/enum_registration_status.py +33 -0
  43. omnibase_infra/enums/enum_registry_response_status.py +28 -0
  44. omnibase_infra/enums/enum_response_status.py +26 -0
  45. omnibase_infra/enums/enum_retry_error_category.py +98 -0
  46. omnibase_infra/enums/enum_security_rule_id.py +103 -0
  47. omnibase_infra/enums/enum_selection_strategy.py +91 -0
  48. omnibase_infra/enums/enum_topic_standard.py +42 -0
  49. omnibase_infra/enums/enum_validation_severity.py +78 -0
  50. omnibase_infra/errors/__init__.py +156 -0
  51. omnibase_infra/errors/error_architecture_violation.py +152 -0
  52. omnibase_infra/errors/error_chain_propagation.py +188 -0
  53. omnibase_infra/errors/error_compute_registry.py +92 -0
  54. omnibase_infra/errors/error_consul.py +132 -0
  55. omnibase_infra/errors/error_container_wiring.py +243 -0
  56. omnibase_infra/errors/error_event_bus_registry.py +102 -0
  57. omnibase_infra/errors/error_infra.py +608 -0
  58. omnibase_infra/errors/error_message_type_registry.py +101 -0
  59. omnibase_infra/errors/error_policy_registry.py +112 -0
  60. omnibase_infra/errors/error_vault.py +123 -0
  61. omnibase_infra/event_bus/__init__.py +72 -0
  62. omnibase_infra/event_bus/configs/kafka_event_bus_config.yaml +86 -0
  63. omnibase_infra/event_bus/event_bus_inmemory.py +743 -0
  64. omnibase_infra/event_bus/event_bus_kafka.py +1658 -0
  65. omnibase_infra/event_bus/mixin_kafka_broadcast.py +184 -0
  66. omnibase_infra/event_bus/mixin_kafka_dlq.py +765 -0
  67. omnibase_infra/event_bus/models/__init__.py +29 -0
  68. omnibase_infra/event_bus/models/config/__init__.py +20 -0
  69. omnibase_infra/event_bus/models/config/model_kafka_event_bus_config.py +725 -0
  70. omnibase_infra/event_bus/models/model_dlq_event.py +206 -0
  71. omnibase_infra/event_bus/models/model_dlq_metrics.py +304 -0
  72. omnibase_infra/event_bus/models/model_event_headers.py +115 -0
  73. omnibase_infra/event_bus/models/model_event_message.py +60 -0
  74. omnibase_infra/event_bus/topic_constants.py +376 -0
  75. omnibase_infra/handlers/__init__.py +75 -0
  76. omnibase_infra/handlers/filesystem/__init__.py +48 -0
  77. omnibase_infra/handlers/filesystem/enum_file_system_operation.py +35 -0
  78. omnibase_infra/handlers/filesystem/model_file_system_request.py +298 -0
  79. omnibase_infra/handlers/filesystem/model_file_system_result.py +166 -0
  80. omnibase_infra/handlers/handler_consul.py +787 -0
  81. omnibase_infra/handlers/handler_db.py +1039 -0
  82. omnibase_infra/handlers/handler_filesystem.py +1478 -0
  83. omnibase_infra/handlers/handler_graph.py +1154 -0
  84. omnibase_infra/handlers/handler_http.py +920 -0
  85. omnibase_infra/handlers/handler_manifest_persistence.contract.yaml +184 -0
  86. omnibase_infra/handlers/handler_manifest_persistence.py +1539 -0
  87. omnibase_infra/handlers/handler_mcp.py +748 -0
  88. omnibase_infra/handlers/handler_qdrant.py +1076 -0
  89. omnibase_infra/handlers/handler_vault.py +422 -0
  90. omnibase_infra/handlers/mcp/__init__.py +19 -0
  91. omnibase_infra/handlers/mcp/adapter_onex_to_mcp.py +446 -0
  92. omnibase_infra/handlers/mcp/protocols.py +178 -0
  93. omnibase_infra/handlers/mcp/transport_streamable_http.py +352 -0
  94. omnibase_infra/handlers/mixins/__init__.py +42 -0
  95. omnibase_infra/handlers/mixins/mixin_consul_initialization.py +349 -0
  96. omnibase_infra/handlers/mixins/mixin_consul_kv.py +337 -0
  97. omnibase_infra/handlers/mixins/mixin_consul_service.py +277 -0
  98. omnibase_infra/handlers/mixins/mixin_vault_initialization.py +338 -0
  99. omnibase_infra/handlers/mixins/mixin_vault_retry.py +412 -0
  100. omnibase_infra/handlers/mixins/mixin_vault_secrets.py +450 -0
  101. omnibase_infra/handlers/mixins/mixin_vault_token.py +365 -0
  102. omnibase_infra/handlers/models/__init__.py +286 -0
  103. omnibase_infra/handlers/models/consul/__init__.py +81 -0
  104. omnibase_infra/handlers/models/consul/enum_consul_operation_type.py +57 -0
  105. omnibase_infra/handlers/models/consul/model_consul_deregister_payload.py +51 -0
  106. omnibase_infra/handlers/models/consul/model_consul_handler_config.py +153 -0
  107. omnibase_infra/handlers/models/consul/model_consul_handler_payload.py +89 -0
  108. omnibase_infra/handlers/models/consul/model_consul_kv_get_found_payload.py +55 -0
  109. omnibase_infra/handlers/models/consul/model_consul_kv_get_not_found_payload.py +49 -0
  110. omnibase_infra/handlers/models/consul/model_consul_kv_get_recurse_payload.py +50 -0
  111. omnibase_infra/handlers/models/consul/model_consul_kv_item.py +33 -0
  112. omnibase_infra/handlers/models/consul/model_consul_kv_put_payload.py +41 -0
  113. omnibase_infra/handlers/models/consul/model_consul_register_payload.py +53 -0
  114. omnibase_infra/handlers/models/consul/model_consul_retry_config.py +66 -0
  115. omnibase_infra/handlers/models/consul/model_payload_consul.py +66 -0
  116. omnibase_infra/handlers/models/consul/registry_payload_consul.py +214 -0
  117. omnibase_infra/handlers/models/graph/__init__.py +35 -0
  118. omnibase_infra/handlers/models/graph/enum_graph_operation_type.py +20 -0
  119. omnibase_infra/handlers/models/graph/model_graph_execute_payload.py +38 -0
  120. omnibase_infra/handlers/models/graph/model_graph_handler_config.py +54 -0
  121. omnibase_infra/handlers/models/graph/model_graph_handler_payload.py +44 -0
  122. omnibase_infra/handlers/models/graph/model_graph_query_payload.py +40 -0
  123. omnibase_infra/handlers/models/graph/model_graph_record.py +22 -0
  124. omnibase_infra/handlers/models/http/__init__.py +50 -0
  125. omnibase_infra/handlers/models/http/enum_http_operation_type.py +29 -0
  126. omnibase_infra/handlers/models/http/model_http_body_content.py +45 -0
  127. omnibase_infra/handlers/models/http/model_http_get_payload.py +88 -0
  128. omnibase_infra/handlers/models/http/model_http_handler_payload.py +90 -0
  129. omnibase_infra/handlers/models/http/model_http_post_payload.py +88 -0
  130. omnibase_infra/handlers/models/http/model_payload_http.py +66 -0
  131. omnibase_infra/handlers/models/http/registry_payload_http.py +212 -0
  132. omnibase_infra/handlers/models/mcp/__init__.py +23 -0
  133. omnibase_infra/handlers/models/mcp/enum_mcp_operation_type.py +24 -0
  134. omnibase_infra/handlers/models/mcp/model_mcp_handler_config.py +40 -0
  135. omnibase_infra/handlers/models/mcp/model_mcp_tool_call.py +32 -0
  136. omnibase_infra/handlers/models/mcp/model_mcp_tool_result.py +45 -0
  137. omnibase_infra/handlers/models/model_consul_handler_response.py +96 -0
  138. omnibase_infra/handlers/models/model_db_describe_response.py +83 -0
  139. omnibase_infra/handlers/models/model_db_query_payload.py +95 -0
  140. omnibase_infra/handlers/models/model_db_query_response.py +60 -0
  141. omnibase_infra/handlers/models/model_filesystem_config.py +98 -0
  142. omnibase_infra/handlers/models/model_filesystem_delete_payload.py +54 -0
  143. omnibase_infra/handlers/models/model_filesystem_delete_result.py +77 -0
  144. omnibase_infra/handlers/models/model_filesystem_directory_entry.py +75 -0
  145. omnibase_infra/handlers/models/model_filesystem_ensure_directory_payload.py +54 -0
  146. omnibase_infra/handlers/models/model_filesystem_ensure_directory_result.py +60 -0
  147. omnibase_infra/handlers/models/model_filesystem_list_directory_payload.py +60 -0
  148. omnibase_infra/handlers/models/model_filesystem_list_directory_result.py +68 -0
  149. omnibase_infra/handlers/models/model_filesystem_read_payload.py +62 -0
  150. omnibase_infra/handlers/models/model_filesystem_read_result.py +61 -0
  151. omnibase_infra/handlers/models/model_filesystem_write_payload.py +70 -0
  152. omnibase_infra/handlers/models/model_filesystem_write_result.py +55 -0
  153. omnibase_infra/handlers/models/model_graph_handler_response.py +98 -0
  154. omnibase_infra/handlers/models/model_handler_response.py +103 -0
  155. omnibase_infra/handlers/models/model_http_handler_response.py +101 -0
  156. omnibase_infra/handlers/models/model_manifest_metadata.py +75 -0
  157. omnibase_infra/handlers/models/model_manifest_persistence_config.py +62 -0
  158. omnibase_infra/handlers/models/model_manifest_query_payload.py +90 -0
  159. omnibase_infra/handlers/models/model_manifest_query_result.py +97 -0
  160. omnibase_infra/handlers/models/model_manifest_retrieve_payload.py +44 -0
  161. omnibase_infra/handlers/models/model_manifest_retrieve_result.py +98 -0
  162. omnibase_infra/handlers/models/model_manifest_store_payload.py +47 -0
  163. omnibase_infra/handlers/models/model_manifest_store_result.py +67 -0
  164. omnibase_infra/handlers/models/model_operation_context.py +187 -0
  165. omnibase_infra/handlers/models/model_qdrant_handler_response.py +98 -0
  166. omnibase_infra/handlers/models/model_retry_state.py +162 -0
  167. omnibase_infra/handlers/models/model_vault_handler_response.py +98 -0
  168. omnibase_infra/handlers/models/qdrant/__init__.py +44 -0
  169. omnibase_infra/handlers/models/qdrant/enum_qdrant_operation_type.py +26 -0
  170. omnibase_infra/handlers/models/qdrant/model_qdrant_collection_payload.py +42 -0
  171. omnibase_infra/handlers/models/qdrant/model_qdrant_delete_payload.py +36 -0
  172. omnibase_infra/handlers/models/qdrant/model_qdrant_handler_config.py +42 -0
  173. omnibase_infra/handlers/models/qdrant/model_qdrant_handler_payload.py +54 -0
  174. omnibase_infra/handlers/models/qdrant/model_qdrant_search_payload.py +42 -0
  175. omnibase_infra/handlers/models/qdrant/model_qdrant_search_result.py +30 -0
  176. omnibase_infra/handlers/models/qdrant/model_qdrant_upsert_payload.py +36 -0
  177. omnibase_infra/handlers/models/vault/__init__.py +69 -0
  178. omnibase_infra/handlers/models/vault/enum_vault_operation_type.py +35 -0
  179. omnibase_infra/handlers/models/vault/model_payload_vault.py +66 -0
  180. omnibase_infra/handlers/models/vault/model_vault_delete_payload.py +57 -0
  181. omnibase_infra/handlers/models/vault/model_vault_handler_config.py +148 -0
  182. omnibase_infra/handlers/models/vault/model_vault_handler_payload.py +101 -0
  183. omnibase_infra/handlers/models/vault/model_vault_list_payload.py +58 -0
  184. omnibase_infra/handlers/models/vault/model_vault_renew_token_payload.py +67 -0
  185. omnibase_infra/handlers/models/vault/model_vault_retry_config.py +66 -0
  186. omnibase_infra/handlers/models/vault/model_vault_secret_payload.py +106 -0
  187. omnibase_infra/handlers/models/vault/model_vault_write_payload.py +66 -0
  188. omnibase_infra/handlers/models/vault/registry_payload_vault.py +213 -0
  189. omnibase_infra/handlers/registration_storage/__init__.py +43 -0
  190. omnibase_infra/handlers/registration_storage/handler_registration_storage_mock.py +392 -0
  191. omnibase_infra/handlers/registration_storage/handler_registration_storage_postgres.py +915 -0
  192. omnibase_infra/handlers/registration_storage/models/__init__.py +23 -0
  193. omnibase_infra/handlers/registration_storage/models/model_delete_registration_request.py +58 -0
  194. omnibase_infra/handlers/registration_storage/models/model_update_registration_request.py +73 -0
  195. omnibase_infra/handlers/registration_storage/protocol_registration_persistence.py +191 -0
  196. omnibase_infra/handlers/service_discovery/__init__.py +43 -0
  197. omnibase_infra/handlers/service_discovery/handler_service_discovery_consul.py +747 -0
  198. omnibase_infra/handlers/service_discovery/handler_service_discovery_mock.py +258 -0
  199. omnibase_infra/handlers/service_discovery/models/__init__.py +22 -0
  200. omnibase_infra/handlers/service_discovery/models/model_discovery_result.py +64 -0
  201. omnibase_infra/handlers/service_discovery/models/model_registration_result.py +138 -0
  202. omnibase_infra/handlers/service_discovery/models/model_service_info.py +99 -0
  203. omnibase_infra/handlers/service_discovery/protocol_discovery_operations.py +170 -0
  204. omnibase_infra/idempotency/__init__.py +94 -0
  205. omnibase_infra/idempotency/models/__init__.py +43 -0
  206. omnibase_infra/idempotency/models/model_idempotency_check_result.py +85 -0
  207. omnibase_infra/idempotency/models/model_idempotency_guard_config.py +130 -0
  208. omnibase_infra/idempotency/models/model_idempotency_record.py +86 -0
  209. omnibase_infra/idempotency/models/model_idempotency_store_health_check_result.py +81 -0
  210. omnibase_infra/idempotency/models/model_idempotency_store_metrics.py +140 -0
  211. omnibase_infra/idempotency/models/model_postgres_idempotency_store_config.py +299 -0
  212. omnibase_infra/idempotency/protocol_idempotency_store.py +184 -0
  213. omnibase_infra/idempotency/store_inmemory.py +265 -0
  214. omnibase_infra/idempotency/store_postgres.py +923 -0
  215. omnibase_infra/infrastructure/__init__.py +0 -0
  216. omnibase_infra/mixins/__init__.py +71 -0
  217. omnibase_infra/mixins/mixin_async_circuit_breaker.py +655 -0
  218. omnibase_infra/mixins/mixin_dict_like_accessors.py +146 -0
  219. omnibase_infra/mixins/mixin_envelope_extraction.py +119 -0
  220. omnibase_infra/mixins/mixin_node_introspection.py +2465 -0
  221. omnibase_infra/mixins/mixin_retry_execution.py +386 -0
  222. omnibase_infra/mixins/protocol_circuit_breaker_aware.py +133 -0
  223. omnibase_infra/models/__init__.py +136 -0
  224. omnibase_infra/models/corpus/__init__.py +17 -0
  225. omnibase_infra/models/corpus/model_capture_config.py +133 -0
  226. omnibase_infra/models/corpus/model_capture_result.py +86 -0
  227. omnibase_infra/models/discovery/__init__.py +42 -0
  228. omnibase_infra/models/discovery/model_dependency_spec.py +319 -0
  229. omnibase_infra/models/discovery/model_discovered_capabilities.py +50 -0
  230. omnibase_infra/models/discovery/model_introspection_config.py +311 -0
  231. omnibase_infra/models/discovery/model_introspection_performance_metrics.py +169 -0
  232. omnibase_infra/models/discovery/model_introspection_task_config.py +116 -0
  233. omnibase_infra/models/dispatch/__init__.py +147 -0
  234. omnibase_infra/models/dispatch/model_dispatch_context.py +439 -0
  235. omnibase_infra/models/dispatch/model_dispatch_error.py +336 -0
  236. omnibase_infra/models/dispatch/model_dispatch_log_context.py +400 -0
  237. omnibase_infra/models/dispatch/model_dispatch_metadata.py +228 -0
  238. omnibase_infra/models/dispatch/model_dispatch_metrics.py +496 -0
  239. omnibase_infra/models/dispatch/model_dispatch_outcome.py +317 -0
  240. omnibase_infra/models/dispatch/model_dispatch_outputs.py +231 -0
  241. omnibase_infra/models/dispatch/model_dispatch_result.py +436 -0
  242. omnibase_infra/models/dispatch/model_dispatch_route.py +279 -0
  243. omnibase_infra/models/dispatch/model_dispatcher_metrics.py +275 -0
  244. omnibase_infra/models/dispatch/model_dispatcher_registration.py +352 -0
  245. omnibase_infra/models/dispatch/model_parsed_topic.py +135 -0
  246. omnibase_infra/models/dispatch/model_topic_parser.py +725 -0
  247. omnibase_infra/models/dispatch/model_tracing_context.py +285 -0
  248. omnibase_infra/models/errors/__init__.py +45 -0
  249. omnibase_infra/models/errors/model_handler_validation_error.py +594 -0
  250. omnibase_infra/models/errors/model_infra_error_context.py +99 -0
  251. omnibase_infra/models/errors/model_message_type_registry_error_context.py +71 -0
  252. omnibase_infra/models/errors/model_timeout_error_context.py +110 -0
  253. omnibase_infra/models/handlers/__init__.py +37 -0
  254. omnibase_infra/models/handlers/model_contract_discovery_result.py +80 -0
  255. omnibase_infra/models/handlers/model_handler_descriptor.py +185 -0
  256. omnibase_infra/models/handlers/model_handler_identifier.py +215 -0
  257. omnibase_infra/models/health/__init__.py +9 -0
  258. omnibase_infra/models/health/model_health_check_result.py +40 -0
  259. omnibase_infra/models/lifecycle/__init__.py +39 -0
  260. omnibase_infra/models/logging/__init__.py +51 -0
  261. omnibase_infra/models/logging/model_log_context.py +756 -0
  262. omnibase_infra/models/model_retry_error_classification.py +78 -0
  263. omnibase_infra/models/projection/__init__.py +43 -0
  264. omnibase_infra/models/projection/model_capability_fields.py +112 -0
  265. omnibase_infra/models/projection/model_registration_projection.py +434 -0
  266. omnibase_infra/models/projection/model_registration_snapshot.py +322 -0
  267. omnibase_infra/models/projection/model_sequence_info.py +182 -0
  268. omnibase_infra/models/projection/model_snapshot_topic_config.py +590 -0
  269. omnibase_infra/models/projectors/__init__.py +41 -0
  270. omnibase_infra/models/projectors/model_projector_column.py +289 -0
  271. omnibase_infra/models/projectors/model_projector_discovery_result.py +65 -0
  272. omnibase_infra/models/projectors/model_projector_index.py +270 -0
  273. omnibase_infra/models/projectors/model_projector_schema.py +415 -0
  274. omnibase_infra/models/projectors/model_projector_validation_error.py +63 -0
  275. omnibase_infra/models/projectors/util_sql_identifiers.py +115 -0
  276. omnibase_infra/models/registration/__init__.py +59 -0
  277. omnibase_infra/models/registration/commands/__init__.py +15 -0
  278. omnibase_infra/models/registration/commands/model_node_registration_acked.py +108 -0
  279. omnibase_infra/models/registration/events/__init__.py +56 -0
  280. omnibase_infra/models/registration/events/model_node_became_active.py +103 -0
  281. omnibase_infra/models/registration/events/model_node_liveness_expired.py +103 -0
  282. omnibase_infra/models/registration/events/model_node_registration_accepted.py +98 -0
  283. omnibase_infra/models/registration/events/model_node_registration_ack_received.py +98 -0
  284. omnibase_infra/models/registration/events/model_node_registration_ack_timed_out.py +112 -0
  285. omnibase_infra/models/registration/events/model_node_registration_initiated.py +107 -0
  286. omnibase_infra/models/registration/events/model_node_registration_rejected.py +104 -0
  287. omnibase_infra/models/registration/model_introspection_metrics.py +253 -0
  288. omnibase_infra/models/registration/model_node_capabilities.py +179 -0
  289. omnibase_infra/models/registration/model_node_heartbeat_event.py +126 -0
  290. omnibase_infra/models/registration/model_node_introspection_event.py +175 -0
  291. omnibase_infra/models/registration/model_node_metadata.py +79 -0
  292. omnibase_infra/models/registration/model_node_registration.py +162 -0
  293. omnibase_infra/models/registration/model_node_registration_record.py +162 -0
  294. omnibase_infra/models/registry/__init__.py +29 -0
  295. omnibase_infra/models/registry/model_domain_constraint.py +202 -0
  296. omnibase_infra/models/registry/model_message_type_entry.py +271 -0
  297. omnibase_infra/models/resilience/__init__.py +9 -0
  298. omnibase_infra/models/resilience/model_circuit_breaker_config.py +227 -0
  299. omnibase_infra/models/routing/__init__.py +25 -0
  300. omnibase_infra/models/routing/model_routing_entry.py +52 -0
  301. omnibase_infra/models/routing/model_routing_subcontract.py +70 -0
  302. omnibase_infra/models/runtime/__init__.py +40 -0
  303. omnibase_infra/models/runtime/model_contract_security_config.py +41 -0
  304. omnibase_infra/models/runtime/model_discovery_error.py +81 -0
  305. omnibase_infra/models/runtime/model_discovery_result.py +162 -0
  306. omnibase_infra/models/runtime/model_discovery_warning.py +74 -0
  307. omnibase_infra/models/runtime/model_failed_plugin_load.py +63 -0
  308. omnibase_infra/models/runtime/model_handler_contract.py +280 -0
  309. omnibase_infra/models/runtime/model_loaded_handler.py +120 -0
  310. omnibase_infra/models/runtime/model_plugin_load_context.py +93 -0
  311. omnibase_infra/models/runtime/model_plugin_load_summary.py +124 -0
  312. omnibase_infra/models/security/__init__.py +50 -0
  313. omnibase_infra/models/security/classification_levels.py +99 -0
  314. omnibase_infra/models/security/model_environment_policy.py +145 -0
  315. omnibase_infra/models/security/model_handler_security_policy.py +107 -0
  316. omnibase_infra/models/security/model_security_error.py +81 -0
  317. omnibase_infra/models/security/model_security_validation_result.py +328 -0
  318. omnibase_infra/models/security/model_security_warning.py +67 -0
  319. omnibase_infra/models/snapshot/__init__.py +27 -0
  320. omnibase_infra/models/snapshot/model_field_change.py +65 -0
  321. omnibase_infra/models/snapshot/model_snapshot.py +270 -0
  322. omnibase_infra/models/snapshot/model_snapshot_diff.py +203 -0
  323. omnibase_infra/models/snapshot/model_subject_ref.py +81 -0
  324. omnibase_infra/models/types/__init__.py +71 -0
  325. omnibase_infra/models/validation/__init__.py +89 -0
  326. omnibase_infra/models/validation/model_any_type_validation_result.py +118 -0
  327. omnibase_infra/models/validation/model_any_type_violation.py +141 -0
  328. omnibase_infra/models/validation/model_category_match_result.py +345 -0
  329. omnibase_infra/models/validation/model_chain_violation.py +166 -0
  330. omnibase_infra/models/validation/model_coverage_metrics.py +316 -0
  331. omnibase_infra/models/validation/model_execution_shape_rule.py +159 -0
  332. omnibase_infra/models/validation/model_execution_shape_validation.py +208 -0
  333. omnibase_infra/models/validation/model_execution_shape_validation_result.py +294 -0
  334. omnibase_infra/models/validation/model_execution_shape_violation.py +122 -0
  335. omnibase_infra/models/validation/model_localhandler_validation_result.py +139 -0
  336. omnibase_infra/models/validation/model_localhandler_violation.py +100 -0
  337. omnibase_infra/models/validation/model_output_validation_params.py +74 -0
  338. omnibase_infra/models/validation/model_validate_and_raise_params.py +84 -0
  339. omnibase_infra/models/validation/model_validation_error_params.py +84 -0
  340. omnibase_infra/models/validation/model_validation_outcome.py +287 -0
  341. omnibase_infra/nodes/__init__.py +48 -0
  342. omnibase_infra/nodes/architecture_validator/__init__.py +79 -0
  343. omnibase_infra/nodes/architecture_validator/contract.yaml +252 -0
  344. omnibase_infra/nodes/architecture_validator/contract_architecture_validator.yaml +208 -0
  345. omnibase_infra/nodes/architecture_validator/mixins/__init__.py +16 -0
  346. omnibase_infra/nodes/architecture_validator/mixins/mixin_file_path_rule.py +92 -0
  347. omnibase_infra/nodes/architecture_validator/models/__init__.py +36 -0
  348. omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_request.py +56 -0
  349. omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_result.py +311 -0
  350. omnibase_infra/nodes/architecture_validator/models/model_architecture_violation.py +163 -0
  351. omnibase_infra/nodes/architecture_validator/models/model_rule_check_result.py +265 -0
  352. omnibase_infra/nodes/architecture_validator/models/model_validation_request.py +105 -0
  353. omnibase_infra/nodes/architecture_validator/models/model_validation_result.py +314 -0
  354. omnibase_infra/nodes/architecture_validator/node.py +262 -0
  355. omnibase_infra/nodes/architecture_validator/node_architecture_validator.py +383 -0
  356. omnibase_infra/nodes/architecture_validator/protocols/__init__.py +9 -0
  357. omnibase_infra/nodes/architecture_validator/protocols/protocol_architecture_rule.py +225 -0
  358. omnibase_infra/nodes/architecture_validator/registry/__init__.py +28 -0
  359. omnibase_infra/nodes/architecture_validator/registry/registry_infra_architecture_validator.py +99 -0
  360. omnibase_infra/nodes/architecture_validator/validators/__init__.py +104 -0
  361. omnibase_infra/nodes/architecture_validator/validators/validator_no_direct_dispatch.py +422 -0
  362. omnibase_infra/nodes/architecture_validator/validators/validator_no_handler_publishing.py +481 -0
  363. omnibase_infra/nodes/architecture_validator/validators/validator_no_orchestrator_fsm.py +491 -0
  364. omnibase_infra/nodes/effects/README.md +358 -0
  365. omnibase_infra/nodes/effects/__init__.py +26 -0
  366. omnibase_infra/nodes/effects/contract.yaml +172 -0
  367. omnibase_infra/nodes/effects/models/__init__.py +32 -0
  368. omnibase_infra/nodes/effects/models/model_backend_result.py +190 -0
  369. omnibase_infra/nodes/effects/models/model_effect_idempotency_config.py +92 -0
  370. omnibase_infra/nodes/effects/models/model_registry_request.py +132 -0
  371. omnibase_infra/nodes/effects/models/model_registry_response.py +263 -0
  372. omnibase_infra/nodes/effects/protocol_consul_client.py +89 -0
  373. omnibase_infra/nodes/effects/protocol_effect_idempotency_store.py +143 -0
  374. omnibase_infra/nodes/effects/protocol_postgres_adapter.py +96 -0
  375. omnibase_infra/nodes/effects/registry_effect.py +525 -0
  376. omnibase_infra/nodes/effects/store_effect_idempotency_inmemory.py +425 -0
  377. omnibase_infra/nodes/node_registration_orchestrator/README.md +542 -0
  378. omnibase_infra/nodes/node_registration_orchestrator/__init__.py +120 -0
  379. omnibase_infra/nodes/node_registration_orchestrator/contract.yaml +475 -0
  380. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/__init__.py +53 -0
  381. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_introspected.py +376 -0
  382. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_registration_acked.py +376 -0
  383. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_runtime_tick.py +373 -0
  384. omnibase_infra/nodes/node_registration_orchestrator/handlers/__init__.py +62 -0
  385. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_heartbeat.py +376 -0
  386. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_introspected.py +609 -0
  387. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_registration_acked.py +458 -0
  388. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_runtime_tick.py +364 -0
  389. omnibase_infra/nodes/node_registration_orchestrator/introspection_event_router.py +544 -0
  390. omnibase_infra/nodes/node_registration_orchestrator/models/__init__.py +75 -0
  391. omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_intent_payload.py +194 -0
  392. omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_registration_intent.py +67 -0
  393. omnibase_infra/nodes/node_registration_orchestrator/models/model_intent_execution_result.py +50 -0
  394. omnibase_infra/nodes/node_registration_orchestrator/models/model_node_liveness_expired.py +107 -0
  395. omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_config.py +67 -0
  396. omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_input.py +41 -0
  397. omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_output.py +166 -0
  398. omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_intent_payload.py +235 -0
  399. omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_upsert_intent.py +68 -0
  400. omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_execution_result.py +384 -0
  401. omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_state.py +60 -0
  402. omnibase_infra/nodes/node_registration_orchestrator/models/model_registration_intent.py +177 -0
  403. omnibase_infra/nodes/node_registration_orchestrator/models/model_registry_intent.py +247 -0
  404. omnibase_infra/nodes/node_registration_orchestrator/node.py +195 -0
  405. omnibase_infra/nodes/node_registration_orchestrator/plugin.py +909 -0
  406. omnibase_infra/nodes/node_registration_orchestrator/protocols.py +439 -0
  407. omnibase_infra/nodes/node_registration_orchestrator/registry/__init__.py +41 -0
  408. omnibase_infra/nodes/node_registration_orchestrator/registry/registry_infra_node_registration_orchestrator.py +525 -0
  409. omnibase_infra/nodes/node_registration_orchestrator/timeout_coordinator.py +392 -0
  410. omnibase_infra/nodes/node_registration_orchestrator/wiring.py +742 -0
  411. omnibase_infra/nodes/node_registration_reducer/__init__.py +15 -0
  412. omnibase_infra/nodes/node_registration_reducer/contract.yaml +301 -0
  413. omnibase_infra/nodes/node_registration_reducer/models/__init__.py +38 -0
  414. omnibase_infra/nodes/node_registration_reducer/models/model_validation_result.py +113 -0
  415. omnibase_infra/nodes/node_registration_reducer/node.py +139 -0
  416. omnibase_infra/nodes/node_registration_reducer/registry/__init__.py +9 -0
  417. omnibase_infra/nodes/node_registration_reducer/registry/registry_infra_node_registration_reducer.py +79 -0
  418. omnibase_infra/nodes/node_registration_storage_effect/__init__.py +41 -0
  419. omnibase_infra/nodes/node_registration_storage_effect/contract.yaml +225 -0
  420. omnibase_infra/nodes/node_registration_storage_effect/models/__init__.py +44 -0
  421. omnibase_infra/nodes/node_registration_storage_effect/models/model_delete_result.py +132 -0
  422. omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_record.py +199 -0
  423. omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_update.py +155 -0
  424. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_details.py +123 -0
  425. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_result.py +117 -0
  426. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_query.py +100 -0
  427. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_result.py +136 -0
  428. omnibase_infra/nodes/node_registration_storage_effect/models/model_upsert_result.py +127 -0
  429. omnibase_infra/nodes/node_registration_storage_effect/node.py +109 -0
  430. omnibase_infra/nodes/node_registration_storage_effect/protocols/__init__.py +22 -0
  431. omnibase_infra/nodes/node_registration_storage_effect/protocols/protocol_registration_persistence.py +333 -0
  432. omnibase_infra/nodes/node_registration_storage_effect/registry/__init__.py +23 -0
  433. omnibase_infra/nodes/node_registration_storage_effect/registry/registry_infra_registration_storage.py +194 -0
  434. omnibase_infra/nodes/node_registry_effect/__init__.py +85 -0
  435. omnibase_infra/nodes/node_registry_effect/contract.yaml +682 -0
  436. omnibase_infra/nodes/node_registry_effect/handlers/__init__.py +70 -0
  437. omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_deregister.py +211 -0
  438. omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_register.py +212 -0
  439. omnibase_infra/nodes/node_registry_effect/handlers/handler_partial_retry.py +416 -0
  440. omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_deactivate.py +215 -0
  441. omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_upsert.py +208 -0
  442. omnibase_infra/nodes/node_registry_effect/models/__init__.py +43 -0
  443. omnibase_infra/nodes/node_registry_effect/models/model_partial_retry_request.py +92 -0
  444. omnibase_infra/nodes/node_registry_effect/node.py +165 -0
  445. omnibase_infra/nodes/node_registry_effect/registry/__init__.py +27 -0
  446. omnibase_infra/nodes/node_registry_effect/registry/registry_infra_registry_effect.py +196 -0
  447. omnibase_infra/nodes/node_service_discovery_effect/__init__.py +111 -0
  448. omnibase_infra/nodes/node_service_discovery_effect/contract.yaml +246 -0
  449. omnibase_infra/nodes/node_service_discovery_effect/models/__init__.py +67 -0
  450. omnibase_infra/nodes/node_service_discovery_effect/models/enum_health_status.py +72 -0
  451. omnibase_infra/nodes/node_service_discovery_effect/models/enum_service_discovery_operation.py +58 -0
  452. omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_query.py +99 -0
  453. omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_result.py +98 -0
  454. omnibase_infra/nodes/node_service_discovery_effect/models/model_health_check_config.py +121 -0
  455. omnibase_infra/nodes/node_service_discovery_effect/models/model_query_metadata.py +63 -0
  456. omnibase_infra/nodes/node_service_discovery_effect/models/model_registration_result.py +130 -0
  457. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_details.py +111 -0
  458. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_result.py +119 -0
  459. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_info.py +106 -0
  460. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_registration.py +121 -0
  461. omnibase_infra/nodes/node_service_discovery_effect/node.py +111 -0
  462. omnibase_infra/nodes/node_service_discovery_effect/protocols/__init__.py +14 -0
  463. omnibase_infra/nodes/node_service_discovery_effect/protocols/protocol_discovery_operations.py +279 -0
  464. omnibase_infra/nodes/node_service_discovery_effect/registry/__init__.py +13 -0
  465. omnibase_infra/nodes/node_service_discovery_effect/registry/registry_infra_service_discovery.py +214 -0
  466. omnibase_infra/nodes/reducers/__init__.py +30 -0
  467. omnibase_infra/nodes/reducers/models/__init__.py +32 -0
  468. omnibase_infra/nodes/reducers/models/model_payload_consul_register.py +76 -0
  469. omnibase_infra/nodes/reducers/models/model_payload_postgres_upsert_registration.py +60 -0
  470. omnibase_infra/nodes/reducers/models/model_registration_confirmation.py +166 -0
  471. omnibase_infra/nodes/reducers/models/model_registration_state.py +433 -0
  472. omnibase_infra/nodes/reducers/registration_reducer.py +1137 -0
  473. omnibase_infra/observability/__init__.py +143 -0
  474. omnibase_infra/observability/constants_metrics.py +91 -0
  475. omnibase_infra/observability/factory_observability_sink.py +525 -0
  476. omnibase_infra/observability/handlers/__init__.py +118 -0
  477. omnibase_infra/observability/handlers/handler_logging_structured.py +967 -0
  478. omnibase_infra/observability/handlers/handler_metrics_prometheus.py +1120 -0
  479. omnibase_infra/observability/handlers/model_logging_handler_config.py +71 -0
  480. omnibase_infra/observability/handlers/model_logging_handler_response.py +77 -0
  481. omnibase_infra/observability/handlers/model_metrics_handler_config.py +172 -0
  482. omnibase_infra/observability/handlers/model_metrics_handler_payload.py +135 -0
  483. omnibase_infra/observability/handlers/model_metrics_handler_response.py +101 -0
  484. omnibase_infra/observability/hooks/__init__.py +74 -0
  485. omnibase_infra/observability/hooks/hook_observability.py +1223 -0
  486. omnibase_infra/observability/models/__init__.py +30 -0
  487. omnibase_infra/observability/models/enum_required_log_context_key.py +77 -0
  488. omnibase_infra/observability/models/model_buffered_log_entry.py +117 -0
  489. omnibase_infra/observability/models/model_logging_sink_config.py +73 -0
  490. omnibase_infra/observability/models/model_metrics_sink_config.py +156 -0
  491. omnibase_infra/observability/sinks/__init__.py +69 -0
  492. omnibase_infra/observability/sinks/sink_logging_structured.py +809 -0
  493. omnibase_infra/observability/sinks/sink_metrics_prometheus.py +710 -0
  494. omnibase_infra/plugins/__init__.py +27 -0
  495. omnibase_infra/plugins/examples/__init__.py +28 -0
  496. omnibase_infra/plugins/examples/plugin_json_normalizer.py +271 -0
  497. omnibase_infra/plugins/examples/plugin_json_normalizer_error_handling.py +210 -0
  498. omnibase_infra/plugins/models/__init__.py +21 -0
  499. omnibase_infra/plugins/models/model_plugin_context.py +76 -0
  500. omnibase_infra/plugins/models/model_plugin_input_data.py +58 -0
  501. omnibase_infra/plugins/models/model_plugin_output_data.py +62 -0
  502. omnibase_infra/plugins/plugin_compute_base.py +435 -0
  503. omnibase_infra/projectors/__init__.py +30 -0
  504. omnibase_infra/projectors/contracts/__init__.py +63 -0
  505. omnibase_infra/projectors/contracts/registration_projector.yaml +370 -0
  506. omnibase_infra/projectors/projection_reader_registration.py +1559 -0
  507. omnibase_infra/projectors/snapshot_publisher_registration.py +1329 -0
  508. omnibase_infra/protocols/__init__.py +99 -0
  509. omnibase_infra/protocols/protocol_capability_projection.py +253 -0
  510. omnibase_infra/protocols/protocol_capability_query.py +251 -0
  511. omnibase_infra/protocols/protocol_event_bus_like.py +127 -0
  512. omnibase_infra/protocols/protocol_event_projector.py +96 -0
  513. omnibase_infra/protocols/protocol_idempotency_store.py +142 -0
  514. omnibase_infra/protocols/protocol_message_dispatcher.py +247 -0
  515. omnibase_infra/protocols/protocol_message_type_registry.py +306 -0
  516. omnibase_infra/protocols/protocol_plugin_compute.py +368 -0
  517. omnibase_infra/protocols/protocol_projector_schema_validator.py +82 -0
  518. omnibase_infra/protocols/protocol_registry_metrics.py +215 -0
  519. omnibase_infra/protocols/protocol_snapshot_publisher.py +396 -0
  520. omnibase_infra/protocols/protocol_snapshot_store.py +567 -0
  521. omnibase_infra/runtime/__init__.py +296 -0
  522. omnibase_infra/runtime/binding_config_resolver.py +2706 -0
  523. omnibase_infra/runtime/chain_aware_dispatch.py +467 -0
  524. omnibase_infra/runtime/contract_handler_discovery.py +582 -0
  525. omnibase_infra/runtime/contract_loaders/__init__.py +42 -0
  526. omnibase_infra/runtime/contract_loaders/handler_routing_loader.py +464 -0
  527. omnibase_infra/runtime/dispatch_context_enforcer.py +427 -0
  528. omnibase_infra/runtime/enums/__init__.py +18 -0
  529. omnibase_infra/runtime/enums/enum_config_ref_scheme.py +33 -0
  530. omnibase_infra/runtime/enums/enum_scheduler_status.py +170 -0
  531. omnibase_infra/runtime/envelope_validator.py +179 -0
  532. omnibase_infra/runtime/handler_contract_source.py +669 -0
  533. omnibase_infra/runtime/handler_plugin_loader.py +2029 -0
  534. omnibase_infra/runtime/handler_registry.py +321 -0
  535. omnibase_infra/runtime/invocation_security_enforcer.py +427 -0
  536. omnibase_infra/runtime/kernel.py +40 -0
  537. omnibase_infra/runtime/mixin_policy_validation.py +522 -0
  538. omnibase_infra/runtime/mixin_semver_cache.py +378 -0
  539. omnibase_infra/runtime/mixins/__init__.py +17 -0
  540. omnibase_infra/runtime/mixins/mixin_projector_sql_operations.py +757 -0
  541. omnibase_infra/runtime/models/__init__.py +192 -0
  542. omnibase_infra/runtime/models/model_batch_lifecycle_result.py +217 -0
  543. omnibase_infra/runtime/models/model_binding_config.py +168 -0
  544. omnibase_infra/runtime/models/model_binding_config_cache_stats.py +135 -0
  545. omnibase_infra/runtime/models/model_binding_config_resolver_config.py +329 -0
  546. omnibase_infra/runtime/models/model_cached_secret.py +138 -0
  547. omnibase_infra/runtime/models/model_compute_key.py +138 -0
  548. omnibase_infra/runtime/models/model_compute_registration.py +97 -0
  549. omnibase_infra/runtime/models/model_config_cache_entry.py +61 -0
  550. omnibase_infra/runtime/models/model_config_ref.py +331 -0
  551. omnibase_infra/runtime/models/model_config_ref_parse_result.py +125 -0
  552. omnibase_infra/runtime/models/model_domain_plugin_config.py +92 -0
  553. omnibase_infra/runtime/models/model_domain_plugin_result.py +270 -0
  554. omnibase_infra/runtime/models/model_duplicate_response.py +54 -0
  555. omnibase_infra/runtime/models/model_enabled_protocols_config.py +61 -0
  556. omnibase_infra/runtime/models/model_event_bus_config.py +54 -0
  557. omnibase_infra/runtime/models/model_failed_component.py +55 -0
  558. omnibase_infra/runtime/models/model_health_check_response.py +168 -0
  559. omnibase_infra/runtime/models/model_health_check_result.py +228 -0
  560. omnibase_infra/runtime/models/model_lifecycle_result.py +245 -0
  561. omnibase_infra/runtime/models/model_logging_config.py +42 -0
  562. omnibase_infra/runtime/models/model_optional_correlation_id.py +167 -0
  563. omnibase_infra/runtime/models/model_optional_string.py +94 -0
  564. omnibase_infra/runtime/models/model_optional_uuid.py +110 -0
  565. omnibase_infra/runtime/models/model_policy_context.py +100 -0
  566. omnibase_infra/runtime/models/model_policy_key.py +138 -0
  567. omnibase_infra/runtime/models/model_policy_registration.py +139 -0
  568. omnibase_infra/runtime/models/model_policy_result.py +103 -0
  569. omnibase_infra/runtime/models/model_policy_type_filter.py +157 -0
  570. omnibase_infra/runtime/models/model_projector_plugin_loader_config.py +47 -0
  571. omnibase_infra/runtime/models/model_protocol_registration_config.py +65 -0
  572. omnibase_infra/runtime/models/model_retry_policy.py +105 -0
  573. omnibase_infra/runtime/models/model_runtime_config.py +150 -0
  574. omnibase_infra/runtime/models/model_runtime_scheduler_config.py +624 -0
  575. omnibase_infra/runtime/models/model_runtime_scheduler_metrics.py +233 -0
  576. omnibase_infra/runtime/models/model_runtime_tick.py +193 -0
  577. omnibase_infra/runtime/models/model_secret_cache_stats.py +82 -0
  578. omnibase_infra/runtime/models/model_secret_mapping.py +63 -0
  579. omnibase_infra/runtime/models/model_secret_resolver_config.py +107 -0
  580. omnibase_infra/runtime/models/model_secret_resolver_metrics.py +111 -0
  581. omnibase_infra/runtime/models/model_secret_source_info.py +72 -0
  582. omnibase_infra/runtime/models/model_secret_source_spec.py +66 -0
  583. omnibase_infra/runtime/models/model_shutdown_batch_result.py +75 -0
  584. omnibase_infra/runtime/models/model_shutdown_config.py +94 -0
  585. omnibase_infra/runtime/projector_plugin_loader.py +1462 -0
  586. omnibase_infra/runtime/projector_schema_manager.py +565 -0
  587. omnibase_infra/runtime/projector_shell.py +1102 -0
  588. omnibase_infra/runtime/protocol_contract_descriptor.py +92 -0
  589. omnibase_infra/runtime/protocol_contract_source.py +92 -0
  590. omnibase_infra/runtime/protocol_domain_plugin.py +474 -0
  591. omnibase_infra/runtime/protocol_handler_discovery.py +221 -0
  592. omnibase_infra/runtime/protocol_handler_plugin_loader.py +327 -0
  593. omnibase_infra/runtime/protocol_lifecycle_executor.py +435 -0
  594. omnibase_infra/runtime/protocol_policy.py +366 -0
  595. omnibase_infra/runtime/protocols/__init__.py +27 -0
  596. omnibase_infra/runtime/protocols/protocol_runtime_scheduler.py +468 -0
  597. omnibase_infra/runtime/registry/__init__.py +93 -0
  598. omnibase_infra/runtime/registry/mixin_message_type_query.py +326 -0
  599. omnibase_infra/runtime/registry/mixin_message_type_registration.py +354 -0
  600. omnibase_infra/runtime/registry/registry_event_bus_binding.py +268 -0
  601. omnibase_infra/runtime/registry/registry_message_type.py +542 -0
  602. omnibase_infra/runtime/registry/registry_protocol_binding.py +444 -0
  603. omnibase_infra/runtime/registry_compute.py +1143 -0
  604. omnibase_infra/runtime/registry_dispatcher.py +678 -0
  605. omnibase_infra/runtime/registry_policy.py +1502 -0
  606. omnibase_infra/runtime/runtime_scheduler.py +1070 -0
  607. omnibase_infra/runtime/secret_resolver.py +2110 -0
  608. omnibase_infra/runtime/security_metadata_validator.py +776 -0
  609. omnibase_infra/runtime/service_kernel.py +1573 -0
  610. omnibase_infra/runtime/service_message_dispatch_engine.py +1805 -0
  611. omnibase_infra/runtime/service_runtime_host_process.py +2260 -0
  612. omnibase_infra/runtime/util_container_wiring.py +1123 -0
  613. omnibase_infra/runtime/util_validation.py +314 -0
  614. omnibase_infra/runtime/util_version.py +98 -0
  615. omnibase_infra/runtime/util_wiring.py +566 -0
  616. omnibase_infra/schemas/schema_registration_projection.sql +320 -0
  617. omnibase_infra/services/__init__.py +68 -0
  618. omnibase_infra/services/corpus_capture.py +678 -0
  619. omnibase_infra/services/service_capability_query.py +945 -0
  620. omnibase_infra/services/service_health.py +897 -0
  621. omnibase_infra/services/service_node_selector.py +530 -0
  622. omnibase_infra/services/service_timeout_emitter.py +682 -0
  623. omnibase_infra/services/service_timeout_scanner.py +390 -0
  624. omnibase_infra/services/snapshot/__init__.py +31 -0
  625. omnibase_infra/services/snapshot/service_snapshot.py +647 -0
  626. omnibase_infra/services/snapshot/store_inmemory.py +637 -0
  627. omnibase_infra/services/snapshot/store_postgres.py +1279 -0
  628. omnibase_infra/shared/__init__.py +8 -0
  629. omnibase_infra/testing/__init__.py +10 -0
  630. omnibase_infra/testing/utils.py +23 -0
  631. omnibase_infra/types/__init__.py +48 -0
  632. omnibase_infra/types/type_cache_info.py +49 -0
  633. omnibase_infra/types/type_dsn.py +173 -0
  634. omnibase_infra/types/type_infra_aliases.py +60 -0
  635. omnibase_infra/types/typed_dict/__init__.py +21 -0
  636. omnibase_infra/types/typed_dict/typed_dict_introspection_cache.py +128 -0
  637. omnibase_infra/types/typed_dict/typed_dict_performance_metrics_cache.py +140 -0
  638. omnibase_infra/types/typed_dict_capabilities.py +64 -0
  639. omnibase_infra/utils/__init__.py +89 -0
  640. omnibase_infra/utils/correlation.py +208 -0
  641. omnibase_infra/utils/util_datetime.py +372 -0
  642. omnibase_infra/utils/util_dsn_validation.py +333 -0
  643. omnibase_infra/utils/util_env_parsing.py +264 -0
  644. omnibase_infra/utils/util_error_sanitization.py +457 -0
  645. omnibase_infra/utils/util_pydantic_validators.py +477 -0
  646. omnibase_infra/utils/util_semver.py +233 -0
  647. omnibase_infra/validation/__init__.py +307 -0
  648. omnibase_infra/validation/enums/__init__.py +11 -0
  649. omnibase_infra/validation/enums/enum_contract_violation_severity.py +13 -0
  650. omnibase_infra/validation/infra_validators.py +1486 -0
  651. omnibase_infra/validation/linter_contract.py +907 -0
  652. omnibase_infra/validation/mixin_any_type_classification.py +120 -0
  653. omnibase_infra/validation/mixin_any_type_exemption.py +580 -0
  654. omnibase_infra/validation/mixin_any_type_reporting.py +106 -0
  655. omnibase_infra/validation/mixin_execution_shape_violation_checks.py +596 -0
  656. omnibase_infra/validation/mixin_node_archetype_detection.py +254 -0
  657. omnibase_infra/validation/models/__init__.py +15 -0
  658. omnibase_infra/validation/models/model_contract_lint_result.py +101 -0
  659. omnibase_infra/validation/models/model_contract_violation.py +41 -0
  660. omnibase_infra/validation/service_validation_aggregator.py +395 -0
  661. omnibase_infra/validation/validation_exemptions.yaml +1710 -0
  662. omnibase_infra/validation/validator_any_type.py +715 -0
  663. omnibase_infra/validation/validator_chain_propagation.py +839 -0
  664. omnibase_infra/validation/validator_execution_shape.py +465 -0
  665. omnibase_infra/validation/validator_localhandler.py +261 -0
  666. omnibase_infra/validation/validator_registration_security.py +410 -0
  667. omnibase_infra/validation/validator_routing_coverage.py +1020 -0
  668. omnibase_infra/validation/validator_runtime_shape.py +915 -0
  669. omnibase_infra/validation/validator_security.py +410 -0
  670. omnibase_infra/validation/validator_topic_category.py +1152 -0
  671. omnibase_infra-0.2.1.dist-info/METADATA +197 -0
  672. omnibase_infra-0.2.1.dist-info/RECORD +675 -0
  673. omnibase_infra-0.2.1.dist-info/WHEEL +4 -0
  674. omnibase_infra-0.2.1.dist-info/entry_points.txt +4 -0
  675. omnibase_infra-0.2.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,747 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Consul Service Discovery Handler.
4
+
5
+ This module provides a Consul-backed implementation of the service discovery
6
+ handler protocol, wrapping existing Consul functionality with circuit breaker
7
+ resilience.
8
+
9
+ Thread Pool Management:
10
+ - All synchronous consul operations run in a dedicated thread pool
11
+ - Configurable max workers (default: 10)
12
+ - Thread pool is lazily initialized on first use
13
+ - Thread pool gracefully shutdown on handler shutdown
14
+
15
+ Circuit Breaker:
16
+ - Uses MixinAsyncCircuitBreaker for consistent resilience
17
+ - Three states: CLOSED (normal), OPEN (blocking), HALF_OPEN (testing)
18
+ - Configurable via ModelCircuitBreakerConfig model
19
+ """
20
+
21
+ from __future__ import annotations
22
+
23
+ import asyncio
24
+ import logging
25
+ import time
26
+ from concurrent.futures import ThreadPoolExecutor
27
+ from datetime import UTC, datetime
28
+ from typing import TYPE_CHECKING, cast
29
+ from uuid import NAMESPACE_DNS, UUID, uuid4, uuid5
30
+
31
+ import consul
32
+
33
+ from omnibase_infra.enums import EnumInfraTransportType
34
+ from omnibase_infra.errors import (
35
+ InfraConnectionError,
36
+ InfraTimeoutError,
37
+ ModelInfraErrorContext,
38
+ ModelTimeoutErrorContext,
39
+ )
40
+ from omnibase_infra.handlers.service_discovery.models import (
41
+ ModelDiscoveryResult,
42
+ ModelHandlerRegistrationResult,
43
+ ModelServiceInfo,
44
+ )
45
+ from omnibase_infra.mixins import MixinAsyncCircuitBreaker
46
+ from omnibase_infra.models.resilience import ModelCircuitBreakerConfig
47
+ from omnibase_infra.nodes.node_service_discovery_effect.models import (
48
+ ModelDiscoveryQuery,
49
+ ModelServiceDiscoveryHealthCheckDetails,
50
+ ModelServiceDiscoveryHealthCheckResult,
51
+ )
52
+ from omnibase_infra.nodes.node_service_discovery_effect.models.enum_health_status import (
53
+ EnumHealthStatus,
54
+ )
55
+ from omnibase_infra.nodes.node_service_discovery_effect.models.enum_service_discovery_operation import (
56
+ EnumServiceDiscoveryOperation,
57
+ )
58
+
59
+ if TYPE_CHECKING:
60
+ from omnibase_infra.nodes.effects.protocol_consul_client import ProtocolConsulClient
61
+
62
+ logger = logging.getLogger(__name__)
63
+
64
+ # Default configuration values
65
+ DEFAULT_MAX_WORKERS = 10
66
+ DEFAULT_TIMEOUT_SECONDS = 30.0
67
+
68
+ # Custom namespace for ONEX service IDs (deterministic but distinct from DNS namespace)
69
+ # This ensures UUID5 generation for non-UUID service IDs is specific to ONEX
70
+ # and won't collide with DNS-based UUID5 values from other systems.
71
+ NAMESPACE_ONEX_SERVICE = uuid5(NAMESPACE_DNS, "omninode.service.discovery")
72
+
73
+
74
+ class HandlerServiceDiscoveryConsul(MixinAsyncCircuitBreaker):
75
+ """Consul implementation of ProtocolServiceDiscoveryHandler.
76
+
77
+ Wraps existing Consul client functionality with circuit breaker resilience
78
+ and proper error handling.
79
+
80
+ Thread Safety:
81
+ This handler is coroutine-safe. All Consul operations are executed
82
+ in a dedicated thread pool, and circuit breaker state is protected
83
+ by asyncio.Lock.
84
+
85
+ Thread Pool Initialization:
86
+ The thread pool executor is lazily initialized on first use via
87
+ ``_ensure_executor()``. This avoids resource allocation until the
88
+ handler is actually used.
89
+
90
+ Attributes:
91
+ handler_type: Returns "consul" identifier.
92
+
93
+ Example:
94
+ >>> handler = HandlerServiceDiscoveryConsul(
95
+ ... consul_client=consul_client,
96
+ ... circuit_breaker_config=ModelCircuitBreakerConfig(threshold=5),
97
+ ... )
98
+ >>> result = await handler.register_service(service_info)
99
+ """
100
+
101
+ def __init__(
102
+ self,
103
+ consul_client: ProtocolConsulClient | None = None,
104
+ consul_host: str = "localhost",
105
+ consul_port: int = 8500,
106
+ consul_scheme: str = "http",
107
+ consul_token: str | None = None,
108
+ circuit_breaker_config: ModelCircuitBreakerConfig
109
+ | dict[str, object]
110
+ | None = None,
111
+ max_workers: int = DEFAULT_MAX_WORKERS,
112
+ timeout_seconds: float = DEFAULT_TIMEOUT_SECONDS,
113
+ ) -> None:
114
+ """Initialize HandlerServiceDiscoveryConsul.
115
+
116
+ Args:
117
+ consul_client: Optional existing Consul client (ProtocolConsulClient).
118
+ If not provided, a new python-consul client will be created.
119
+ consul_host: Consul server hostname (default: "localhost").
120
+ consul_port: Consul server port (default: 8500).
121
+ consul_scheme: HTTP scheme "http" or "https" (default: "http").
122
+ consul_token: Optional Consul ACL token.
123
+ circuit_breaker_config: Optional circuit breaker configuration.
124
+ Can be a ModelCircuitBreakerConfig instance or a dict with keys:
125
+ - threshold: Max failures before opening (default: 5)
126
+ - reset_timeout_seconds: Seconds before reset (default: 60.0)
127
+ - service_name: Service identifier (default: "consul.discovery")
128
+ If not provided, uses ModelCircuitBreakerConfig defaults.
129
+ max_workers: Thread pool max workers (default: 10).
130
+ timeout_seconds: Operation timeout in seconds (default: 30.0).
131
+ """
132
+ # Parse circuit breaker configuration using ModelCircuitBreakerConfig
133
+ if isinstance(circuit_breaker_config, ModelCircuitBreakerConfig):
134
+ cb_config = circuit_breaker_config
135
+ elif circuit_breaker_config is not None:
136
+ # Handle legacy dict format with key mapping
137
+ config_dict = dict(circuit_breaker_config)
138
+ # Map legacy 'reset_timeout' key to 'reset_timeout_seconds'
139
+ if (
140
+ "reset_timeout" in config_dict
141
+ and "reset_timeout_seconds" not in config_dict
142
+ ):
143
+ config_dict["reset_timeout_seconds"] = config_dict.pop("reset_timeout")
144
+ # Set defaults for service_name and transport_type if not provided
145
+ config_dict.setdefault("service_name", "consul.discovery")
146
+ config_dict.setdefault("transport_type", EnumInfraTransportType.CONSUL)
147
+ cb_config = ModelCircuitBreakerConfig(**config_dict)
148
+ else:
149
+ cb_config = ModelCircuitBreakerConfig(
150
+ service_name="consul.discovery",
151
+ transport_type=EnumInfraTransportType.CONSUL,
152
+ )
153
+
154
+ self._init_circuit_breaker(
155
+ threshold=cb_config.threshold,
156
+ reset_timeout=cb_config.reset_timeout_seconds,
157
+ service_name=cb_config.service_name,
158
+ transport_type=cb_config.transport_type,
159
+ )
160
+
161
+ # Store configuration
162
+ self._consul_host = consul_host
163
+ self._consul_port = consul_port
164
+ self._consul_scheme = consul_scheme
165
+ self._consul_token = consul_token
166
+ self._timeout_seconds = timeout_seconds
167
+
168
+ # Initialize Consul client
169
+ # Note: We use consul.Consul type since that's what we create internally.
170
+ # External clients are expected to duck-type as consul.Consul.
171
+ self._consul_client: consul.Consul | None
172
+ if consul_client is not None:
173
+ # Use provided client (duck-typed ProtocolConsulClient)
174
+ self._consul_client = consul_client
175
+ self._owns_client = False
176
+ else:
177
+ # Create python-consul client
178
+ self._consul_client = consul.Consul(
179
+ host=consul_host,
180
+ port=consul_port,
181
+ scheme=consul_scheme,
182
+ token=consul_token,
183
+ )
184
+ self._owns_client = True
185
+
186
+ # Lazy thread pool initialization
187
+ self._executor: ThreadPoolExecutor | None = None
188
+ self._executor_lock = asyncio.Lock()
189
+ self._max_workers = max_workers
190
+
191
+ logger.info(
192
+ "HandlerServiceDiscoveryConsul initialized",
193
+ extra={
194
+ "consul_host": consul_host,
195
+ "consul_port": consul_port,
196
+ "max_workers": max_workers,
197
+ },
198
+ )
199
+
200
+ @property
201
+ def handler_type(self) -> str:
202
+ """Return the handler type identifier.
203
+
204
+ Returns:
205
+ "consul" identifier string.
206
+ """
207
+ return "consul"
208
+
209
+ async def _ensure_executor(self) -> ThreadPoolExecutor:
210
+ """Ensure thread pool executor is initialized.
211
+
212
+ Uses double-checked locking for thread-safe lazy initialization.
213
+ The executor is created on first use rather than at handler
214
+ construction time to avoid allocating resources for handlers
215
+ that may never be used.
216
+
217
+ Returns:
218
+ The ThreadPoolExecutor instance.
219
+ """
220
+ if self._executor is not None:
221
+ return self._executor
222
+
223
+ async with self._executor_lock:
224
+ if self._executor is None:
225
+ self._executor = ThreadPoolExecutor(max_workers=self._max_workers)
226
+ logger.debug(
227
+ "Thread pool executor initialized",
228
+ extra={"max_workers": self._max_workers},
229
+ )
230
+ return self._executor
231
+
232
+ def _check_not_shutdown(
233
+ self,
234
+ operation: str,
235
+ correlation_id: UUID,
236
+ ) -> None:
237
+ """Check that handler has not been shut down.
238
+
239
+ Args:
240
+ operation: Name of the operation being attempted.
241
+ correlation_id: Correlation ID for tracing.
242
+
243
+ Raises:
244
+ InfraConnectionError: If handler has been shut down.
245
+ """
246
+ if self._consul_client is None:
247
+ context = ModelInfraErrorContext(
248
+ transport_type=EnumInfraTransportType.CONSUL,
249
+ operation=operation,
250
+ target_name="consul.discovery",
251
+ correlation_id=correlation_id,
252
+ )
253
+ raise InfraConnectionError(
254
+ "Handler has been shut down, cannot perform operation",
255
+ context=context,
256
+ )
257
+
258
+ async def register_service(
259
+ self,
260
+ service_info: ModelServiceInfo,
261
+ correlation_id: UUID | None = None,
262
+ ) -> ModelHandlerRegistrationResult:
263
+ """Register a service with Consul.
264
+
265
+ Args:
266
+ service_info: Service information to register.
267
+ correlation_id: Optional correlation ID for tracing.
268
+
269
+ Returns:
270
+ ModelHandlerRegistrationResult with registration outcome.
271
+
272
+ Raises:
273
+ InfraConnectionError: If connection to Consul fails.
274
+ InfraTimeoutError: If operation times out.
275
+ InfraUnavailableError: If circuit breaker is open.
276
+ """
277
+ correlation_id = correlation_id or uuid4()
278
+ start_time = time.monotonic()
279
+
280
+ # Guard against use-after-shutdown
281
+ self._check_not_shutdown("register_service", correlation_id)
282
+
283
+ # Check circuit breaker
284
+ async with self._circuit_breaker_lock:
285
+ await self._check_circuit_breaker(
286
+ operation="register_service",
287
+ correlation_id=correlation_id,
288
+ )
289
+
290
+ try:
291
+ # Build health check config if URL provided
292
+ check_config: dict[str, str] | None = None
293
+ if service_info.health_check_url:
294
+ check_config = {
295
+ "http": service_info.health_check_url,
296
+ "interval": "10s",
297
+ "timeout": "5s",
298
+ }
299
+
300
+ # Execute registration in thread pool
301
+ # Client is typed as consul.Consul (duck-typed for injected clients)
302
+ client = self._consul_client
303
+ executor = await self._ensure_executor()
304
+ loop = asyncio.get_running_loop()
305
+ # Convert UUID to string for Consul API compatibility
306
+ service_id_str = str(service_info.service_id)
307
+ await asyncio.wait_for(
308
+ loop.run_in_executor(
309
+ executor,
310
+ # NOTE: client is duck-typed ProtocolConsulClient; mypy cannot verify
311
+ # agent.service.register exists on Optional[Consul] union type.
312
+ lambda: client.agent.service.register( # type: ignore[union-attr] # NOTE: duck-typed client
313
+ name=service_info.service_name,
314
+ service_id=service_id_str,
315
+ address=service_info.address,
316
+ port=service_info.port,
317
+ tags=list(service_info.tags),
318
+ meta=service_info.metadata,
319
+ check=check_config,
320
+ ),
321
+ ),
322
+ timeout=self._timeout_seconds,
323
+ )
324
+
325
+ # Reset circuit breaker on success
326
+ async with self._circuit_breaker_lock:
327
+ await self._reset_circuit_breaker()
328
+
329
+ duration_ms = (time.monotonic() - start_time) * 1000
330
+
331
+ logger.info(
332
+ "Service registered with Consul",
333
+ extra={
334
+ "service_id": service_id_str,
335
+ "service_name": service_info.service_name,
336
+ "duration_ms": duration_ms,
337
+ "correlation_id": str(correlation_id),
338
+ },
339
+ )
340
+
341
+ return ModelHandlerRegistrationResult(
342
+ success=True,
343
+ service_id=service_info.service_id,
344
+ operation=EnumServiceDiscoveryOperation.REGISTER,
345
+ duration_ms=duration_ms,
346
+ backend_type=self.handler_type,
347
+ correlation_id=correlation_id,
348
+ )
349
+
350
+ except TimeoutError as e:
351
+ async with self._circuit_breaker_lock:
352
+ await self._record_circuit_failure(
353
+ operation="register_service",
354
+ correlation_id=correlation_id,
355
+ )
356
+ duration_ms = (time.monotonic() - start_time) * 1000
357
+ raise InfraTimeoutError(
358
+ f"Consul registration timed out after {self._timeout_seconds}s",
359
+ context=ModelTimeoutErrorContext(
360
+ transport_type=EnumInfraTransportType.CONSUL,
361
+ operation="register_service",
362
+ target_name="consul.discovery",
363
+ correlation_id=correlation_id,
364
+ timeout_seconds=self._timeout_seconds,
365
+ ),
366
+ ) from e
367
+
368
+ except consul.ConsulException as e:
369
+ async with self._circuit_breaker_lock:
370
+ await self._record_circuit_failure(
371
+ operation="register_service",
372
+ correlation_id=correlation_id,
373
+ )
374
+ duration_ms = (time.monotonic() - start_time) * 1000
375
+ context = ModelInfraErrorContext(
376
+ transport_type=EnumInfraTransportType.CONSUL,
377
+ operation="register_service",
378
+ target_name="consul.discovery",
379
+ correlation_id=correlation_id,
380
+ )
381
+ raise InfraConnectionError(
382
+ "Consul registration failed",
383
+ context=context,
384
+ ) from e
385
+
386
+ except Exception as e:
387
+ async with self._circuit_breaker_lock:
388
+ await self._record_circuit_failure(
389
+ operation="register_service",
390
+ correlation_id=correlation_id,
391
+ )
392
+ duration_ms = (time.monotonic() - start_time) * 1000
393
+ context = ModelInfraErrorContext(
394
+ transport_type=EnumInfraTransportType.CONSUL,
395
+ operation="register_service",
396
+ target_name="consul.discovery",
397
+ correlation_id=correlation_id,
398
+ )
399
+ raise InfraConnectionError(
400
+ f"Consul registration failed: {type(e).__name__}",
401
+ context=context,
402
+ ) from e
403
+
404
+ async def deregister_service(
405
+ self,
406
+ service_id: UUID,
407
+ correlation_id: UUID | None = None,
408
+ ) -> None:
409
+ """Deregister a service from Consul.
410
+
411
+ Args:
412
+ service_id: UUID of the service to deregister.
413
+ correlation_id: Optional correlation ID for tracing.
414
+
415
+ Raises:
416
+ InfraConnectionError: If connection to Consul fails.
417
+ InfraTimeoutError: If operation times out.
418
+ InfraUnavailableError: If circuit breaker is open.
419
+ """
420
+ correlation_id = correlation_id or uuid4()
421
+ # Convert UUID to string for Consul API
422
+ service_id_str = str(service_id)
423
+
424
+ # Guard against use-after-shutdown
425
+ self._check_not_shutdown("deregister_service", correlation_id)
426
+
427
+ # Check circuit breaker
428
+ async with self._circuit_breaker_lock:
429
+ await self._check_circuit_breaker(
430
+ operation="deregister_service",
431
+ correlation_id=correlation_id,
432
+ )
433
+
434
+ try:
435
+ # Client is typed as consul.Consul (duck-typed for injected clients)
436
+ client = self._consul_client
437
+ executor = await self._ensure_executor()
438
+ loop = asyncio.get_running_loop()
439
+ await asyncio.wait_for(
440
+ loop.run_in_executor(
441
+ executor,
442
+ # NOTE: client is duck-typed ProtocolConsulClient; mypy cannot verify
443
+ # agent.service.deregister exists on Optional[Consul] union type.
444
+ lambda: client.agent.service.deregister(service_id_str), # type: ignore[union-attr] # NOTE: duck-typed client
445
+ ),
446
+ timeout=self._timeout_seconds,
447
+ )
448
+
449
+ # Reset circuit breaker on success
450
+ async with self._circuit_breaker_lock:
451
+ await self._reset_circuit_breaker()
452
+
453
+ logger.info(
454
+ "Service deregistered from Consul",
455
+ extra={
456
+ "service_id": service_id_str,
457
+ "correlation_id": str(correlation_id),
458
+ },
459
+ )
460
+
461
+ except TimeoutError as e:
462
+ async with self._circuit_breaker_lock:
463
+ await self._record_circuit_failure(
464
+ operation="deregister_service",
465
+ correlation_id=correlation_id,
466
+ )
467
+ raise InfraTimeoutError(
468
+ f"Consul deregistration timed out after {self._timeout_seconds}s",
469
+ context=ModelTimeoutErrorContext(
470
+ transport_type=EnumInfraTransportType.CONSUL,
471
+ operation="deregister_service",
472
+ target_name="consul.discovery",
473
+ correlation_id=correlation_id,
474
+ timeout_seconds=self._timeout_seconds,
475
+ ),
476
+ ) from e
477
+
478
+ except consul.ConsulException as e:
479
+ async with self._circuit_breaker_lock:
480
+ await self._record_circuit_failure(
481
+ operation="deregister_service",
482
+ correlation_id=correlation_id,
483
+ )
484
+ context = ModelInfraErrorContext(
485
+ transport_type=EnumInfraTransportType.CONSUL,
486
+ operation="deregister_service",
487
+ target_name="consul.discovery",
488
+ correlation_id=correlation_id,
489
+ )
490
+ raise InfraConnectionError(
491
+ "Consul deregistration failed",
492
+ context=context,
493
+ ) from e
494
+
495
+ async def discover_services(
496
+ self,
497
+ query: ModelDiscoveryQuery,
498
+ correlation_id: UUID | None = None,
499
+ ) -> ModelDiscoveryResult:
500
+ """Discover services matching the query criteria.
501
+
502
+ Args:
503
+ query: Query parameters including service_name, tags,
504
+ and health_filter for filtering services.
505
+ correlation_id: Optional correlation ID for tracing.
506
+ If not provided, uses query.correlation_id, then generates new.
507
+
508
+ Returns:
509
+ ModelDiscoveryResult with list of matching services.
510
+
511
+ Raises:
512
+ InfraConnectionError: If connection to Consul fails.
513
+ InfraTimeoutError: If operation times out.
514
+ InfraUnavailableError: If circuit breaker is open.
515
+
516
+ Note:
517
+ Service IDs from Consul are converted to UUIDs. If the Consul service
518
+ ID is not a valid UUID string, a deterministic UUID5 is generated
519
+ using the ONEX service namespace. This ensures consistent IDs across
520
+ discovery calls while maintaining UUID format compatibility.
521
+ """
522
+ # Standardized correlation ID handling: explicit > query > generate
523
+ correlation_id = correlation_id or query.correlation_id or uuid4()
524
+ service_name = query.service_name or ""
525
+ tags = query.tags
526
+ start_time = time.monotonic()
527
+
528
+ # Guard against use-after-shutdown
529
+ self._check_not_shutdown("discover_services", correlation_id)
530
+
531
+ # Check circuit breaker
532
+ async with self._circuit_breaker_lock:
533
+ await self._check_circuit_breaker(
534
+ operation="discover_services",
535
+ correlation_id=correlation_id,
536
+ )
537
+
538
+ try:
539
+ # Query Consul catalog
540
+ # Client is typed as consul.Consul (duck-typed for injected clients)
541
+ client = self._consul_client
542
+ executor = await self._ensure_executor()
543
+ loop = asyncio.get_running_loop()
544
+
545
+ def _query_services() -> tuple[int, list[dict[str, object]]]:
546
+ # Use health endpoint for service discovery (includes health status)
547
+ tag = tags[0] if tags else None
548
+ # NOTE: client is duck-typed ProtocolConsulClient; mypy cannot verify
549
+ # health.service exists on Optional[Consul] union type.
550
+ result: tuple[int, list[dict[str, object]]] = client.health.service( # type: ignore[union-attr] # NOTE: duck-typed client
551
+ service_name,
552
+ tag=tag,
553
+ passing=True, # Only healthy services
554
+ )
555
+ return result
556
+
557
+ _, services = await asyncio.wait_for(
558
+ loop.run_in_executor(executor, _query_services),
559
+ timeout=self._timeout_seconds,
560
+ )
561
+
562
+ # Reset circuit breaker on success
563
+ async with self._circuit_breaker_lock:
564
+ await self._reset_circuit_breaker()
565
+
566
+ # Convert to ModelServiceInfo list
567
+ service_infos: list[ModelServiceInfo] = []
568
+ for svc in services:
569
+ # Cast nested dicts for type safety
570
+ svc_data = cast(dict[str, object], svc.get("Service", {}))
571
+ node_data = cast(dict[str, object], svc.get("Node", {}))
572
+ svc_id_str = str(svc_data.get("ID", ""))
573
+ svc_name = svc_data.get("Service", "")
574
+ address = svc_data.get("Address", "") or node_data.get("Address", "")
575
+ port_raw = svc_data.get("Port", 0)
576
+ port = int(port_raw) if isinstance(port_raw, int | float | str) else 0
577
+ svc_tags = cast(list[str], svc_data.get("Tags", []))
578
+ svc_meta = cast(dict[str, str], svc_data.get("Meta", {}))
579
+
580
+ if svc_id_str and svc_name and address and port:
581
+ # Convert Consul service ID string to UUID
582
+ # Try to parse as UUID, otherwise generate deterministic UUID from string
583
+ try:
584
+ svc_id = UUID(svc_id_str)
585
+ except ValueError:
586
+ # Non-UUID service ID from Consul - generate deterministic UUID5
587
+ # using ONEX-specific namespace to avoid collisions
588
+ logger.warning(
589
+ "Non-UUID service ID from Consul, using deterministic UUID5 conversion",
590
+ extra={
591
+ "original_id": svc_id_str,
592
+ "correlation_id": str(correlation_id),
593
+ },
594
+ )
595
+ svc_id = uuid5(NAMESPACE_ONEX_SERVICE, svc_id_str)
596
+
597
+ service_infos.append(
598
+ ModelServiceInfo(
599
+ service_id=svc_id,
600
+ service_name=str(svc_name),
601
+ address=str(address),
602
+ port=port,
603
+ tags=tuple(svc_tags or []),
604
+ health_status=EnumHealthStatus.HEALTHY,
605
+ metadata=svc_meta or {},
606
+ registered_at=datetime.now(UTC),
607
+ correlation_id=correlation_id,
608
+ )
609
+ )
610
+
611
+ duration_ms = (time.monotonic() - start_time) * 1000
612
+
613
+ logger.info(
614
+ "Service discovery completed",
615
+ extra={
616
+ "service_name": service_name,
617
+ "found_count": len(service_infos),
618
+ "duration_ms": duration_ms,
619
+ "correlation_id": str(correlation_id),
620
+ },
621
+ )
622
+
623
+ return ModelDiscoveryResult(
624
+ success=True,
625
+ services=tuple(service_infos),
626
+ duration_ms=duration_ms,
627
+ backend_type=self.handler_type,
628
+ correlation_id=correlation_id,
629
+ )
630
+
631
+ except TimeoutError as e:
632
+ async with self._circuit_breaker_lock:
633
+ await self._record_circuit_failure(
634
+ operation="discover_services",
635
+ correlation_id=correlation_id,
636
+ )
637
+ duration_ms = (time.monotonic() - start_time) * 1000
638
+ raise InfraTimeoutError(
639
+ f"Consul discovery timed out after {self._timeout_seconds}s",
640
+ context=ModelTimeoutErrorContext(
641
+ transport_type=EnumInfraTransportType.CONSUL,
642
+ operation="discover_services",
643
+ target_name="consul.discovery",
644
+ correlation_id=correlation_id,
645
+ timeout_seconds=self._timeout_seconds,
646
+ ),
647
+ ) from e
648
+
649
+ except consul.ConsulException as e:
650
+ async with self._circuit_breaker_lock:
651
+ await self._record_circuit_failure(
652
+ operation="discover_services",
653
+ correlation_id=correlation_id,
654
+ )
655
+ duration_ms = (time.monotonic() - start_time) * 1000
656
+ context = ModelInfraErrorContext(
657
+ transport_type=EnumInfraTransportType.CONSUL,
658
+ operation="discover_services",
659
+ target_name="consul.discovery",
660
+ correlation_id=correlation_id,
661
+ )
662
+ raise InfraConnectionError(
663
+ "Consul discovery failed",
664
+ context=context,
665
+ ) from e
666
+
667
+ async def health_check(
668
+ self,
669
+ correlation_id: UUID | None = None,
670
+ ) -> ModelServiceDiscoveryHealthCheckResult:
671
+ """Perform a health check on the Consul connection.
672
+
673
+ Args:
674
+ correlation_id: Optional correlation ID for tracing.
675
+
676
+ Returns:
677
+ ModelServiceDiscoveryHealthCheckResult with health status information.
678
+ """
679
+ correlation_id = correlation_id or uuid4()
680
+ start_time = time.monotonic()
681
+
682
+ # Guard against use-after-shutdown
683
+ self._check_not_shutdown("health_check", correlation_id)
684
+
685
+ try:
686
+ # Client is typed as consul.Consul (duck-typed for injected clients)
687
+ client = self._consul_client
688
+ executor = await self._ensure_executor()
689
+ loop = asyncio.get_running_loop()
690
+ leader = await asyncio.wait_for(
691
+ loop.run_in_executor(
692
+ executor,
693
+ # NOTE: client is duck-typed ProtocolConsulClient; mypy cannot verify
694
+ # status.leader exists on Optional[Consul] union type.
695
+ lambda: client.status.leader(), # type: ignore[union-attr] # NOTE: duck-typed client
696
+ ),
697
+ timeout=5.0, # Short timeout for health check
698
+ )
699
+
700
+ duration_ms = (time.monotonic() - start_time) * 1000
701
+
702
+ return ModelServiceDiscoveryHealthCheckResult(
703
+ healthy=True,
704
+ backend_type=self.handler_type,
705
+ latency_ms=duration_ms,
706
+ reason="ok",
707
+ details=ModelServiceDiscoveryHealthCheckDetails(
708
+ agent_address=f"{self._consul_host}:{self._consul_port}",
709
+ leader=str(leader) if leader else None,
710
+ ),
711
+ correlation_id=correlation_id,
712
+ )
713
+
714
+ except Exception as e:
715
+ duration_ms = (time.monotonic() - start_time) * 1000
716
+ return ModelServiceDiscoveryHealthCheckResult(
717
+ healthy=False,
718
+ backend_type=self.handler_type,
719
+ latency_ms=duration_ms,
720
+ reason=f"Health check failed: {type(e).__name__}",
721
+ error_type=type(e).__name__,
722
+ details=ModelServiceDiscoveryHealthCheckDetails(
723
+ agent_address=f"{self._consul_host}:{self._consul_port}",
724
+ ),
725
+ correlation_id=correlation_id,
726
+ )
727
+
728
+ async def shutdown(self) -> None:
729
+ """Shutdown the handler and release resources.
730
+
731
+ Cleans up:
732
+ - Thread pool executor (always)
733
+ - Consul client (only if handler owns it)
734
+ """
735
+ if self._executor is not None:
736
+ self._executor.shutdown(wait=True)
737
+ self._executor = None
738
+
739
+ # Clean up owned Consul client
740
+ if self._owns_client:
741
+ self._consul_client = None
742
+ self._owns_client = False
743
+
744
+ logger.info("HandlerServiceDiscoveryConsul shutdown complete")
745
+
746
+
747
+ __all__ = ["HandlerServiceDiscoveryConsul"]