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,945 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Capability Query Service.
4
+
5
+ Provides high-level service for querying the registry by capability rather
6
+ than by name. This enables capability-based auto-configuration where nodes
7
+ declare what they need, not who provides it.
8
+
9
+ Core Principle: "I'm interested in what you do, not what you are."
10
+
11
+ Coroutine Safety:
12
+ This service uses MixinAsyncCircuitBreaker for coroutine-safe circuit
13
+ breaker protection. The circuit breaker provides defense-in-depth on top
14
+ of the underlying ProjectionReaderRegistration's circuit breaker.
15
+
16
+ Circuit Breaker:
17
+ This service implements its own circuit breaker as a defense-in-depth layer.
18
+ While ProjectionReaderRegistration also has circuit breakers, having them
19
+ at the service layer provides:
20
+ - Service-level failure isolation
21
+ - Independent failure thresholds tuned for query patterns
22
+ - Protection against issues beyond database connectivity
23
+
24
+ Related Tickets:
25
+ - OMN-1135: ServiceCapabilityQuery for capability-based discovery
26
+ - OMN-1134: Registry Projection Extensions for Capabilities
27
+
28
+ Example:
29
+ >>> from omnibase_infra.services import ServiceCapabilityQuery
30
+ >>> from omnibase_infra.projectors import ProjectionReaderRegistration
31
+ >>>
32
+ >>> reader = ProjectionReaderRegistration(pool)
33
+ >>> query = ServiceCapabilityQuery(reader)
34
+ >>>
35
+ >>> # Find all postgres storage providers
36
+ >>> nodes = await query.find_nodes_by_capability("postgres.storage")
37
+ >>>
38
+ >>> # Resolve a dependency spec
39
+ >>> spec = ModelDependencySpec(name="db", type="node", capability="postgres.storage")
40
+ >>> node = await query.resolve_dependency(spec)
41
+ """
42
+
43
+ from __future__ import annotations
44
+
45
+ import logging
46
+ from typing import TYPE_CHECKING
47
+ from uuid import UUID, uuid4
48
+
49
+ from omnibase_core.container import ModelONEXContainer
50
+ from omnibase_infra.enums import (
51
+ EnumInfraTransportType,
52
+ EnumRegistrationState,
53
+ EnumSelectionStrategy,
54
+ )
55
+ from omnibase_infra.errors import ProtocolConfigurationError, RuntimeHostError
56
+ from omnibase_infra.mixins import MixinAsyncCircuitBreaker
57
+ from omnibase_infra.models.discovery.model_dependency_spec import ModelDependencySpec
58
+ from omnibase_infra.models.errors.model_infra_error_context import (
59
+ ModelInfraErrorContext,
60
+ )
61
+ from omnibase_infra.models.projection import ModelRegistrationProjection
62
+ from omnibase_infra.services.service_node_selector import ServiceNodeSelector
63
+
64
+ if TYPE_CHECKING:
65
+ from omnibase_infra.projectors.projection_reader_registration import (
66
+ ProjectionReaderRegistration,
67
+ )
68
+
69
+ logger = logging.getLogger(__name__)
70
+
71
+
72
+ class ServiceCapabilityQuery(MixinAsyncCircuitBreaker):
73
+ """Queries registry for nodes by capability, not by name.
74
+
75
+ Core Principle: "I'm interested in what you do, not what you are."
76
+
77
+ This service wraps ProjectionReaderRegistration to provide high-level
78
+ capability-based discovery. Instead of hardcoding module paths, consumers
79
+ can declare what capabilities they need and the system discovers which
80
+ nodes provide them.
81
+
82
+ Query Methods:
83
+ - find_nodes_by_capability: Find by capability tag
84
+ - find_nodes_by_intent_type: Find by single intent type handled
85
+ - find_nodes_by_intent_types: Find by multiple intent types (bulk query)
86
+ - find_nodes_by_protocol: Find by protocol implemented
87
+
88
+ Dependency Resolution:
89
+ The resolve_dependency method takes a ModelDependencySpec and:
90
+ 1. Determines the discovery strategy (capability/intent/protocol)
91
+ 2. Queries the registry for matching nodes
92
+ 3. Applies the selection strategy to choose one node
93
+
94
+ Circuit Breaker:
95
+ This service implements MixinAsyncCircuitBreaker for defense-in-depth
96
+ protection. While ProjectionReaderRegistration has its own circuit
97
+ breakers, the service-level circuit breaker provides:
98
+ - Independent failure isolation at the service layer
99
+ - Service-specific failure thresholds (5 failures, 60s reset)
100
+ - Protection against issues beyond database connectivity
101
+
102
+ Design Notes:
103
+ - All queries delegate to ProjectionReaderRegistration
104
+ - Service-level circuit breaker provides defense-in-depth
105
+ - Node selection is handled by ServiceNodeSelector
106
+ - Round-robin state is maintained per-service instance
107
+
108
+ Example:
109
+ >>> reader = ProjectionReaderRegistration(pool)
110
+ >>> query = ServiceCapabilityQuery(reader)
111
+ >>>
112
+ >>> # Find active Kafka consumers
113
+ >>> nodes = await query.find_nodes_by_capability(
114
+ ... "kafka.consumer",
115
+ ... state=EnumRegistrationState.ACTIVE,
116
+ ... )
117
+ >>>
118
+ >>> # Find nodes that handle postgres.upsert intent
119
+ >>> handlers = await query.find_nodes_by_intent_type(
120
+ ... "postgres.upsert",
121
+ ... contract_type="effect",
122
+ ... )
123
+
124
+ Raises:
125
+ InfraConnectionError: If database connection fails
126
+ InfraTimeoutError: If query times out
127
+ InfraUnavailableError: If circuit breaker is open
128
+ RuntimeHostError: For other database errors
129
+
130
+ Note:
131
+ Dependency Injection Pattern: This service is a leaf infrastructure
132
+ service that receives its dependencies directly via constructor
133
+ parameters rather than resolving them from a container. Unlike
134
+ orchestrators that use ``container.service_registry.resolve_service()``
135
+ to obtain services dynamically, leaf services like this one are
136
+ instantiated with concrete dependencies (projection_reader, node_selector)
137
+ and are themselves resolved by higher-level components.
138
+ """
139
+
140
+ def __init__(
141
+ self,
142
+ projection_reader: ProjectionReaderRegistration,
143
+ container: ModelONEXContainer | None = None,
144
+ node_selector: ServiceNodeSelector | None = None,
145
+ ) -> None:
146
+ """Initialize the capability query service.
147
+
148
+ Args:
149
+ projection_reader: The projection reader for database queries.
150
+ Must be initialized with an asyncpg connection pool.
151
+ container: Optional ONEX container for dependency injection.
152
+ Passed to default ServiceNodeSelector if node_selector is None.
153
+ node_selector: Optional node selector for selection strategies.
154
+ If None, creates a new ServiceNodeSelector instance.
155
+
156
+ Example:
157
+ >>> pool = await asyncpg.create_pool(dsn)
158
+ >>> reader = ProjectionReaderRegistration(pool)
159
+ >>> query = ServiceCapabilityQuery(reader)
160
+ """
161
+ # Initialize circuit breaker for defense-in-depth protection
162
+ self._init_circuit_breaker(
163
+ threshold=5,
164
+ reset_timeout=60.0,
165
+ service_name="capability-query",
166
+ transport_type=EnumInfraTransportType.DATABASE,
167
+ )
168
+
169
+ self._projection_reader = projection_reader
170
+ self._container = container
171
+ self._node_selector = node_selector or ServiceNodeSelector(container=container)
172
+
173
+ async def find_nodes_by_capability(
174
+ self,
175
+ capability: str,
176
+ contract_type: str | None = None,
177
+ state: EnumRegistrationState | None = None,
178
+ correlation_id: UUID | None = None,
179
+ ) -> list[ModelRegistrationProjection]:
180
+ """Find nodes that provide a specific capability.
181
+
182
+ Queries the registry for nodes with the specified capability tag.
183
+ Results can be filtered by contract type and registration state.
184
+
185
+ Coroutine Safety:
186
+ This method is coroutine-safe when called concurrently from multiple
187
+ coroutines within the same event loop. The circuit breaker state is
188
+ protected by an asyncio.Lock.
189
+
190
+ Args:
191
+ capability: Capability tag to search for (e.g., "postgres.storage",
192
+ "kafka.consumer", "consul.registration").
193
+ contract_type: Optional filter by contract type ("effect", "compute",
194
+ "reducer", "orchestrator").
195
+ state: Registration state filter. When None (default), filters to
196
+ EnumRegistrationState.ACTIVE to return only actively registered
197
+ nodes. Pass an explicit EnumRegistrationState value to query
198
+ nodes in other states (e.g., PENDING_REGISTRATION, LIVENESS_EXPIRED).
199
+ correlation_id: Optional correlation ID for distributed tracing.
200
+ When provided, included in all log messages for request tracking.
201
+
202
+ Returns:
203
+ List of matching registration projections. Empty list if no matches.
204
+
205
+ Raises:
206
+ InfraConnectionError: If database connection fails
207
+ InfraTimeoutError: If query times out
208
+ InfraUnavailableError: If circuit breaker is open
209
+ RuntimeHostError: For other database errors
210
+
211
+ Example:
212
+ >>> nodes = await query.find_nodes_by_capability(
213
+ ... "postgres.storage",
214
+ ... contract_type="effect",
215
+ ... state=EnumRegistrationState.ACTIVE,
216
+ ... )
217
+ >>> for node in nodes:
218
+ ... print(f"Found: {node.entity_id} - {node.node_type}")
219
+ """
220
+ correlation_id = self._ensure_correlation_id(correlation_id)
221
+ state = state or EnumRegistrationState.ACTIVE
222
+
223
+ # Check circuit breaker before operation
224
+ async with self._circuit_breaker_lock:
225
+ await self._check_circuit_breaker(
226
+ operation="find_nodes_by_capability",
227
+ correlation_id=correlation_id,
228
+ )
229
+
230
+ logger.debug(
231
+ "Finding nodes by capability",
232
+ extra={
233
+ "capability": capability,
234
+ "contract_type": contract_type,
235
+ "state": str(state),
236
+ "correlation_id": str(correlation_id),
237
+ },
238
+ )
239
+
240
+ try:
241
+ # Query by capability tag
242
+ results = await self._projection_reader.get_by_capability_tag(
243
+ tag=capability,
244
+ state=state,
245
+ correlation_id=correlation_id,
246
+ )
247
+
248
+ results = self._filter_by_contract_type(results, contract_type)
249
+
250
+ # Record success
251
+ async with self._circuit_breaker_lock:
252
+ await self._reset_circuit_breaker()
253
+
254
+ logger.debug(
255
+ "Capability query completed",
256
+ extra={
257
+ "capability": capability,
258
+ "result_count": len(results),
259
+ "correlation_id": str(correlation_id),
260
+ },
261
+ )
262
+
263
+ return results
264
+
265
+ except RuntimeHostError:
266
+ # Record failure and re-raise infrastructure errors as-is
267
+ async with self._circuit_breaker_lock:
268
+ await self._record_circuit_failure(
269
+ operation="find_nodes_by_capability",
270
+ correlation_id=correlation_id,
271
+ )
272
+ raise
273
+ except Exception as e:
274
+ # Record failure
275
+ async with self._circuit_breaker_lock:
276
+ await self._record_circuit_failure(
277
+ operation="find_nodes_by_capability",
278
+ correlation_id=correlation_id,
279
+ )
280
+ # Wrap unexpected exceptions with RuntimeHostError
281
+ context = ModelInfraErrorContext(
282
+ transport_type=EnumInfraTransportType.DATABASE,
283
+ operation="find_nodes_by_capability",
284
+ correlation_id=correlation_id,
285
+ )
286
+ raise RuntimeHostError(
287
+ f"Capability query failed: {type(e).__name__}",
288
+ context=context,
289
+ capability=capability,
290
+ ) from e
291
+
292
+ async def find_nodes_by_intent_type(
293
+ self,
294
+ intent_type: str,
295
+ contract_type: str = "effect",
296
+ state: EnumRegistrationState | None = None,
297
+ correlation_id: UUID | None = None,
298
+ ) -> list[ModelRegistrationProjection]:
299
+ """Find effect nodes that handle a specific intent type.
300
+
301
+ Queries the registry for nodes that can handle the specified intent type.
302
+ Typically used to find effect nodes that execute specific intents.
303
+
304
+ Coroutine Safety:
305
+ This method is coroutine-safe when called concurrently from multiple
306
+ coroutines within the same event loop. The circuit breaker state is
307
+ protected by an asyncio.Lock.
308
+
309
+ Args:
310
+ intent_type: Intent type to search for (e.g., "postgres.upsert",
311
+ "consul.register", "kafka.publish").
312
+ contract_type: Filter by contract type (default: "effect").
313
+ Intents are typically handled by effect nodes.
314
+ state: Registration state filter. When None (default), filters to
315
+ EnumRegistrationState.ACTIVE to return only actively registered
316
+ nodes. Pass an explicit EnumRegistrationState value to query
317
+ nodes in other states (e.g., PENDING_REGISTRATION, LIVENESS_EXPIRED).
318
+ correlation_id: Optional correlation ID for distributed tracing.
319
+ When provided, included in all log messages for request tracking.
320
+
321
+ Returns:
322
+ List of matching registration projections. Empty list if no matches.
323
+
324
+ Raises:
325
+ InfraConnectionError: If database connection fails
326
+ InfraTimeoutError: If query times out
327
+ InfraUnavailableError: If circuit breaker is open
328
+ RuntimeHostError: For other database errors
329
+
330
+ Example:
331
+ >>> handlers = await query.find_nodes_by_intent_type(
332
+ ... "postgres.query",
333
+ ... contract_type="effect",
334
+ ... state=EnumRegistrationState.ACTIVE,
335
+ ... )
336
+ >>> for handler in handlers:
337
+ ... print(f"Can handle postgres.query: {handler.entity_id}")
338
+ """
339
+ correlation_id = self._ensure_correlation_id(correlation_id)
340
+ state = state or EnumRegistrationState.ACTIVE
341
+
342
+ # Check circuit breaker before operation
343
+ async with self._circuit_breaker_lock:
344
+ await self._check_circuit_breaker(
345
+ operation="find_nodes_by_intent_type",
346
+ correlation_id=correlation_id,
347
+ )
348
+
349
+ logger.debug(
350
+ "Finding nodes by intent type",
351
+ extra={
352
+ "intent_type": intent_type,
353
+ "contract_type": contract_type,
354
+ "state": str(state),
355
+ "correlation_id": str(correlation_id),
356
+ },
357
+ )
358
+
359
+ try:
360
+ # Query by intent type
361
+ results = await self._projection_reader.get_by_intent_type(
362
+ intent_type=intent_type,
363
+ state=state,
364
+ correlation_id=correlation_id,
365
+ )
366
+
367
+ results = self._filter_by_contract_type(results, contract_type)
368
+
369
+ # Record success
370
+ async with self._circuit_breaker_lock:
371
+ await self._reset_circuit_breaker()
372
+
373
+ logger.debug(
374
+ "Intent type query completed",
375
+ extra={
376
+ "intent_type": intent_type,
377
+ "result_count": len(results),
378
+ "correlation_id": str(correlation_id),
379
+ },
380
+ )
381
+
382
+ return results
383
+
384
+ except RuntimeHostError:
385
+ # Record failure and re-raise infrastructure errors as-is
386
+ async with self._circuit_breaker_lock:
387
+ await self._record_circuit_failure(
388
+ operation="find_nodes_by_intent_type",
389
+ correlation_id=correlation_id,
390
+ )
391
+ raise
392
+ except Exception as e:
393
+ # Record failure
394
+ async with self._circuit_breaker_lock:
395
+ await self._record_circuit_failure(
396
+ operation="find_nodes_by_intent_type",
397
+ correlation_id=correlation_id,
398
+ )
399
+ # Wrap unexpected exceptions with RuntimeHostError
400
+ context = ModelInfraErrorContext(
401
+ transport_type=EnumInfraTransportType.DATABASE,
402
+ operation="find_nodes_by_intent_type",
403
+ correlation_id=correlation_id,
404
+ )
405
+ raise RuntimeHostError(
406
+ f"Intent type query failed: {type(e).__name__}",
407
+ context=context,
408
+ intent_type=intent_type,
409
+ ) from e
410
+
411
+ async def find_nodes_by_intent_types(
412
+ self,
413
+ intent_types: list[str],
414
+ contract_type: str = "effect",
415
+ state: EnumRegistrationState | None = None,
416
+ correlation_id: UUID | None = None,
417
+ ) -> list[ModelRegistrationProjection]:
418
+ """Find effect nodes that handle ANY of the specified intent types.
419
+
420
+ Bulk query method that retrieves nodes matching any intent type in a single
421
+ database call. This is more efficient than calling find_nodes_by_intent_type
422
+ repeatedly for each intent type.
423
+
424
+ Coroutine Safety:
425
+ This method is coroutine-safe when called concurrently from multiple
426
+ coroutines within the same event loop. The circuit breaker state is
427
+ protected by an asyncio.Lock.
428
+
429
+ Performance Note:
430
+ This method reduces N database queries to 1 query when resolving
431
+ dependencies with multiple intent types. For N intent types:
432
+ - Previous: N sequential database calls
433
+ - Now: 1 bulk query using SQL array overlap
434
+
435
+ Args:
436
+ intent_types: List of intent types to search for (e.g.,
437
+ ["postgres.upsert", "postgres.query", "postgres.delete"]).
438
+ contract_type: Filter by contract type (default: "effect").
439
+ Intents are typically handled by effect nodes.
440
+ state: Registration state filter. When None (default), filters to
441
+ EnumRegistrationState.ACTIVE to return only actively registered
442
+ nodes. Pass an explicit EnumRegistrationState value to query
443
+ nodes in other states (e.g., PENDING_REGISTRATION, LIVENESS_EXPIRED).
444
+ correlation_id: Optional correlation ID for distributed tracing.
445
+ When provided, included in all log messages for request tracking.
446
+
447
+ Returns:
448
+ List of matching registration projections. Empty list if no matches
449
+ or if intent_types list is empty.
450
+
451
+ Raises:
452
+ InfraConnectionError: If database connection fails
453
+ InfraTimeoutError: If query times out
454
+ InfraUnavailableError: If circuit breaker is open
455
+ RuntimeHostError: For other database errors
456
+
457
+ Example:
458
+ >>> handlers = await query.find_nodes_by_intent_types(
459
+ ... ["postgres.query", "postgres.upsert", "postgres.delete"],
460
+ ... contract_type="effect",
461
+ ... state=EnumRegistrationState.ACTIVE,
462
+ ... )
463
+ >>> for handler in handlers:
464
+ ... print(f"Can handle postgres intents: {handler.entity_id}")
465
+ """
466
+ correlation_id = self._ensure_correlation_id(correlation_id)
467
+ if not intent_types:
468
+ return []
469
+
470
+ state = state or EnumRegistrationState.ACTIVE
471
+
472
+ # Check circuit breaker before operation
473
+ async with self._circuit_breaker_lock:
474
+ await self._check_circuit_breaker(
475
+ operation="find_nodes_by_intent_types",
476
+ correlation_id=correlation_id,
477
+ )
478
+
479
+ logger.debug(
480
+ "Finding nodes by intent types (bulk)",
481
+ extra={
482
+ "intent_types": intent_types,
483
+ "intent_count": len(intent_types),
484
+ "contract_type": contract_type,
485
+ "state": str(state),
486
+ "correlation_id": str(correlation_id),
487
+ },
488
+ )
489
+
490
+ try:
491
+ # Query by intent types (bulk)
492
+ results = await self._projection_reader.get_by_intent_types(
493
+ intent_types=intent_types,
494
+ state=state,
495
+ correlation_id=correlation_id,
496
+ )
497
+
498
+ results = self._filter_by_contract_type(results, contract_type)
499
+
500
+ # Record success
501
+ async with self._circuit_breaker_lock:
502
+ await self._reset_circuit_breaker()
503
+
504
+ logger.debug(
505
+ "Intent types query completed (bulk)",
506
+ extra={
507
+ "intent_types": intent_types,
508
+ "result_count": len(results),
509
+ "correlation_id": str(correlation_id),
510
+ },
511
+ )
512
+
513
+ return results
514
+
515
+ except RuntimeHostError:
516
+ # Record failure and re-raise infrastructure errors as-is
517
+ async with self._circuit_breaker_lock:
518
+ await self._record_circuit_failure(
519
+ operation="find_nodes_by_intent_types",
520
+ correlation_id=correlation_id,
521
+ )
522
+ raise
523
+ except Exception as e:
524
+ # Record failure
525
+ async with self._circuit_breaker_lock:
526
+ await self._record_circuit_failure(
527
+ operation="find_nodes_by_intent_types",
528
+ correlation_id=correlation_id,
529
+ )
530
+ # Wrap unexpected exceptions with RuntimeHostError
531
+ context = ModelInfraErrorContext(
532
+ transport_type=EnumInfraTransportType.DATABASE,
533
+ operation="find_nodes_by_intent_types",
534
+ correlation_id=correlation_id,
535
+ )
536
+ raise RuntimeHostError(
537
+ f"Intent types query failed: {type(e).__name__}",
538
+ context=context,
539
+ intent_types=intent_types,
540
+ ) from e
541
+
542
+ async def find_nodes_by_protocol(
543
+ self,
544
+ protocol: str,
545
+ contract_type: str | None = None,
546
+ state: EnumRegistrationState | None = None,
547
+ correlation_id: UUID | None = None,
548
+ ) -> list[ModelRegistrationProjection]:
549
+ """Find nodes implementing a specific protocol.
550
+
551
+ Queries the registry for nodes that implement the specified protocol.
552
+ Useful for finding nodes that satisfy interface requirements.
553
+
554
+ Coroutine Safety:
555
+ This method is coroutine-safe when called concurrently from multiple
556
+ coroutines within the same event loop. The circuit breaker state is
557
+ protected by an asyncio.Lock.
558
+
559
+ Args:
560
+ protocol: Protocol name to search for (e.g., "ProtocolEventPublisher",
561
+ "ProtocolReducer", "ProtocolDatabaseAdapter").
562
+ contract_type: Optional filter by contract type ("effect", "compute",
563
+ "reducer", "orchestrator").
564
+ state: Registration state filter. When None (default), filters to
565
+ EnumRegistrationState.ACTIVE to return only actively registered
566
+ nodes. Pass an explicit EnumRegistrationState value to query
567
+ nodes in other states (e.g., PENDING_REGISTRATION, LIVENESS_EXPIRED).
568
+ correlation_id: Optional correlation ID for distributed tracing.
569
+ When provided, included in all log messages for request tracking.
570
+
571
+ Returns:
572
+ List of matching registration projections. Empty list if no matches.
573
+
574
+ Raises:
575
+ InfraConnectionError: If database connection fails
576
+ InfraTimeoutError: If query times out
577
+ InfraUnavailableError: If circuit breaker is open
578
+ RuntimeHostError: For other database errors
579
+
580
+ Example:
581
+ >>> adapters = await query.find_nodes_by_protocol(
582
+ ... "ProtocolEventPublisher",
583
+ ... state=EnumRegistrationState.ACTIVE,
584
+ ... )
585
+ >>> print(f"Found {len(adapters)} event publishers")
586
+ """
587
+ correlation_id = self._ensure_correlation_id(correlation_id)
588
+ state = state or EnumRegistrationState.ACTIVE
589
+
590
+ # Check circuit breaker before operation
591
+ async with self._circuit_breaker_lock:
592
+ await self._check_circuit_breaker(
593
+ operation="find_nodes_by_protocol",
594
+ correlation_id=correlation_id,
595
+ )
596
+
597
+ logger.debug(
598
+ "Finding nodes by protocol",
599
+ extra={
600
+ "protocol": protocol,
601
+ "contract_type": contract_type,
602
+ "state": str(state),
603
+ "correlation_id": str(correlation_id),
604
+ },
605
+ )
606
+
607
+ try:
608
+ # Query by protocol
609
+ results = await self._projection_reader.get_by_protocol(
610
+ protocol_name=protocol,
611
+ state=state,
612
+ correlation_id=correlation_id,
613
+ )
614
+
615
+ results = self._filter_by_contract_type(results, contract_type)
616
+
617
+ # Record success
618
+ async with self._circuit_breaker_lock:
619
+ await self._reset_circuit_breaker()
620
+
621
+ logger.debug(
622
+ "Protocol query completed",
623
+ extra={
624
+ "protocol": protocol,
625
+ "result_count": len(results),
626
+ "correlation_id": str(correlation_id),
627
+ },
628
+ )
629
+
630
+ return results
631
+
632
+ except RuntimeHostError:
633
+ # Record failure and re-raise infrastructure errors as-is
634
+ async with self._circuit_breaker_lock:
635
+ await self._record_circuit_failure(
636
+ operation="find_nodes_by_protocol",
637
+ correlation_id=correlation_id,
638
+ )
639
+ raise
640
+ except Exception as e:
641
+ # Record failure
642
+ async with self._circuit_breaker_lock:
643
+ await self._record_circuit_failure(
644
+ operation="find_nodes_by_protocol",
645
+ correlation_id=correlation_id,
646
+ )
647
+ # Wrap unexpected exceptions with RuntimeHostError
648
+ context = ModelInfraErrorContext(
649
+ transport_type=EnumInfraTransportType.DATABASE,
650
+ operation="find_nodes_by_protocol",
651
+ correlation_id=correlation_id,
652
+ )
653
+ raise RuntimeHostError(
654
+ f"Protocol query failed: {type(e).__name__}",
655
+ context=context,
656
+ protocol=protocol,
657
+ ) from e
658
+
659
+ async def resolve_dependency(
660
+ self,
661
+ dependency_spec: ModelDependencySpec,
662
+ correlation_id: UUID | None = None,
663
+ ) -> ModelRegistrationProjection | None:
664
+ """Resolve a dependency specification to a concrete node.
665
+
666
+ Uses the dependency specification to query the registry and select
667
+ a node that matches the specified capability criteria.
668
+
669
+ Resolution Strategy:
670
+ 1. If capability specified -> find by capability
671
+ 2. If intent_types specified -> find by intent types (bulk query)
672
+ 3. If protocol specified -> find by protocol
673
+ 4. Apply selection strategy from spec to choose among matches
674
+
675
+ Coroutine Safety:
676
+ This method is coroutine-safe when called concurrently from multiple
677
+ coroutines within the same event loop. Uses circuit-breaker-protected
678
+ query methods internally.
679
+
680
+ Args:
681
+ dependency_spec: Dependency specification from contract.
682
+ Contains capability filters and selection strategy.
683
+ correlation_id: Optional correlation ID for distributed tracing.
684
+ When provided, included in all log messages for request tracking.
685
+
686
+ Returns:
687
+ Resolved node registration, or None if not found.
688
+
689
+ Note:
690
+ Performance: When resolving by intent types, this method uses a bulk
691
+ query that retrieves all matching nodes in a single database call using
692
+ SQL array overlap. This reduces N queries to 1 query regardless of the
693
+ number of intent types in the dependency spec.
694
+
695
+ Example:
696
+ >>> spec = ModelDependencySpec(
697
+ ... name="storage",
698
+ ... type="node",
699
+ ... capability="postgres.storage",
700
+ ... contract_type="effect",
701
+ ... selection_strategy="round_robin",
702
+ ... )
703
+ >>> node = await query.resolve_dependency(spec)
704
+ >>> if node:
705
+ ... print(f"Resolved to: {node.entity_id}")
706
+ ... else:
707
+ ... print("No node found for capability")
708
+ """
709
+ correlation_id = self._ensure_correlation_id(correlation_id)
710
+ logger.debug(
711
+ "Resolving dependency",
712
+ extra={
713
+ "dependency_name": dependency_spec.name,
714
+ "dependency_type": dependency_spec.type,
715
+ "capability": dependency_spec.capability,
716
+ "intent_types": dependency_spec.intent_types,
717
+ "protocol": dependency_spec.protocol,
718
+ "selection_strategy": dependency_spec.selection_strategy,
719
+ "correlation_id": str(correlation_id),
720
+ },
721
+ )
722
+
723
+ # Determine state filter
724
+ state = self._parse_state(dependency_spec.state, correlation_id)
725
+
726
+ # Find candidates based on discovery strategy
727
+ candidates: list[ModelRegistrationProjection] = []
728
+
729
+ if dependency_spec.has_capability_filter():
730
+ # Assert for type narrowing - has_capability_filter guarantees not None
731
+ assert dependency_spec.capability is not None
732
+ candidates = await self.find_nodes_by_capability(
733
+ capability=dependency_spec.capability,
734
+ contract_type=dependency_spec.contract_type,
735
+ state=state,
736
+ correlation_id=correlation_id,
737
+ )
738
+
739
+ elif dependency_spec.has_intent_filter():
740
+ # Use bulk query for multiple intent types (single database call)
741
+ intent_types = dependency_spec.intent_types
742
+ if intent_types:
743
+ candidates = await self.find_nodes_by_intent_types(
744
+ intent_types=intent_types,
745
+ contract_type=dependency_spec.contract_type or "effect",
746
+ state=state,
747
+ correlation_id=correlation_id,
748
+ )
749
+
750
+ elif dependency_spec.has_protocol_filter():
751
+ # Assert for type narrowing - has_protocol_filter guarantees not None
752
+ assert dependency_spec.protocol is not None
753
+ candidates = await self.find_nodes_by_protocol(
754
+ protocol=dependency_spec.protocol,
755
+ contract_type=dependency_spec.contract_type,
756
+ state=state,
757
+ correlation_id=correlation_id,
758
+ )
759
+
760
+ # No matches found
761
+ if not candidates:
762
+ logger.debug(
763
+ "No candidates found for dependency",
764
+ extra={
765
+ "dependency_name": dependency_spec.name,
766
+ "correlation_id": str(correlation_id),
767
+ },
768
+ )
769
+ return None
770
+
771
+ # Apply selection strategy
772
+ strategy = self._parse_selection_strategy(
773
+ dependency_spec.selection_strategy, correlation_id
774
+ )
775
+ selected = await self._node_selector.select(
776
+ candidates=candidates,
777
+ strategy=strategy,
778
+ selection_key=dependency_spec.name,
779
+ correlation_id=correlation_id,
780
+ )
781
+
782
+ if selected:
783
+ logger.debug(
784
+ "Dependency resolved",
785
+ extra={
786
+ "dependency_name": dependency_spec.name,
787
+ "selected_entity_id": str(selected.entity_id),
788
+ "total_candidates": len(candidates),
789
+ "strategy": dependency_spec.selection_strategy,
790
+ "correlation_id": str(correlation_id),
791
+ },
792
+ )
793
+ else:
794
+ logger.debug(
795
+ "No node selected for dependency",
796
+ extra={
797
+ "dependency_name": dependency_spec.name,
798
+ "correlation_id": str(correlation_id),
799
+ },
800
+ )
801
+
802
+ return selected
803
+
804
+ def _ensure_correlation_id(self, correlation_id: UUID | None) -> UUID:
805
+ """Ensure correlation ID is present, generating one if missing.
806
+
807
+ Args:
808
+ correlation_id: Optional correlation ID from caller. Accepts UUID
809
+ or None.
810
+
811
+ Returns:
812
+ The provided correlation ID, or a newly generated UUID4.
813
+ """
814
+ return correlation_id or uuid4()
815
+
816
+ def _parse_state(
817
+ self,
818
+ state_value: EnumRegistrationState | str | None,
819
+ correlation_id: UUID | None = None,
820
+ ) -> EnumRegistrationState:
821
+ """Parse state value to EnumRegistrationState.
822
+
823
+ Accepts either an EnumRegistrationState enum value (returned as-is),
824
+ a string representation (parsed to enum), or None (defaults to ACTIVE).
825
+
826
+ Args:
827
+ state_value: State as EnumRegistrationState, string (e.g., "ACTIVE", "active"),
828
+ or None. When None, defaults to EnumRegistrationState.ACTIVE.
829
+ correlation_id: Optional correlation ID for tracing.
830
+
831
+ Returns:
832
+ EnumRegistrationState value.
833
+
834
+ Raises:
835
+ ProtocolConfigurationError: If state string is not a valid state or
836
+ if an unexpected error occurs during parsing.
837
+ """
838
+ # Handle None - default to ACTIVE
839
+ if state_value is None:
840
+ return EnumRegistrationState.ACTIVE
841
+
842
+ # If already an enum, return directly
843
+ if isinstance(state_value, EnumRegistrationState):
844
+ return state_value
845
+
846
+ # Parse string to enum
847
+ try:
848
+ return EnumRegistrationState(state_value.lower())
849
+ except ValueError as e:
850
+ valid_states = [s.value for s in EnumRegistrationState]
851
+ raise ProtocolConfigurationError(
852
+ f"Invalid registration state '{state_value}'. "
853
+ f"Valid states are: {valid_states}",
854
+ details={
855
+ "state": state_value,
856
+ "valid_states": valid_states,
857
+ "correlation_id": correlation_id,
858
+ },
859
+ ) from e
860
+ except Exception as e:
861
+ # Catch any other unexpected errors (e.g., AttributeError if state_value
862
+ # is an unexpected type that passed type checking)
863
+ raise ProtocolConfigurationError(
864
+ f"Failed to parse registration state: {type(e).__name__}",
865
+ details={
866
+ "state": str(state_value),
867
+ "error": str(e),
868
+ "correlation_id": correlation_id,
869
+ },
870
+ ) from e
871
+
872
+ def _parse_selection_strategy(
873
+ self,
874
+ strategy: str | EnumSelectionStrategy,
875
+ correlation_id: UUID | None = None,
876
+ ) -> EnumSelectionStrategy:
877
+ """Parse selection strategy to enum.
878
+
879
+ Accepts either an EnumSelectionStrategy enum value (returned as-is)
880
+ or a string representation (parsed to enum).
881
+
882
+ Args:
883
+ strategy: Strategy as EnumSelectionStrategy or string
884
+ (e.g., "first", "round_robin").
885
+ correlation_id: Optional correlation ID for tracing.
886
+
887
+ Returns:
888
+ EnumSelectionStrategy value.
889
+
890
+ Raises:
891
+ ProtocolConfigurationError: If strategy string is not a valid strategy
892
+ or if an unexpected error occurs during parsing.
893
+ """
894
+ # If already an enum, return directly
895
+ if isinstance(strategy, EnumSelectionStrategy):
896
+ return strategy
897
+
898
+ # Parse string to enum
899
+ try:
900
+ return EnumSelectionStrategy(strategy.lower())
901
+ except ValueError as e:
902
+ valid_strategies = [s.value for s in EnumSelectionStrategy]
903
+ raise ProtocolConfigurationError(
904
+ f"Invalid selection strategy '{strategy}'. "
905
+ f"Valid strategies are: {valid_strategies}",
906
+ details={
907
+ "strategy": strategy,
908
+ "valid_strategies": valid_strategies,
909
+ "correlation_id": correlation_id,
910
+ },
911
+ ) from e
912
+ except Exception as e:
913
+ # Catch any other unexpected errors (e.g., AttributeError if strategy
914
+ # is an unexpected type that passed type checking)
915
+ raise ProtocolConfigurationError(
916
+ f"Failed to parse selection strategy: {type(e).__name__}",
917
+ details={
918
+ "strategy": str(strategy),
919
+ "error": str(e),
920
+ "correlation_id": correlation_id,
921
+ },
922
+ ) from e
923
+
924
+ def _filter_by_contract_type(
925
+ self,
926
+ results: list[ModelRegistrationProjection],
927
+ contract_type: str | None,
928
+ ) -> list[ModelRegistrationProjection]:
929
+ """Filter results by contract type if specified.
930
+
931
+ Args:
932
+ results: List of registration projections to filter.
933
+ contract_type: Optional contract type to filter by. If None, returns
934
+ results unchanged.
935
+
936
+ Returns:
937
+ Filtered list of projections matching the contract type, or original
938
+ list if contract_type is None.
939
+ """
940
+ if contract_type is None:
941
+ return results
942
+ return [r for r in results if r.contract_type == contract_type]
943
+
944
+
945
+ __all__: list[str] = ["ServiceCapabilityQuery"]