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,984 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Kafka-Based Contract Source for Event-Driven Discovery.
4
+
5
+ This module provides KafkaContractSource for discovering handler contracts
6
+ via Kafka events instead of filesystem or registry polling.
7
+
8
+ Part of OMN-1654: KafkaContractSource (cache + discovery).
9
+
10
+ **Beta Implementation**: Cache-only model. Does NOT wire business subscriptions
11
+ dynamically. Discovered contracts take effect on next restart.
12
+
13
+ Contract Event Flow:
14
+ 1. External system publishes ModelContractRegisteredEvent to platform topic
15
+ 2. KafkaContractSource receives event via baseline-wired subscription
16
+ 3. Contract YAML is parsed and cached as ModelHandlerDescriptor
17
+ 4. Next call to discover_handlers() returns cached descriptors
18
+ 5. Runtime restart applies new handler configuration
19
+
20
+ Event Topics (Platform Reserved):
21
+ - Registration: {env}.{TOPIC_SUFFIX_CONTRACT_REGISTERED}
22
+ - Deregistration: {env}.{TOPIC_SUFFIX_CONTRACT_DEREGISTERED}
23
+
24
+ Topic suffixes are imported from omnibase_core.constants for single source of truth.
25
+
26
+ See Also:
27
+ - HandlerContractSource: Filesystem-based discovery
28
+ - RegistryContractSource: Consul KV-based discovery
29
+ - ProtocolContractSource: Protocol definition
30
+
31
+ Error Codes:
32
+ This module uses structured error codes for precise error classification:
33
+
34
+ **Parse Errors (KAFKA_CONTRACT_001)**:
35
+ - ``KAFKA_CONTRACT_001`` (PARSE_FAILURE_STRICT_MODE): Contract parsing failed
36
+ in strict mode (graceful_mode=False). Raised when YAML parsing, Pydantic
37
+ validation, or contract schema validation fails.
38
+
39
+ **When Raised**: Only in strict mode. In graceful mode, parse errors are
40
+ logged and cached as ``ModelParseError`` instead of raising.
41
+
42
+ **Remediation**:
43
+ 1. Check contract YAML syntax with a YAML linter
44
+ 2. Validate contract against ``ModelHandlerContract`` schema
45
+ 3. Enable ``graceful_mode=True`` if partial failures are acceptable
46
+ 4. Check logs for the underlying error (YAML, validation, etc.)
47
+
48
+ **Size Limit Errors (KAFKA_CONTRACT_002)**:
49
+ - ``KAFKA_CONTRACT_002`` (CONTRACT_SIZE_EXCEEDED): Contract YAML exceeds
50
+ the 10MB size limit. This is a hard limit applied before YAML parsing
51
+ to prevent memory exhaustion attacks.
52
+
53
+ **When Raised**: During contract parsing when the UTF-8 encoded contract
54
+ exceeds ``MAX_CONTRACT_SIZE`` (10,485,760 bytes).
55
+
56
+ **Remediation**:
57
+ 1. Reduce contract size by removing unnecessary fields
58
+ 2. Split large handler configurations into multiple contracts
59
+ 3. Move large static data (e.g., schemas) to external files
60
+ 4. Verify the contract isn't corrupted or duplicated
61
+
62
+ Error codes are accessible via ``error.error_code`` on raised ``ModelOnexError``
63
+ exceptions. Include the correlation ID from logs when reporting errors.
64
+
65
+ .. versionadded:: 0.8.0
66
+ Created as part of OMN-1654 Kafka-based contract discovery.
67
+ """
68
+
69
+ from __future__ import annotations
70
+
71
+ import logging
72
+ import threading
73
+ from typing import Protocol, cast, get_args, runtime_checkable
74
+ from uuid import UUID, uuid4
75
+
76
+ import yaml
77
+ from pydantic import ValidationError
78
+
79
+ from omnibase_core.constants import (
80
+ TOPIC_SUFFIX_CONTRACT_DEREGISTERED,
81
+ TOPIC_SUFFIX_CONTRACT_REGISTERED,
82
+ )
83
+ from omnibase_core.models.contracts.model_handler_contract import ModelHandlerContract
84
+ from omnibase_core.models.errors import ModelOnexError
85
+ from omnibase_core.models.events import (
86
+ ModelContractDeregisteredEvent,
87
+ ModelContractRegisteredEvent,
88
+ )
89
+ from omnibase_infra.enums import EnumHandlerErrorType, EnumHandlerSourceType
90
+ from omnibase_infra.models.errors import ModelHandlerValidationError
91
+ from omnibase_infra.models.handlers import (
92
+ LiteralHandlerKind,
93
+ ModelContractDiscoveryResult,
94
+ ModelHandlerDescriptor,
95
+ ModelHandlerIdentifier,
96
+ )
97
+ from omnibase_infra.runtime.protocol_contract_source import ProtocolContractSource
98
+
99
+ logger = logging.getLogger(__name__)
100
+
101
+ # Forward Reference Resolution:
102
+ # ModelContractDiscoveryResult uses a forward reference to ModelHandlerValidationError.
103
+ # Since we import ModelHandlerValidationError above, we can call model_rebuild() here
104
+ # to resolve the forward reference. This call is idempotent - multiple calls are harmless.
105
+ ModelContractDiscoveryResult.model_rebuild()
106
+
107
+ # Maximum contract size (same as other sources)
108
+ MAX_CONTRACT_SIZE = 10 * 1024 * 1024 # 10MB
109
+
110
+
111
+ class ContractYamlParser:
112
+ """Parse contract YAML into ModelHandlerDescriptor.
113
+
114
+ This class handles YAML parsing, validation, and error creation
115
+ for contract documents received via Kafka events. It encapsulates
116
+ all YAML-to-descriptor conversion logic in a single responsibility
117
+ class.
118
+
119
+ Attributes:
120
+ environment: The environment name used for constructing contract paths.
121
+
122
+ Example:
123
+ >>> parser = ContractYamlParser(environment="dev")
124
+ >>> descriptor = parser.parse("my.node", yaml_content, correlation_id)
125
+ >>> print(descriptor.handler_id)
126
+
127
+ .. versionadded:: 0.8.0
128
+ Extracted from KafkaContractSource for single-responsibility.
129
+ """
130
+
131
+ __slots__ = ("_environment",)
132
+
133
+ def __init__(self, environment: str = "dev") -> None:
134
+ """Initialize the parser.
135
+
136
+ Args:
137
+ environment: Environment name for topic prefix (e.g., "dev", "prod").
138
+ Used for constructing contract_path URIs.
139
+ """
140
+ self._environment = environment
141
+
142
+ @property
143
+ def environment(self) -> str:
144
+ """Return the environment name.
145
+
146
+ Returns:
147
+ The environment name (e.g., "dev", "prod").
148
+ """
149
+ return self._environment
150
+
151
+ def parse(
152
+ self,
153
+ node_name: str,
154
+ contract_yaml: str,
155
+ correlation_id: UUID,
156
+ ) -> ModelHandlerDescriptor:
157
+ """Parse contract YAML into ModelHandlerDescriptor.
158
+
159
+ Args:
160
+ node_name: Node identifier (used for error context and path).
161
+ contract_yaml: Full YAML content of the handler contract.
162
+ correlation_id: Correlation ID for tracing.
163
+
164
+ Returns:
165
+ ModelHandlerDescriptor parsed from the contract.
166
+
167
+ Raises:
168
+ yaml.YAMLError: If YAML parsing fails.
169
+ ValidationError: If Pydantic validation fails.
170
+ ModelOnexError: If contract exceeds size limit.
171
+ ValueError: If contract data is invalid.
172
+ """
173
+ # Check size limit
174
+ contract_bytes = contract_yaml.encode("utf-8")
175
+ if len(contract_bytes) > MAX_CONTRACT_SIZE:
176
+ raise ModelOnexError(
177
+ f"Contract exceeds size limit: {len(contract_bytes)} bytes "
178
+ f"(max: {MAX_CONTRACT_SIZE} bytes)",
179
+ error_code="KAFKA_CONTRACT_002",
180
+ )
181
+
182
+ # Parse YAML
183
+ contract_data = yaml.safe_load(contract_yaml)
184
+ if not contract_data:
185
+ raise ValueError("Contract YAML is empty or invalid")
186
+
187
+ # Validate against ModelHandlerContract
188
+ contract = ModelHandlerContract.model_validate(contract_data)
189
+
190
+ # Extract handler_class from metadata section
191
+ # NOTE: handler_class must be in metadata per ModelHandlerContract schema
192
+ # (root-level extra fields are forbidden by Pydantic extra='forbid')
193
+ # TODO [OMN-1420]: Use contract.handler_class once available in schema
194
+ handler_class = None
195
+ if isinstance(contract_data, dict):
196
+ metadata = contract_data.get("metadata", {})
197
+ if isinstance(metadata, dict):
198
+ handler_class = metadata.get("handler_class")
199
+
200
+ if handler_class is None:
201
+ logger.debug(
202
+ "handler_class missing from contract, handler may not be loadable",
203
+ extra={
204
+ "node_name": node_name,
205
+ "handler_id": contract.handler_id,
206
+ "correlation_id": str(correlation_id),
207
+ },
208
+ )
209
+
210
+ # Build descriptor - validate handler_kind before casting
211
+ archetype_value = contract.descriptor.node_archetype.value
212
+ valid_handler_kinds = get_args(LiteralHandlerKind)
213
+ if archetype_value not in valid_handler_kinds:
214
+ raise ValueError(
215
+ f"Invalid node_archetype value '{archetype_value}'. "
216
+ f"Expected one of: {valid_handler_kinds}"
217
+ )
218
+ # Value validated above, cast is now safe
219
+ handler_kind = cast("LiteralHandlerKind", archetype_value)
220
+
221
+ return ModelHandlerDescriptor(
222
+ handler_id=contract.handler_id,
223
+ name=contract.name,
224
+ version=contract.contract_version,
225
+ handler_kind=handler_kind,
226
+ input_model=contract.input_model,
227
+ output_model=contract.output_model,
228
+ description=contract.description,
229
+ handler_class=handler_class,
230
+ contract_path=f"kafka://{self._environment}/contracts/{node_name}",
231
+ contract_config=contract_data,
232
+ )
233
+
234
+ def create_parse_error(
235
+ self,
236
+ node_name: str,
237
+ error: Exception,
238
+ correlation_id: UUID,
239
+ ) -> ModelHandlerValidationError:
240
+ """Create a validation error for contract parse failures.
241
+
242
+ Args:
243
+ node_name: The node identifier.
244
+ error: The parsing error.
245
+ correlation_id: Correlation ID for tracing.
246
+
247
+ Returns:
248
+ ModelHandlerValidationError with parse error details.
249
+ """
250
+ handler_identity = ModelHandlerIdentifier.from_handler_id(
251
+ f"kafka://{node_name}"
252
+ )
253
+
254
+ return ModelHandlerValidationError(
255
+ error_type=EnumHandlerErrorType.CONTRACT_PARSE_ERROR,
256
+ rule_id="KAFKA-001",
257
+ handler_identity=handler_identity,
258
+ source_type=EnumHandlerSourceType.CONTRACT,
259
+ message=f"Failed to parse contract from Kafka event for node '{node_name}': {error}",
260
+ remediation_hint="Check YAML syntax and required contract fields in the registration event",
261
+ correlation_id=correlation_id,
262
+ )
263
+
264
+
265
+ class KafkaContractCache:
266
+ """Thread-safe cache for contract descriptors and validation errors.
267
+
268
+ This class manages the in-memory storage of handler descriptors discovered
269
+ from Kafka contract registration events. All operations are thread-safe
270
+ and can be called concurrently from multiple Kafka consumer threads.
271
+
272
+ The cache provides atomic operations for:
273
+ - Adding/removing handler descriptors by node name
274
+ - Collecting validation errors during event processing
275
+ - Retrieving all cached data with proper thread synchronization
276
+
277
+ Attributes:
278
+ count: Number of cached descriptors (thread-safe read).
279
+ error_count: Number of pending validation errors (thread-safe read).
280
+
281
+ Example:
282
+ >>> cache = KafkaContractCache()
283
+ >>> cache.add("my.node", descriptor)
284
+ >>> assert cache.count == 1
285
+ >>> removed = cache.remove("my.node")
286
+ >>> assert removed is not None
287
+
288
+ .. versionadded:: 0.8.0
289
+ Extracted from KafkaContractSource for single-responsibility.
290
+ """
291
+
292
+ __slots__ = ("_descriptors", "_errors", "_lock")
293
+
294
+ def __init__(self) -> None:
295
+ """Initialize an empty cache with thread-safe locking."""
296
+ self._descriptors: dict[str, ModelHandlerDescriptor] = {}
297
+ self._errors: list[ModelHandlerValidationError] = []
298
+ self._lock = threading.Lock()
299
+
300
+ @property
301
+ def count(self) -> int:
302
+ """Return the number of cached descriptors.
303
+
304
+ Returns:
305
+ Number of handler descriptors currently in the cache.
306
+ """
307
+ with self._lock:
308
+ return len(self._descriptors)
309
+
310
+ @property
311
+ def error_count(self) -> int:
312
+ """Return the number of pending validation errors.
313
+
314
+ Returns:
315
+ Number of validation errors awaiting retrieval.
316
+ """
317
+ with self._lock:
318
+ return len(self._errors)
319
+
320
+ def add(self, node_name: str, descriptor: ModelHandlerDescriptor) -> None:
321
+ """Add or update a descriptor in the cache.
322
+
323
+ If a descriptor with the same node_name exists, it is replaced.
324
+
325
+ Args:
326
+ node_name: Unique identifier for the node (cache key).
327
+ descriptor: The handler descriptor to cache.
328
+ """
329
+ with self._lock:
330
+ self._descriptors[node_name] = descriptor
331
+
332
+ def remove(self, node_name: str) -> ModelHandlerDescriptor | None:
333
+ """Remove a descriptor from the cache.
334
+
335
+ Args:
336
+ node_name: Unique identifier for the node to remove.
337
+
338
+ Returns:
339
+ The removed descriptor if found, None otherwise.
340
+ """
341
+ with self._lock:
342
+ return self._descriptors.pop(node_name, None)
343
+
344
+ def get_all(self) -> list[ModelHandlerDescriptor]:
345
+ """Return all cached descriptors.
346
+
347
+ Returns:
348
+ A copy of all cached descriptors. Modifying the returned
349
+ list does not affect the cache.
350
+ """
351
+ with self._lock:
352
+ return list(self._descriptors.values())
353
+
354
+ def add_error(self, error: ModelHandlerValidationError) -> None:
355
+ """Add a validation error to the pending errors list.
356
+
357
+ Args:
358
+ error: The validation error to add.
359
+ """
360
+ with self._lock:
361
+ self._errors.append(error)
362
+
363
+ def get_errors(self) -> list[ModelHandlerValidationError]:
364
+ """Return pending errors WITHOUT clearing them.
365
+
366
+ This method provides read-only access to pending errors for
367
+ inspection without consuming them.
368
+
369
+ Returns:
370
+ A copy of the pending validation errors.
371
+ """
372
+ with self._lock:
373
+ return list(self._errors)
374
+
375
+ def get_and_clear_errors(self) -> list[ModelHandlerValidationError]:
376
+ """Atomically get and clear all pending errors.
377
+
378
+ This method returns the current errors and clears the internal
379
+ list in a single atomic operation, ensuring no errors are lost
380
+ in concurrent access scenarios.
381
+
382
+ Returns:
383
+ The list of pending errors that were cleared.
384
+ """
385
+ with self._lock:
386
+ errors = list(self._errors)
387
+ self._errors.clear()
388
+ return errors
389
+
390
+ def clear(self) -> int:
391
+ """Clear all cached descriptors and pending errors.
392
+
393
+ Returns:
394
+ Number of descriptors that were cleared.
395
+ """
396
+ with self._lock:
397
+ count = len(self._descriptors)
398
+ self._descriptors.clear()
399
+ self._errors.clear()
400
+ return count
401
+
402
+
403
+ @runtime_checkable
404
+ class ProtocolContractEventCallbacks(Protocol):
405
+ """Protocol defining callbacks for contract registration events.
406
+
407
+ This protocol defines the interface required by MixinTypedContractEvents
408
+ for delegating typed event handling to the host class. Any class using
409
+ MixinTypedContractEvents must implement these methods.
410
+
411
+ The protocol enables type-safe cross-mixin method access without
412
+ inheritance conflicts or type: ignore comments.
413
+
414
+ Methods:
415
+ on_contract_registered: Process a contract registration event.
416
+ on_contract_deregistered: Process a contract deregistration event.
417
+
418
+ Example:
419
+ >>> class MySource(MixinTypedContractEvents, ProtocolContractSource):
420
+ ... def on_contract_registered(
421
+ ... self, node_name: str, contract_yaml: str, correlation_id: UUID | None
422
+ ... ) -> bool:
423
+ ... # Implementation here
424
+ ... return True
425
+ ...
426
+ ... def on_contract_deregistered(
427
+ ... self, node_name: str, correlation_id: UUID | None
428
+ ... ) -> bool:
429
+ ... # Implementation here
430
+ ... return True
431
+
432
+ .. versionadded:: 0.8.0
433
+ Created for type-safe mixin composition in MixinTypedContractEvents.
434
+ """
435
+
436
+ def on_contract_registered(
437
+ self,
438
+ node_name: str,
439
+ contract_yaml: str,
440
+ correlation_id: UUID | None = None,
441
+ ) -> bool:
442
+ """Cache descriptor from contract registration event.
443
+
444
+ Args:
445
+ node_name: Unique identifier for the node (used as cache key).
446
+ contract_yaml: Full YAML content of the handler contract.
447
+ correlation_id: Optional correlation ID from the event for tracing.
448
+
449
+ Returns:
450
+ True if the contract was successfully cached, False if parsing failed.
451
+ """
452
+ ...
453
+
454
+ def on_contract_deregistered(
455
+ self,
456
+ node_name: str,
457
+ correlation_id: UUID | None = None,
458
+ ) -> bool:
459
+ """Remove descriptor from cache on deregistration event.
460
+
461
+ Args:
462
+ node_name: Unique identifier for the node to remove.
463
+ correlation_id: Optional correlation ID from the event for tracing.
464
+
465
+ Returns:
466
+ True if a descriptor was removed, False if not found in cache.
467
+ """
468
+ ...
469
+
470
+
471
+ class MixinTypedContractEvents:
472
+ """Mixin providing typed event handler and error inspection methods.
473
+
474
+ This mixin provides convenience methods for handling typed contract
475
+ events from omnibase_core and inspecting pending validation errors.
476
+ It delegates to the primitive methods (on_contract_registered,
477
+ on_contract_deregistered) and the cache which must be available
478
+ in the class using this mixin.
479
+
480
+ This mixin reduces method count in KafkaContractSource by extracting
481
+ the typed event handling and error inspection into a separate concern.
482
+
483
+ Requirements:
484
+ Classes using this mixin MUST implement ProtocolContractEventCallbacks
485
+ (i.e., provide on_contract_registered and on_contract_deregistered methods).
486
+
487
+ .. versionadded:: 0.8.0
488
+ Extracted from KafkaContractSource for single-responsibility.
489
+ """
490
+
491
+ # Type hints for mixin - these must be provided by the using class
492
+ _cache: KafkaContractCache
493
+
494
+ def _as_event_handler(self) -> ProtocolContractEventCallbacks:
495
+ """Cast self to ProtocolContractEventCallbacks for type-safe method access.
496
+
497
+ Returns:
498
+ Self cast as ProtocolContractEventCallbacks for type checker.
499
+
500
+ Note:
501
+ Only call this method when the host class implements
502
+ ProtocolContractEventCallbacks (provides on_contract_registered
503
+ and on_contract_deregistered methods).
504
+ """
505
+ return cast("ProtocolContractEventCallbacks", self)
506
+
507
+ def get_pending_errors(self) -> list[ModelHandlerValidationError]:
508
+ """Return pending validation errors WITHOUT clearing them.
509
+
510
+ This method provides read-only access to pending errors for inspection
511
+ purposes. Unlike ``discover_handlers()`` which clears errors after
512
+ returning them (one-shot behavior), this method allows repeated
513
+ inspection of the same errors.
514
+
515
+ Use this method when you need to:
516
+ - Check error state without consuming errors
517
+ - Log or display errors before a discover_handlers() call
518
+ - Implement custom error handling before the next discovery cycle
519
+
520
+ Returns:
521
+ A copy of the pending validation errors list. Modifying the
522
+ returned list does not affect the internal state.
523
+
524
+ Thread Safety:
525
+ This method is thread-safe. The returned list is a copy created
526
+ while holding the internal lock.
527
+
528
+ Example:
529
+ >>> source = KafkaContractSource()
530
+ >>> # Inspect errors without consuming
531
+ >>> errors = source.get_pending_errors()
532
+ >>> print(f"Found {len(errors)} pending errors")
533
+ >>>
534
+ >>> # Errors are still available for discover_handlers()
535
+ >>> result = await source.discover_handlers()
536
+ >>> assert len(result.validation_errors) == len(errors)
537
+ >>>
538
+ >>> # Now errors are cleared (one-shot)
539
+ >>> assert source.pending_error_count == 0
540
+
541
+ See Also:
542
+ - ``pending_error_count``: Quick count check without list copy.
543
+ - ``discover_handlers()``: Consumes errors (one-shot retrieval).
544
+ """
545
+ return self._cache.get_errors()
546
+
547
+ def handle_registered_event(
548
+ self,
549
+ event: ModelContractRegisteredEvent,
550
+ ) -> bool:
551
+ """Handle a typed contract registration event.
552
+
553
+ This is the preferred method for processing registration events when
554
+ using the typed event models from omnibase_core. It extracts the
555
+ relevant fields and delegates to on_contract_registered().
556
+
557
+ Args:
558
+ event: The typed contract registration event from Kafka.
559
+
560
+ Returns:
561
+ True if the contract was successfully cached, False if parsing failed.
562
+
563
+ Example:
564
+ >>> source = KafkaContractSource()
565
+ >>> event = ModelContractRegisteredEvent(
566
+ ... node_name="my.handler",
567
+ ... contract_yaml="...",
568
+ ... # ... other fields
569
+ ... )
570
+ >>> success = source.handle_registered_event(event)
571
+ """
572
+ return self._as_event_handler().on_contract_registered(
573
+ node_name=event.node_name,
574
+ contract_yaml=event.contract_yaml,
575
+ correlation_id=event.correlation_id,
576
+ )
577
+
578
+ def handle_deregistered_event(
579
+ self,
580
+ event: ModelContractDeregisteredEvent,
581
+ ) -> bool:
582
+ """Handle a typed contract deregistration event.
583
+
584
+ This is the preferred method for processing deregistration events when
585
+ using the typed event models from omnibase_core. It extracts the
586
+ relevant fields and delegates to on_contract_deregistered().
587
+
588
+ Args:
589
+ event: The typed contract deregistration event from Kafka.
590
+
591
+ Returns:
592
+ True if a descriptor was removed, False if not found in cache.
593
+
594
+ Example:
595
+ >>> source = KafkaContractSource()
596
+ >>> event = ModelContractDeregisteredEvent(
597
+ ... node_name="my.handler",
598
+ ... reason=EnumDeregistrationReason.SHUTDOWN,
599
+ ... # ... other fields
600
+ ... )
601
+ >>> removed = source.handle_deregistered_event(event)
602
+ """
603
+ return self._as_event_handler().on_contract_deregistered(
604
+ node_name=event.node_name,
605
+ correlation_id=event.correlation_id,
606
+ )
607
+
608
+
609
+ class KafkaContractSource(MixinTypedContractEvents, ProtocolContractSource):
610
+ """Kafka-based contract source - cache + discovery only.
611
+
612
+ Subscribes to platform-reserved contract topics (baseline-wired).
613
+ Maintains in-memory cache of descriptors derived from contract YAML.
614
+
615
+ Does NOT wire business subscriptions dynamically.
616
+ For beta: discover + next restart applies.
617
+
618
+ This source maintains an in-memory cache of handler descriptors that is
619
+ populated by contract registration events received via Kafka. The cache
620
+ is read-only from the discover_handlers() perspective - it simply returns
621
+ whatever has been cached from events.
622
+
623
+ Thread Safety:
624
+ This class is thread-safe. All access to the internal cache
625
+ (``_cached_descriptors``) and error list (``_pending_errors``) is
626
+ protected by a ``threading.Lock``. Multiple Kafka consumer threads
627
+ may safely call ``on_contract_registered()`` and
628
+ ``on_contract_deregistered()`` concurrently.
629
+
630
+ Attributes:
631
+ source_type: Returns "KAFKA_EVENTS" as the source type identifier.
632
+
633
+ Example:
634
+ >>> source = KafkaContractSource(environment="dev")
635
+ >>>
636
+ >>> # Event handler wiring (done by runtime)
637
+ >>> source.on_contract_registered(event)
638
+ >>>
639
+ >>> # Discovery returns cached descriptors
640
+ >>> result = await source.discover_handlers()
641
+ >>> for desc in result.descriptors:
642
+ ... print(f"Cached: {desc.handler_id}")
643
+
644
+ Note:
645
+ This class does NOT handle Kafka subscription setup. The runtime is
646
+ responsible for wiring the platform-reserved contract topics to the
647
+ on_contract_registered/on_contract_deregistered methods.
648
+
649
+ .. versionadded:: 0.8.0
650
+ Created as part of OMN-1654 Kafka-based contract discovery.
651
+ """
652
+
653
+ __slots__ = (
654
+ "_cache",
655
+ "_correlation_id",
656
+ "_environment",
657
+ "_graceful_mode",
658
+ "_parser",
659
+ )
660
+
661
+ def __init__(
662
+ self,
663
+ environment: str = "dev",
664
+ graceful_mode: bool = True,
665
+ ) -> None:
666
+ """Initialize the Kafka contract source.
667
+
668
+ Args:
669
+ environment: Environment name for topic prefix (e.g., "dev", "prod").
670
+ Used for observability logging only - actual topic wiring is
671
+ done by the runtime.
672
+ graceful_mode: If True (default), collect errors instead of raising.
673
+ For cache-based sources, graceful mode is typically preferred
674
+ since individual event failures should not crash the runtime.
675
+ """
676
+ self._environment = environment
677
+ self._graceful_mode = graceful_mode
678
+ self._correlation_id = uuid4()
679
+ self._cache = KafkaContractCache()
680
+ self._parser = ContractYamlParser(environment=environment)
681
+
682
+ logger.info(
683
+ "KafkaContractSource initialized",
684
+ extra={
685
+ "environment": environment,
686
+ "graceful_mode": graceful_mode,
687
+ "correlation_id": str(self._correlation_id),
688
+ },
689
+ )
690
+
691
+ @property
692
+ def source_type(self) -> str:
693
+ """Return source type identifier.
694
+
695
+ Returns:
696
+ "KAFKA_EVENTS" as the source type.
697
+ """
698
+ return "KAFKA_EVENTS"
699
+
700
+ @property
701
+ def cached_count(self) -> int:
702
+ """Return the number of cached descriptors.
703
+
704
+ Returns:
705
+ Number of handler descriptors currently cached.
706
+ """
707
+ return self._cache.count
708
+
709
+ @property
710
+ def environment(self) -> str:
711
+ """Return the environment name.
712
+
713
+ Returns:
714
+ The environment name (e.g., "dev", "prod").
715
+ """
716
+ return self._environment
717
+
718
+ @property
719
+ def graceful_mode(self) -> bool:
720
+ """Return whether graceful mode is enabled.
721
+
722
+ Returns:
723
+ True if graceful mode is enabled, False otherwise.
724
+ """
725
+ return self._graceful_mode
726
+
727
+ @property
728
+ def correlation_id(self) -> UUID:
729
+ """Return the source correlation ID.
730
+
731
+ Returns:
732
+ The unique correlation ID for this source instance.
733
+ """
734
+ return self._correlation_id
735
+
736
+ @property
737
+ def pending_error_count(self) -> int:
738
+ """Return the number of pending validation errors.
739
+
740
+ This property provides a quick way to check if there are pending
741
+ errors without consuming them. Use ``get_pending_errors()`` to
742
+ inspect errors without clearing, or ``discover_handlers()`` to
743
+ consume errors (one-shot retrieval).
744
+
745
+ Returns:
746
+ Number of validation errors currently pending.
747
+
748
+ Example:
749
+ >>> source = KafkaContractSource()
750
+ >>> if source.pending_error_count > 0:
751
+ ... errors = source.get_pending_errors()
752
+ ... for err in errors:
753
+ ... print(f"Pending error: {err.message}")
754
+ """
755
+ return self._cache.error_count
756
+
757
+ async def discover_handlers(self) -> ModelContractDiscoveryResult:
758
+ """Return cached descriptors from contract events.
759
+
760
+ This method returns whatever descriptors have been cached from
761
+ contract registration events. It does not perform any I/O or
762
+ network operations - it simply returns the current cache state.
763
+
764
+ Warning:
765
+ **One-Shot Error Retrieval**: Validation errors are cleared after
766
+ being returned. Calling this method twice will return an empty
767
+ error list on the second call (unless new errors occurred between
768
+ calls). Use ``get_pending_errors()`` to inspect errors without
769
+ consuming them, or ``pending_error_count`` for a quick count check.
770
+
771
+ Returns:
772
+ ModelContractDiscoveryResult with cached descriptors and any
773
+ validation errors encountered during event processing. Errors
774
+ are cleared from internal state after this call returns.
775
+
776
+ Example:
777
+ >>> source = KafkaContractSource()
778
+ >>> # First call returns accumulated errors
779
+ >>> result1 = await source.discover_handlers()
780
+ >>> print(f"Errors: {len(result1.validation_errors)}")
781
+ >>>
782
+ >>> # Second call has empty errors (already consumed)
783
+ >>> result2 = await source.discover_handlers()
784
+ >>> assert len(result2.validation_errors) == 0
785
+
786
+ Implementation Detail:
787
+ This method uses a two-step retrieval pattern: errors are cleared
788
+ first, then descriptors are fetched. Each step is individually
789
+ atomic (protected by the cache lock), but there is a brief window
790
+ between the two operations where new events could arrive.
791
+
792
+ If a contract event fails parsing between ``get_and_clear_errors()``
793
+ and ``get_all()``, the resulting error will NOT be included in this
794
+ discovery result - it will appear in the next ``discover_handlers()``
795
+ call. Similarly, a successful registration between the two calls
796
+ will include the new descriptor but any error from a concurrent
797
+ failed registration will be deferred.
798
+
799
+ This eventual consistency is acceptable for the cache-only beta
800
+ model where discovered contracts take effect on the next restart
801
+ anyway. The design prioritizes simplicity over perfect atomicity,
802
+ avoiding the complexity of a single lock spanning both operations
803
+ (which would increase lock contention with concurrent Kafka
804
+ consumer threads).
805
+
806
+ See Also:
807
+ - ``get_pending_errors()``: Inspect errors without clearing.
808
+ - ``pending_error_count``: Quick count check.
809
+ """
810
+ # Two-step retrieval: errors cleared first, then descriptors fetched.
811
+ # See "Implementation Detail" in docstring for timing window behavior.
812
+ errors = self._cache.get_and_clear_errors()
813
+ descriptors = self._cache.get_all()
814
+
815
+ logger.info(
816
+ "Handler discovery completed (KAFKA_EVENTS mode)",
817
+ extra={
818
+ "cached_descriptor_count": len(descriptors),
819
+ "validation_error_count": len(errors),
820
+ "environment": self._environment,
821
+ "correlation_id": str(self._correlation_id),
822
+ },
823
+ )
824
+
825
+ return ModelContractDiscoveryResult(
826
+ descriptors=descriptors,
827
+ validation_errors=errors,
828
+ )
829
+
830
+ def on_contract_registered(
831
+ self,
832
+ node_name: str,
833
+ contract_yaml: str,
834
+ correlation_id: UUID | None = None,
835
+ ) -> bool:
836
+ """Cache descriptor from contract registration event.
837
+
838
+ Called by the runtime when a contract registration event is received
839
+ on the platform-reserved contract topic.
840
+
841
+ Args:
842
+ node_name: Unique identifier for the node (used as cache key).
843
+ contract_yaml: Full YAML content of the handler contract.
844
+ correlation_id: Optional correlation ID from the event for tracing.
845
+
846
+ Returns:
847
+ True if the contract was successfully cached, False if parsing failed.
848
+
849
+ Note:
850
+ In graceful mode, parsing errors are collected in pending_errors
851
+ and returned on the next discover_handlers() call. In strict mode,
852
+ errors are raised immediately.
853
+ """
854
+ event_correlation = correlation_id or uuid4()
855
+
856
+ logger.debug(
857
+ "Processing contract registration event",
858
+ extra={
859
+ "node_name": node_name,
860
+ "contract_size": len(contract_yaml),
861
+ "correlation_id": str(event_correlation),
862
+ "source_correlation_id": str(self._correlation_id),
863
+ },
864
+ )
865
+
866
+ try:
867
+ descriptor = self._parser.parse(
868
+ node_name=node_name,
869
+ contract_yaml=contract_yaml,
870
+ correlation_id=event_correlation,
871
+ )
872
+ self._cache.add(node_name, descriptor)
873
+
874
+ logger.info(
875
+ "Contract registered and cached",
876
+ extra={
877
+ "node_name": node_name,
878
+ "handler_id": descriptor.handler_id,
879
+ "handler_version": str(descriptor.version),
880
+ "correlation_id": str(event_correlation),
881
+ },
882
+ )
883
+ return True
884
+
885
+ except (yaml.YAMLError, ValidationError, ModelOnexError, ValueError) as e:
886
+ error = self._parser.create_parse_error(
887
+ node_name=node_name,
888
+ error=e,
889
+ correlation_id=event_correlation,
890
+ )
891
+
892
+ if self._graceful_mode:
893
+ self._cache.add_error(error)
894
+ logger.warning(
895
+ "Contract registration failed (graceful mode)",
896
+ extra={
897
+ "node_name": node_name,
898
+ "error": str(e),
899
+ "error_type": type(e).__name__,
900
+ "correlation_id": str(event_correlation),
901
+ },
902
+ )
903
+ return False
904
+ else:
905
+ raise ModelOnexError(
906
+ f"Failed to parse contract for node '{node_name}': {e}",
907
+ error_code="KAFKA_CONTRACT_001",
908
+ correlation_id=event_correlation,
909
+ ) from e
910
+
911
+ def on_contract_deregistered(
912
+ self,
913
+ node_name: str,
914
+ correlation_id: UUID | None = None,
915
+ ) -> bool:
916
+ """Remove descriptor from cache on deregistration event.
917
+
918
+ Called by the runtime when a contract deregistration event is received
919
+ on the platform-reserved contract topic.
920
+
921
+ Args:
922
+ node_name: Unique identifier for the node to remove.
923
+ correlation_id: Optional correlation ID from the event for tracing.
924
+
925
+ Returns:
926
+ True if a descriptor was removed, False if not found in cache.
927
+ """
928
+ event_correlation = correlation_id or uuid4()
929
+
930
+ removed = self._cache.remove(node_name)
931
+
932
+ if removed is not None:
933
+ logger.info(
934
+ "Contract deregistered and removed from cache",
935
+ extra={
936
+ "node_name": node_name,
937
+ "handler_id": removed.handler_id,
938
+ "correlation_id": str(event_correlation),
939
+ },
940
+ )
941
+ return True
942
+ else:
943
+ logger.debug(
944
+ "Contract deregistration for unknown node (no-op)",
945
+ extra={
946
+ "node_name": node_name,
947
+ "correlation_id": str(event_correlation),
948
+ },
949
+ )
950
+ return False
951
+
952
+ def clear_cache(self) -> int:
953
+ """Clear all cached descriptors.
954
+
955
+ Utility method for testing and runtime reset scenarios.
956
+
957
+ Returns:
958
+ Number of descriptors that were cleared.
959
+ """
960
+ count = self._cache.clear()
961
+
962
+ logger.info(
963
+ "Contract cache cleared",
964
+ extra={
965
+ "cleared_count": count,
966
+ "correlation_id": str(self._correlation_id),
967
+ },
968
+ )
969
+ return count
970
+
971
+
972
+ __all__ = [
973
+ "ContractYamlParser",
974
+ "KafkaContractCache",
975
+ "KafkaContractSource",
976
+ "MAX_CONTRACT_SIZE",
977
+ "MixinTypedContractEvents",
978
+ "ProtocolContractEventCallbacks",
979
+ # Re-exported from omnibase_core for convenience
980
+ "ModelContractDeregisteredEvent",
981
+ "ModelContractRegisteredEvent",
982
+ "TOPIC_SUFFIX_CONTRACT_DEREGISTERED",
983
+ "TOPIC_SUFFIX_CONTRACT_REGISTERED",
984
+ ]