omnibase_infra 0.2.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (833) hide show
  1. omnibase_infra/__init__.py +101 -0
  2. omnibase_infra/adapters/adapter_onex_tool_execution.py +451 -0
  3. omnibase_infra/capabilities/__init__.py +15 -0
  4. omnibase_infra/capabilities/capability_inference_rules.py +211 -0
  5. omnibase_infra/capabilities/contract_capability_extractor.py +221 -0
  6. omnibase_infra/capabilities/intent_type_extractor.py +160 -0
  7. omnibase_infra/cli/__init__.py +1 -0
  8. omnibase_infra/cli/commands.py +216 -0
  9. omnibase_infra/clients/__init__.py +0 -0
  10. omnibase_infra/configs/widget_mapping.yaml +176 -0
  11. omnibase_infra/constants_topic_patterns.py +26 -0
  12. omnibase_infra/contracts/handlers/filesystem/handler_contract.yaml +264 -0
  13. omnibase_infra/contracts/handlers/mcp/handler_contract.yaml +141 -0
  14. omnibase_infra/decorators/__init__.py +29 -0
  15. omnibase_infra/decorators/allow_any.py +109 -0
  16. omnibase_infra/dlq/__init__.py +90 -0
  17. omnibase_infra/dlq/constants_dlq.py +57 -0
  18. omnibase_infra/dlq/models/__init__.py +26 -0
  19. omnibase_infra/dlq/models/enum_replay_status.py +37 -0
  20. omnibase_infra/dlq/models/model_dlq_replay_record.py +135 -0
  21. omnibase_infra/dlq/models/model_dlq_tracking_config.py +184 -0
  22. omnibase_infra/dlq/service_dlq_tracking.py +611 -0
  23. omnibase_infra/enums/__init__.py +132 -0
  24. omnibase_infra/enums/enum_any_type_violation.py +104 -0
  25. omnibase_infra/enums/enum_backend_type.py +27 -0
  26. omnibase_infra/enums/enum_capture_outcome.py +42 -0
  27. omnibase_infra/enums/enum_capture_state.py +88 -0
  28. omnibase_infra/enums/enum_chain_violation_type.py +119 -0
  29. omnibase_infra/enums/enum_circuit_state.py +51 -0
  30. omnibase_infra/enums/enum_confirmation_event_type.py +27 -0
  31. omnibase_infra/enums/enum_consumer_group_purpose.py +92 -0
  32. omnibase_infra/enums/enum_contract_type.py +84 -0
  33. omnibase_infra/enums/enum_dedupe_strategy.py +46 -0
  34. omnibase_infra/enums/enum_dispatch_status.py +191 -0
  35. omnibase_infra/enums/enum_environment.py +46 -0
  36. omnibase_infra/enums/enum_execution_shape_violation.py +103 -0
  37. omnibase_infra/enums/enum_handler_error_type.py +111 -0
  38. omnibase_infra/enums/enum_handler_loader_error.py +178 -0
  39. omnibase_infra/enums/enum_handler_source_mode.py +86 -0
  40. omnibase_infra/enums/enum_handler_source_type.py +87 -0
  41. omnibase_infra/enums/enum_handler_type.py +77 -0
  42. omnibase_infra/enums/enum_handler_type_category.py +61 -0
  43. omnibase_infra/enums/enum_infra_transport_type.py +73 -0
  44. omnibase_infra/enums/enum_introspection_reason.py +154 -0
  45. omnibase_infra/enums/enum_kafka_acks.py +99 -0
  46. omnibase_infra/enums/enum_message_category.py +213 -0
  47. omnibase_infra/enums/enum_node_archetype.py +74 -0
  48. omnibase_infra/enums/enum_node_output_type.py +185 -0
  49. omnibase_infra/enums/enum_non_retryable_error_category.py +224 -0
  50. omnibase_infra/enums/enum_policy_type.py +32 -0
  51. omnibase_infra/enums/enum_registration_state.py +261 -0
  52. omnibase_infra/enums/enum_registration_status.py +33 -0
  53. omnibase_infra/enums/enum_registry_response_status.py +28 -0
  54. omnibase_infra/enums/enum_response_status.py +26 -0
  55. omnibase_infra/enums/enum_retry_error_category.py +98 -0
  56. omnibase_infra/enums/enum_security_rule_id.py +103 -0
  57. omnibase_infra/enums/enum_selection_strategy.py +91 -0
  58. omnibase_infra/enums/enum_topic_standard.py +42 -0
  59. omnibase_infra/enums/enum_validation_severity.py +78 -0
  60. omnibase_infra/errors/__init__.py +160 -0
  61. omnibase_infra/errors/error_architecture_violation.py +152 -0
  62. omnibase_infra/errors/error_binding_resolution.py +128 -0
  63. omnibase_infra/errors/error_chain_propagation.py +188 -0
  64. omnibase_infra/errors/error_compute_registry.py +95 -0
  65. omnibase_infra/errors/error_consul.py +132 -0
  66. omnibase_infra/errors/error_container_wiring.py +243 -0
  67. omnibase_infra/errors/error_event_bus_registry.py +105 -0
  68. omnibase_infra/errors/error_infra.py +610 -0
  69. omnibase_infra/errors/error_message_type_registry.py +101 -0
  70. omnibase_infra/errors/error_policy_registry.py +115 -0
  71. omnibase_infra/errors/error_vault.py +123 -0
  72. omnibase_infra/event_bus/__init__.py +72 -0
  73. omnibase_infra/event_bus/configs/kafka_event_bus_config.yaml +84 -0
  74. omnibase_infra/event_bus/event_bus_inmemory.py +797 -0
  75. omnibase_infra/event_bus/event_bus_kafka.py +1716 -0
  76. omnibase_infra/event_bus/mixin_kafka_broadcast.py +180 -0
  77. omnibase_infra/event_bus/mixin_kafka_dlq.py +771 -0
  78. omnibase_infra/event_bus/models/__init__.py +29 -0
  79. omnibase_infra/event_bus/models/config/__init__.py +20 -0
  80. omnibase_infra/event_bus/models/config/model_kafka_event_bus_config.py +693 -0
  81. omnibase_infra/event_bus/models/model_dlq_event.py +206 -0
  82. omnibase_infra/event_bus/models/model_dlq_metrics.py +304 -0
  83. omnibase_infra/event_bus/models/model_event_headers.py +115 -0
  84. omnibase_infra/event_bus/models/model_event_message.py +60 -0
  85. omnibase_infra/event_bus/testing/__init__.py +26 -0
  86. omnibase_infra/event_bus/testing/adapter_protocol_event_publisher_inmemory.py +418 -0
  87. omnibase_infra/event_bus/testing/model_publisher_metrics.py +64 -0
  88. omnibase_infra/event_bus/topic_constants.py +376 -0
  89. omnibase_infra/handlers/__init__.py +82 -0
  90. omnibase_infra/handlers/filesystem/__init__.py +48 -0
  91. omnibase_infra/handlers/filesystem/enum_file_system_operation.py +35 -0
  92. omnibase_infra/handlers/filesystem/model_file_system_request.py +298 -0
  93. omnibase_infra/handlers/filesystem/model_file_system_result.py +166 -0
  94. omnibase_infra/handlers/handler_consul.py +795 -0
  95. omnibase_infra/handlers/handler_db.py +1046 -0
  96. omnibase_infra/handlers/handler_filesystem.py +1478 -0
  97. omnibase_infra/handlers/handler_graph.py +2015 -0
  98. omnibase_infra/handlers/handler_http.py +926 -0
  99. omnibase_infra/handlers/handler_intent.py +387 -0
  100. omnibase_infra/handlers/handler_manifest_persistence.contract.yaml +184 -0
  101. omnibase_infra/handlers/handler_manifest_persistence.py +1539 -0
  102. omnibase_infra/handlers/handler_mcp.py +1430 -0
  103. omnibase_infra/handlers/handler_qdrant.py +1076 -0
  104. omnibase_infra/handlers/handler_vault.py +428 -0
  105. omnibase_infra/handlers/mcp/__init__.py +19 -0
  106. omnibase_infra/handlers/mcp/adapter_onex_to_mcp.py +446 -0
  107. omnibase_infra/handlers/mcp/protocols.py +178 -0
  108. omnibase_infra/handlers/mcp/transport_streamable_http.py +352 -0
  109. omnibase_infra/handlers/mixins/__init__.py +47 -0
  110. omnibase_infra/handlers/mixins/mixin_consul_initialization.py +349 -0
  111. omnibase_infra/handlers/mixins/mixin_consul_kv.py +338 -0
  112. omnibase_infra/handlers/mixins/mixin_consul_service.py +542 -0
  113. omnibase_infra/handlers/mixins/mixin_consul_topic_index.py +585 -0
  114. omnibase_infra/handlers/mixins/mixin_vault_initialization.py +338 -0
  115. omnibase_infra/handlers/mixins/mixin_vault_retry.py +412 -0
  116. omnibase_infra/handlers/mixins/mixin_vault_secrets.py +450 -0
  117. omnibase_infra/handlers/mixins/mixin_vault_token.py +365 -0
  118. omnibase_infra/handlers/models/__init__.py +286 -0
  119. omnibase_infra/handlers/models/consul/__init__.py +81 -0
  120. omnibase_infra/handlers/models/consul/enum_consul_operation_type.py +57 -0
  121. omnibase_infra/handlers/models/consul/model_consul_deregister_payload.py +51 -0
  122. omnibase_infra/handlers/models/consul/model_consul_handler_config.py +153 -0
  123. omnibase_infra/handlers/models/consul/model_consul_handler_payload.py +89 -0
  124. omnibase_infra/handlers/models/consul/model_consul_kv_get_found_payload.py +55 -0
  125. omnibase_infra/handlers/models/consul/model_consul_kv_get_not_found_payload.py +49 -0
  126. omnibase_infra/handlers/models/consul/model_consul_kv_get_recurse_payload.py +50 -0
  127. omnibase_infra/handlers/models/consul/model_consul_kv_item.py +33 -0
  128. omnibase_infra/handlers/models/consul/model_consul_kv_put_payload.py +41 -0
  129. omnibase_infra/handlers/models/consul/model_consul_register_payload.py +53 -0
  130. omnibase_infra/handlers/models/consul/model_consul_retry_config.py +66 -0
  131. omnibase_infra/handlers/models/consul/model_payload_consul.py +66 -0
  132. omnibase_infra/handlers/models/consul/registry_payload_consul.py +214 -0
  133. omnibase_infra/handlers/models/graph/__init__.py +35 -0
  134. omnibase_infra/handlers/models/graph/enum_graph_operation_type.py +20 -0
  135. omnibase_infra/handlers/models/graph/model_graph_execute_payload.py +38 -0
  136. omnibase_infra/handlers/models/graph/model_graph_handler_config.py +54 -0
  137. omnibase_infra/handlers/models/graph/model_graph_handler_payload.py +44 -0
  138. omnibase_infra/handlers/models/graph/model_graph_query_payload.py +40 -0
  139. omnibase_infra/handlers/models/graph/model_graph_record.py +22 -0
  140. omnibase_infra/handlers/models/http/__init__.py +50 -0
  141. omnibase_infra/handlers/models/http/enum_http_operation_type.py +29 -0
  142. omnibase_infra/handlers/models/http/model_http_body_content.py +45 -0
  143. omnibase_infra/handlers/models/http/model_http_get_payload.py +88 -0
  144. omnibase_infra/handlers/models/http/model_http_handler_payload.py +90 -0
  145. omnibase_infra/handlers/models/http/model_http_post_payload.py +88 -0
  146. omnibase_infra/handlers/models/http/model_payload_http.py +66 -0
  147. omnibase_infra/handlers/models/http/registry_payload_http.py +212 -0
  148. omnibase_infra/handlers/models/mcp/__init__.py +23 -0
  149. omnibase_infra/handlers/models/mcp/enum_mcp_operation_type.py +24 -0
  150. omnibase_infra/handlers/models/mcp/model_mcp_handler_config.py +40 -0
  151. omnibase_infra/handlers/models/mcp/model_mcp_tool_call.py +32 -0
  152. omnibase_infra/handlers/models/mcp/model_mcp_tool_result.py +45 -0
  153. omnibase_infra/handlers/models/model_consul_handler_response.py +96 -0
  154. omnibase_infra/handlers/models/model_db_describe_response.py +83 -0
  155. omnibase_infra/handlers/models/model_db_query_payload.py +95 -0
  156. omnibase_infra/handlers/models/model_db_query_response.py +60 -0
  157. omnibase_infra/handlers/models/model_filesystem_config.py +98 -0
  158. omnibase_infra/handlers/models/model_filesystem_delete_payload.py +54 -0
  159. omnibase_infra/handlers/models/model_filesystem_delete_result.py +77 -0
  160. omnibase_infra/handlers/models/model_filesystem_directory_entry.py +75 -0
  161. omnibase_infra/handlers/models/model_filesystem_ensure_directory_payload.py +54 -0
  162. omnibase_infra/handlers/models/model_filesystem_ensure_directory_result.py +60 -0
  163. omnibase_infra/handlers/models/model_filesystem_list_directory_payload.py +60 -0
  164. omnibase_infra/handlers/models/model_filesystem_list_directory_result.py +68 -0
  165. omnibase_infra/handlers/models/model_filesystem_read_payload.py +62 -0
  166. omnibase_infra/handlers/models/model_filesystem_read_result.py +61 -0
  167. omnibase_infra/handlers/models/model_filesystem_write_payload.py +70 -0
  168. omnibase_infra/handlers/models/model_filesystem_write_result.py +55 -0
  169. omnibase_infra/handlers/models/model_graph_handler_response.py +98 -0
  170. omnibase_infra/handlers/models/model_handler_response.py +103 -0
  171. omnibase_infra/handlers/models/model_http_handler_response.py +101 -0
  172. omnibase_infra/handlers/models/model_manifest_metadata.py +75 -0
  173. omnibase_infra/handlers/models/model_manifest_persistence_config.py +62 -0
  174. omnibase_infra/handlers/models/model_manifest_query_payload.py +90 -0
  175. omnibase_infra/handlers/models/model_manifest_query_result.py +97 -0
  176. omnibase_infra/handlers/models/model_manifest_retrieve_payload.py +44 -0
  177. omnibase_infra/handlers/models/model_manifest_retrieve_result.py +98 -0
  178. omnibase_infra/handlers/models/model_manifest_store_payload.py +47 -0
  179. omnibase_infra/handlers/models/model_manifest_store_result.py +67 -0
  180. omnibase_infra/handlers/models/model_operation_context.py +187 -0
  181. omnibase_infra/handlers/models/model_qdrant_handler_response.py +98 -0
  182. omnibase_infra/handlers/models/model_retry_state.py +162 -0
  183. omnibase_infra/handlers/models/model_vault_handler_response.py +98 -0
  184. omnibase_infra/handlers/models/qdrant/__init__.py +44 -0
  185. omnibase_infra/handlers/models/qdrant/enum_qdrant_operation_type.py +26 -0
  186. omnibase_infra/handlers/models/qdrant/model_qdrant_collection_payload.py +42 -0
  187. omnibase_infra/handlers/models/qdrant/model_qdrant_delete_payload.py +36 -0
  188. omnibase_infra/handlers/models/qdrant/model_qdrant_handler_config.py +42 -0
  189. omnibase_infra/handlers/models/qdrant/model_qdrant_handler_payload.py +54 -0
  190. omnibase_infra/handlers/models/qdrant/model_qdrant_search_payload.py +42 -0
  191. omnibase_infra/handlers/models/qdrant/model_qdrant_search_result.py +30 -0
  192. omnibase_infra/handlers/models/qdrant/model_qdrant_upsert_payload.py +36 -0
  193. omnibase_infra/handlers/models/vault/__init__.py +69 -0
  194. omnibase_infra/handlers/models/vault/enum_vault_operation_type.py +35 -0
  195. omnibase_infra/handlers/models/vault/model_payload_vault.py +66 -0
  196. omnibase_infra/handlers/models/vault/model_vault_delete_payload.py +57 -0
  197. omnibase_infra/handlers/models/vault/model_vault_handler_config.py +148 -0
  198. omnibase_infra/handlers/models/vault/model_vault_handler_payload.py +101 -0
  199. omnibase_infra/handlers/models/vault/model_vault_list_payload.py +58 -0
  200. omnibase_infra/handlers/models/vault/model_vault_renew_token_payload.py +67 -0
  201. omnibase_infra/handlers/models/vault/model_vault_retry_config.py +66 -0
  202. omnibase_infra/handlers/models/vault/model_vault_secret_payload.py +106 -0
  203. omnibase_infra/handlers/models/vault/model_vault_write_payload.py +66 -0
  204. omnibase_infra/handlers/models/vault/registry_payload_vault.py +213 -0
  205. omnibase_infra/handlers/registration_storage/__init__.py +43 -0
  206. omnibase_infra/handlers/registration_storage/handler_registration_storage_mock.py +392 -0
  207. omnibase_infra/handlers/registration_storage/handler_registration_storage_postgres.py +922 -0
  208. omnibase_infra/handlers/registration_storage/models/__init__.py +23 -0
  209. omnibase_infra/handlers/registration_storage/models/model_delete_registration_request.py +58 -0
  210. omnibase_infra/handlers/registration_storage/models/model_update_registration_request.py +73 -0
  211. omnibase_infra/handlers/registration_storage/protocol_registration_persistence.py +191 -0
  212. omnibase_infra/handlers/service_discovery/__init__.py +43 -0
  213. omnibase_infra/handlers/service_discovery/handler_service_discovery_consul.py +1051 -0
  214. omnibase_infra/handlers/service_discovery/handler_service_discovery_mock.py +258 -0
  215. omnibase_infra/handlers/service_discovery/models/__init__.py +22 -0
  216. omnibase_infra/handlers/service_discovery/models/model_discovery_result.py +64 -0
  217. omnibase_infra/handlers/service_discovery/models/model_registration_result.py +138 -0
  218. omnibase_infra/handlers/service_discovery/models/model_service_info.py +109 -0
  219. omnibase_infra/handlers/service_discovery/protocol_discovery_operations.py +170 -0
  220. omnibase_infra/idempotency/__init__.py +94 -0
  221. omnibase_infra/idempotency/models/__init__.py +43 -0
  222. omnibase_infra/idempotency/models/model_idempotency_check_result.py +85 -0
  223. omnibase_infra/idempotency/models/model_idempotency_guard_config.py +130 -0
  224. omnibase_infra/idempotency/models/model_idempotency_record.py +86 -0
  225. omnibase_infra/idempotency/models/model_idempotency_store_health_check_result.py +81 -0
  226. omnibase_infra/idempotency/models/model_idempotency_store_metrics.py +140 -0
  227. omnibase_infra/idempotency/models/model_postgres_idempotency_store_config.py +299 -0
  228. omnibase_infra/idempotency/protocol_idempotency_store.py +184 -0
  229. omnibase_infra/idempotency/store_inmemory.py +265 -0
  230. omnibase_infra/idempotency/store_postgres.py +923 -0
  231. omnibase_infra/infrastructure/__init__.py +0 -0
  232. omnibase_infra/migrations/001_create_event_ledger.sql +166 -0
  233. omnibase_infra/migrations/001_drop_event_ledger.sql +18 -0
  234. omnibase_infra/mixins/__init__.py +71 -0
  235. omnibase_infra/mixins/mixin_async_circuit_breaker.py +656 -0
  236. omnibase_infra/mixins/mixin_dict_like_accessors.py +146 -0
  237. omnibase_infra/mixins/mixin_envelope_extraction.py +119 -0
  238. omnibase_infra/mixins/mixin_node_introspection.py +2670 -0
  239. omnibase_infra/mixins/mixin_retry_execution.py +386 -0
  240. omnibase_infra/mixins/protocol_circuit_breaker_aware.py +133 -0
  241. omnibase_infra/models/__init__.py +144 -0
  242. omnibase_infra/models/bindings/__init__.py +59 -0
  243. omnibase_infra/models/bindings/constants.py +144 -0
  244. omnibase_infra/models/bindings/model_binding_resolution_result.py +103 -0
  245. omnibase_infra/models/bindings/model_operation_binding.py +44 -0
  246. omnibase_infra/models/bindings/model_operation_bindings_subcontract.py +152 -0
  247. omnibase_infra/models/bindings/model_parsed_binding.py +52 -0
  248. omnibase_infra/models/corpus/__init__.py +17 -0
  249. omnibase_infra/models/corpus/model_capture_config.py +133 -0
  250. omnibase_infra/models/corpus/model_capture_result.py +86 -0
  251. omnibase_infra/models/discovery/__init__.py +42 -0
  252. omnibase_infra/models/discovery/model_dependency_spec.py +319 -0
  253. omnibase_infra/models/discovery/model_discovered_capabilities.py +50 -0
  254. omnibase_infra/models/discovery/model_introspection_config.py +330 -0
  255. omnibase_infra/models/discovery/model_introspection_performance_metrics.py +169 -0
  256. omnibase_infra/models/discovery/model_introspection_task_config.py +116 -0
  257. omnibase_infra/models/dispatch/__init__.py +155 -0
  258. omnibase_infra/models/dispatch/model_debug_trace_snapshot.py +114 -0
  259. omnibase_infra/models/dispatch/model_dispatch_context.py +439 -0
  260. omnibase_infra/models/dispatch/model_dispatch_error.py +336 -0
  261. omnibase_infra/models/dispatch/model_dispatch_log_context.py +400 -0
  262. omnibase_infra/models/dispatch/model_dispatch_metadata.py +228 -0
  263. omnibase_infra/models/dispatch/model_dispatch_metrics.py +496 -0
  264. omnibase_infra/models/dispatch/model_dispatch_outcome.py +317 -0
  265. omnibase_infra/models/dispatch/model_dispatch_outputs.py +231 -0
  266. omnibase_infra/models/dispatch/model_dispatch_result.py +436 -0
  267. omnibase_infra/models/dispatch/model_dispatch_route.py +279 -0
  268. omnibase_infra/models/dispatch/model_dispatcher_metrics.py +275 -0
  269. omnibase_infra/models/dispatch/model_dispatcher_registration.py +352 -0
  270. omnibase_infra/models/dispatch/model_materialized_dispatch.py +141 -0
  271. omnibase_infra/models/dispatch/model_parsed_topic.py +135 -0
  272. omnibase_infra/models/dispatch/model_topic_parser.py +725 -0
  273. omnibase_infra/models/dispatch/model_tracing_context.py +285 -0
  274. omnibase_infra/models/errors/__init__.py +45 -0
  275. omnibase_infra/models/errors/model_handler_validation_error.py +594 -0
  276. omnibase_infra/models/errors/model_infra_error_context.py +99 -0
  277. omnibase_infra/models/errors/model_message_type_registry_error_context.py +71 -0
  278. omnibase_infra/models/errors/model_timeout_error_context.py +110 -0
  279. omnibase_infra/models/handlers/__init__.py +80 -0
  280. omnibase_infra/models/handlers/model_bootstrap_handler_descriptor.py +162 -0
  281. omnibase_infra/models/handlers/model_contract_discovery_result.py +82 -0
  282. omnibase_infra/models/handlers/model_handler_descriptor.py +200 -0
  283. omnibase_infra/models/handlers/model_handler_identifier.py +215 -0
  284. omnibase_infra/models/handlers/model_handler_source_config.py +220 -0
  285. omnibase_infra/models/health/__init__.py +9 -0
  286. omnibase_infra/models/health/model_health_check_result.py +40 -0
  287. omnibase_infra/models/lifecycle/__init__.py +39 -0
  288. omnibase_infra/models/logging/__init__.py +51 -0
  289. omnibase_infra/models/logging/model_log_context.py +756 -0
  290. omnibase_infra/models/mcp/__init__.py +15 -0
  291. omnibase_infra/models/mcp/model_mcp_contract_config.py +80 -0
  292. omnibase_infra/models/mcp/model_mcp_server_config.py +67 -0
  293. omnibase_infra/models/mcp/model_mcp_tool_definition.py +73 -0
  294. omnibase_infra/models/mcp/model_mcp_tool_parameter.py +35 -0
  295. omnibase_infra/models/model_node_identity.py +126 -0
  296. omnibase_infra/models/model_retry_error_classification.py +78 -0
  297. omnibase_infra/models/projection/__init__.py +43 -0
  298. omnibase_infra/models/projection/model_capability_fields.py +112 -0
  299. omnibase_infra/models/projection/model_registration_projection.py +434 -0
  300. omnibase_infra/models/projection/model_registration_snapshot.py +322 -0
  301. omnibase_infra/models/projection/model_sequence_info.py +182 -0
  302. omnibase_infra/models/projection/model_snapshot_topic_config.py +591 -0
  303. omnibase_infra/models/projectors/__init__.py +41 -0
  304. omnibase_infra/models/projectors/model_projector_column.py +289 -0
  305. omnibase_infra/models/projectors/model_projector_discovery_result.py +65 -0
  306. omnibase_infra/models/projectors/model_projector_index.py +270 -0
  307. omnibase_infra/models/projectors/model_projector_schema.py +415 -0
  308. omnibase_infra/models/projectors/model_projector_validation_error.py +63 -0
  309. omnibase_infra/models/projectors/util_sql_identifiers.py +115 -0
  310. omnibase_infra/models/registration/__init__.py +68 -0
  311. omnibase_infra/models/registration/commands/__init__.py +15 -0
  312. omnibase_infra/models/registration/commands/model_node_registration_acked.py +108 -0
  313. omnibase_infra/models/registration/events/__init__.py +56 -0
  314. omnibase_infra/models/registration/events/model_node_became_active.py +103 -0
  315. omnibase_infra/models/registration/events/model_node_liveness_expired.py +103 -0
  316. omnibase_infra/models/registration/events/model_node_registration_accepted.py +98 -0
  317. omnibase_infra/models/registration/events/model_node_registration_ack_received.py +98 -0
  318. omnibase_infra/models/registration/events/model_node_registration_ack_timed_out.py +112 -0
  319. omnibase_infra/models/registration/events/model_node_registration_initiated.py +107 -0
  320. omnibase_infra/models/registration/events/model_node_registration_rejected.py +104 -0
  321. omnibase_infra/models/registration/model_event_bus_topic_entry.py +59 -0
  322. omnibase_infra/models/registration/model_introspection_metrics.py +253 -0
  323. omnibase_infra/models/registration/model_node_capabilities.py +190 -0
  324. omnibase_infra/models/registration/model_node_event_bus_config.py +99 -0
  325. omnibase_infra/models/registration/model_node_heartbeat_event.py +126 -0
  326. omnibase_infra/models/registration/model_node_introspection_event.py +195 -0
  327. omnibase_infra/models/registration/model_node_metadata.py +79 -0
  328. omnibase_infra/models/registration/model_node_registration.py +162 -0
  329. omnibase_infra/models/registration/model_node_registration_record.py +162 -0
  330. omnibase_infra/models/registry/__init__.py +29 -0
  331. omnibase_infra/models/registry/model_domain_constraint.py +202 -0
  332. omnibase_infra/models/registry/model_message_type_entry.py +271 -0
  333. omnibase_infra/models/resilience/__init__.py +9 -0
  334. omnibase_infra/models/resilience/model_circuit_breaker_config.py +227 -0
  335. omnibase_infra/models/routing/__init__.py +25 -0
  336. omnibase_infra/models/routing/model_routing_entry.py +52 -0
  337. omnibase_infra/models/routing/model_routing_subcontract.py +70 -0
  338. omnibase_infra/models/runtime/__init__.py +49 -0
  339. omnibase_infra/models/runtime/model_contract_security_config.py +41 -0
  340. omnibase_infra/models/runtime/model_discovery_error.py +81 -0
  341. omnibase_infra/models/runtime/model_discovery_result.py +162 -0
  342. omnibase_infra/models/runtime/model_discovery_warning.py +74 -0
  343. omnibase_infra/models/runtime/model_failed_plugin_load.py +63 -0
  344. omnibase_infra/models/runtime/model_handler_contract.py +296 -0
  345. omnibase_infra/models/runtime/model_loaded_handler.py +129 -0
  346. omnibase_infra/models/runtime/model_plugin_load_context.py +93 -0
  347. omnibase_infra/models/runtime/model_plugin_load_summary.py +124 -0
  348. omnibase_infra/models/security/__init__.py +50 -0
  349. omnibase_infra/models/security/classification_levels.py +99 -0
  350. omnibase_infra/models/security/model_environment_policy.py +145 -0
  351. omnibase_infra/models/security/model_handler_security_policy.py +107 -0
  352. omnibase_infra/models/security/model_security_error.py +81 -0
  353. omnibase_infra/models/security/model_security_validation_result.py +328 -0
  354. omnibase_infra/models/security/model_security_warning.py +67 -0
  355. omnibase_infra/models/snapshot/__init__.py +27 -0
  356. omnibase_infra/models/snapshot/model_field_change.py +65 -0
  357. omnibase_infra/models/snapshot/model_snapshot.py +270 -0
  358. omnibase_infra/models/snapshot/model_snapshot_diff.py +203 -0
  359. omnibase_infra/models/snapshot/model_subject_ref.py +81 -0
  360. omnibase_infra/models/types/__init__.py +71 -0
  361. omnibase_infra/models/validation/__init__.py +89 -0
  362. omnibase_infra/models/validation/model_any_type_validation_result.py +118 -0
  363. omnibase_infra/models/validation/model_any_type_violation.py +141 -0
  364. omnibase_infra/models/validation/model_category_match_result.py +345 -0
  365. omnibase_infra/models/validation/model_chain_violation.py +166 -0
  366. omnibase_infra/models/validation/model_coverage_metrics.py +316 -0
  367. omnibase_infra/models/validation/model_execution_shape_rule.py +159 -0
  368. omnibase_infra/models/validation/model_execution_shape_validation.py +208 -0
  369. omnibase_infra/models/validation/model_execution_shape_validation_result.py +294 -0
  370. omnibase_infra/models/validation/model_execution_shape_violation.py +122 -0
  371. omnibase_infra/models/validation/model_localhandler_validation_result.py +139 -0
  372. omnibase_infra/models/validation/model_localhandler_violation.py +100 -0
  373. omnibase_infra/models/validation/model_output_validation_params.py +74 -0
  374. omnibase_infra/models/validation/model_validate_and_raise_params.py +84 -0
  375. omnibase_infra/models/validation/model_validation_error_params.py +84 -0
  376. omnibase_infra/models/validation/model_validation_outcome.py +287 -0
  377. omnibase_infra/nodes/__init__.py +57 -0
  378. omnibase_infra/nodes/architecture_validator/__init__.py +79 -0
  379. omnibase_infra/nodes/architecture_validator/contract.yaml +252 -0
  380. omnibase_infra/nodes/architecture_validator/contract_architecture_validator.yaml +203 -0
  381. omnibase_infra/nodes/architecture_validator/mixins/__init__.py +16 -0
  382. omnibase_infra/nodes/architecture_validator/mixins/mixin_file_path_rule.py +92 -0
  383. omnibase_infra/nodes/architecture_validator/models/__init__.py +36 -0
  384. omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_request.py +56 -0
  385. omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_result.py +311 -0
  386. omnibase_infra/nodes/architecture_validator/models/model_architecture_violation.py +163 -0
  387. omnibase_infra/nodes/architecture_validator/models/model_rule_check_result.py +265 -0
  388. omnibase_infra/nodes/architecture_validator/models/model_validation_request.py +105 -0
  389. omnibase_infra/nodes/architecture_validator/models/model_validation_result.py +314 -0
  390. omnibase_infra/nodes/architecture_validator/node.py +262 -0
  391. omnibase_infra/nodes/architecture_validator/node_architecture_validator.py +383 -0
  392. omnibase_infra/nodes/architecture_validator/protocols/__init__.py +9 -0
  393. omnibase_infra/nodes/architecture_validator/protocols/protocol_architecture_rule.py +225 -0
  394. omnibase_infra/nodes/architecture_validator/registry/__init__.py +28 -0
  395. omnibase_infra/nodes/architecture_validator/registry/registry_infra_architecture_validator.py +106 -0
  396. omnibase_infra/nodes/architecture_validator/validators/__init__.py +104 -0
  397. omnibase_infra/nodes/architecture_validator/validators/validator_no_direct_dispatch.py +422 -0
  398. omnibase_infra/nodes/architecture_validator/validators/validator_no_handler_publishing.py +481 -0
  399. omnibase_infra/nodes/architecture_validator/validators/validator_no_orchestrator_fsm.py +491 -0
  400. omnibase_infra/nodes/contract_registry_reducer/__init__.py +29 -0
  401. omnibase_infra/nodes/contract_registry_reducer/contract.yaml +255 -0
  402. omnibase_infra/nodes/contract_registry_reducer/models/__init__.py +38 -0
  403. omnibase_infra/nodes/contract_registry_reducer/models/model_contract_registry_state.py +266 -0
  404. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_cleanup_topic_references.py +55 -0
  405. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_deactivate_contract.py +58 -0
  406. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_mark_stale.py +49 -0
  407. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_update_heartbeat.py +71 -0
  408. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_update_topic.py +66 -0
  409. omnibase_infra/nodes/contract_registry_reducer/models/model_payload_upsert_contract.py +92 -0
  410. omnibase_infra/nodes/contract_registry_reducer/node.py +121 -0
  411. omnibase_infra/nodes/contract_registry_reducer/reducer.py +784 -0
  412. omnibase_infra/nodes/contract_registry_reducer/registry/__init__.py +9 -0
  413. omnibase_infra/nodes/contract_registry_reducer/registry/registry_infra_contract_registry_reducer.py +101 -0
  414. omnibase_infra/nodes/effects/README.md +358 -0
  415. omnibase_infra/nodes/effects/__init__.py +26 -0
  416. omnibase_infra/nodes/effects/contract.yaml +167 -0
  417. omnibase_infra/nodes/effects/models/__init__.py +32 -0
  418. omnibase_infra/nodes/effects/models/model_backend_result.py +190 -0
  419. omnibase_infra/nodes/effects/models/model_effect_idempotency_config.py +92 -0
  420. omnibase_infra/nodes/effects/models/model_registry_request.py +132 -0
  421. omnibase_infra/nodes/effects/models/model_registry_response.py +263 -0
  422. omnibase_infra/nodes/effects/protocol_consul_client.py +89 -0
  423. omnibase_infra/nodes/effects/protocol_effect_idempotency_store.py +143 -0
  424. omnibase_infra/nodes/effects/protocol_postgres_adapter.py +96 -0
  425. omnibase_infra/nodes/effects/registry_effect.py +525 -0
  426. omnibase_infra/nodes/effects/store_effect_idempotency_inmemory.py +425 -0
  427. omnibase_infra/nodes/handlers/consul/contract.yaml +85 -0
  428. omnibase_infra/nodes/handlers/db/contract.yaml +72 -0
  429. omnibase_infra/nodes/handlers/graph/contract.yaml +127 -0
  430. omnibase_infra/nodes/handlers/http/contract.yaml +74 -0
  431. omnibase_infra/nodes/handlers/intent/contract.yaml +66 -0
  432. omnibase_infra/nodes/handlers/mcp/contract.yaml +69 -0
  433. omnibase_infra/nodes/handlers/vault/contract.yaml +91 -0
  434. omnibase_infra/nodes/node_intent_storage_effect/__init__.py +50 -0
  435. omnibase_infra/nodes/node_intent_storage_effect/contract.yaml +194 -0
  436. omnibase_infra/nodes/node_intent_storage_effect/models/__init__.py +24 -0
  437. omnibase_infra/nodes/node_intent_storage_effect/models/model_intent_storage_input.py +141 -0
  438. omnibase_infra/nodes/node_intent_storage_effect/models/model_intent_storage_output.py +130 -0
  439. omnibase_infra/nodes/node_intent_storage_effect/node.py +94 -0
  440. omnibase_infra/nodes/node_intent_storage_effect/registry/__init__.py +35 -0
  441. omnibase_infra/nodes/node_intent_storage_effect/registry/registry_infra_intent_storage.py +294 -0
  442. omnibase_infra/nodes/node_ledger_projection_compute/__init__.py +50 -0
  443. omnibase_infra/nodes/node_ledger_projection_compute/contract.yaml +104 -0
  444. omnibase_infra/nodes/node_ledger_projection_compute/node.py +284 -0
  445. omnibase_infra/nodes/node_ledger_projection_compute/registry/__init__.py +29 -0
  446. omnibase_infra/nodes/node_ledger_projection_compute/registry/registry_infra_ledger_projection.py +118 -0
  447. omnibase_infra/nodes/node_ledger_write_effect/__init__.py +82 -0
  448. omnibase_infra/nodes/node_ledger_write_effect/contract.yaml +200 -0
  449. omnibase_infra/nodes/node_ledger_write_effect/handlers/__init__.py +22 -0
  450. omnibase_infra/nodes/node_ledger_write_effect/handlers/handler_ledger_append.py +372 -0
  451. omnibase_infra/nodes/node_ledger_write_effect/handlers/handler_ledger_query.py +597 -0
  452. omnibase_infra/nodes/node_ledger_write_effect/models/__init__.py +31 -0
  453. omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_append_result.py +54 -0
  454. omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_entry.py +92 -0
  455. omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_query.py +53 -0
  456. omnibase_infra/nodes/node_ledger_write_effect/models/model_ledger_query_result.py +41 -0
  457. omnibase_infra/nodes/node_ledger_write_effect/node.py +89 -0
  458. omnibase_infra/nodes/node_ledger_write_effect/protocols/__init__.py +13 -0
  459. omnibase_infra/nodes/node_ledger_write_effect/protocols/protocol_ledger_persistence.py +127 -0
  460. omnibase_infra/nodes/node_ledger_write_effect/registry/__init__.py +9 -0
  461. omnibase_infra/nodes/node_ledger_write_effect/registry/registry_infra_ledger_write.py +121 -0
  462. omnibase_infra/nodes/node_registration_orchestrator/README.md +542 -0
  463. omnibase_infra/nodes/node_registration_orchestrator/__init__.py +120 -0
  464. omnibase_infra/nodes/node_registration_orchestrator/contract.yaml +482 -0
  465. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/__init__.py +53 -0
  466. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_introspected.py +376 -0
  467. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_registration_acked.py +376 -0
  468. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_runtime_tick.py +373 -0
  469. omnibase_infra/nodes/node_registration_orchestrator/handlers/__init__.py +62 -0
  470. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_heartbeat.py +376 -0
  471. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_introspected.py +694 -0
  472. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_registration_acked.py +458 -0
  473. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_runtime_tick.py +364 -0
  474. omnibase_infra/nodes/node_registration_orchestrator/introspection_event_router.py +544 -0
  475. omnibase_infra/nodes/node_registration_orchestrator/models/__init__.py +75 -0
  476. omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_intent_payload.py +194 -0
  477. omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_registration_intent.py +67 -0
  478. omnibase_infra/nodes/node_registration_orchestrator/models/model_intent_execution_result.py +50 -0
  479. omnibase_infra/nodes/node_registration_orchestrator/models/model_node_liveness_expired.py +107 -0
  480. omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_config.py +67 -0
  481. omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_input.py +41 -0
  482. omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_output.py +166 -0
  483. omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_intent_payload.py +235 -0
  484. omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_upsert_intent.py +68 -0
  485. omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_execution_result.py +384 -0
  486. omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_state.py +60 -0
  487. omnibase_infra/nodes/node_registration_orchestrator/models/model_registration_intent.py +177 -0
  488. omnibase_infra/nodes/node_registration_orchestrator/models/model_registry_intent.py +247 -0
  489. omnibase_infra/nodes/node_registration_orchestrator/node.py +195 -0
  490. omnibase_infra/nodes/node_registration_orchestrator/plugin.py +909 -0
  491. omnibase_infra/nodes/node_registration_orchestrator/protocols.py +439 -0
  492. omnibase_infra/nodes/node_registration_orchestrator/registry/__init__.py +41 -0
  493. omnibase_infra/nodes/node_registration_orchestrator/registry/registry_infra_node_registration_orchestrator.py +528 -0
  494. omnibase_infra/nodes/node_registration_orchestrator/timeout_coordinator.py +393 -0
  495. omnibase_infra/nodes/node_registration_orchestrator/wiring.py +743 -0
  496. omnibase_infra/nodes/node_registration_reducer/__init__.py +15 -0
  497. omnibase_infra/nodes/node_registration_reducer/contract.yaml +301 -0
  498. omnibase_infra/nodes/node_registration_reducer/models/__init__.py +38 -0
  499. omnibase_infra/nodes/node_registration_reducer/models/model_validation_result.py +113 -0
  500. omnibase_infra/nodes/node_registration_reducer/node.py +139 -0
  501. omnibase_infra/nodes/node_registration_reducer/registry/__init__.py +9 -0
  502. omnibase_infra/nodes/node_registration_reducer/registry/registry_infra_node_registration_reducer.py +79 -0
  503. omnibase_infra/nodes/node_registration_storage_effect/__init__.py +41 -0
  504. omnibase_infra/nodes/node_registration_storage_effect/contract.yaml +220 -0
  505. omnibase_infra/nodes/node_registration_storage_effect/models/__init__.py +44 -0
  506. omnibase_infra/nodes/node_registration_storage_effect/models/model_delete_result.py +132 -0
  507. omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_record.py +199 -0
  508. omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_update.py +155 -0
  509. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_details.py +123 -0
  510. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_result.py +117 -0
  511. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_query.py +100 -0
  512. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_result.py +136 -0
  513. omnibase_infra/nodes/node_registration_storage_effect/models/model_upsert_result.py +127 -0
  514. omnibase_infra/nodes/node_registration_storage_effect/node.py +112 -0
  515. omnibase_infra/nodes/node_registration_storage_effect/protocols/__init__.py +22 -0
  516. omnibase_infra/nodes/node_registration_storage_effect/protocols/protocol_registration_persistence.py +333 -0
  517. omnibase_infra/nodes/node_registration_storage_effect/registry/__init__.py +23 -0
  518. omnibase_infra/nodes/node_registration_storage_effect/registry/registry_infra_registration_storage.py +215 -0
  519. omnibase_infra/nodes/node_registry_effect/__init__.py +85 -0
  520. omnibase_infra/nodes/node_registry_effect/contract.yaml +677 -0
  521. omnibase_infra/nodes/node_registry_effect/handlers/__init__.py +70 -0
  522. omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_deregister.py +211 -0
  523. omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_register.py +212 -0
  524. omnibase_infra/nodes/node_registry_effect/handlers/handler_partial_retry.py +417 -0
  525. omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_deactivate.py +215 -0
  526. omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_upsert.py +208 -0
  527. omnibase_infra/nodes/node_registry_effect/models/__init__.py +43 -0
  528. omnibase_infra/nodes/node_registry_effect/models/model_partial_retry_request.py +92 -0
  529. omnibase_infra/nodes/node_registry_effect/node.py +165 -0
  530. omnibase_infra/nodes/node_registry_effect/registry/__init__.py +27 -0
  531. omnibase_infra/nodes/node_registry_effect/registry/registry_infra_registry_effect.py +196 -0
  532. omnibase_infra/nodes/node_service_discovery_effect/__init__.py +111 -0
  533. omnibase_infra/nodes/node_service_discovery_effect/contract.yaml +246 -0
  534. omnibase_infra/nodes/node_service_discovery_effect/models/__init__.py +67 -0
  535. omnibase_infra/nodes/node_service_discovery_effect/models/enum_health_status.py +72 -0
  536. omnibase_infra/nodes/node_service_discovery_effect/models/enum_service_discovery_operation.py +58 -0
  537. omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_query.py +99 -0
  538. omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_result.py +98 -0
  539. omnibase_infra/nodes/node_service_discovery_effect/models/model_health_check_config.py +121 -0
  540. omnibase_infra/nodes/node_service_discovery_effect/models/model_query_metadata.py +63 -0
  541. omnibase_infra/nodes/node_service_discovery_effect/models/model_registration_result.py +130 -0
  542. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_details.py +111 -0
  543. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_result.py +119 -0
  544. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_info.py +106 -0
  545. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_registration.py +121 -0
  546. omnibase_infra/nodes/node_service_discovery_effect/node.py +111 -0
  547. omnibase_infra/nodes/node_service_discovery_effect/protocols/__init__.py +14 -0
  548. omnibase_infra/nodes/node_service_discovery_effect/protocols/protocol_discovery_operations.py +279 -0
  549. omnibase_infra/nodes/node_service_discovery_effect/registry/__init__.py +13 -0
  550. omnibase_infra/nodes/node_service_discovery_effect/registry/registry_infra_service_discovery.py +222 -0
  551. omnibase_infra/nodes/reducers/__init__.py +30 -0
  552. omnibase_infra/nodes/reducers/models/__init__.py +37 -0
  553. omnibase_infra/nodes/reducers/models/model_payload_consul_register.py +87 -0
  554. omnibase_infra/nodes/reducers/models/model_payload_ledger_append.py +133 -0
  555. omnibase_infra/nodes/reducers/models/model_payload_postgres_upsert_registration.py +60 -0
  556. omnibase_infra/nodes/reducers/models/model_registration_confirmation.py +166 -0
  557. omnibase_infra/nodes/reducers/models/model_registration_state.py +433 -0
  558. omnibase_infra/nodes/reducers/registration_reducer.py +1138 -0
  559. omnibase_infra/observability/__init__.py +143 -0
  560. omnibase_infra/observability/constants_metrics.py +91 -0
  561. omnibase_infra/observability/factory_observability_sink.py +525 -0
  562. omnibase_infra/observability/handlers/__init__.py +118 -0
  563. omnibase_infra/observability/handlers/handler_logging_structured.py +967 -0
  564. omnibase_infra/observability/handlers/handler_metrics_prometheus.py +1120 -0
  565. omnibase_infra/observability/handlers/model_logging_handler_config.py +71 -0
  566. omnibase_infra/observability/handlers/model_logging_handler_response.py +77 -0
  567. omnibase_infra/observability/handlers/model_metrics_handler_config.py +172 -0
  568. omnibase_infra/observability/handlers/model_metrics_handler_payload.py +135 -0
  569. omnibase_infra/observability/handlers/model_metrics_handler_response.py +101 -0
  570. omnibase_infra/observability/hooks/__init__.py +74 -0
  571. omnibase_infra/observability/hooks/hook_observability.py +1223 -0
  572. omnibase_infra/observability/models/__init__.py +30 -0
  573. omnibase_infra/observability/models/enum_required_log_context_key.py +77 -0
  574. omnibase_infra/observability/models/model_buffered_log_entry.py +117 -0
  575. omnibase_infra/observability/models/model_logging_sink_config.py +73 -0
  576. omnibase_infra/observability/models/model_metrics_sink_config.py +156 -0
  577. omnibase_infra/observability/sinks/__init__.py +69 -0
  578. omnibase_infra/observability/sinks/sink_logging_structured.py +809 -0
  579. omnibase_infra/observability/sinks/sink_metrics_prometheus.py +710 -0
  580. omnibase_infra/plugins/__init__.py +27 -0
  581. omnibase_infra/plugins/examples/__init__.py +28 -0
  582. omnibase_infra/plugins/examples/plugin_json_normalizer.py +271 -0
  583. omnibase_infra/plugins/examples/plugin_json_normalizer_error_handling.py +210 -0
  584. omnibase_infra/plugins/models/__init__.py +21 -0
  585. omnibase_infra/plugins/models/model_plugin_context.py +76 -0
  586. omnibase_infra/plugins/models/model_plugin_input_data.py +58 -0
  587. omnibase_infra/plugins/models/model_plugin_output_data.py +62 -0
  588. omnibase_infra/plugins/plugin_compute_base.py +449 -0
  589. omnibase_infra/projectors/__init__.py +30 -0
  590. omnibase_infra/projectors/contracts/__init__.py +63 -0
  591. omnibase_infra/projectors/contracts/registration_projector.yaml +370 -0
  592. omnibase_infra/projectors/projection_reader_registration.py +1559 -0
  593. omnibase_infra/projectors/snapshot_publisher_registration.py +1329 -0
  594. omnibase_infra/protocols/__init__.py +104 -0
  595. omnibase_infra/protocols/protocol_capability_projection.py +253 -0
  596. omnibase_infra/protocols/protocol_capability_query.py +251 -0
  597. omnibase_infra/protocols/protocol_container_aware.py +200 -0
  598. omnibase_infra/protocols/protocol_dispatch_engine.py +152 -0
  599. omnibase_infra/protocols/protocol_event_bus_like.py +127 -0
  600. omnibase_infra/protocols/protocol_event_projector.py +96 -0
  601. omnibase_infra/protocols/protocol_idempotency_store.py +142 -0
  602. omnibase_infra/protocols/protocol_message_dispatcher.py +247 -0
  603. omnibase_infra/protocols/protocol_message_type_registry.py +306 -0
  604. omnibase_infra/protocols/protocol_plugin_compute.py +368 -0
  605. omnibase_infra/protocols/protocol_projector_schema_validator.py +82 -0
  606. omnibase_infra/protocols/protocol_registry_metrics.py +215 -0
  607. omnibase_infra/protocols/protocol_snapshot_publisher.py +396 -0
  608. omnibase_infra/protocols/protocol_snapshot_store.py +567 -0
  609. omnibase_infra/runtime/__init__.py +445 -0
  610. omnibase_infra/runtime/binding_config_resolver.py +2771 -0
  611. omnibase_infra/runtime/binding_resolver.py +753 -0
  612. omnibase_infra/runtime/chain_aware_dispatch.py +467 -0
  613. omnibase_infra/runtime/constants_notification.py +75 -0
  614. omnibase_infra/runtime/constants_security.py +70 -0
  615. omnibase_infra/runtime/contract_handler_discovery.py +587 -0
  616. omnibase_infra/runtime/contract_loaders/__init__.py +51 -0
  617. omnibase_infra/runtime/contract_loaders/handler_routing_loader.py +464 -0
  618. omnibase_infra/runtime/contract_loaders/operation_bindings_loader.py +789 -0
  619. omnibase_infra/runtime/dispatch_context_enforcer.py +427 -0
  620. omnibase_infra/runtime/emit_daemon/__init__.py +97 -0
  621. omnibase_infra/runtime/emit_daemon/cli.py +844 -0
  622. omnibase_infra/runtime/emit_daemon/client.py +811 -0
  623. omnibase_infra/runtime/emit_daemon/config.py +535 -0
  624. omnibase_infra/runtime/emit_daemon/daemon.py +812 -0
  625. omnibase_infra/runtime/emit_daemon/event_registry.py +477 -0
  626. omnibase_infra/runtime/emit_daemon/model_daemon_request.py +139 -0
  627. omnibase_infra/runtime/emit_daemon/model_daemon_response.py +191 -0
  628. omnibase_infra/runtime/emit_daemon/queue.py +618 -0
  629. omnibase_infra/runtime/enums/__init__.py +18 -0
  630. omnibase_infra/runtime/enums/enum_config_ref_scheme.py +33 -0
  631. omnibase_infra/runtime/enums/enum_scheduler_status.py +170 -0
  632. omnibase_infra/runtime/envelope_validator.py +179 -0
  633. omnibase_infra/runtime/event_bus_subcontract_wiring.py +466 -0
  634. omnibase_infra/runtime/handler_bootstrap_source.py +507 -0
  635. omnibase_infra/runtime/handler_contract_config_loader.py +603 -0
  636. omnibase_infra/runtime/handler_contract_source.py +750 -0
  637. omnibase_infra/runtime/handler_identity.py +81 -0
  638. omnibase_infra/runtime/handler_plugin_loader.py +2046 -0
  639. omnibase_infra/runtime/handler_registry.py +329 -0
  640. omnibase_infra/runtime/handler_source_resolver.py +367 -0
  641. omnibase_infra/runtime/invocation_security_enforcer.py +427 -0
  642. omnibase_infra/runtime/kafka_contract_source.py +984 -0
  643. omnibase_infra/runtime/kernel.py +40 -0
  644. omnibase_infra/runtime/mixin_policy_validation.py +522 -0
  645. omnibase_infra/runtime/mixin_semver_cache.py +402 -0
  646. omnibase_infra/runtime/mixins/__init__.py +24 -0
  647. omnibase_infra/runtime/mixins/mixin_projector_notification_publishing.py +566 -0
  648. omnibase_infra/runtime/mixins/mixin_projector_sql_operations.py +778 -0
  649. omnibase_infra/runtime/models/__init__.py +229 -0
  650. omnibase_infra/runtime/models/model_batch_lifecycle_result.py +217 -0
  651. omnibase_infra/runtime/models/model_binding_config.py +168 -0
  652. omnibase_infra/runtime/models/model_binding_config_cache_stats.py +135 -0
  653. omnibase_infra/runtime/models/model_binding_config_resolver_config.py +329 -0
  654. omnibase_infra/runtime/models/model_cached_secret.py +138 -0
  655. omnibase_infra/runtime/models/model_compute_key.py +138 -0
  656. omnibase_infra/runtime/models/model_compute_registration.py +97 -0
  657. omnibase_infra/runtime/models/model_config_cache_entry.py +61 -0
  658. omnibase_infra/runtime/models/model_config_ref.py +331 -0
  659. omnibase_infra/runtime/models/model_config_ref_parse_result.py +125 -0
  660. omnibase_infra/runtime/models/model_contract_load_result.py +224 -0
  661. omnibase_infra/runtime/models/model_domain_plugin_config.py +92 -0
  662. omnibase_infra/runtime/models/model_domain_plugin_result.py +270 -0
  663. omnibase_infra/runtime/models/model_duplicate_response.py +54 -0
  664. omnibase_infra/runtime/models/model_enabled_protocols_config.py +61 -0
  665. omnibase_infra/runtime/models/model_event_bus_config.py +54 -0
  666. omnibase_infra/runtime/models/model_failed_component.py +55 -0
  667. omnibase_infra/runtime/models/model_health_check_response.py +168 -0
  668. omnibase_infra/runtime/models/model_health_check_result.py +229 -0
  669. omnibase_infra/runtime/models/model_lifecycle_result.py +245 -0
  670. omnibase_infra/runtime/models/model_logging_config.py +42 -0
  671. omnibase_infra/runtime/models/model_optional_correlation_id.py +167 -0
  672. omnibase_infra/runtime/models/model_optional_string.py +94 -0
  673. omnibase_infra/runtime/models/model_optional_uuid.py +110 -0
  674. omnibase_infra/runtime/models/model_policy_context.py +100 -0
  675. omnibase_infra/runtime/models/model_policy_key.py +138 -0
  676. omnibase_infra/runtime/models/model_policy_registration.py +139 -0
  677. omnibase_infra/runtime/models/model_policy_result.py +103 -0
  678. omnibase_infra/runtime/models/model_policy_type_filter.py +157 -0
  679. omnibase_infra/runtime/models/model_projector_notification_config.py +171 -0
  680. omnibase_infra/runtime/models/model_projector_plugin_loader_config.py +47 -0
  681. omnibase_infra/runtime/models/model_protocol_registration_config.py +65 -0
  682. omnibase_infra/runtime/models/model_retry_policy.py +105 -0
  683. omnibase_infra/runtime/models/model_runtime_config.py +150 -0
  684. omnibase_infra/runtime/models/model_runtime_contract_config.py +268 -0
  685. omnibase_infra/runtime/models/model_runtime_scheduler_config.py +625 -0
  686. omnibase_infra/runtime/models/model_runtime_scheduler_metrics.py +233 -0
  687. omnibase_infra/runtime/models/model_runtime_tick.py +193 -0
  688. omnibase_infra/runtime/models/model_secret_cache_stats.py +82 -0
  689. omnibase_infra/runtime/models/model_secret_mapping.py +63 -0
  690. omnibase_infra/runtime/models/model_secret_resolver_config.py +107 -0
  691. omnibase_infra/runtime/models/model_secret_resolver_metrics.py +111 -0
  692. omnibase_infra/runtime/models/model_secret_source_info.py +72 -0
  693. omnibase_infra/runtime/models/model_secret_source_spec.py +66 -0
  694. omnibase_infra/runtime/models/model_security_config.py +109 -0
  695. omnibase_infra/runtime/models/model_shutdown_batch_result.py +75 -0
  696. omnibase_infra/runtime/models/model_shutdown_config.py +94 -0
  697. omnibase_infra/runtime/models/model_transition_notification_outbox_config.py +112 -0
  698. omnibase_infra/runtime/models/model_transition_notification_outbox_metrics.py +140 -0
  699. omnibase_infra/runtime/models/model_transition_notification_publisher_metrics.py +357 -0
  700. omnibase_infra/runtime/projector_plugin_loader.py +1462 -0
  701. omnibase_infra/runtime/projector_schema_manager.py +565 -0
  702. omnibase_infra/runtime/projector_shell.py +1330 -0
  703. omnibase_infra/runtime/protocol_contract_descriptor.py +92 -0
  704. omnibase_infra/runtime/protocol_contract_source.py +92 -0
  705. omnibase_infra/runtime/protocol_domain_plugin.py +474 -0
  706. omnibase_infra/runtime/protocol_handler_discovery.py +221 -0
  707. omnibase_infra/runtime/protocol_handler_plugin_loader.py +327 -0
  708. omnibase_infra/runtime/protocol_lifecycle_executor.py +435 -0
  709. omnibase_infra/runtime/protocol_policy.py +366 -0
  710. omnibase_infra/runtime/protocols/__init__.py +37 -0
  711. omnibase_infra/runtime/protocols/protocol_runtime_scheduler.py +468 -0
  712. omnibase_infra/runtime/publisher_topic_scoped.py +294 -0
  713. omnibase_infra/runtime/registry/__init__.py +93 -0
  714. omnibase_infra/runtime/registry/mixin_message_type_query.py +326 -0
  715. omnibase_infra/runtime/registry/mixin_message_type_registration.py +354 -0
  716. omnibase_infra/runtime/registry/registry_event_bus_binding.py +268 -0
  717. omnibase_infra/runtime/registry/registry_message_type.py +542 -0
  718. omnibase_infra/runtime/registry/registry_protocol_binding.py +445 -0
  719. omnibase_infra/runtime/registry_compute.py +1143 -0
  720. omnibase_infra/runtime/registry_contract_source.py +693 -0
  721. omnibase_infra/runtime/registry_dispatcher.py +678 -0
  722. omnibase_infra/runtime/registry_policy.py +1185 -0
  723. omnibase_infra/runtime/runtime_contract_config_loader.py +406 -0
  724. omnibase_infra/runtime/runtime_scheduler.py +1070 -0
  725. omnibase_infra/runtime/secret_resolver.py +2112 -0
  726. omnibase_infra/runtime/security_metadata_validator.py +776 -0
  727. omnibase_infra/runtime/service_kernel.py +1651 -0
  728. omnibase_infra/runtime/service_message_dispatch_engine.py +2350 -0
  729. omnibase_infra/runtime/service_runtime_host_process.py +3493 -0
  730. omnibase_infra/runtime/transition_notification_outbox.py +1190 -0
  731. omnibase_infra/runtime/transition_notification_publisher.py +765 -0
  732. omnibase_infra/runtime/util_container_wiring.py +1124 -0
  733. omnibase_infra/runtime/util_validation.py +314 -0
  734. omnibase_infra/runtime/util_version.py +98 -0
  735. omnibase_infra/runtime/util_wiring.py +723 -0
  736. omnibase_infra/schemas/schema_registration_projection.sql +320 -0
  737. omnibase_infra/schemas/schema_transition_notification_outbox.sql +245 -0
  738. omnibase_infra/services/__init__.py +89 -0
  739. omnibase_infra/services/corpus_capture.py +684 -0
  740. omnibase_infra/services/mcp/__init__.py +31 -0
  741. omnibase_infra/services/mcp/mcp_server_lifecycle.py +449 -0
  742. omnibase_infra/services/mcp/service_mcp_tool_discovery.py +411 -0
  743. omnibase_infra/services/mcp/service_mcp_tool_registry.py +329 -0
  744. omnibase_infra/services/mcp/service_mcp_tool_sync.py +565 -0
  745. omnibase_infra/services/registry_api/__init__.py +40 -0
  746. omnibase_infra/services/registry_api/main.py +261 -0
  747. omnibase_infra/services/registry_api/models/__init__.py +66 -0
  748. omnibase_infra/services/registry_api/models/model_capability_widget_mapping.py +38 -0
  749. omnibase_infra/services/registry_api/models/model_pagination_info.py +48 -0
  750. omnibase_infra/services/registry_api/models/model_registry_discovery_response.py +73 -0
  751. omnibase_infra/services/registry_api/models/model_registry_health_response.py +49 -0
  752. omnibase_infra/services/registry_api/models/model_registry_instance_view.py +88 -0
  753. omnibase_infra/services/registry_api/models/model_registry_node_view.py +88 -0
  754. omnibase_infra/services/registry_api/models/model_registry_summary.py +60 -0
  755. omnibase_infra/services/registry_api/models/model_response_list_instances.py +43 -0
  756. omnibase_infra/services/registry_api/models/model_response_list_nodes.py +51 -0
  757. omnibase_infra/services/registry_api/models/model_warning.py +49 -0
  758. omnibase_infra/services/registry_api/models/model_widget_defaults.py +28 -0
  759. omnibase_infra/services/registry_api/models/model_widget_mapping.py +51 -0
  760. omnibase_infra/services/registry_api/routes.py +371 -0
  761. omnibase_infra/services/registry_api/service.py +837 -0
  762. omnibase_infra/services/service_capability_query.py +945 -0
  763. omnibase_infra/services/service_health.py +898 -0
  764. omnibase_infra/services/service_node_selector.py +530 -0
  765. omnibase_infra/services/service_timeout_emitter.py +699 -0
  766. omnibase_infra/services/service_timeout_scanner.py +394 -0
  767. omnibase_infra/services/session/__init__.py +56 -0
  768. omnibase_infra/services/session/config_consumer.py +137 -0
  769. omnibase_infra/services/session/config_store.py +139 -0
  770. omnibase_infra/services/session/consumer.py +1007 -0
  771. omnibase_infra/services/session/protocol_session_aggregator.py +117 -0
  772. omnibase_infra/services/session/store.py +997 -0
  773. omnibase_infra/services/snapshot/__init__.py +31 -0
  774. omnibase_infra/services/snapshot/service_snapshot.py +647 -0
  775. omnibase_infra/services/snapshot/store_inmemory.py +637 -0
  776. omnibase_infra/services/snapshot/store_postgres.py +1279 -0
  777. omnibase_infra/shared/__init__.py +8 -0
  778. omnibase_infra/testing/__init__.py +10 -0
  779. omnibase_infra/testing/utils.py +23 -0
  780. omnibase_infra/topics/__init__.py +45 -0
  781. omnibase_infra/topics/platform_topic_suffixes.py +140 -0
  782. omnibase_infra/topics/util_topic_composition.py +95 -0
  783. omnibase_infra/types/__init__.py +48 -0
  784. omnibase_infra/types/type_cache_info.py +49 -0
  785. omnibase_infra/types/type_dsn.py +173 -0
  786. omnibase_infra/types/type_infra_aliases.py +60 -0
  787. omnibase_infra/types/typed_dict/__init__.py +29 -0
  788. omnibase_infra/types/typed_dict/typed_dict_envelope_build_params.py +115 -0
  789. omnibase_infra/types/typed_dict/typed_dict_introspection_cache.py +128 -0
  790. omnibase_infra/types/typed_dict/typed_dict_performance_metrics_cache.py +140 -0
  791. omnibase_infra/types/typed_dict_capabilities.py +64 -0
  792. omnibase_infra/utils/__init__.py +117 -0
  793. omnibase_infra/utils/correlation.py +208 -0
  794. omnibase_infra/utils/util_atomic_file.py +261 -0
  795. omnibase_infra/utils/util_consumer_group.py +232 -0
  796. omnibase_infra/utils/util_datetime.py +372 -0
  797. omnibase_infra/utils/util_db_transaction.py +239 -0
  798. omnibase_infra/utils/util_dsn_validation.py +333 -0
  799. omnibase_infra/utils/util_env_parsing.py +264 -0
  800. omnibase_infra/utils/util_error_sanitization.py +457 -0
  801. omnibase_infra/utils/util_pydantic_validators.py +477 -0
  802. omnibase_infra/utils/util_retry_optimistic.py +281 -0
  803. omnibase_infra/utils/util_semver.py +233 -0
  804. omnibase_infra/validation/__init__.py +307 -0
  805. omnibase_infra/validation/contracts/security.validation.yaml +114 -0
  806. omnibase_infra/validation/enums/__init__.py +11 -0
  807. omnibase_infra/validation/enums/enum_contract_violation_severity.py +13 -0
  808. omnibase_infra/validation/infra_validators.py +1514 -0
  809. omnibase_infra/validation/linter_contract.py +907 -0
  810. omnibase_infra/validation/mixin_any_type_classification.py +120 -0
  811. omnibase_infra/validation/mixin_any_type_exemption.py +580 -0
  812. omnibase_infra/validation/mixin_any_type_reporting.py +106 -0
  813. omnibase_infra/validation/mixin_execution_shape_violation_checks.py +596 -0
  814. omnibase_infra/validation/mixin_node_archetype_detection.py +254 -0
  815. omnibase_infra/validation/models/__init__.py +15 -0
  816. omnibase_infra/validation/models/model_contract_lint_result.py +101 -0
  817. omnibase_infra/validation/models/model_contract_violation.py +41 -0
  818. omnibase_infra/validation/service_validation_aggregator.py +395 -0
  819. omnibase_infra/validation/validation_exemptions.yaml +2033 -0
  820. omnibase_infra/validation/validator_any_type.py +715 -0
  821. omnibase_infra/validation/validator_chain_propagation.py +839 -0
  822. omnibase_infra/validation/validator_execution_shape.py +465 -0
  823. omnibase_infra/validation/validator_localhandler.py +261 -0
  824. omnibase_infra/validation/validator_registration_security.py +410 -0
  825. omnibase_infra/validation/validator_routing_coverage.py +1020 -0
  826. omnibase_infra/validation/validator_runtime_shape.py +915 -0
  827. omnibase_infra/validation/validator_security.py +513 -0
  828. omnibase_infra/validation/validator_topic_category.py +1152 -0
  829. omnibase_infra-0.2.6.dist-info/METADATA +197 -0
  830. omnibase_infra-0.2.6.dist-info/RECORD +833 -0
  831. omnibase_infra-0.2.6.dist-info/WHEEL +4 -0
  832. omnibase_infra-0.2.6.dist-info/entry_points.txt +5 -0
  833. omnibase_infra-0.2.6.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,922 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """PostgreSQL Registration Storage Handler.
4
+
5
+ This module provides a PostgreSQL-backed implementation of the registration
6
+ storage handler protocol, wrapping existing PostgreSQL functionality with
7
+ circuit breaker resilience.
8
+
9
+ Connection Pooling:
10
+ - Uses asyncpg connection pool for efficient database access
11
+ - Configurable pool size (default: 10)
12
+ - Pool gracefully closed on handler shutdown
13
+
14
+ Circuit Breaker:
15
+ - Uses MixinAsyncCircuitBreaker for consistent resilience
16
+ - Three states: CLOSED (normal), OPEN (blocking), HALF_OPEN (testing)
17
+ - Configurable failure threshold and reset timeout
18
+
19
+ SQL Security:
20
+ All SQL queries in this module use parameterized queries with positional
21
+ placeholders ($1, $2, etc.) to prevent SQL injection attacks. The asyncpg
22
+ library handles proper escaping and type conversion for all parameters.
23
+
24
+ Query parameters are ALWAYS passed as separate arguments to execute/fetch
25
+ methods, never interpolated into SQL strings:
26
+
27
+ SAFE:
28
+ await conn.execute("SELECT * FROM users WHERE id = $1", user_id)
29
+
30
+ UNSAFE (never do this):
31
+ await conn.execute(f"SELECT * FROM users WHERE id = {user_id}") # WRONG!
32
+
33
+ Dynamic WHERE clauses (e.g., in query_registrations) are built by appending
34
+ conditions with parameterized placeholders, not by string interpolation of
35
+ user values.
36
+ """
37
+
38
+ from __future__ import annotations
39
+
40
+ import asyncio
41
+ import json
42
+ import logging
43
+ import time
44
+ from datetime import UTC, datetime
45
+ from typing import TYPE_CHECKING
46
+ from uuid import UUID, uuid4
47
+
48
+ # Import asyncpg at module level to avoid redundant imports inside methods
49
+ import asyncpg
50
+
51
+ from omnibase_core.container import ModelONEXContainer
52
+ from omnibase_core.enums.enum_node_kind import EnumNodeKind
53
+ from omnibase_infra.enums import EnumInfraTransportType
54
+ from omnibase_infra.errors import (
55
+ InfraConnectionError,
56
+ InfraTimeoutError,
57
+ ModelInfraErrorContext,
58
+ ModelTimeoutErrorContext,
59
+ )
60
+ from omnibase_infra.handlers.registration_storage.models import (
61
+ ModelDeleteRegistrationRequest,
62
+ ModelUpdateRegistrationRequest,
63
+ )
64
+ from omnibase_infra.mixins import MixinAsyncCircuitBreaker
65
+ from omnibase_infra.models.resilience import ModelCircuitBreakerConfig
66
+ from omnibase_infra.nodes.node_registration_storage_effect.models import (
67
+ ModelDeleteResult,
68
+ ModelRegistrationRecord,
69
+ ModelStorageHealthCheckDetails,
70
+ ModelStorageHealthCheckResult,
71
+ ModelStorageQuery,
72
+ ModelStorageResult,
73
+ ModelUpsertResult,
74
+ )
75
+
76
+ if TYPE_CHECKING:
77
+ from omnibase_infra.nodes.effects.protocol_postgres_adapter import (
78
+ ProtocolPostgresAdapter,
79
+ )
80
+
81
+ logger = logging.getLogger(__name__)
82
+
83
+ # Default configuration values
84
+ DEFAULT_CIRCUIT_BREAKER_THRESHOLD = 5
85
+ DEFAULT_CIRCUIT_BREAKER_RESET_TIMEOUT = 30.0
86
+ DEFAULT_POOL_SIZE = 10
87
+ DEFAULT_TIMEOUT_SECONDS = 30.0
88
+
89
+ # SQL statements
90
+ SQL_CREATE_TABLE = """
91
+ CREATE TABLE IF NOT EXISTS node_registrations (
92
+ node_id UUID PRIMARY KEY,
93
+ node_type VARCHAR(64) NOT NULL,
94
+ node_version VARCHAR(32) NOT NULL,
95
+ capabilities JSONB NOT NULL DEFAULT '[]',
96
+ endpoints JSONB NOT NULL DEFAULT '{}',
97
+ metadata JSONB NOT NULL DEFAULT '{}',
98
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
99
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
100
+ );
101
+ """
102
+
103
+ SQL_UPSERT = """
104
+ INSERT INTO node_registrations (node_id, node_type, node_version, capabilities, endpoints, metadata, created_at, updated_at)
105
+ VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
106
+ ON CONFLICT (node_id) DO UPDATE SET
107
+ node_type = EXCLUDED.node_type,
108
+ node_version = EXCLUDED.node_version,
109
+ capabilities = EXCLUDED.capabilities,
110
+ endpoints = EXCLUDED.endpoints,
111
+ metadata = EXCLUDED.metadata,
112
+ updated_at = EXCLUDED.updated_at
113
+ RETURNING (xmax = 0) AS was_insert;
114
+ """
115
+
116
+ SQL_QUERY_BASE = """
117
+ SELECT node_id, node_type, node_version, capabilities, endpoints, metadata, created_at, updated_at
118
+ FROM node_registrations
119
+ """
120
+
121
+ SQL_QUERY_COUNT = """
122
+ SELECT COUNT(*) FROM node_registrations
123
+ """
124
+
125
+ SQL_UPDATE = """
126
+ UPDATE node_registrations SET
127
+ capabilities = COALESCE($2, capabilities),
128
+ endpoints = COALESCE($3, endpoints),
129
+ metadata = COALESCE($4, metadata),
130
+ node_version = COALESCE($5, node_version),
131
+ updated_at = NOW()
132
+ WHERE node_id = $1
133
+ RETURNING node_id;
134
+ """
135
+
136
+ SQL_DELETE = """
137
+ DELETE FROM node_registrations WHERE node_id = $1 RETURNING node_id;
138
+ """
139
+
140
+
141
+ class HandlerRegistrationStoragePostgres(MixinAsyncCircuitBreaker):
142
+ """PostgreSQL implementation of ProtocolRegistrationStorageHandler.
143
+
144
+ Wraps existing PostgreSQL adapter functionality with circuit breaker
145
+ resilience and proper error handling.
146
+
147
+ Thread Safety:
148
+ This handler is coroutine-safe. All database operations use
149
+ asyncpg's connection pool, and circuit breaker state is protected
150
+ by asyncio.Lock.
151
+
152
+ Attributes:
153
+ handler_type: Returns "postgresql" identifier.
154
+
155
+ Example:
156
+ >>> from omnibase_core.container import ModelONEXContainer
157
+ >>> container = ModelONEXContainer(...)
158
+ >>> handler = HandlerRegistrationStoragePostgres(
159
+ ... container=container,
160
+ ... postgres_adapter=postgres_adapter,
161
+ ... circuit_breaker_config={"threshold": 5, "reset_timeout": 30.0},
162
+ ... )
163
+ >>> result = await handler.store_registration(record)
164
+ """
165
+
166
+ def __init__(
167
+ self,
168
+ container: ModelONEXContainer,
169
+ postgres_adapter: ProtocolPostgresAdapter | None = None,
170
+ dsn: str | None = None,
171
+ host: str = "localhost",
172
+ port: int = 5432,
173
+ database: str = "omninode_bridge",
174
+ user: str = "postgres",
175
+ password: str | None = None,
176
+ pool_size: int = DEFAULT_POOL_SIZE,
177
+ circuit_breaker_config: ModelCircuitBreakerConfig
178
+ | dict[str, object]
179
+ | None = None,
180
+ timeout_seconds: float = DEFAULT_TIMEOUT_SECONDS,
181
+ auto_create_schema: bool = False,
182
+ ) -> None:
183
+ """Initialize HandlerRegistrationStoragePostgres.
184
+
185
+ Args:
186
+ container: ONEX dependency injection container (required).
187
+ postgres_adapter: Optional existing PostgreSQL adapter (ProtocolPostgresAdapter).
188
+ If not provided, a new asyncpg connection pool will be created.
189
+ dsn: Optional PostgreSQL connection DSN (overrides host/port/etc).
190
+ host: PostgreSQL server hostname (default: "localhost").
191
+ port: PostgreSQL server port (default: 5432).
192
+ database: Database name (default: "omninode_bridge").
193
+ user: Database user (default: "postgres").
194
+ password: Optional database password.
195
+ pool_size: Connection pool size (default: 10).
196
+ circuit_breaker_config: Optional circuit breaker configuration.
197
+ Accepts ModelCircuitBreakerConfig or dict with keys:
198
+ - threshold: Max failures before opening (default: 5)
199
+ - reset_timeout_seconds: Seconds before reset (default: 60.0)
200
+ - service_name: Service identifier (default: "postgres.storage")
201
+ timeout_seconds: Operation timeout in seconds (default: 30.0).
202
+ auto_create_schema: If True, automatically create the node_registrations
203
+ table on first connection. Default is False. Production deployments
204
+ should use database migrations instead of auto-creation.
205
+ """
206
+ self._container = container
207
+ # Normalize circuit breaker config to ModelCircuitBreakerConfig
208
+ if isinstance(circuit_breaker_config, ModelCircuitBreakerConfig):
209
+ cb_config = circuit_breaker_config
210
+ elif circuit_breaker_config is not None:
211
+ # Handle dict with legacy key names (reset_timeout -> reset_timeout_seconds)
212
+ config_dict = dict(circuit_breaker_config)
213
+ if (
214
+ "reset_timeout" in config_dict
215
+ and "reset_timeout_seconds" not in config_dict
216
+ ):
217
+ config_dict["reset_timeout_seconds"] = config_dict.pop("reset_timeout")
218
+ # Set defaults for service_name and transport_type if not provided
219
+ config_dict.setdefault("service_name", "postgres.storage")
220
+ config_dict.setdefault("transport_type", EnumInfraTransportType.DATABASE)
221
+ cb_config = ModelCircuitBreakerConfig(**config_dict)
222
+ else:
223
+ cb_config = ModelCircuitBreakerConfig(
224
+ service_name="postgres.storage",
225
+ transport_type=EnumInfraTransportType.DATABASE,
226
+ )
227
+
228
+ self._init_circuit_breaker(
229
+ threshold=cb_config.threshold,
230
+ reset_timeout=cb_config.reset_timeout_seconds,
231
+ service_name=cb_config.service_name,
232
+ transport_type=cb_config.transport_type,
233
+ )
234
+
235
+ # Store configuration
236
+ self._dsn = dsn
237
+ self._host = host
238
+ self._port = port
239
+ self._database = database
240
+ self._user = user
241
+ self._password = password
242
+ self._pool_size = pool_size
243
+ self._timeout_seconds = timeout_seconds
244
+ self._auto_create_schema = auto_create_schema
245
+
246
+ # Connection pool (initialized on first use)
247
+ self._pool: asyncpg.Pool | None = None
248
+ self._pool_lock = asyncio.Lock()
249
+ self._initialized = False
250
+
251
+ # External adapter (if provided)
252
+ self._postgres_adapter = postgres_adapter
253
+
254
+ logger.info(
255
+ "HandlerRegistrationStoragePostgres created",
256
+ extra={
257
+ "host": host,
258
+ "port": port,
259
+ "database": database,
260
+ "pool_size": pool_size,
261
+ },
262
+ )
263
+
264
+ @property
265
+ def handler_type(self) -> str:
266
+ """Return the handler type identifier.
267
+
268
+ Returns:
269
+ "postgresql" identifier string.
270
+ """
271
+ return "postgresql"
272
+
273
+ async def _ensure_pool(
274
+ self,
275
+ correlation_id: UUID | None = None,
276
+ ) -> asyncpg.Pool:
277
+ """Ensure connection pool is initialized.
278
+
279
+ Args:
280
+ correlation_id: Optional correlation ID for tracing.
281
+
282
+ Returns:
283
+ The asyncpg connection pool.
284
+
285
+ Raises:
286
+ InfraConnectionError: If pool creation fails.
287
+ """
288
+ if self._pool is not None:
289
+ return self._pool
290
+
291
+ async with self._pool_lock:
292
+ # Double-check after acquiring lock
293
+ if self._pool is not None:
294
+ return self._pool
295
+
296
+ try:
297
+ if self._dsn:
298
+ self._pool = await asyncpg.create_pool(
299
+ dsn=self._dsn,
300
+ min_size=1,
301
+ max_size=self._pool_size,
302
+ )
303
+ else:
304
+ self._pool = await asyncpg.create_pool(
305
+ host=self._host,
306
+ port=self._port,
307
+ database=self._database,
308
+ user=self._user,
309
+ password=self._password,
310
+ min_size=1,
311
+ max_size=self._pool_size,
312
+ )
313
+
314
+ # Create table only if auto_create_schema is enabled
315
+ # Production deployments should use database migrations
316
+ if self._auto_create_schema:
317
+ async with self._pool.acquire() as conn:
318
+ await conn.execute(SQL_CREATE_TABLE)
319
+
320
+ self._initialized = True
321
+
322
+ logger.info(
323
+ "PostgreSQL connection pool initialized",
324
+ extra={
325
+ "host": self._host,
326
+ "port": self._port,
327
+ "database": self._database,
328
+ "auto_create_schema": self._auto_create_schema,
329
+ },
330
+ )
331
+
332
+ return self._pool
333
+
334
+ except Exception as e:
335
+ context = ModelInfraErrorContext(
336
+ transport_type=EnumInfraTransportType.DATABASE,
337
+ operation="initialize_pool",
338
+ target_name="postgres.storage",
339
+ correlation_id=correlation_id,
340
+ )
341
+ raise InfraConnectionError(
342
+ f"Failed to initialize PostgreSQL pool: {type(e).__name__}",
343
+ context=context,
344
+ ) from e
345
+
346
+ async def store_registration(
347
+ self,
348
+ record: ModelRegistrationRecord,
349
+ correlation_id: UUID | None = None,
350
+ ) -> ModelUpsertResult:
351
+ """Store a registration record in PostgreSQL.
352
+
353
+ Args:
354
+ record: Registration record to store.
355
+ correlation_id: Optional correlation ID for tracing.
356
+
357
+ Returns:
358
+ ModelUpsertResult with upsert outcome.
359
+
360
+ Raises:
361
+ InfraConnectionError: If connection to PostgreSQL fails.
362
+ InfraTimeoutError: If operation times out.
363
+ InfraUnavailableError: If circuit breaker is open.
364
+ """
365
+ correlation_id = correlation_id or uuid4()
366
+ start_time = time.monotonic()
367
+
368
+ # Check circuit breaker
369
+ async with self._circuit_breaker_lock:
370
+ await self._check_circuit_breaker(
371
+ operation="store_registration",
372
+ correlation_id=correlation_id,
373
+ )
374
+
375
+ try:
376
+ pool = await self._ensure_pool(correlation_id=correlation_id)
377
+
378
+ now = datetime.now(UTC)
379
+ capabilities_json = json.dumps(record.capabilities)
380
+ endpoints_json = json.dumps(record.endpoints)
381
+ metadata_json = json.dumps(record.metadata)
382
+
383
+ async with pool.acquire() as conn:
384
+ result = await asyncio.wait_for(
385
+ conn.fetchrow(
386
+ SQL_UPSERT,
387
+ record.node_id,
388
+ record.node_type.value,
389
+ record.node_version,
390
+ capabilities_json,
391
+ endpoints_json,
392
+ metadata_json,
393
+ record.created_at or now,
394
+ now,
395
+ ),
396
+ timeout=self._timeout_seconds,
397
+ )
398
+
399
+ # Reset circuit breaker on success
400
+ async with self._circuit_breaker_lock:
401
+ await self._reset_circuit_breaker()
402
+
403
+ was_insert = result["was_insert"] if result else False
404
+ operation = "insert" if was_insert else "update"
405
+ duration_ms = (time.monotonic() - start_time) * 1000
406
+
407
+ logger.info(
408
+ "Registration stored in PostgreSQL",
409
+ extra={
410
+ "node_id": str(record.node_id),
411
+ "operation": operation,
412
+ "duration_ms": duration_ms,
413
+ "correlation_id": str(correlation_id),
414
+ },
415
+ )
416
+
417
+ return ModelUpsertResult(
418
+ success=True,
419
+ node_id=record.node_id,
420
+ operation=operation,
421
+ duration_ms=duration_ms,
422
+ backend_type=self.handler_type,
423
+ correlation_id=correlation_id,
424
+ )
425
+
426
+ except TimeoutError as e:
427
+ async with self._circuit_breaker_lock:
428
+ await self._record_circuit_failure(
429
+ operation="store_registration",
430
+ correlation_id=correlation_id,
431
+ )
432
+ duration_ms = (time.monotonic() - start_time) * 1000
433
+ raise InfraTimeoutError(
434
+ f"PostgreSQL upsert timed out after {self._timeout_seconds}s",
435
+ context=ModelTimeoutErrorContext(
436
+ transport_type=EnumInfraTransportType.DATABASE,
437
+ operation="store_registration",
438
+ target_name="postgres.storage",
439
+ correlation_id=correlation_id,
440
+ timeout_seconds=self._timeout_seconds,
441
+ ),
442
+ ) from e
443
+
444
+ except Exception as e:
445
+ async with self._circuit_breaker_lock:
446
+ await self._record_circuit_failure(
447
+ operation="store_registration",
448
+ correlation_id=correlation_id,
449
+ )
450
+ duration_ms = (time.monotonic() - start_time) * 1000
451
+ context = ModelInfraErrorContext(
452
+ transport_type=EnumInfraTransportType.DATABASE,
453
+ operation="store_registration",
454
+ target_name="postgres.storage",
455
+ correlation_id=correlation_id,
456
+ )
457
+ raise InfraConnectionError(
458
+ f"PostgreSQL upsert failed: {type(e).__name__}",
459
+ context=context,
460
+ ) from e
461
+
462
+ async def query_registrations(
463
+ self,
464
+ query: ModelStorageQuery,
465
+ correlation_id: UUID | None = None,
466
+ ) -> ModelStorageResult:
467
+ """Query registration records from PostgreSQL.
468
+
469
+ Args:
470
+ query: ModelStorageQuery containing filter and pagination parameters.
471
+ correlation_id: Optional correlation ID for tracing.
472
+
473
+ Returns:
474
+ ModelStorageResult with list of matching records.
475
+
476
+ Raises:
477
+ InfraConnectionError: If connection to PostgreSQL fails.
478
+ InfraTimeoutError: If operation times out.
479
+ InfraUnavailableError: If circuit breaker is open.
480
+ """
481
+ correlation_id = correlation_id or uuid4()
482
+ start_time = time.monotonic()
483
+
484
+ # Check circuit breaker
485
+ async with self._circuit_breaker_lock:
486
+ await self._check_circuit_breaker(
487
+ operation="query_registrations",
488
+ correlation_id=correlation_id,
489
+ )
490
+
491
+ try:
492
+ pool = await self._ensure_pool(correlation_id=correlation_id)
493
+
494
+ # Build query with parameterized filters
495
+ # NOTE: All filter values use positional parameters ($1, $2, etc.)
496
+ # to prevent SQL injection. The param_idx tracks parameter positions.
497
+ # User values are NEVER interpolated into SQL strings.
498
+ conditions: list[str] = []
499
+ params: list[object] = []
500
+ param_idx = 1
501
+
502
+ # Filter by node_id if specified (exact match)
503
+ if query.node_id is not None:
504
+ conditions.append(f"node_id = ${param_idx}")
505
+ params.append(query.node_id)
506
+ param_idx += 1
507
+
508
+ # Filter by node_type if specified
509
+ if query.node_type is not None:
510
+ conditions.append(f"node_type = ${param_idx}")
511
+ params.append(query.node_type.value)
512
+ param_idx += 1
513
+
514
+ # Filter by capability (JSONB array contains match)
515
+ if query.capability_filter is not None:
516
+ # Use JSONB containment operator to check if capability exists in array
517
+ conditions.append(f"capabilities @> ${param_idx}::jsonb")
518
+ params.append(json.dumps([query.capability_filter]))
519
+ param_idx += 1
520
+
521
+ where_clause = ""
522
+ if conditions:
523
+ where_clause = " WHERE " + " AND ".join(conditions)
524
+
525
+ # Query for records with pagination
526
+ sql_query = f"{SQL_QUERY_BASE}{where_clause} ORDER BY updated_at DESC LIMIT ${param_idx} OFFSET ${param_idx + 1}"
527
+ params.extend([query.limit, query.offset])
528
+
529
+ # Query for total count
530
+ count_query = f"{SQL_QUERY_COUNT}{where_clause}"
531
+ count_params = params[:-2] # Exclude limit and offset
532
+
533
+ async with pool.acquire() as conn:
534
+ rows, count_result = await asyncio.gather(
535
+ asyncio.wait_for(
536
+ conn.fetch(sql_query, *params),
537
+ timeout=self._timeout_seconds,
538
+ ),
539
+ asyncio.wait_for(
540
+ conn.fetchval(count_query, *count_params),
541
+ timeout=self._timeout_seconds,
542
+ ),
543
+ )
544
+
545
+ # Reset circuit breaker on success
546
+ async with self._circuit_breaker_lock:
547
+ await self._reset_circuit_breaker()
548
+
549
+ # Convert rows to records
550
+ records: list[ModelRegistrationRecord] = []
551
+ for row in rows:
552
+ capabilities = (
553
+ json.loads(row["capabilities"]) if row["capabilities"] else []
554
+ )
555
+ endpoints = json.loads(row["endpoints"]) if row["endpoints"] else {}
556
+ metadata = json.loads(row["metadata"]) if row["metadata"] else {}
557
+
558
+ records.append(
559
+ ModelRegistrationRecord(
560
+ node_id=row["node_id"],
561
+ node_type=EnumNodeKind(row["node_type"]),
562
+ node_version=row["node_version"],
563
+ capabilities=capabilities,
564
+ endpoints=endpoints,
565
+ metadata=metadata,
566
+ created_at=row["created_at"],
567
+ updated_at=row["updated_at"],
568
+ correlation_id=correlation_id,
569
+ )
570
+ )
571
+
572
+ duration_ms = (time.monotonic() - start_time) * 1000
573
+ total_count = count_result or 0
574
+
575
+ logger.info(
576
+ "Registration query completed",
577
+ extra={
578
+ "record_count": len(records),
579
+ "total_count": total_count,
580
+ "duration_ms": duration_ms,
581
+ "correlation_id": str(correlation_id),
582
+ },
583
+ )
584
+
585
+ return ModelStorageResult(
586
+ success=True,
587
+ records=tuple(records),
588
+ total_count=total_count,
589
+ duration_ms=duration_ms,
590
+ backend_type=self.handler_type,
591
+ correlation_id=correlation_id,
592
+ )
593
+
594
+ except TimeoutError as e:
595
+ async with self._circuit_breaker_lock:
596
+ await self._record_circuit_failure(
597
+ operation="query_registrations",
598
+ correlation_id=correlation_id,
599
+ )
600
+ duration_ms = (time.monotonic() - start_time) * 1000
601
+ raise InfraTimeoutError(
602
+ f"PostgreSQL query timed out after {self._timeout_seconds}s",
603
+ context=ModelTimeoutErrorContext(
604
+ transport_type=EnumInfraTransportType.DATABASE,
605
+ operation="query_registrations",
606
+ target_name="postgres.storage",
607
+ correlation_id=correlation_id,
608
+ timeout_seconds=self._timeout_seconds,
609
+ ),
610
+ ) from e
611
+
612
+ except Exception as e:
613
+ async with self._circuit_breaker_lock:
614
+ await self._record_circuit_failure(
615
+ operation="query_registrations",
616
+ correlation_id=correlation_id,
617
+ )
618
+ duration_ms = (time.monotonic() - start_time) * 1000
619
+ context = ModelInfraErrorContext(
620
+ transport_type=EnumInfraTransportType.DATABASE,
621
+ operation="query_registrations",
622
+ target_name="postgres.storage",
623
+ correlation_id=correlation_id,
624
+ )
625
+ raise InfraConnectionError(
626
+ f"PostgreSQL query failed: {type(e).__name__}",
627
+ context=context,
628
+ ) from e
629
+
630
+ async def update_registration(
631
+ self,
632
+ request: ModelUpdateRegistrationRequest,
633
+ ) -> ModelUpsertResult:
634
+ """Update an existing registration record.
635
+
636
+ Args:
637
+ request: ModelUpdateRegistrationRequest containing:
638
+ - node_id: ID of the node to update
639
+ - updates: ModelRegistrationUpdate with fields to update
640
+ (only non-None fields will be applied)
641
+ - correlation_id: Optional correlation ID for tracing
642
+
643
+ Returns:
644
+ ModelUpsertResult with update outcome.
645
+
646
+ Raises:
647
+ InfraConnectionError: If connection to PostgreSQL fails.
648
+ InfraTimeoutError: If operation times out.
649
+ InfraUnavailableError: If circuit breaker is open.
650
+ """
651
+ # Extract fields from request model
652
+ node_id = request.node_id
653
+ updates = request.updates
654
+ correlation_id = request.correlation_id or uuid4()
655
+ start_time = time.monotonic()
656
+
657
+ # Check circuit breaker
658
+ async with self._circuit_breaker_lock:
659
+ await self._check_circuit_breaker(
660
+ operation="update_registration",
661
+ correlation_id=correlation_id,
662
+ )
663
+
664
+ try:
665
+ pool = await self._ensure_pool(correlation_id=correlation_id)
666
+
667
+ # Extract fields from the update model
668
+ # Use `is not None` checks to allow explicitly clearing fields with empty
669
+ # lists/dicts. Truthiness checks would treat [] and {} as "no update".
670
+ capabilities_json = (
671
+ json.dumps(updates.capabilities)
672
+ if updates.capabilities is not None
673
+ else None
674
+ )
675
+ endpoints_json = (
676
+ json.dumps(updates.endpoints) if updates.endpoints is not None else None
677
+ )
678
+ metadata_json = (
679
+ json.dumps(updates.metadata) if updates.metadata is not None else None
680
+ )
681
+ node_version = updates.node_version
682
+
683
+ async with pool.acquire() as conn:
684
+ result = await asyncio.wait_for(
685
+ conn.fetchval(
686
+ SQL_UPDATE,
687
+ node_id,
688
+ capabilities_json,
689
+ endpoints_json,
690
+ metadata_json,
691
+ node_version,
692
+ ),
693
+ timeout=self._timeout_seconds,
694
+ )
695
+
696
+ # Reset circuit breaker on success
697
+ async with self._circuit_breaker_lock:
698
+ await self._reset_circuit_breaker()
699
+
700
+ success = result is not None
701
+ duration_ms = (time.monotonic() - start_time) * 1000
702
+
703
+ logger.info(
704
+ "Registration updated",
705
+ extra={
706
+ "node_id": str(node_id),
707
+ "success": success,
708
+ "duration_ms": duration_ms,
709
+ "correlation_id": str(correlation_id),
710
+ },
711
+ )
712
+
713
+ return ModelUpsertResult(
714
+ success=success,
715
+ node_id=node_id,
716
+ operation="update",
717
+ error="Record not found" if not success else None,
718
+ duration_ms=duration_ms,
719
+ backend_type=self.handler_type,
720
+ correlation_id=correlation_id,
721
+ )
722
+
723
+ except TimeoutError as e:
724
+ async with self._circuit_breaker_lock:
725
+ await self._record_circuit_failure(
726
+ operation="update_registration",
727
+ correlation_id=correlation_id,
728
+ )
729
+ duration_ms = (time.monotonic() - start_time) * 1000
730
+ raise InfraTimeoutError(
731
+ f"PostgreSQL update timed out after {self._timeout_seconds}s",
732
+ context=ModelTimeoutErrorContext(
733
+ transport_type=EnumInfraTransportType.DATABASE,
734
+ operation="update_registration",
735
+ target_name="postgres.storage",
736
+ correlation_id=correlation_id,
737
+ timeout_seconds=self._timeout_seconds,
738
+ ),
739
+ ) from e
740
+
741
+ except Exception as e:
742
+ async with self._circuit_breaker_lock:
743
+ await self._record_circuit_failure(
744
+ operation="update_registration",
745
+ correlation_id=correlation_id,
746
+ )
747
+ duration_ms = (time.monotonic() - start_time) * 1000
748
+ context = ModelInfraErrorContext(
749
+ transport_type=EnumInfraTransportType.DATABASE,
750
+ operation="update_registration",
751
+ target_name="postgres.storage",
752
+ correlation_id=correlation_id,
753
+ )
754
+ raise InfraConnectionError(
755
+ f"PostgreSQL update failed: {type(e).__name__}",
756
+ context=context,
757
+ ) from e
758
+
759
+ async def delete_registration(
760
+ self,
761
+ request: ModelDeleteRegistrationRequest,
762
+ ) -> ModelDeleteResult:
763
+ """Delete a registration record from PostgreSQL.
764
+
765
+ Args:
766
+ request: ModelDeleteRegistrationRequest containing:
767
+ - node_id: ID of the node to delete
768
+ - correlation_id: Optional correlation ID for tracing
769
+
770
+ Returns:
771
+ ModelDeleteResult with deletion outcome.
772
+
773
+ Raises:
774
+ InfraConnectionError: If connection to PostgreSQL fails.
775
+ InfraTimeoutError: If operation times out.
776
+ InfraUnavailableError: If circuit breaker is open.
777
+ """
778
+ # Extract fields from request model
779
+ node_id = request.node_id
780
+ correlation_id = request.correlation_id or uuid4()
781
+ start_time = time.monotonic()
782
+
783
+ # Check circuit breaker
784
+ async with self._circuit_breaker_lock:
785
+ await self._check_circuit_breaker(
786
+ operation="delete_registration",
787
+ correlation_id=correlation_id,
788
+ )
789
+
790
+ try:
791
+ pool = await self._ensure_pool(correlation_id=correlation_id)
792
+
793
+ async with pool.acquire() as conn:
794
+ result = await asyncio.wait_for(
795
+ conn.fetchval(SQL_DELETE, node_id),
796
+ timeout=self._timeout_seconds,
797
+ )
798
+
799
+ # Reset circuit breaker on success
800
+ async with self._circuit_breaker_lock:
801
+ await self._reset_circuit_breaker()
802
+
803
+ deleted = result is not None
804
+ duration_ms = (time.monotonic() - start_time) * 1000
805
+
806
+ logger.info(
807
+ "Registration deletion completed",
808
+ extra={
809
+ "node_id": str(node_id),
810
+ "deleted": deleted,
811
+ "duration_ms": duration_ms,
812
+ "correlation_id": str(correlation_id),
813
+ },
814
+ )
815
+
816
+ return ModelDeleteResult(
817
+ success=True,
818
+ node_id=node_id,
819
+ deleted=deleted,
820
+ duration_ms=duration_ms,
821
+ backend_type=self.handler_type,
822
+ correlation_id=correlation_id,
823
+ )
824
+
825
+ except TimeoutError as e:
826
+ async with self._circuit_breaker_lock:
827
+ await self._record_circuit_failure(
828
+ operation="delete_registration",
829
+ correlation_id=correlation_id,
830
+ )
831
+ raise InfraTimeoutError(
832
+ f"PostgreSQL delete timed out after {self._timeout_seconds}s",
833
+ context=ModelTimeoutErrorContext(
834
+ transport_type=EnumInfraTransportType.DATABASE,
835
+ operation="delete_registration",
836
+ target_name="postgres.storage",
837
+ correlation_id=correlation_id,
838
+ timeout_seconds=self._timeout_seconds,
839
+ ),
840
+ ) from e
841
+
842
+ except Exception as e:
843
+ async with self._circuit_breaker_lock:
844
+ await self._record_circuit_failure(
845
+ operation="delete_registration",
846
+ correlation_id=correlation_id,
847
+ )
848
+ context = ModelInfraErrorContext(
849
+ transport_type=EnumInfraTransportType.DATABASE,
850
+ operation="delete_registration",
851
+ target_name="postgres.storage",
852
+ correlation_id=correlation_id,
853
+ )
854
+ raise InfraConnectionError(
855
+ f"PostgreSQL delete failed: {type(e).__name__}",
856
+ context=context,
857
+ ) from e
858
+
859
+ async def health_check(
860
+ self,
861
+ correlation_id: UUID | None = None,
862
+ ) -> ModelStorageHealthCheckResult:
863
+ """Perform a health check on the PostgreSQL connection.
864
+
865
+ Args:
866
+ correlation_id: Optional correlation ID for tracing.
867
+
868
+ Returns:
869
+ ModelStorageHealthCheckResult with health status information.
870
+ """
871
+ correlation_id = correlation_id or uuid4()
872
+ start_time = time.monotonic()
873
+
874
+ try:
875
+ pool = await self._ensure_pool(correlation_id=correlation_id)
876
+
877
+ async with pool.acquire() as conn:
878
+ await asyncio.wait_for(
879
+ conn.fetchval("SELECT 1"),
880
+ timeout=5.0, # Short timeout for health check
881
+ )
882
+
883
+ duration_ms = (time.monotonic() - start_time) * 1000
884
+
885
+ return ModelStorageHealthCheckResult(
886
+ healthy=True,
887
+ backend_type=self.handler_type,
888
+ latency_ms=duration_ms,
889
+ reason="ok",
890
+ details=ModelStorageHealthCheckDetails(
891
+ pool_size=self._pool_size,
892
+ database_name=self._database,
893
+ ),
894
+ correlation_id=correlation_id,
895
+ )
896
+
897
+ except Exception as e:
898
+ duration_ms = (time.monotonic() - start_time) * 1000
899
+ return ModelStorageHealthCheckResult(
900
+ healthy=False,
901
+ backend_type=self.handler_type,
902
+ latency_ms=duration_ms,
903
+ reason=f"Health check failed: {type(e).__name__}",
904
+ error_type=type(e).__name__,
905
+ details=ModelStorageHealthCheckDetails(
906
+ pool_size=self._pool_size,
907
+ database_name=self._database,
908
+ ),
909
+ correlation_id=correlation_id,
910
+ )
911
+
912
+ async def shutdown(self) -> None:
913
+ """Shutdown the handler and release resources."""
914
+ if self._pool is not None:
915
+ await self._pool.close()
916
+ self._pool = None
917
+
918
+ self._initialized = False
919
+ logger.info("HandlerRegistrationStoragePostgres shutdown complete")
920
+
921
+
922
+ __all__ = ["HandlerRegistrationStoragePostgres"]