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,787 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """HashiCorp Consul Handler - MVP implementation using python-consul client.
4
+
5
+ Supports service discovery operations with configurable retry logic and
6
+ circuit breaker pattern for fault tolerance.
7
+
8
+ Security Features:
9
+ - SecretStr protection for ACL tokens (prevents accidental logging)
10
+ - Sanitized error messages (never expose tokens in logs)
11
+ - Token handling follows security best practices
12
+
13
+ Supported Operations:
14
+ - consul.kv_get: Retrieve value from KV store
15
+ - consul.kv_put: Store value in KV store
16
+ - consul.register: Register service with Consul agent
17
+ - consul.deregister: Deregister service from Consul agent
18
+
19
+ Envelope-Based Routing:
20
+ This handler uses envelope-based operation routing. See CLAUDE.md section
21
+ "Intent Model Architecture > Envelope-Based Handler Routing" for the full
22
+ design pattern and how orchestrators translate intents to handler envelopes.
23
+ """
24
+
25
+ from __future__ import annotations
26
+
27
+ import asyncio
28
+ import logging
29
+ from collections.abc import Callable
30
+ from concurrent.futures import ThreadPoolExecutor
31
+ from typing import NamedTuple, TypeVar
32
+ from uuid import UUID, uuid4
33
+
34
+ import consul
35
+
36
+ from omnibase_core.models.dispatch import ModelHandlerOutput
37
+ from omnibase_infra.enums import (
38
+ EnumHandlerType,
39
+ EnumHandlerTypeCategory,
40
+ EnumInfraTransportType,
41
+ EnumResponseStatus,
42
+ )
43
+ from omnibase_infra.errors import (
44
+ InfraAuthenticationError,
45
+ InfraConnectionError,
46
+ InfraConsulError,
47
+ ModelInfraErrorContext,
48
+ RuntimeHostError,
49
+ )
50
+ from omnibase_infra.handlers.mixins import (
51
+ MixinConsulInitialization,
52
+ MixinConsulKV,
53
+ MixinConsulService,
54
+ )
55
+ from omnibase_infra.handlers.models import (
56
+ ModelOperationContext,
57
+ ModelRetryState,
58
+ )
59
+ from omnibase_infra.handlers.models.consul import (
60
+ ConsulPayload,
61
+ ModelConsulHandlerConfig,
62
+ ModelConsulHandlerPayload,
63
+ )
64
+ from omnibase_infra.handlers.models.model_consul_handler_response import (
65
+ ModelConsulHandlerResponse,
66
+ )
67
+ from omnibase_infra.mixins import (
68
+ EnumRetryErrorCategory,
69
+ MixinAsyncCircuitBreaker,
70
+ MixinEnvelopeExtraction,
71
+ MixinRetryExecution,
72
+ ModelRetryErrorClassification,
73
+ )
74
+
75
+ T = TypeVar("T")
76
+
77
+ logger = logging.getLogger(__name__)
78
+
79
+ # Handler ID for ModelHandlerOutput
80
+ HANDLER_ID_CONSUL: str = "consul-handler"
81
+
82
+ SUPPORTED_OPERATIONS: frozenset[str] = frozenset(
83
+ {
84
+ "consul.kv_get",
85
+ "consul.kv_put",
86
+ "consul.register",
87
+ "consul.deregister",
88
+ }
89
+ )
90
+
91
+
92
+ class RetryContext(NamedTuple):
93
+ """Context for retry operations containing state and operation metadata.
94
+
95
+ This named tuple provides clear field access for retry initialization,
96
+ improving code clarity over plain tuples.
97
+
98
+ Attributes:
99
+ retry_state: Current retry state including attempt count and delays.
100
+ operation_context: Operation context with correlation ID and timeout.
101
+ """
102
+
103
+ retry_state: ModelRetryState
104
+ operation_context: ModelOperationContext
105
+
106
+
107
+ class HandlerConsul(
108
+ MixinAsyncCircuitBreaker,
109
+ MixinRetryExecution,
110
+ MixinEnvelopeExtraction,
111
+ MixinConsulInitialization,
112
+ MixinConsulKV,
113
+ MixinConsulService,
114
+ ):
115
+ """HashiCorp Consul handler using python-consul client (MVP: KV, service registration).
116
+
117
+ Security Policy - Token Handling:
118
+ The Consul ACL token contains sensitive credentials and is treated as a secret
119
+ throughout this handler. The following security measures are enforced:
120
+
121
+ 1. Token is stored as SecretStr in config (never logged or exposed)
122
+ 2. All error messages use generic descriptions without exposing token
123
+ 3. The describe() method returns capabilities without credentials
124
+
125
+ See CLAUDE.md "Error Sanitization Guidelines" for the full security policy
126
+ on what information is safe vs unsafe to include in errors and logs.
127
+
128
+ Thread Pool Management (Production-Grade):
129
+ - Bounded ThreadPoolExecutor prevents resource exhaustion
130
+ - Configurable max_concurrent_operations (default: 10, max: 100)
131
+ - Thread pool gracefully shutdown on handler.shutdown()
132
+ - All consul (synchronous) operations run in dedicated thread pool
133
+
134
+ Queue Size Management (MVP Behavior):
135
+ ThreadPoolExecutor uses an unbounded queue by default. The max_queue_size
136
+ parameter is calculated (max_workers * multiplier) for monitoring purposes,
137
+ but is NOT enforced by the executor.
138
+
139
+ Why unbounded is acceptable for MVP:
140
+ - Consul operations are typically short-lived (KV get/put)
141
+ - Circuit breaker provides backpressure when Consul is unavailable
142
+ - Thread pool size limits concurrent execution (default: 10 workers)
143
+ - Memory exhaustion from queue growth is unlikely in normal operation
144
+
145
+ Future Enhancement Path:
146
+ For production deployments with strict resource controls, implement a
147
+ custom executor with bounded queue using queue.Queue(maxsize=N):
148
+
149
+ from queue import Queue
150
+ from concurrent.futures import ThreadPoolExecutor
151
+
152
+ class BoundedThreadPoolExecutor(ThreadPoolExecutor):
153
+ def __init__(self, max_workers, max_queue_size):
154
+ super().__init__(max_workers)
155
+ self._work_queue = Queue(maxsize=max_queue_size)
156
+
157
+ This would reject tasks when queue is full, enabling explicit backpressure.
158
+
159
+ Circuit Breaker Pattern (Production-Grade):
160
+ - Uses MixinAsyncCircuitBreaker for consistent circuit breaker implementation
161
+ - Prevents cascading failures to Consul service
162
+ - Three states: CLOSED (normal), OPEN (blocking), HALF_OPEN (testing)
163
+ - Configurable failure_threshold (default: 5 consecutive failures)
164
+ - Configurable reset_timeout (default: 30 seconds)
165
+ - Raises InfraUnavailableError when circuit is OPEN
166
+
167
+ Retry Logic:
168
+ - All operations use exponential backoff retry logic
169
+ - Retry configuration from ModelConsulRetryConfig
170
+ - Backoff calculation: initial_delay * (exponential_base ** attempt)
171
+ - Max backoff capped at max_delay_seconds
172
+ - Circuit breaker checked before retry execution
173
+
174
+ Error Context Design:
175
+ Error contexts use static target_name="consul_handler" for consistency with
176
+ HandlerVault and other infrastructure handlers. This provides predictable
177
+ error categorization and log filtering across all Consul operations.
178
+
179
+ For multi-DC deployments, datacenter differentiation is achieved via:
180
+ - Circuit breaker service_name (e.g., "consul.dc1", "consul.dc2")
181
+ - Structured logging with datacenter field in extra dict
182
+ - Correlation IDs that can be traced across datacenters
183
+
184
+ This design keeps error aggregation unified (all Consul errors grouped under
185
+ "consul_handler") while still providing operational visibility per-datacenter
186
+ through circuit breaker metrics and structured logs.
187
+
188
+ Future Enhancement: If error differentiation per-DC becomes a requirement
189
+ (e.g., for DC-specific alerting), target_name could be made dynamic:
190
+ target_name=f"consul.{self._config.datacenter or 'default'}"
191
+ """
192
+
193
+ def __init__(self) -> None:
194
+ """Initialize HandlerConsul in uninitialized state.
195
+
196
+ Note: Circuit breaker is initialized during initialize() call when
197
+ configuration is available. The mixin's _init_circuit_breaker() method
198
+ is called there with the actual config values.
199
+ """
200
+ self._client: consul.Consul | None = None
201
+ self._config: ModelConsulHandlerConfig | None = None
202
+ self._initialized: bool = False
203
+ self._executor: ThreadPoolExecutor | None = None
204
+ self._max_workers: int = 0
205
+ self._max_queue_size: int = 0
206
+ # Circuit breaker initialized flag - set after _init_circuit_breaker called
207
+ self._circuit_breaker_initialized: bool = False
208
+
209
+ @property
210
+ def handler_type(self) -> EnumHandlerType:
211
+ """Return the architectural role of this handler.
212
+
213
+ Returns:
214
+ EnumHandlerType.INFRA_HANDLER - This handler is an infrastructure
215
+ protocol/transport handler (as opposed to NODE_HANDLER for event
216
+ processing, PROJECTION_HANDLER for read models, or COMPUTE_HANDLER
217
+ for pure computation).
218
+
219
+ Note:
220
+ handler_type determines lifecycle, protocol selection, and runtime
221
+ invocation patterns. It answers "what is this handler in the architecture?"
222
+
223
+ See Also:
224
+ - handler_category: Behavioral classification (EFFECT/COMPUTE)
225
+ - docs/architecture/HANDLER_PROTOCOL_DRIVEN_ARCHITECTURE.md
226
+ """
227
+ return EnumHandlerType.INFRA_HANDLER
228
+
229
+ @property
230
+ def handler_category(self) -> EnumHandlerTypeCategory:
231
+ """Return the behavioral classification of this handler.
232
+
233
+ Returns:
234
+ EnumHandlerTypeCategory.EFFECT - This handler performs side-effecting
235
+ I/O operations (Consul KV store and service registry). EFFECT handlers
236
+ are not deterministic and interact with external systems.
237
+
238
+ Note:
239
+ handler_category determines security rules, determinism guarantees,
240
+ replay safety, and permissions. It answers "how does this handler
241
+ behave at runtime?"
242
+
243
+ Categories:
244
+ - COMPUTE: Pure, deterministic transformations (no side effects)
245
+ - EFFECT: Side-effecting I/O (database, HTTP, service calls)
246
+ - NONDETERMINISTIC_COMPUTE: Pure but not deterministic (UUID, random)
247
+
248
+ See Also:
249
+ - handler_type: Architectural role (INFRA_HANDLER/NODE_HANDLER/etc.)
250
+ - docs/architecture/HANDLER_PROTOCOL_DRIVEN_ARCHITECTURE.md
251
+ """
252
+ return EnumHandlerTypeCategory.EFFECT
253
+
254
+ @property
255
+ def max_workers(self) -> int:
256
+ """Return thread pool max workers (public API for tests)."""
257
+ return self._max_workers
258
+
259
+ @property
260
+ def max_queue_size(self) -> int:
261
+ """Return maximum queue size (public API for tests)."""
262
+ return self._max_queue_size
263
+
264
+ # MixinRetryExecution abstract method implementations
265
+
266
+ def _get_transport_type(self) -> EnumInfraTransportType:
267
+ """Return transport type for error context."""
268
+ return EnumInfraTransportType.CONSUL
269
+
270
+ def _get_target_name(self) -> str:
271
+ """Return target name for error context."""
272
+ return "consul_handler"
273
+
274
+ def _classify_error(
275
+ self, error: Exception, operation: str
276
+ ) -> ModelRetryErrorClassification:
277
+ """Classify Consul-specific exceptions for retry handling.
278
+
279
+ Args:
280
+ error: The exception to classify.
281
+ operation: The operation name for context.
282
+
283
+ Returns:
284
+ ModelRetryErrorClassification with retry decision and error details.
285
+ """
286
+ if isinstance(error, TimeoutError):
287
+ return ModelRetryErrorClassification(
288
+ category=EnumRetryErrorCategory.TIMEOUT,
289
+ should_retry=True,
290
+ record_circuit_failure=True,
291
+ error_message=f"Timeout: {type(error).__name__}",
292
+ )
293
+
294
+ if isinstance(error, consul.ACLPermissionDenied):
295
+ return ModelRetryErrorClassification(
296
+ category=EnumRetryErrorCategory.AUTHENTICATION,
297
+ should_retry=False,
298
+ record_circuit_failure=True,
299
+ error_message="Consul ACL permission denied - check token permissions",
300
+ )
301
+
302
+ if isinstance(error, consul.Timeout):
303
+ return ModelRetryErrorClassification(
304
+ category=EnumRetryErrorCategory.TIMEOUT,
305
+ should_retry=True,
306
+ record_circuit_failure=True,
307
+ error_message=f"Consul timeout: {type(error).__name__}",
308
+ )
309
+
310
+ if isinstance(error, consul.ConsulException):
311
+ return ModelRetryErrorClassification(
312
+ category=EnumRetryErrorCategory.CONNECTION,
313
+ should_retry=True,
314
+ record_circuit_failure=True,
315
+ error_message=f"Consul error: {type(error).__name__}",
316
+ )
317
+
318
+ # Unknown error - retry eligible
319
+ return ModelRetryErrorClassification(
320
+ category=EnumRetryErrorCategory.UNKNOWN,
321
+ should_retry=True,
322
+ record_circuit_failure=True,
323
+ error_message=f"Unexpected error: {type(error).__name__}",
324
+ )
325
+
326
+ async def initialize(self, config: dict[str, object]) -> None:
327
+ """Initialize Consul client with configuration.
328
+
329
+ Args:
330
+ config: Configuration dict containing:
331
+ - host: Consul server hostname (default: "localhost")
332
+ - port: Consul server port (default: 8500)
333
+ - scheme: HTTP scheme "http" or "https" (default: "http")
334
+ - token: Optional Consul ACL token
335
+ - timeout_seconds: Optional timeout (default 30.0)
336
+ - datacenter: Optional datacenter for multi-DC deployments
337
+
338
+ Raises:
339
+ ProtocolConfigurationError: If configuration validation fails.
340
+ InfraAuthenticationError: If token authentication fails.
341
+ InfraConnectionError: If connection to Consul server fails.
342
+ RuntimeHostError: If client initialization fails for other reasons.
343
+
344
+ Security:
345
+ Token must be provided via environment variable, not hardcoded in config.
346
+ Use SecretStr for token to prevent accidental logging.
347
+ """
348
+ init_correlation_id = uuid4()
349
+
350
+ logger.info(
351
+ "Initializing %s",
352
+ self.__class__.__name__,
353
+ extra={
354
+ "handler": self.__class__.__name__,
355
+ "correlation_id": str(init_correlation_id),
356
+ },
357
+ )
358
+
359
+ # Validate configuration
360
+ self._config = self._validate_consul_config(config, init_correlation_id)
361
+
362
+ # Set up client and infrastructure
363
+ try:
364
+ self._client = self._setup_consul_client(self._config)
365
+ self._verify_consul_connection(self._client, init_correlation_id)
366
+ self._setup_thread_pool(self._config)
367
+ self._setup_circuit_breaker(self._config)
368
+
369
+ self._initialized = True
370
+ self._log_initialization_success(self._config, init_correlation_id)
371
+
372
+ except (InfraConnectionError, InfraAuthenticationError):
373
+ raise
374
+ except consul.ACLPermissionDenied as e:
375
+ self._raise_auth_error(init_correlation_id, e)
376
+ except consul.ConsulException as e:
377
+ self._raise_connection_error(init_correlation_id, e)
378
+ except Exception as e:
379
+ self._raise_runtime_error(init_correlation_id, e)
380
+
381
+ async def shutdown(self) -> None:
382
+ """Close Consul client and release resources.
383
+
384
+ Cleanup includes:
385
+ - Shutting down thread pool executor (waits for pending tasks)
386
+ - Clearing Consul client connection
387
+ - Resetting circuit breaker state (thread-safe via mixin)
388
+ """
389
+ shutdown_correlation_id = uuid4()
390
+
391
+ if self._executor is not None:
392
+ # Shutdown thread pool gracefully (wait for pending tasks)
393
+ self._executor.shutdown(wait=True)
394
+ self._executor = None
395
+
396
+ if self._client is not None:
397
+ # python-consul.Client doesn't have close method, just clear reference
398
+ self._client = None
399
+
400
+ # Reset circuit breaker state using mixin (thread-safe)
401
+ if self._circuit_breaker_initialized:
402
+ async with self._circuit_breaker_lock:
403
+ await self._reset_circuit_breaker()
404
+
405
+ self._initialized = False
406
+ self._config = None
407
+ self._circuit_breaker_initialized = False
408
+ logger.info(
409
+ "HandlerConsul shutdown complete",
410
+ extra={
411
+ "correlation_id": str(shutdown_correlation_id),
412
+ },
413
+ )
414
+
415
+ def _build_response(
416
+ self,
417
+ typed_payload: ConsulPayload,
418
+ correlation_id: UUID,
419
+ input_envelope_id: UUID,
420
+ ) -> ModelHandlerOutput[ModelConsulHandlerResponse]:
421
+ """Build standardized ModelConsulHandlerResponse wrapped in ModelHandlerOutput.
422
+
423
+ This helper method ensures consistent response formatting across all
424
+ Consul operations, matching the pattern used by HandlerDb.
425
+
426
+ Args:
427
+ typed_payload: Strongly-typed payload from the discriminated union.
428
+ correlation_id: Correlation ID for tracing.
429
+ input_envelope_id: Input envelope ID for causality tracking.
430
+
431
+ Returns:
432
+ ModelHandlerOutput wrapping ModelConsulHandlerResponse.
433
+ """
434
+ response = ModelConsulHandlerResponse(
435
+ status=EnumResponseStatus.SUCCESS,
436
+ payload=ModelConsulHandlerPayload(data=typed_payload),
437
+ correlation_id=correlation_id,
438
+ )
439
+ return ModelHandlerOutput.for_compute(
440
+ input_envelope_id=input_envelope_id,
441
+ correlation_id=correlation_id,
442
+ handler_id=HANDLER_ID_CONSUL,
443
+ result=response,
444
+ )
445
+
446
+ async def execute(
447
+ self, envelope: dict[str, object]
448
+ ) -> ModelHandlerOutput[ModelConsulHandlerResponse]:
449
+ """Execute Consul operation from envelope.
450
+
451
+ Args:
452
+ envelope: Request envelope containing:
453
+ - operation: Consul operation (consul.kv_get, consul.kv_put, etc.)
454
+ - payload: dict with operation-specific parameters
455
+ - correlation_id: Optional correlation ID for tracing
456
+ - envelope_id: Optional envelope ID for causality tracking
457
+
458
+ Returns:
459
+ ModelHandlerOutput wrapping the operation result with correlation tracking
460
+
461
+ Raises:
462
+ RuntimeHostError: If handler not initialized or invalid input.
463
+ InfraConnectionError: If Consul connection fails.
464
+ InfraAuthenticationError: If authentication fails.
465
+ InfraUnavailableError: If circuit breaker is open.
466
+ """
467
+ correlation_id = self._extract_correlation_id(envelope)
468
+ input_envelope_id = self._extract_envelope_id(envelope)
469
+
470
+ if not self._initialized or self._client is None or self._config is None:
471
+ ctx = ModelInfraErrorContext(
472
+ transport_type=EnumInfraTransportType.CONSUL,
473
+ operation="execute",
474
+ target_name="consul_handler",
475
+ correlation_id=correlation_id,
476
+ )
477
+ raise RuntimeHostError(
478
+ "Consul client not initialized for operation 'execute'. "
479
+ "Call initialize() first.",
480
+ context=ctx,
481
+ )
482
+
483
+ operation = envelope.get("operation")
484
+ if not isinstance(operation, str):
485
+ ctx = ModelInfraErrorContext(
486
+ transport_type=EnumInfraTransportType.CONSUL,
487
+ operation="execute",
488
+ target_name="consul_handler",
489
+ correlation_id=correlation_id,
490
+ )
491
+ raise RuntimeHostError(
492
+ "Missing or invalid 'operation' in envelope",
493
+ context=ctx,
494
+ )
495
+
496
+ if operation not in SUPPORTED_OPERATIONS:
497
+ ctx = ModelInfraErrorContext(
498
+ transport_type=EnumInfraTransportType.CONSUL,
499
+ operation=operation,
500
+ target_name="consul_handler",
501
+ correlation_id=correlation_id,
502
+ )
503
+ raise RuntimeHostError(
504
+ f"Operation '{operation}' not supported in MVP. "
505
+ f"Available: {', '.join(sorted(SUPPORTED_OPERATIONS))}",
506
+ context=ctx,
507
+ )
508
+
509
+ payload = envelope.get("payload")
510
+ if not isinstance(payload, dict):
511
+ ctx = ModelInfraErrorContext(
512
+ transport_type=EnumInfraTransportType.CONSUL,
513
+ operation=operation,
514
+ target_name="consul_handler",
515
+ correlation_id=correlation_id,
516
+ )
517
+ raise RuntimeHostError(
518
+ "Missing or invalid 'payload' in envelope",
519
+ context=ctx,
520
+ )
521
+
522
+ # Route to appropriate handler
523
+ if operation == "consul.kv_get":
524
+ return await self._kv_get(payload, correlation_id, input_envelope_id)
525
+ elif operation == "consul.kv_put":
526
+ return await self._kv_put(payload, correlation_id, input_envelope_id)
527
+ elif operation == "consul.register":
528
+ return await self._register_service(
529
+ payload, correlation_id, input_envelope_id
530
+ )
531
+ else: # consul.deregister - validated above, guaranteed to be deregister
532
+ return await self._deregister_service(
533
+ payload, correlation_id, input_envelope_id
534
+ )
535
+
536
+ async def _execute_with_retry(
537
+ self,
538
+ operation: str,
539
+ func: Callable[[], T],
540
+ correlation_id: UUID,
541
+ ) -> T:
542
+ """Execute operation with exponential backoff retry logic and circuit breaker.
543
+
544
+ Thread-Safety:
545
+ This method is concurrency-safe. Each call maintains its own retry
546
+ state stack, with no shared mutable state between concurrent operations.
547
+ This allows multiple operations to execute in parallel without
548
+ interfering with each other's retry logic.
549
+
550
+ Thread Pool Integration:
551
+ All consul operations (which are synchronous) are executed in a dedicated
552
+ thread pool via loop.run_in_executor(). This prevents blocking the async
553
+ event loop and allows concurrent Consul operations up to max_workers limit.
554
+
555
+ Circuit breaker integration (via MixinAsyncCircuitBreaker):
556
+ - Checks circuit state before execution (raises if OPEN)
557
+ - Records success/failure for circuit state management
558
+ - Allows test request in HALF_OPEN state
559
+
560
+ Args:
561
+ operation: Operation name for logging
562
+ func: Callable to execute (synchronous consul method)
563
+ correlation_id: Correlation ID for tracing
564
+
565
+ Returns:
566
+ Result from func()
567
+
568
+ Raises:
569
+ InfraTimeoutError: If all retries exhausted or operation times out
570
+ InfraConnectionError: If connection fails
571
+ InfraAuthenticationError: If authentication fails
572
+ InfraUnavailableError: If circuit breaker is OPEN
573
+ """
574
+ if self._config is None:
575
+ context = ModelInfraErrorContext(
576
+ transport_type=EnumInfraTransportType.CONSUL,
577
+ operation=operation,
578
+ target_name="consul_handler",
579
+ correlation_id=correlation_id,
580
+ )
581
+ raise InfraConsulError("Consul config not initialized", context=context)
582
+
583
+ await self._check_circuit_if_enabled(operation, correlation_id)
584
+
585
+ ctx = self._init_retry_context(operation, correlation_id)
586
+ retry_state = ctx.retry_state
587
+ op_context = ctx.operation_context
588
+
589
+ # Track last exception for proper error chaining when retries exhaust
590
+ last_exception: Exception | None = None
591
+
592
+ while retry_state.is_retriable():
593
+ (
594
+ result_tuple,
595
+ retry_state,
596
+ caught_exception,
597
+ ) = await self._try_execute_operation(
598
+ func, retry_state, op_context, operation, correlation_id
599
+ )
600
+ if result_tuple is not None:
601
+ return result_tuple[0] # Unpack the result tuple
602
+
603
+ # Track the last exception for error chaining
604
+ last_exception = caught_exception
605
+
606
+ await self._log_retry_attempt(operation, retry_state, correlation_id)
607
+ await asyncio.sleep(retry_state.delay_seconds)
608
+
609
+ # Should never reach here, but satisfy type checker
610
+ context = ModelInfraErrorContext(
611
+ transport_type=EnumInfraTransportType.CONSUL,
612
+ operation=operation,
613
+ target_name="consul_handler",
614
+ correlation_id=correlation_id,
615
+ )
616
+ if retry_state.last_error is not None:
617
+ # Chain to original exception to preserve root cause for debugging
618
+ raise InfraConsulError(
619
+ f"Retry exhausted: {retry_state.last_error}",
620
+ context=context,
621
+ ) from last_exception
622
+ raise InfraConsulError(
623
+ "Retry loop completed without result",
624
+ context=context,
625
+ ) from last_exception
626
+
627
+ def _init_retry_context(self, operation: str, correlation_id: UUID) -> RetryContext:
628
+ """Initialize retry state and operation context.
629
+
630
+ Args:
631
+ operation: Operation name for context.
632
+ correlation_id: Correlation ID for tracing.
633
+
634
+ Returns:
635
+ RetryContext with initialized retry_state and operation_context.
636
+ """
637
+ if self._config is None:
638
+ context = ModelInfraErrorContext(
639
+ transport_type=EnumInfraTransportType.CONSUL,
640
+ operation=operation,
641
+ target_name="consul_handler",
642
+ correlation_id=correlation_id,
643
+ )
644
+ raise InfraConsulError("Consul config not initialized", context=context)
645
+
646
+ retry_config = self._config.retry
647
+ retry_state = ModelRetryState(
648
+ attempt=0,
649
+ max_attempts=retry_config.max_attempts,
650
+ delay_seconds=retry_config.initial_delay_seconds,
651
+ backoff_multiplier=retry_config.exponential_base,
652
+ )
653
+
654
+ op_context = ModelOperationContext.create(
655
+ operation_name=operation,
656
+ correlation_id=correlation_id,
657
+ timeout_seconds=self._config.timeout_seconds,
658
+ )
659
+
660
+ return RetryContext(
661
+ retry_state=retry_state,
662
+ operation_context=op_context,
663
+ )
664
+
665
+ async def _try_execute_operation(
666
+ self,
667
+ func: Callable[[], T],
668
+ retry_state: ModelRetryState,
669
+ op_context: ModelOperationContext,
670
+ operation: str,
671
+ correlation_id: UUID,
672
+ ) -> (
673
+ tuple[tuple[T], ModelRetryState, None] | tuple[None, ModelRetryState, Exception]
674
+ ):
675
+ """Try to execute an operation once with error handling.
676
+
677
+ Thread-Safety:
678
+ This method is concurrency-safe. All retry state is passed explicitly
679
+ as parameters and returned as values. No shared mutable state is used.
680
+ This allows multiple concurrent operations to execute independently.
681
+
682
+ Args:
683
+ func: Callable to execute.
684
+ retry_state: Current retry state.
685
+ op_context: Operation context.
686
+ operation: Operation name.
687
+ correlation_id: Correlation ID.
688
+
689
+ Returns:
690
+ Tuple of ((result,), retry_state, None) if successful.
691
+ Tuple of (None, updated_retry_state, exception) if should retry.
692
+ The exception is returned to enable proper error chaining when
693
+ retries are eventually exhausted.
694
+
695
+ Raises:
696
+ InfraTimeoutError, InfraConnectionError, InfraAuthenticationError:
697
+ If error is not retriable or retries are exhausted.
698
+ """
699
+ if self._config is None:
700
+ context = ModelInfraErrorContext(
701
+ transport_type=EnumInfraTransportType.CONSUL,
702
+ operation=operation,
703
+ target_name="consul_handler",
704
+ correlation_id=correlation_id,
705
+ )
706
+ raise InfraConsulError("Consul config not initialized", context=context)
707
+
708
+ retry_config = self._config.retry
709
+ try:
710
+ loop = asyncio.get_running_loop()
711
+ result = await asyncio.wait_for(
712
+ loop.run_in_executor(self._executor, func),
713
+ timeout=op_context.timeout_seconds,
714
+ )
715
+
716
+ await self._reset_circuit_if_enabled()
717
+ return (result,), retry_state, None
718
+
719
+ except Exception as e:
720
+ classification = self._classify_error(e, operation)
721
+
722
+ if not classification.should_retry:
723
+ error = await self._handle_non_retriable_error(
724
+ classification, operation, correlation_id, e
725
+ )
726
+ raise error from e
727
+
728
+ new_state, error_to_raise = await self._handle_retriable_error(
729
+ classification,
730
+ retry_state,
731
+ retry_config.max_delay_seconds,
732
+ operation,
733
+ correlation_id,
734
+ op_context,
735
+ e,
736
+ )
737
+
738
+ if error_to_raise is not None:
739
+ raise error_to_raise from e
740
+
741
+ return None, new_state, e
742
+
743
+ def describe(self) -> dict[str, object]:
744
+ """Return handler metadata and capabilities for introspection.
745
+
746
+ This method exposes the handler's type classification along with its
747
+ operational configuration and capabilities.
748
+
749
+ Returns:
750
+ dict containing:
751
+ - handler_type: Architectural role from handler_type property
752
+ (e.g., "infra_handler"). See EnumHandlerType for valid values.
753
+ - handler_category: Behavioral classification from handler_category
754
+ property (e.g., "effect"). See EnumHandlerTypeCategory for valid values.
755
+ - supported_operations: List of supported operations
756
+ - timeout_seconds: Request timeout in seconds
757
+ - initialized: Whether the handler is initialized
758
+ - version: Handler version string
759
+
760
+ Note:
761
+ The handler_type and handler_category fields form the handler
762
+ classification system:
763
+
764
+ 1. handler_type (architectural role): Determines lifecycle and invocation
765
+ patterns. This handler is INFRA_HANDLER (protocol/transport handler).
766
+
767
+ 2. handler_category (behavioral classification): Determines security rules
768
+ and replay safety. This handler is EFFECT (side-effecting I/O).
769
+
770
+ The transport type for this handler is CONSUL (service discovery).
771
+
772
+ See Also:
773
+ - handler_type property: Full documentation of architectural role
774
+ - handler_category property: Full documentation of behavioral classification
775
+ - docs/architecture/HANDLER_PROTOCOL_DRIVEN_ARCHITECTURE.md
776
+ """
777
+ return {
778
+ "handler_type": self.handler_type.value,
779
+ "handler_category": self.handler_category.value,
780
+ "supported_operations": sorted(SUPPORTED_OPERATIONS),
781
+ "timeout_seconds": self._config.timeout_seconds if self._config else 30.0,
782
+ "initialized": self._initialized,
783
+ "version": "0.1.0-mvp",
784
+ }
785
+
786
+
787
+ __all__: list[str] = ["HandlerConsul", "RetryContext"]