omnibase_infra 0.2.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (675) hide show
  1. omnibase_infra/__init__.py +101 -0
  2. omnibase_infra/cli/__init__.py +1 -0
  3. omnibase_infra/cli/commands.py +216 -0
  4. omnibase_infra/clients/__init__.py +0 -0
  5. omnibase_infra/contracts/handlers/filesystem/handler_contract.yaml +261 -0
  6. omnibase_infra/contracts/handlers/mcp/handler_contract.yaml +138 -0
  7. omnibase_infra/decorators/__init__.py +29 -0
  8. omnibase_infra/decorators/allow_any.py +109 -0
  9. omnibase_infra/dlq/__init__.py +90 -0
  10. omnibase_infra/dlq/constants_dlq.py +57 -0
  11. omnibase_infra/dlq/models/__init__.py +26 -0
  12. omnibase_infra/dlq/models/enum_replay_status.py +37 -0
  13. omnibase_infra/dlq/models/model_dlq_replay_record.py +135 -0
  14. omnibase_infra/dlq/models/model_dlq_tracking_config.py +184 -0
  15. omnibase_infra/dlq/service_dlq_tracking.py +611 -0
  16. omnibase_infra/enums/__init__.py +123 -0
  17. omnibase_infra/enums/enum_any_type_violation.py +104 -0
  18. omnibase_infra/enums/enum_backend_type.py +27 -0
  19. omnibase_infra/enums/enum_capture_outcome.py +42 -0
  20. omnibase_infra/enums/enum_capture_state.py +88 -0
  21. omnibase_infra/enums/enum_chain_violation_type.py +119 -0
  22. omnibase_infra/enums/enum_circuit_state.py +51 -0
  23. omnibase_infra/enums/enum_confirmation_event_type.py +27 -0
  24. omnibase_infra/enums/enum_contract_type.py +84 -0
  25. omnibase_infra/enums/enum_dedupe_strategy.py +46 -0
  26. omnibase_infra/enums/enum_dispatch_status.py +191 -0
  27. omnibase_infra/enums/enum_environment.py +46 -0
  28. omnibase_infra/enums/enum_execution_shape_violation.py +103 -0
  29. omnibase_infra/enums/enum_handler_error_type.py +101 -0
  30. omnibase_infra/enums/enum_handler_loader_error.py +178 -0
  31. omnibase_infra/enums/enum_handler_source_type.py +87 -0
  32. omnibase_infra/enums/enum_handler_type.py +77 -0
  33. omnibase_infra/enums/enum_handler_type_category.py +61 -0
  34. omnibase_infra/enums/enum_infra_transport_type.py +73 -0
  35. omnibase_infra/enums/enum_introspection_reason.py +154 -0
  36. omnibase_infra/enums/enum_message_category.py +213 -0
  37. omnibase_infra/enums/enum_node_archetype.py +74 -0
  38. omnibase_infra/enums/enum_node_output_type.py +185 -0
  39. omnibase_infra/enums/enum_non_retryable_error_category.py +224 -0
  40. omnibase_infra/enums/enum_policy_type.py +32 -0
  41. omnibase_infra/enums/enum_registration_state.py +261 -0
  42. omnibase_infra/enums/enum_registration_status.py +33 -0
  43. omnibase_infra/enums/enum_registry_response_status.py +28 -0
  44. omnibase_infra/enums/enum_response_status.py +26 -0
  45. omnibase_infra/enums/enum_retry_error_category.py +98 -0
  46. omnibase_infra/enums/enum_security_rule_id.py +103 -0
  47. omnibase_infra/enums/enum_selection_strategy.py +91 -0
  48. omnibase_infra/enums/enum_topic_standard.py +42 -0
  49. omnibase_infra/enums/enum_validation_severity.py +78 -0
  50. omnibase_infra/errors/__init__.py +156 -0
  51. omnibase_infra/errors/error_architecture_violation.py +152 -0
  52. omnibase_infra/errors/error_chain_propagation.py +188 -0
  53. omnibase_infra/errors/error_compute_registry.py +92 -0
  54. omnibase_infra/errors/error_consul.py +132 -0
  55. omnibase_infra/errors/error_container_wiring.py +243 -0
  56. omnibase_infra/errors/error_event_bus_registry.py +102 -0
  57. omnibase_infra/errors/error_infra.py +608 -0
  58. omnibase_infra/errors/error_message_type_registry.py +101 -0
  59. omnibase_infra/errors/error_policy_registry.py +112 -0
  60. omnibase_infra/errors/error_vault.py +123 -0
  61. omnibase_infra/event_bus/__init__.py +72 -0
  62. omnibase_infra/event_bus/configs/kafka_event_bus_config.yaml +86 -0
  63. omnibase_infra/event_bus/event_bus_inmemory.py +743 -0
  64. omnibase_infra/event_bus/event_bus_kafka.py +1658 -0
  65. omnibase_infra/event_bus/mixin_kafka_broadcast.py +184 -0
  66. omnibase_infra/event_bus/mixin_kafka_dlq.py +765 -0
  67. omnibase_infra/event_bus/models/__init__.py +29 -0
  68. omnibase_infra/event_bus/models/config/__init__.py +20 -0
  69. omnibase_infra/event_bus/models/config/model_kafka_event_bus_config.py +725 -0
  70. omnibase_infra/event_bus/models/model_dlq_event.py +206 -0
  71. omnibase_infra/event_bus/models/model_dlq_metrics.py +304 -0
  72. omnibase_infra/event_bus/models/model_event_headers.py +115 -0
  73. omnibase_infra/event_bus/models/model_event_message.py +60 -0
  74. omnibase_infra/event_bus/topic_constants.py +376 -0
  75. omnibase_infra/handlers/__init__.py +75 -0
  76. omnibase_infra/handlers/filesystem/__init__.py +48 -0
  77. omnibase_infra/handlers/filesystem/enum_file_system_operation.py +35 -0
  78. omnibase_infra/handlers/filesystem/model_file_system_request.py +298 -0
  79. omnibase_infra/handlers/filesystem/model_file_system_result.py +166 -0
  80. omnibase_infra/handlers/handler_consul.py +787 -0
  81. omnibase_infra/handlers/handler_db.py +1039 -0
  82. omnibase_infra/handlers/handler_filesystem.py +1478 -0
  83. omnibase_infra/handlers/handler_graph.py +1154 -0
  84. omnibase_infra/handlers/handler_http.py +920 -0
  85. omnibase_infra/handlers/handler_manifest_persistence.contract.yaml +184 -0
  86. omnibase_infra/handlers/handler_manifest_persistence.py +1539 -0
  87. omnibase_infra/handlers/handler_mcp.py +748 -0
  88. omnibase_infra/handlers/handler_qdrant.py +1076 -0
  89. omnibase_infra/handlers/handler_vault.py +422 -0
  90. omnibase_infra/handlers/mcp/__init__.py +19 -0
  91. omnibase_infra/handlers/mcp/adapter_onex_to_mcp.py +446 -0
  92. omnibase_infra/handlers/mcp/protocols.py +178 -0
  93. omnibase_infra/handlers/mcp/transport_streamable_http.py +352 -0
  94. omnibase_infra/handlers/mixins/__init__.py +42 -0
  95. omnibase_infra/handlers/mixins/mixin_consul_initialization.py +349 -0
  96. omnibase_infra/handlers/mixins/mixin_consul_kv.py +337 -0
  97. omnibase_infra/handlers/mixins/mixin_consul_service.py +277 -0
  98. omnibase_infra/handlers/mixins/mixin_vault_initialization.py +338 -0
  99. omnibase_infra/handlers/mixins/mixin_vault_retry.py +412 -0
  100. omnibase_infra/handlers/mixins/mixin_vault_secrets.py +450 -0
  101. omnibase_infra/handlers/mixins/mixin_vault_token.py +365 -0
  102. omnibase_infra/handlers/models/__init__.py +286 -0
  103. omnibase_infra/handlers/models/consul/__init__.py +81 -0
  104. omnibase_infra/handlers/models/consul/enum_consul_operation_type.py +57 -0
  105. omnibase_infra/handlers/models/consul/model_consul_deregister_payload.py +51 -0
  106. omnibase_infra/handlers/models/consul/model_consul_handler_config.py +153 -0
  107. omnibase_infra/handlers/models/consul/model_consul_handler_payload.py +89 -0
  108. omnibase_infra/handlers/models/consul/model_consul_kv_get_found_payload.py +55 -0
  109. omnibase_infra/handlers/models/consul/model_consul_kv_get_not_found_payload.py +49 -0
  110. omnibase_infra/handlers/models/consul/model_consul_kv_get_recurse_payload.py +50 -0
  111. omnibase_infra/handlers/models/consul/model_consul_kv_item.py +33 -0
  112. omnibase_infra/handlers/models/consul/model_consul_kv_put_payload.py +41 -0
  113. omnibase_infra/handlers/models/consul/model_consul_register_payload.py +53 -0
  114. omnibase_infra/handlers/models/consul/model_consul_retry_config.py +66 -0
  115. omnibase_infra/handlers/models/consul/model_payload_consul.py +66 -0
  116. omnibase_infra/handlers/models/consul/registry_payload_consul.py +214 -0
  117. omnibase_infra/handlers/models/graph/__init__.py +35 -0
  118. omnibase_infra/handlers/models/graph/enum_graph_operation_type.py +20 -0
  119. omnibase_infra/handlers/models/graph/model_graph_execute_payload.py +38 -0
  120. omnibase_infra/handlers/models/graph/model_graph_handler_config.py +54 -0
  121. omnibase_infra/handlers/models/graph/model_graph_handler_payload.py +44 -0
  122. omnibase_infra/handlers/models/graph/model_graph_query_payload.py +40 -0
  123. omnibase_infra/handlers/models/graph/model_graph_record.py +22 -0
  124. omnibase_infra/handlers/models/http/__init__.py +50 -0
  125. omnibase_infra/handlers/models/http/enum_http_operation_type.py +29 -0
  126. omnibase_infra/handlers/models/http/model_http_body_content.py +45 -0
  127. omnibase_infra/handlers/models/http/model_http_get_payload.py +88 -0
  128. omnibase_infra/handlers/models/http/model_http_handler_payload.py +90 -0
  129. omnibase_infra/handlers/models/http/model_http_post_payload.py +88 -0
  130. omnibase_infra/handlers/models/http/model_payload_http.py +66 -0
  131. omnibase_infra/handlers/models/http/registry_payload_http.py +212 -0
  132. omnibase_infra/handlers/models/mcp/__init__.py +23 -0
  133. omnibase_infra/handlers/models/mcp/enum_mcp_operation_type.py +24 -0
  134. omnibase_infra/handlers/models/mcp/model_mcp_handler_config.py +40 -0
  135. omnibase_infra/handlers/models/mcp/model_mcp_tool_call.py +32 -0
  136. omnibase_infra/handlers/models/mcp/model_mcp_tool_result.py +45 -0
  137. omnibase_infra/handlers/models/model_consul_handler_response.py +96 -0
  138. omnibase_infra/handlers/models/model_db_describe_response.py +83 -0
  139. omnibase_infra/handlers/models/model_db_query_payload.py +95 -0
  140. omnibase_infra/handlers/models/model_db_query_response.py +60 -0
  141. omnibase_infra/handlers/models/model_filesystem_config.py +98 -0
  142. omnibase_infra/handlers/models/model_filesystem_delete_payload.py +54 -0
  143. omnibase_infra/handlers/models/model_filesystem_delete_result.py +77 -0
  144. omnibase_infra/handlers/models/model_filesystem_directory_entry.py +75 -0
  145. omnibase_infra/handlers/models/model_filesystem_ensure_directory_payload.py +54 -0
  146. omnibase_infra/handlers/models/model_filesystem_ensure_directory_result.py +60 -0
  147. omnibase_infra/handlers/models/model_filesystem_list_directory_payload.py +60 -0
  148. omnibase_infra/handlers/models/model_filesystem_list_directory_result.py +68 -0
  149. omnibase_infra/handlers/models/model_filesystem_read_payload.py +62 -0
  150. omnibase_infra/handlers/models/model_filesystem_read_result.py +61 -0
  151. omnibase_infra/handlers/models/model_filesystem_write_payload.py +70 -0
  152. omnibase_infra/handlers/models/model_filesystem_write_result.py +55 -0
  153. omnibase_infra/handlers/models/model_graph_handler_response.py +98 -0
  154. omnibase_infra/handlers/models/model_handler_response.py +103 -0
  155. omnibase_infra/handlers/models/model_http_handler_response.py +101 -0
  156. omnibase_infra/handlers/models/model_manifest_metadata.py +75 -0
  157. omnibase_infra/handlers/models/model_manifest_persistence_config.py +62 -0
  158. omnibase_infra/handlers/models/model_manifest_query_payload.py +90 -0
  159. omnibase_infra/handlers/models/model_manifest_query_result.py +97 -0
  160. omnibase_infra/handlers/models/model_manifest_retrieve_payload.py +44 -0
  161. omnibase_infra/handlers/models/model_manifest_retrieve_result.py +98 -0
  162. omnibase_infra/handlers/models/model_manifest_store_payload.py +47 -0
  163. omnibase_infra/handlers/models/model_manifest_store_result.py +67 -0
  164. omnibase_infra/handlers/models/model_operation_context.py +187 -0
  165. omnibase_infra/handlers/models/model_qdrant_handler_response.py +98 -0
  166. omnibase_infra/handlers/models/model_retry_state.py +162 -0
  167. omnibase_infra/handlers/models/model_vault_handler_response.py +98 -0
  168. omnibase_infra/handlers/models/qdrant/__init__.py +44 -0
  169. omnibase_infra/handlers/models/qdrant/enum_qdrant_operation_type.py +26 -0
  170. omnibase_infra/handlers/models/qdrant/model_qdrant_collection_payload.py +42 -0
  171. omnibase_infra/handlers/models/qdrant/model_qdrant_delete_payload.py +36 -0
  172. omnibase_infra/handlers/models/qdrant/model_qdrant_handler_config.py +42 -0
  173. omnibase_infra/handlers/models/qdrant/model_qdrant_handler_payload.py +54 -0
  174. omnibase_infra/handlers/models/qdrant/model_qdrant_search_payload.py +42 -0
  175. omnibase_infra/handlers/models/qdrant/model_qdrant_search_result.py +30 -0
  176. omnibase_infra/handlers/models/qdrant/model_qdrant_upsert_payload.py +36 -0
  177. omnibase_infra/handlers/models/vault/__init__.py +69 -0
  178. omnibase_infra/handlers/models/vault/enum_vault_operation_type.py +35 -0
  179. omnibase_infra/handlers/models/vault/model_payload_vault.py +66 -0
  180. omnibase_infra/handlers/models/vault/model_vault_delete_payload.py +57 -0
  181. omnibase_infra/handlers/models/vault/model_vault_handler_config.py +148 -0
  182. omnibase_infra/handlers/models/vault/model_vault_handler_payload.py +101 -0
  183. omnibase_infra/handlers/models/vault/model_vault_list_payload.py +58 -0
  184. omnibase_infra/handlers/models/vault/model_vault_renew_token_payload.py +67 -0
  185. omnibase_infra/handlers/models/vault/model_vault_retry_config.py +66 -0
  186. omnibase_infra/handlers/models/vault/model_vault_secret_payload.py +106 -0
  187. omnibase_infra/handlers/models/vault/model_vault_write_payload.py +66 -0
  188. omnibase_infra/handlers/models/vault/registry_payload_vault.py +213 -0
  189. omnibase_infra/handlers/registration_storage/__init__.py +43 -0
  190. omnibase_infra/handlers/registration_storage/handler_registration_storage_mock.py +392 -0
  191. omnibase_infra/handlers/registration_storage/handler_registration_storage_postgres.py +915 -0
  192. omnibase_infra/handlers/registration_storage/models/__init__.py +23 -0
  193. omnibase_infra/handlers/registration_storage/models/model_delete_registration_request.py +58 -0
  194. omnibase_infra/handlers/registration_storage/models/model_update_registration_request.py +73 -0
  195. omnibase_infra/handlers/registration_storage/protocol_registration_persistence.py +191 -0
  196. omnibase_infra/handlers/service_discovery/__init__.py +43 -0
  197. omnibase_infra/handlers/service_discovery/handler_service_discovery_consul.py +747 -0
  198. omnibase_infra/handlers/service_discovery/handler_service_discovery_mock.py +258 -0
  199. omnibase_infra/handlers/service_discovery/models/__init__.py +22 -0
  200. omnibase_infra/handlers/service_discovery/models/model_discovery_result.py +64 -0
  201. omnibase_infra/handlers/service_discovery/models/model_registration_result.py +138 -0
  202. omnibase_infra/handlers/service_discovery/models/model_service_info.py +99 -0
  203. omnibase_infra/handlers/service_discovery/protocol_discovery_operations.py +170 -0
  204. omnibase_infra/idempotency/__init__.py +94 -0
  205. omnibase_infra/idempotency/models/__init__.py +43 -0
  206. omnibase_infra/idempotency/models/model_idempotency_check_result.py +85 -0
  207. omnibase_infra/idempotency/models/model_idempotency_guard_config.py +130 -0
  208. omnibase_infra/idempotency/models/model_idempotency_record.py +86 -0
  209. omnibase_infra/idempotency/models/model_idempotency_store_health_check_result.py +81 -0
  210. omnibase_infra/idempotency/models/model_idempotency_store_metrics.py +140 -0
  211. omnibase_infra/idempotency/models/model_postgres_idempotency_store_config.py +299 -0
  212. omnibase_infra/idempotency/protocol_idempotency_store.py +184 -0
  213. omnibase_infra/idempotency/store_inmemory.py +265 -0
  214. omnibase_infra/idempotency/store_postgres.py +923 -0
  215. omnibase_infra/infrastructure/__init__.py +0 -0
  216. omnibase_infra/mixins/__init__.py +71 -0
  217. omnibase_infra/mixins/mixin_async_circuit_breaker.py +655 -0
  218. omnibase_infra/mixins/mixin_dict_like_accessors.py +146 -0
  219. omnibase_infra/mixins/mixin_envelope_extraction.py +119 -0
  220. omnibase_infra/mixins/mixin_node_introspection.py +2465 -0
  221. omnibase_infra/mixins/mixin_retry_execution.py +386 -0
  222. omnibase_infra/mixins/protocol_circuit_breaker_aware.py +133 -0
  223. omnibase_infra/models/__init__.py +136 -0
  224. omnibase_infra/models/corpus/__init__.py +17 -0
  225. omnibase_infra/models/corpus/model_capture_config.py +133 -0
  226. omnibase_infra/models/corpus/model_capture_result.py +86 -0
  227. omnibase_infra/models/discovery/__init__.py +42 -0
  228. omnibase_infra/models/discovery/model_dependency_spec.py +319 -0
  229. omnibase_infra/models/discovery/model_discovered_capabilities.py +50 -0
  230. omnibase_infra/models/discovery/model_introspection_config.py +311 -0
  231. omnibase_infra/models/discovery/model_introspection_performance_metrics.py +169 -0
  232. omnibase_infra/models/discovery/model_introspection_task_config.py +116 -0
  233. omnibase_infra/models/dispatch/__init__.py +147 -0
  234. omnibase_infra/models/dispatch/model_dispatch_context.py +439 -0
  235. omnibase_infra/models/dispatch/model_dispatch_error.py +336 -0
  236. omnibase_infra/models/dispatch/model_dispatch_log_context.py +400 -0
  237. omnibase_infra/models/dispatch/model_dispatch_metadata.py +228 -0
  238. omnibase_infra/models/dispatch/model_dispatch_metrics.py +496 -0
  239. omnibase_infra/models/dispatch/model_dispatch_outcome.py +317 -0
  240. omnibase_infra/models/dispatch/model_dispatch_outputs.py +231 -0
  241. omnibase_infra/models/dispatch/model_dispatch_result.py +436 -0
  242. omnibase_infra/models/dispatch/model_dispatch_route.py +279 -0
  243. omnibase_infra/models/dispatch/model_dispatcher_metrics.py +275 -0
  244. omnibase_infra/models/dispatch/model_dispatcher_registration.py +352 -0
  245. omnibase_infra/models/dispatch/model_parsed_topic.py +135 -0
  246. omnibase_infra/models/dispatch/model_topic_parser.py +725 -0
  247. omnibase_infra/models/dispatch/model_tracing_context.py +285 -0
  248. omnibase_infra/models/errors/__init__.py +45 -0
  249. omnibase_infra/models/errors/model_handler_validation_error.py +594 -0
  250. omnibase_infra/models/errors/model_infra_error_context.py +99 -0
  251. omnibase_infra/models/errors/model_message_type_registry_error_context.py +71 -0
  252. omnibase_infra/models/errors/model_timeout_error_context.py +110 -0
  253. omnibase_infra/models/handlers/__init__.py +37 -0
  254. omnibase_infra/models/handlers/model_contract_discovery_result.py +80 -0
  255. omnibase_infra/models/handlers/model_handler_descriptor.py +185 -0
  256. omnibase_infra/models/handlers/model_handler_identifier.py +215 -0
  257. omnibase_infra/models/health/__init__.py +9 -0
  258. omnibase_infra/models/health/model_health_check_result.py +40 -0
  259. omnibase_infra/models/lifecycle/__init__.py +39 -0
  260. omnibase_infra/models/logging/__init__.py +51 -0
  261. omnibase_infra/models/logging/model_log_context.py +756 -0
  262. omnibase_infra/models/model_retry_error_classification.py +78 -0
  263. omnibase_infra/models/projection/__init__.py +43 -0
  264. omnibase_infra/models/projection/model_capability_fields.py +112 -0
  265. omnibase_infra/models/projection/model_registration_projection.py +434 -0
  266. omnibase_infra/models/projection/model_registration_snapshot.py +322 -0
  267. omnibase_infra/models/projection/model_sequence_info.py +182 -0
  268. omnibase_infra/models/projection/model_snapshot_topic_config.py +590 -0
  269. omnibase_infra/models/projectors/__init__.py +41 -0
  270. omnibase_infra/models/projectors/model_projector_column.py +289 -0
  271. omnibase_infra/models/projectors/model_projector_discovery_result.py +65 -0
  272. omnibase_infra/models/projectors/model_projector_index.py +270 -0
  273. omnibase_infra/models/projectors/model_projector_schema.py +415 -0
  274. omnibase_infra/models/projectors/model_projector_validation_error.py +63 -0
  275. omnibase_infra/models/projectors/util_sql_identifiers.py +115 -0
  276. omnibase_infra/models/registration/__init__.py +59 -0
  277. omnibase_infra/models/registration/commands/__init__.py +15 -0
  278. omnibase_infra/models/registration/commands/model_node_registration_acked.py +108 -0
  279. omnibase_infra/models/registration/events/__init__.py +56 -0
  280. omnibase_infra/models/registration/events/model_node_became_active.py +103 -0
  281. omnibase_infra/models/registration/events/model_node_liveness_expired.py +103 -0
  282. omnibase_infra/models/registration/events/model_node_registration_accepted.py +98 -0
  283. omnibase_infra/models/registration/events/model_node_registration_ack_received.py +98 -0
  284. omnibase_infra/models/registration/events/model_node_registration_ack_timed_out.py +112 -0
  285. omnibase_infra/models/registration/events/model_node_registration_initiated.py +107 -0
  286. omnibase_infra/models/registration/events/model_node_registration_rejected.py +104 -0
  287. omnibase_infra/models/registration/model_introspection_metrics.py +253 -0
  288. omnibase_infra/models/registration/model_node_capabilities.py +179 -0
  289. omnibase_infra/models/registration/model_node_heartbeat_event.py +126 -0
  290. omnibase_infra/models/registration/model_node_introspection_event.py +175 -0
  291. omnibase_infra/models/registration/model_node_metadata.py +79 -0
  292. omnibase_infra/models/registration/model_node_registration.py +162 -0
  293. omnibase_infra/models/registration/model_node_registration_record.py +162 -0
  294. omnibase_infra/models/registry/__init__.py +29 -0
  295. omnibase_infra/models/registry/model_domain_constraint.py +202 -0
  296. omnibase_infra/models/registry/model_message_type_entry.py +271 -0
  297. omnibase_infra/models/resilience/__init__.py +9 -0
  298. omnibase_infra/models/resilience/model_circuit_breaker_config.py +227 -0
  299. omnibase_infra/models/routing/__init__.py +25 -0
  300. omnibase_infra/models/routing/model_routing_entry.py +52 -0
  301. omnibase_infra/models/routing/model_routing_subcontract.py +70 -0
  302. omnibase_infra/models/runtime/__init__.py +40 -0
  303. omnibase_infra/models/runtime/model_contract_security_config.py +41 -0
  304. omnibase_infra/models/runtime/model_discovery_error.py +81 -0
  305. omnibase_infra/models/runtime/model_discovery_result.py +162 -0
  306. omnibase_infra/models/runtime/model_discovery_warning.py +74 -0
  307. omnibase_infra/models/runtime/model_failed_plugin_load.py +63 -0
  308. omnibase_infra/models/runtime/model_handler_contract.py +280 -0
  309. omnibase_infra/models/runtime/model_loaded_handler.py +120 -0
  310. omnibase_infra/models/runtime/model_plugin_load_context.py +93 -0
  311. omnibase_infra/models/runtime/model_plugin_load_summary.py +124 -0
  312. omnibase_infra/models/security/__init__.py +50 -0
  313. omnibase_infra/models/security/classification_levels.py +99 -0
  314. omnibase_infra/models/security/model_environment_policy.py +145 -0
  315. omnibase_infra/models/security/model_handler_security_policy.py +107 -0
  316. omnibase_infra/models/security/model_security_error.py +81 -0
  317. omnibase_infra/models/security/model_security_validation_result.py +328 -0
  318. omnibase_infra/models/security/model_security_warning.py +67 -0
  319. omnibase_infra/models/snapshot/__init__.py +27 -0
  320. omnibase_infra/models/snapshot/model_field_change.py +65 -0
  321. omnibase_infra/models/snapshot/model_snapshot.py +270 -0
  322. omnibase_infra/models/snapshot/model_snapshot_diff.py +203 -0
  323. omnibase_infra/models/snapshot/model_subject_ref.py +81 -0
  324. omnibase_infra/models/types/__init__.py +71 -0
  325. omnibase_infra/models/validation/__init__.py +89 -0
  326. omnibase_infra/models/validation/model_any_type_validation_result.py +118 -0
  327. omnibase_infra/models/validation/model_any_type_violation.py +141 -0
  328. omnibase_infra/models/validation/model_category_match_result.py +345 -0
  329. omnibase_infra/models/validation/model_chain_violation.py +166 -0
  330. omnibase_infra/models/validation/model_coverage_metrics.py +316 -0
  331. omnibase_infra/models/validation/model_execution_shape_rule.py +159 -0
  332. omnibase_infra/models/validation/model_execution_shape_validation.py +208 -0
  333. omnibase_infra/models/validation/model_execution_shape_validation_result.py +294 -0
  334. omnibase_infra/models/validation/model_execution_shape_violation.py +122 -0
  335. omnibase_infra/models/validation/model_localhandler_validation_result.py +139 -0
  336. omnibase_infra/models/validation/model_localhandler_violation.py +100 -0
  337. omnibase_infra/models/validation/model_output_validation_params.py +74 -0
  338. omnibase_infra/models/validation/model_validate_and_raise_params.py +84 -0
  339. omnibase_infra/models/validation/model_validation_error_params.py +84 -0
  340. omnibase_infra/models/validation/model_validation_outcome.py +287 -0
  341. omnibase_infra/nodes/__init__.py +48 -0
  342. omnibase_infra/nodes/architecture_validator/__init__.py +79 -0
  343. omnibase_infra/nodes/architecture_validator/contract.yaml +252 -0
  344. omnibase_infra/nodes/architecture_validator/contract_architecture_validator.yaml +208 -0
  345. omnibase_infra/nodes/architecture_validator/mixins/__init__.py +16 -0
  346. omnibase_infra/nodes/architecture_validator/mixins/mixin_file_path_rule.py +92 -0
  347. omnibase_infra/nodes/architecture_validator/models/__init__.py +36 -0
  348. omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_request.py +56 -0
  349. omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_result.py +311 -0
  350. omnibase_infra/nodes/architecture_validator/models/model_architecture_violation.py +163 -0
  351. omnibase_infra/nodes/architecture_validator/models/model_rule_check_result.py +265 -0
  352. omnibase_infra/nodes/architecture_validator/models/model_validation_request.py +105 -0
  353. omnibase_infra/nodes/architecture_validator/models/model_validation_result.py +314 -0
  354. omnibase_infra/nodes/architecture_validator/node.py +262 -0
  355. omnibase_infra/nodes/architecture_validator/node_architecture_validator.py +383 -0
  356. omnibase_infra/nodes/architecture_validator/protocols/__init__.py +9 -0
  357. omnibase_infra/nodes/architecture_validator/protocols/protocol_architecture_rule.py +225 -0
  358. omnibase_infra/nodes/architecture_validator/registry/__init__.py +28 -0
  359. omnibase_infra/nodes/architecture_validator/registry/registry_infra_architecture_validator.py +99 -0
  360. omnibase_infra/nodes/architecture_validator/validators/__init__.py +104 -0
  361. omnibase_infra/nodes/architecture_validator/validators/validator_no_direct_dispatch.py +422 -0
  362. omnibase_infra/nodes/architecture_validator/validators/validator_no_handler_publishing.py +481 -0
  363. omnibase_infra/nodes/architecture_validator/validators/validator_no_orchestrator_fsm.py +491 -0
  364. omnibase_infra/nodes/effects/README.md +358 -0
  365. omnibase_infra/nodes/effects/__init__.py +26 -0
  366. omnibase_infra/nodes/effects/contract.yaml +172 -0
  367. omnibase_infra/nodes/effects/models/__init__.py +32 -0
  368. omnibase_infra/nodes/effects/models/model_backend_result.py +190 -0
  369. omnibase_infra/nodes/effects/models/model_effect_idempotency_config.py +92 -0
  370. omnibase_infra/nodes/effects/models/model_registry_request.py +132 -0
  371. omnibase_infra/nodes/effects/models/model_registry_response.py +263 -0
  372. omnibase_infra/nodes/effects/protocol_consul_client.py +89 -0
  373. omnibase_infra/nodes/effects/protocol_effect_idempotency_store.py +143 -0
  374. omnibase_infra/nodes/effects/protocol_postgres_adapter.py +96 -0
  375. omnibase_infra/nodes/effects/registry_effect.py +525 -0
  376. omnibase_infra/nodes/effects/store_effect_idempotency_inmemory.py +425 -0
  377. omnibase_infra/nodes/node_registration_orchestrator/README.md +542 -0
  378. omnibase_infra/nodes/node_registration_orchestrator/__init__.py +120 -0
  379. omnibase_infra/nodes/node_registration_orchestrator/contract.yaml +475 -0
  380. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/__init__.py +53 -0
  381. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_introspected.py +376 -0
  382. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_registration_acked.py +376 -0
  383. omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_runtime_tick.py +373 -0
  384. omnibase_infra/nodes/node_registration_orchestrator/handlers/__init__.py +62 -0
  385. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_heartbeat.py +376 -0
  386. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_introspected.py +609 -0
  387. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_registration_acked.py +458 -0
  388. omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_runtime_tick.py +364 -0
  389. omnibase_infra/nodes/node_registration_orchestrator/introspection_event_router.py +544 -0
  390. omnibase_infra/nodes/node_registration_orchestrator/models/__init__.py +75 -0
  391. omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_intent_payload.py +194 -0
  392. omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_registration_intent.py +67 -0
  393. omnibase_infra/nodes/node_registration_orchestrator/models/model_intent_execution_result.py +50 -0
  394. omnibase_infra/nodes/node_registration_orchestrator/models/model_node_liveness_expired.py +107 -0
  395. omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_config.py +67 -0
  396. omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_input.py +41 -0
  397. omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_output.py +166 -0
  398. omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_intent_payload.py +235 -0
  399. omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_upsert_intent.py +68 -0
  400. omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_execution_result.py +384 -0
  401. omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_state.py +60 -0
  402. omnibase_infra/nodes/node_registration_orchestrator/models/model_registration_intent.py +177 -0
  403. omnibase_infra/nodes/node_registration_orchestrator/models/model_registry_intent.py +247 -0
  404. omnibase_infra/nodes/node_registration_orchestrator/node.py +195 -0
  405. omnibase_infra/nodes/node_registration_orchestrator/plugin.py +909 -0
  406. omnibase_infra/nodes/node_registration_orchestrator/protocols.py +439 -0
  407. omnibase_infra/nodes/node_registration_orchestrator/registry/__init__.py +41 -0
  408. omnibase_infra/nodes/node_registration_orchestrator/registry/registry_infra_node_registration_orchestrator.py +525 -0
  409. omnibase_infra/nodes/node_registration_orchestrator/timeout_coordinator.py +392 -0
  410. omnibase_infra/nodes/node_registration_orchestrator/wiring.py +742 -0
  411. omnibase_infra/nodes/node_registration_reducer/__init__.py +15 -0
  412. omnibase_infra/nodes/node_registration_reducer/contract.yaml +301 -0
  413. omnibase_infra/nodes/node_registration_reducer/models/__init__.py +38 -0
  414. omnibase_infra/nodes/node_registration_reducer/models/model_validation_result.py +113 -0
  415. omnibase_infra/nodes/node_registration_reducer/node.py +139 -0
  416. omnibase_infra/nodes/node_registration_reducer/registry/__init__.py +9 -0
  417. omnibase_infra/nodes/node_registration_reducer/registry/registry_infra_node_registration_reducer.py +79 -0
  418. omnibase_infra/nodes/node_registration_storage_effect/__init__.py +41 -0
  419. omnibase_infra/nodes/node_registration_storage_effect/contract.yaml +225 -0
  420. omnibase_infra/nodes/node_registration_storage_effect/models/__init__.py +44 -0
  421. omnibase_infra/nodes/node_registration_storage_effect/models/model_delete_result.py +132 -0
  422. omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_record.py +199 -0
  423. omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_update.py +155 -0
  424. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_details.py +123 -0
  425. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_result.py +117 -0
  426. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_query.py +100 -0
  427. omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_result.py +136 -0
  428. omnibase_infra/nodes/node_registration_storage_effect/models/model_upsert_result.py +127 -0
  429. omnibase_infra/nodes/node_registration_storage_effect/node.py +109 -0
  430. omnibase_infra/nodes/node_registration_storage_effect/protocols/__init__.py +22 -0
  431. omnibase_infra/nodes/node_registration_storage_effect/protocols/protocol_registration_persistence.py +333 -0
  432. omnibase_infra/nodes/node_registration_storage_effect/registry/__init__.py +23 -0
  433. omnibase_infra/nodes/node_registration_storage_effect/registry/registry_infra_registration_storage.py +194 -0
  434. omnibase_infra/nodes/node_registry_effect/__init__.py +85 -0
  435. omnibase_infra/nodes/node_registry_effect/contract.yaml +682 -0
  436. omnibase_infra/nodes/node_registry_effect/handlers/__init__.py +70 -0
  437. omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_deregister.py +211 -0
  438. omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_register.py +212 -0
  439. omnibase_infra/nodes/node_registry_effect/handlers/handler_partial_retry.py +416 -0
  440. omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_deactivate.py +215 -0
  441. omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_upsert.py +208 -0
  442. omnibase_infra/nodes/node_registry_effect/models/__init__.py +43 -0
  443. omnibase_infra/nodes/node_registry_effect/models/model_partial_retry_request.py +92 -0
  444. omnibase_infra/nodes/node_registry_effect/node.py +165 -0
  445. omnibase_infra/nodes/node_registry_effect/registry/__init__.py +27 -0
  446. omnibase_infra/nodes/node_registry_effect/registry/registry_infra_registry_effect.py +196 -0
  447. omnibase_infra/nodes/node_service_discovery_effect/__init__.py +111 -0
  448. omnibase_infra/nodes/node_service_discovery_effect/contract.yaml +246 -0
  449. omnibase_infra/nodes/node_service_discovery_effect/models/__init__.py +67 -0
  450. omnibase_infra/nodes/node_service_discovery_effect/models/enum_health_status.py +72 -0
  451. omnibase_infra/nodes/node_service_discovery_effect/models/enum_service_discovery_operation.py +58 -0
  452. omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_query.py +99 -0
  453. omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_result.py +98 -0
  454. omnibase_infra/nodes/node_service_discovery_effect/models/model_health_check_config.py +121 -0
  455. omnibase_infra/nodes/node_service_discovery_effect/models/model_query_metadata.py +63 -0
  456. omnibase_infra/nodes/node_service_discovery_effect/models/model_registration_result.py +130 -0
  457. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_details.py +111 -0
  458. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_result.py +119 -0
  459. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_info.py +106 -0
  460. omnibase_infra/nodes/node_service_discovery_effect/models/model_service_registration.py +121 -0
  461. omnibase_infra/nodes/node_service_discovery_effect/node.py +111 -0
  462. omnibase_infra/nodes/node_service_discovery_effect/protocols/__init__.py +14 -0
  463. omnibase_infra/nodes/node_service_discovery_effect/protocols/protocol_discovery_operations.py +279 -0
  464. omnibase_infra/nodes/node_service_discovery_effect/registry/__init__.py +13 -0
  465. omnibase_infra/nodes/node_service_discovery_effect/registry/registry_infra_service_discovery.py +214 -0
  466. omnibase_infra/nodes/reducers/__init__.py +30 -0
  467. omnibase_infra/nodes/reducers/models/__init__.py +32 -0
  468. omnibase_infra/nodes/reducers/models/model_payload_consul_register.py +76 -0
  469. omnibase_infra/nodes/reducers/models/model_payload_postgres_upsert_registration.py +60 -0
  470. omnibase_infra/nodes/reducers/models/model_registration_confirmation.py +166 -0
  471. omnibase_infra/nodes/reducers/models/model_registration_state.py +433 -0
  472. omnibase_infra/nodes/reducers/registration_reducer.py +1137 -0
  473. omnibase_infra/observability/__init__.py +143 -0
  474. omnibase_infra/observability/constants_metrics.py +91 -0
  475. omnibase_infra/observability/factory_observability_sink.py +525 -0
  476. omnibase_infra/observability/handlers/__init__.py +118 -0
  477. omnibase_infra/observability/handlers/handler_logging_structured.py +967 -0
  478. omnibase_infra/observability/handlers/handler_metrics_prometheus.py +1120 -0
  479. omnibase_infra/observability/handlers/model_logging_handler_config.py +71 -0
  480. omnibase_infra/observability/handlers/model_logging_handler_response.py +77 -0
  481. omnibase_infra/observability/handlers/model_metrics_handler_config.py +172 -0
  482. omnibase_infra/observability/handlers/model_metrics_handler_payload.py +135 -0
  483. omnibase_infra/observability/handlers/model_metrics_handler_response.py +101 -0
  484. omnibase_infra/observability/hooks/__init__.py +74 -0
  485. omnibase_infra/observability/hooks/hook_observability.py +1223 -0
  486. omnibase_infra/observability/models/__init__.py +30 -0
  487. omnibase_infra/observability/models/enum_required_log_context_key.py +77 -0
  488. omnibase_infra/observability/models/model_buffered_log_entry.py +117 -0
  489. omnibase_infra/observability/models/model_logging_sink_config.py +73 -0
  490. omnibase_infra/observability/models/model_metrics_sink_config.py +156 -0
  491. omnibase_infra/observability/sinks/__init__.py +69 -0
  492. omnibase_infra/observability/sinks/sink_logging_structured.py +809 -0
  493. omnibase_infra/observability/sinks/sink_metrics_prometheus.py +710 -0
  494. omnibase_infra/plugins/__init__.py +27 -0
  495. omnibase_infra/plugins/examples/__init__.py +28 -0
  496. omnibase_infra/plugins/examples/plugin_json_normalizer.py +271 -0
  497. omnibase_infra/plugins/examples/plugin_json_normalizer_error_handling.py +210 -0
  498. omnibase_infra/plugins/models/__init__.py +21 -0
  499. omnibase_infra/plugins/models/model_plugin_context.py +76 -0
  500. omnibase_infra/plugins/models/model_plugin_input_data.py +58 -0
  501. omnibase_infra/plugins/models/model_plugin_output_data.py +62 -0
  502. omnibase_infra/plugins/plugin_compute_base.py +435 -0
  503. omnibase_infra/projectors/__init__.py +30 -0
  504. omnibase_infra/projectors/contracts/__init__.py +63 -0
  505. omnibase_infra/projectors/contracts/registration_projector.yaml +370 -0
  506. omnibase_infra/projectors/projection_reader_registration.py +1559 -0
  507. omnibase_infra/projectors/snapshot_publisher_registration.py +1329 -0
  508. omnibase_infra/protocols/__init__.py +99 -0
  509. omnibase_infra/protocols/protocol_capability_projection.py +253 -0
  510. omnibase_infra/protocols/protocol_capability_query.py +251 -0
  511. omnibase_infra/protocols/protocol_event_bus_like.py +127 -0
  512. omnibase_infra/protocols/protocol_event_projector.py +96 -0
  513. omnibase_infra/protocols/protocol_idempotency_store.py +142 -0
  514. omnibase_infra/protocols/protocol_message_dispatcher.py +247 -0
  515. omnibase_infra/protocols/protocol_message_type_registry.py +306 -0
  516. omnibase_infra/protocols/protocol_plugin_compute.py +368 -0
  517. omnibase_infra/protocols/protocol_projector_schema_validator.py +82 -0
  518. omnibase_infra/protocols/protocol_registry_metrics.py +215 -0
  519. omnibase_infra/protocols/protocol_snapshot_publisher.py +396 -0
  520. omnibase_infra/protocols/protocol_snapshot_store.py +567 -0
  521. omnibase_infra/runtime/__init__.py +296 -0
  522. omnibase_infra/runtime/binding_config_resolver.py +2706 -0
  523. omnibase_infra/runtime/chain_aware_dispatch.py +467 -0
  524. omnibase_infra/runtime/contract_handler_discovery.py +582 -0
  525. omnibase_infra/runtime/contract_loaders/__init__.py +42 -0
  526. omnibase_infra/runtime/contract_loaders/handler_routing_loader.py +464 -0
  527. omnibase_infra/runtime/dispatch_context_enforcer.py +427 -0
  528. omnibase_infra/runtime/enums/__init__.py +18 -0
  529. omnibase_infra/runtime/enums/enum_config_ref_scheme.py +33 -0
  530. omnibase_infra/runtime/enums/enum_scheduler_status.py +170 -0
  531. omnibase_infra/runtime/envelope_validator.py +179 -0
  532. omnibase_infra/runtime/handler_contract_source.py +669 -0
  533. omnibase_infra/runtime/handler_plugin_loader.py +2029 -0
  534. omnibase_infra/runtime/handler_registry.py +321 -0
  535. omnibase_infra/runtime/invocation_security_enforcer.py +427 -0
  536. omnibase_infra/runtime/kernel.py +40 -0
  537. omnibase_infra/runtime/mixin_policy_validation.py +522 -0
  538. omnibase_infra/runtime/mixin_semver_cache.py +378 -0
  539. omnibase_infra/runtime/mixins/__init__.py +17 -0
  540. omnibase_infra/runtime/mixins/mixin_projector_sql_operations.py +757 -0
  541. omnibase_infra/runtime/models/__init__.py +192 -0
  542. omnibase_infra/runtime/models/model_batch_lifecycle_result.py +217 -0
  543. omnibase_infra/runtime/models/model_binding_config.py +168 -0
  544. omnibase_infra/runtime/models/model_binding_config_cache_stats.py +135 -0
  545. omnibase_infra/runtime/models/model_binding_config_resolver_config.py +329 -0
  546. omnibase_infra/runtime/models/model_cached_secret.py +138 -0
  547. omnibase_infra/runtime/models/model_compute_key.py +138 -0
  548. omnibase_infra/runtime/models/model_compute_registration.py +97 -0
  549. omnibase_infra/runtime/models/model_config_cache_entry.py +61 -0
  550. omnibase_infra/runtime/models/model_config_ref.py +331 -0
  551. omnibase_infra/runtime/models/model_config_ref_parse_result.py +125 -0
  552. omnibase_infra/runtime/models/model_domain_plugin_config.py +92 -0
  553. omnibase_infra/runtime/models/model_domain_plugin_result.py +270 -0
  554. omnibase_infra/runtime/models/model_duplicate_response.py +54 -0
  555. omnibase_infra/runtime/models/model_enabled_protocols_config.py +61 -0
  556. omnibase_infra/runtime/models/model_event_bus_config.py +54 -0
  557. omnibase_infra/runtime/models/model_failed_component.py +55 -0
  558. omnibase_infra/runtime/models/model_health_check_response.py +168 -0
  559. omnibase_infra/runtime/models/model_health_check_result.py +228 -0
  560. omnibase_infra/runtime/models/model_lifecycle_result.py +245 -0
  561. omnibase_infra/runtime/models/model_logging_config.py +42 -0
  562. omnibase_infra/runtime/models/model_optional_correlation_id.py +167 -0
  563. omnibase_infra/runtime/models/model_optional_string.py +94 -0
  564. omnibase_infra/runtime/models/model_optional_uuid.py +110 -0
  565. omnibase_infra/runtime/models/model_policy_context.py +100 -0
  566. omnibase_infra/runtime/models/model_policy_key.py +138 -0
  567. omnibase_infra/runtime/models/model_policy_registration.py +139 -0
  568. omnibase_infra/runtime/models/model_policy_result.py +103 -0
  569. omnibase_infra/runtime/models/model_policy_type_filter.py +157 -0
  570. omnibase_infra/runtime/models/model_projector_plugin_loader_config.py +47 -0
  571. omnibase_infra/runtime/models/model_protocol_registration_config.py +65 -0
  572. omnibase_infra/runtime/models/model_retry_policy.py +105 -0
  573. omnibase_infra/runtime/models/model_runtime_config.py +150 -0
  574. omnibase_infra/runtime/models/model_runtime_scheduler_config.py +624 -0
  575. omnibase_infra/runtime/models/model_runtime_scheduler_metrics.py +233 -0
  576. omnibase_infra/runtime/models/model_runtime_tick.py +193 -0
  577. omnibase_infra/runtime/models/model_secret_cache_stats.py +82 -0
  578. omnibase_infra/runtime/models/model_secret_mapping.py +63 -0
  579. omnibase_infra/runtime/models/model_secret_resolver_config.py +107 -0
  580. omnibase_infra/runtime/models/model_secret_resolver_metrics.py +111 -0
  581. omnibase_infra/runtime/models/model_secret_source_info.py +72 -0
  582. omnibase_infra/runtime/models/model_secret_source_spec.py +66 -0
  583. omnibase_infra/runtime/models/model_shutdown_batch_result.py +75 -0
  584. omnibase_infra/runtime/models/model_shutdown_config.py +94 -0
  585. omnibase_infra/runtime/projector_plugin_loader.py +1462 -0
  586. omnibase_infra/runtime/projector_schema_manager.py +565 -0
  587. omnibase_infra/runtime/projector_shell.py +1102 -0
  588. omnibase_infra/runtime/protocol_contract_descriptor.py +92 -0
  589. omnibase_infra/runtime/protocol_contract_source.py +92 -0
  590. omnibase_infra/runtime/protocol_domain_plugin.py +474 -0
  591. omnibase_infra/runtime/protocol_handler_discovery.py +221 -0
  592. omnibase_infra/runtime/protocol_handler_plugin_loader.py +327 -0
  593. omnibase_infra/runtime/protocol_lifecycle_executor.py +435 -0
  594. omnibase_infra/runtime/protocol_policy.py +366 -0
  595. omnibase_infra/runtime/protocols/__init__.py +27 -0
  596. omnibase_infra/runtime/protocols/protocol_runtime_scheduler.py +468 -0
  597. omnibase_infra/runtime/registry/__init__.py +93 -0
  598. omnibase_infra/runtime/registry/mixin_message_type_query.py +326 -0
  599. omnibase_infra/runtime/registry/mixin_message_type_registration.py +354 -0
  600. omnibase_infra/runtime/registry/registry_event_bus_binding.py +268 -0
  601. omnibase_infra/runtime/registry/registry_message_type.py +542 -0
  602. omnibase_infra/runtime/registry/registry_protocol_binding.py +444 -0
  603. omnibase_infra/runtime/registry_compute.py +1143 -0
  604. omnibase_infra/runtime/registry_dispatcher.py +678 -0
  605. omnibase_infra/runtime/registry_policy.py +1502 -0
  606. omnibase_infra/runtime/runtime_scheduler.py +1070 -0
  607. omnibase_infra/runtime/secret_resolver.py +2110 -0
  608. omnibase_infra/runtime/security_metadata_validator.py +776 -0
  609. omnibase_infra/runtime/service_kernel.py +1573 -0
  610. omnibase_infra/runtime/service_message_dispatch_engine.py +1805 -0
  611. omnibase_infra/runtime/service_runtime_host_process.py +2260 -0
  612. omnibase_infra/runtime/util_container_wiring.py +1123 -0
  613. omnibase_infra/runtime/util_validation.py +314 -0
  614. omnibase_infra/runtime/util_version.py +98 -0
  615. omnibase_infra/runtime/util_wiring.py +566 -0
  616. omnibase_infra/schemas/schema_registration_projection.sql +320 -0
  617. omnibase_infra/services/__init__.py +68 -0
  618. omnibase_infra/services/corpus_capture.py +678 -0
  619. omnibase_infra/services/service_capability_query.py +945 -0
  620. omnibase_infra/services/service_health.py +897 -0
  621. omnibase_infra/services/service_node_selector.py +530 -0
  622. omnibase_infra/services/service_timeout_emitter.py +682 -0
  623. omnibase_infra/services/service_timeout_scanner.py +390 -0
  624. omnibase_infra/services/snapshot/__init__.py +31 -0
  625. omnibase_infra/services/snapshot/service_snapshot.py +647 -0
  626. omnibase_infra/services/snapshot/store_inmemory.py +637 -0
  627. omnibase_infra/services/snapshot/store_postgres.py +1279 -0
  628. omnibase_infra/shared/__init__.py +8 -0
  629. omnibase_infra/testing/__init__.py +10 -0
  630. omnibase_infra/testing/utils.py +23 -0
  631. omnibase_infra/types/__init__.py +48 -0
  632. omnibase_infra/types/type_cache_info.py +49 -0
  633. omnibase_infra/types/type_dsn.py +173 -0
  634. omnibase_infra/types/type_infra_aliases.py +60 -0
  635. omnibase_infra/types/typed_dict/__init__.py +21 -0
  636. omnibase_infra/types/typed_dict/typed_dict_introspection_cache.py +128 -0
  637. omnibase_infra/types/typed_dict/typed_dict_performance_metrics_cache.py +140 -0
  638. omnibase_infra/types/typed_dict_capabilities.py +64 -0
  639. omnibase_infra/utils/__init__.py +89 -0
  640. omnibase_infra/utils/correlation.py +208 -0
  641. omnibase_infra/utils/util_datetime.py +372 -0
  642. omnibase_infra/utils/util_dsn_validation.py +333 -0
  643. omnibase_infra/utils/util_env_parsing.py +264 -0
  644. omnibase_infra/utils/util_error_sanitization.py +457 -0
  645. omnibase_infra/utils/util_pydantic_validators.py +477 -0
  646. omnibase_infra/utils/util_semver.py +233 -0
  647. omnibase_infra/validation/__init__.py +307 -0
  648. omnibase_infra/validation/enums/__init__.py +11 -0
  649. omnibase_infra/validation/enums/enum_contract_violation_severity.py +13 -0
  650. omnibase_infra/validation/infra_validators.py +1486 -0
  651. omnibase_infra/validation/linter_contract.py +907 -0
  652. omnibase_infra/validation/mixin_any_type_classification.py +120 -0
  653. omnibase_infra/validation/mixin_any_type_exemption.py +580 -0
  654. omnibase_infra/validation/mixin_any_type_reporting.py +106 -0
  655. omnibase_infra/validation/mixin_execution_shape_violation_checks.py +596 -0
  656. omnibase_infra/validation/mixin_node_archetype_detection.py +254 -0
  657. omnibase_infra/validation/models/__init__.py +15 -0
  658. omnibase_infra/validation/models/model_contract_lint_result.py +101 -0
  659. omnibase_infra/validation/models/model_contract_violation.py +41 -0
  660. omnibase_infra/validation/service_validation_aggregator.py +395 -0
  661. omnibase_infra/validation/validation_exemptions.yaml +1710 -0
  662. omnibase_infra/validation/validator_any_type.py +715 -0
  663. omnibase_infra/validation/validator_chain_propagation.py +839 -0
  664. omnibase_infra/validation/validator_execution_shape.py +465 -0
  665. omnibase_infra/validation/validator_localhandler.py +261 -0
  666. omnibase_infra/validation/validator_registration_security.py +410 -0
  667. omnibase_infra/validation/validator_routing_coverage.py +1020 -0
  668. omnibase_infra/validation/validator_runtime_shape.py +915 -0
  669. omnibase_infra/validation/validator_security.py +410 -0
  670. omnibase_infra/validation/validator_topic_category.py +1152 -0
  671. omnibase_infra-0.2.1.dist-info/METADATA +197 -0
  672. omnibase_infra-0.2.1.dist-info/RECORD +675 -0
  673. omnibase_infra-0.2.1.dist-info/WHEEL +4 -0
  674. omnibase_infra-0.2.1.dist-info/entry_points.txt +4 -0
  675. omnibase_infra-0.2.1.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,915 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Runtime Shape Validator for ONEX Handler Output Validation.
4
+
5
+ This module provides runtime validation of handler outputs against the
6
+ ONEX 4-node architecture execution shape constraints. It ensures that
7
+ handlers only produce message types that are allowed for their handler type.
8
+
9
+ Scope and Design:
10
+ This is a RUNTIME validator, not static analysis. It operates under these
11
+ assumptions:
12
+
13
+ 1. **Syntactically Valid Code**: Code has already been parsed by Python's
14
+ interpreter. Syntax errors are detected at import/compile time before
15
+ this validator runs.
16
+
17
+ 2. **Executing Handler Context**: The validator operates on actual return
18
+ values from executing handlers, not on AST representations.
19
+
20
+ 3. **Known Handler Type**: Handler type is explicitly declared via the
21
+ @enforce_execution_shape decorator or passed to validation methods.
22
+
23
+ **Complementary Validators**:
24
+ - validator_execution_shape.py: AST-based static analysis (catches issues
25
+ before runtime, analyzes code structure)
26
+ - validator_runtime_shape.py (this module): Runtime validation (catches
27
+ issues when actual values are produced)
28
+
29
+ The runtime validator catches violations that cannot be determined statically,
30
+ such as dynamically constructed return values or conditional returns.
31
+
32
+ Execution Shape Rules (imported from validator_execution_shape):
33
+ - EFFECT: Can return EVENTs and COMMANDs, but not PROJECTIONs
34
+ - COMPUTE: Can return any message type (most permissive)
35
+ - REDUCER: Can return PROJECTIONs only, not EVENTs (deterministic state management)
36
+ - ORCHESTRATOR: Can return COMMANDs and EVENTs, but not INTENTs or PROJECTIONs
37
+
38
+ Thread Safety:
39
+ This module uses a module-level singleton validator (`_default_validator`) for
40
+ efficiency. The singleton is thread-safe because:
41
+
42
+ - The validator is stateless after initialization (only stores immutable rules)
43
+ - No per-validation state is stored in the validator instance
44
+ - Each validation creates fresh violation result objects (no shared mutable state)
45
+ - The singleton is created at module import time (before any threads)
46
+ - The @enforce_execution_shape decorator uses this singleton safely from any thread
47
+
48
+ For custom validation rules, create a new RuntimeShapeValidator instance with
49
+ a custom rules dictionary. For most use cases, the singleton provides optimal
50
+ performance without thread safety concerns.
51
+
52
+ Security Design (Intentional Fail-Open Architecture):
53
+ This validator uses a FAIL-OPEN design by default. This is an INTENTIONAL
54
+ architectural decision, NOT a security vulnerability. Understanding the
55
+ rationale is critical for proper security architecture.
56
+
57
+ **What Fail-Open Means Here**:
58
+ - Unknown handler types: Validation returns True (allowed) instead of blocking
59
+ - Undetectable message categories: Decorator skips validation and allows return
60
+ - Missing rules: No exception raised, output is permitted
61
+
62
+ **Why Fail-Open is Correct for This Validator**:
63
+
64
+ 1. **This is an Architectural Validator, NOT a Security Boundary**:
65
+ The RuntimeShapeValidator enforces ONEX 4-node design patterns (Effect,
66
+ Compute, Reducer, Orchestrator) to catch developer mistakes at build/test
67
+ time. It is NOT designed to prevent malicious inputs or unauthorized access.
68
+
69
+ 2. **Defense-in-Depth Model**:
70
+ Security boundaries should be implemented at the infrastructure layer,
71
+ not in architectural pattern validators:
72
+
73
+ - Authentication: Verify identity at API gateway/ingress (OAuth, JWT, mTLS)
74
+ - Authorization: Enforce permissions in service layer (RBAC, ABAC policies)
75
+ - Input Validation: Sanitize untrusted data at entry points (schema validation)
76
+ - Network Security: Restrict access via firewall rules and service mesh
77
+
78
+ This validator operates AFTER these security layers, on trusted internal
79
+ handler outputs, making fail-open safe and appropriate.
80
+
81
+ 3. **Extensibility and Forward Compatibility**:
82
+ New handler types or message categories should work by default without
83
+ requiring immediate rule definitions. Fail-closed would break valid code
84
+ during handler type evolution and prevent progressive adoption.
85
+
86
+ 4. **Developer Experience**:
87
+ Teams can adopt execution shape validation incrementally. Handlers
88
+ returning non-categorized types continue working while teams add category
89
+ annotations to their message types.
90
+
91
+ **When Strict Validation is Needed**:
92
+ If your use case requires fail-closed behavior (e.g., security-critical
93
+ enforcement in production), implement one of these approaches:
94
+
95
+ 1. **Fail-Closed Wrapper**::
96
+
97
+ def strict_is_output_allowed(node_archetype, output_category) -> bool:
98
+ if node_archetype not in EXECUTION_SHAPE_RULES:
99
+ return False # Fail-closed for unknown types
100
+ return validator.is_output_allowed(node_archetype, output_category)
101
+
102
+ 2. **Policy Decorator**::
103
+
104
+ @require_known_category # Custom decorator that rejects None categories
105
+ @enforce_execution_shape(EnumNodeArchetype.REDUCER)
106
+ def my_strict_handler(event):
107
+ return result
108
+
109
+ 3. **Pre-Validation Check**::
110
+
111
+ from omnibase_infra.models.validation import ModelValidateAndRaiseParams
112
+
113
+ category = detect_message_category(result)
114
+ if category is None:
115
+ raise ValueError("All outputs must have detectable categories")
116
+ params = ModelValidateAndRaiseParams(
117
+ node_archetype=node_archetype,
118
+ output=result,
119
+ output_category=category,
120
+ )
121
+ validator.validate_and_raise(params)
122
+
123
+ **Security Responsibility Boundaries**:
124
+ - This validator: Architectural pattern enforcement (developer guardrails)
125
+ - Infrastructure layer: Authentication, authorization, input validation
126
+ - Application layer: Business logic validation, access control
127
+ - Network layer: TLS, firewall rules, service mesh policies
128
+
129
+ Usage:
130
+ >>> from omnibase_infra.validation.validator_runtime_shape import (
131
+ ... RuntimeShapeValidator,
132
+ ... enforce_execution_shape,
133
+ ... )
134
+ >>> from omnibase_infra.models.validation import ModelOutputValidationParams
135
+ >>> from omnibase_infra.enums import EnumNodeArchetype, EnumMessageCategory
136
+ >>>
137
+ >>> # Direct validation
138
+ >>> validator = RuntimeShapeValidator()
139
+ >>> params = ModelOutputValidationParams(
140
+ ... node_archetype=EnumNodeArchetype.REDUCER,
141
+ ... output=some_event,
142
+ ... output_category=EnumMessageCategory.EVENT,
143
+ ... )
144
+ >>> violation = validator.validate_handler_output(params)
145
+ >>> if violation:
146
+ ... print(f"Violation: {violation.message}")
147
+ >>>
148
+ >>> # Decorator usage
149
+ >>> @enforce_execution_shape(EnumNodeArchetype.REDUCER)
150
+ ... def my_reducer_handler(event):
151
+ ... return ProjectionResult(...) # OK
152
+ ... # return EventResult(...) # Would raise ExecutionShapeViolationError
153
+
154
+ Exception:
155
+ ExecutionShapeViolationError: Raised when handler output violates
156
+ execution shape constraints. Contains the full violation details
157
+ in the `violation` attribute.
158
+ """
159
+
160
+ from __future__ import annotations
161
+
162
+ import functools
163
+ import inspect
164
+ from collections.abc import Callable
165
+ from typing import TypeVar, cast
166
+ from uuid import UUID, uuid4
167
+
168
+ from omnibase_core.enums import EnumCoreErrorCode
169
+ from omnibase_core.models.errors import ModelOnexError
170
+ from omnibase_infra.enums import (
171
+ EnumExecutionShapeViolation,
172
+ EnumInfraTransportType,
173
+ EnumMessageCategory,
174
+ EnumNodeArchetype,
175
+ EnumNodeOutputType,
176
+ EnumValidationSeverity,
177
+ )
178
+ from omnibase_infra.errors import ModelInfraErrorContext, ProtocolConfigurationError
179
+ from omnibase_infra.models.validation.model_execution_shape_rule import (
180
+ ModelExecutionShapeRule,
181
+ )
182
+ from omnibase_infra.models.validation.model_execution_shape_violation import (
183
+ ModelExecutionShapeViolationResult,
184
+ )
185
+ from omnibase_infra.models.validation.model_output_validation_params import (
186
+ ModelOutputValidationParams,
187
+ )
188
+ from omnibase_infra.models.validation.model_validate_and_raise_params import (
189
+ ModelValidateAndRaiseParams,
190
+ )
191
+ from omnibase_infra.types import MessageOutputCategory
192
+
193
+ # Import canonical execution shape rules from validator_execution_shape (single source of truth)
194
+ from omnibase_infra.validation.validator_execution_shape import (
195
+ EXECUTION_SHAPE_RULES,
196
+ )
197
+
198
+ # Type variable for generic function signature preservation
199
+ F = TypeVar("F", bound=Callable[..., object])
200
+
201
+
202
+ # ==============================================================================
203
+ # Violation Type Mapping
204
+ # ==============================================================================
205
+
206
+ # Maps (node_archetype, forbidden_category) to specific violation type.
207
+ #
208
+ # This mapping covers explicitly forbidden return types from EXECUTION_SHAPE_RULES:
209
+ # - EFFECT: Cannot return PROJECTION (explicit forbidden)
210
+ # - REDUCER: Cannot return EVENT (explicit forbidden)
211
+ # - ORCHESTRATOR: Cannot return INTENT, PROJECTION (explicit forbidden)
212
+ #
213
+ # Note: Some categories are implicitly forbidden because they're not in the
214
+ # allowed_return_types list (allow-list mode). For example:
215
+ # - REDUCER only allows PROJECTION, so COMMAND and INTENT are implicitly forbidden
216
+ # - EFFECT only allows EVENT and COMMAND, so INTENT is implicitly forbidden
217
+ #
218
+ # These implicit violations use FORBIDDEN_RETURN_TYPE as the fallback, which is
219
+ # semantically correct: the handler is returning a type that's not in its allow-list.
220
+ _VIOLATION_TYPE_MAP: dict[
221
+ tuple[EnumNodeArchetype, MessageOutputCategory],
222
+ EnumExecutionShapeViolation,
223
+ ] = {
224
+ (
225
+ EnumNodeArchetype.REDUCER,
226
+ EnumMessageCategory.EVENT,
227
+ ): EnumExecutionShapeViolation.REDUCER_RETURNS_EVENTS,
228
+ (
229
+ EnumNodeArchetype.ORCHESTRATOR,
230
+ EnumMessageCategory.INTENT,
231
+ ): EnumExecutionShapeViolation.ORCHESTRATOR_RETURNS_INTENTS,
232
+ (
233
+ EnumNodeArchetype.ORCHESTRATOR,
234
+ EnumNodeOutputType.PROJECTION,
235
+ ): EnumExecutionShapeViolation.ORCHESTRATOR_RETURNS_PROJECTIONS,
236
+ (
237
+ EnumNodeArchetype.EFFECT,
238
+ EnumNodeOutputType.PROJECTION,
239
+ ): EnumExecutionShapeViolation.EFFECT_RETURNS_PROJECTIONS,
240
+ }
241
+
242
+
243
+ # ==============================================================================
244
+ # Exception Class
245
+ # ==============================================================================
246
+
247
+
248
+ class ExecutionShapeViolationError(ModelOnexError):
249
+ """Raised when handler output violates execution shape constraints.
250
+
251
+ This error is raised at runtime when a handler produces output that
252
+ is forbidden for its declared handler type. For example, a REDUCER
253
+ handler returning an EVENT message.
254
+
255
+ Attributes:
256
+ violation: The full violation result with type, handler, and context.
257
+
258
+ Example:
259
+ >>> from omnibase_infra.models.validation import ModelValidateAndRaiseParams
260
+ >>> from omnibase_infra.enums import EnumNodeArchetype, EnumMessageCategory
261
+ >>> validator = RuntimeShapeValidator()
262
+ >>> try:
263
+ ... params = ModelValidateAndRaiseParams(
264
+ ... node_archetype=EnumNodeArchetype.REDUCER,
265
+ ... output=event_output,
266
+ ... output_category=EnumMessageCategory.EVENT,
267
+ ... )
268
+ ... validator.validate_and_raise(params)
269
+ ... except ExecutionShapeViolationError as e:
270
+ ... print(f"Violation: {e.violation.violation_type}")
271
+ ... print(f"Message: {e.violation.message}")
272
+
273
+ Correlation ID Support:
274
+ When a correlation_id is provided, it is included in the error context
275
+ for distributed tracing. This enables tracking validation failures back
276
+ to specific requests in multi-service architectures::
277
+
278
+ >>> from uuid import uuid4
279
+ >>> correlation_id = uuid4()
280
+ >>> raise ExecutionShapeViolationError(violation, correlation_id=correlation_id)
281
+ """
282
+
283
+ def __init__(
284
+ self,
285
+ violation: ModelExecutionShapeViolationResult,
286
+ correlation_id: UUID | None = None,
287
+ ) -> None:
288
+ """Initialize ExecutionShapeViolationError.
289
+
290
+ Args:
291
+ violation: The execution shape violation result with full context.
292
+ correlation_id: Optional correlation ID for distributed tracing.
293
+ When provided, enables tracking this validation failure back
294
+ to specific requests across service boundaries.
295
+ """
296
+ self.violation = violation
297
+ # node_archetype may be None if the archetype couldn't be determined
298
+ node_archetype_value = (
299
+ violation.node_archetype.value
300
+ if violation.node_archetype is not None
301
+ else None
302
+ )
303
+ super().__init__(
304
+ message=violation.message,
305
+ error_code=EnumCoreErrorCode.VALIDATION_FAILED,
306
+ correlation_id=correlation_id,
307
+ violation_type=violation.violation_type.value,
308
+ node_archetype=node_archetype_value,
309
+ severity=violation.severity,
310
+ file_path=violation.file_path,
311
+ line_number=violation.line_number,
312
+ )
313
+
314
+
315
+ # ==============================================================================
316
+ # Type Conversion Utilities
317
+ # ==============================================================================
318
+
319
+
320
+ # Mapping from EnumMessageCategory to EnumNodeOutputType for validation.
321
+ # Both enums share EVENT, COMMAND, INTENT with identical string values.
322
+ _MESSAGE_CATEGORY_TO_NODE_OUTPUT: dict[EnumMessageCategory, EnumNodeOutputType] = {
323
+ EnumMessageCategory.EVENT: EnumNodeOutputType.EVENT,
324
+ EnumMessageCategory.COMMAND: EnumNodeOutputType.COMMAND,
325
+ EnumMessageCategory.INTENT: EnumNodeOutputType.INTENT,
326
+ }
327
+
328
+
329
+ def _to_node_output_type(
330
+ category: MessageOutputCategory,
331
+ ) -> EnumNodeOutputType:
332
+ """Convert a message category or node output type to EnumNodeOutputType.
333
+
334
+ This utility handles the mapping between EnumMessageCategory (routing)
335
+ and EnumNodeOutputType (validation). Since EVENT, COMMAND, and INTENT
336
+ exist in both enums with the same values, they can be safely converted.
337
+
338
+ Args:
339
+ category: Either an EnumMessageCategory or EnumNodeOutputType.
340
+
341
+ Returns:
342
+ The corresponding EnumNodeOutputType.
343
+
344
+ Raises:
345
+ ValueError: If an EnumMessageCategory cannot be mapped to EnumNodeOutputType
346
+ (should not happen with valid enum values).
347
+ """
348
+ if isinstance(category, EnumNodeOutputType):
349
+ return category
350
+
351
+ if isinstance(category, EnumMessageCategory):
352
+ if category in _MESSAGE_CATEGORY_TO_NODE_OUTPUT:
353
+ return _MESSAGE_CATEGORY_TO_NODE_OUTPUT[category]
354
+ # This should never happen with valid EnumMessageCategory values
355
+ context = ModelInfraErrorContext(
356
+ transport_type=EnumInfraTransportType.RUNTIME,
357
+ operation="to_node_output_type",
358
+ correlation_id=uuid4(),
359
+ )
360
+ raise ProtocolConfigurationError(
361
+ f"Cannot convert {category} to EnumNodeOutputType",
362
+ context=context,
363
+ category=str(category),
364
+ )
365
+
366
+ # Type safety fallback (should not be reached with proper typing)
367
+ context = ModelInfraErrorContext(
368
+ transport_type=EnumInfraTransportType.RUNTIME,
369
+ operation="to_node_output_type",
370
+ correlation_id=uuid4(),
371
+ )
372
+ raise ProtocolConfigurationError(
373
+ f"Expected EnumMessageCategory or EnumNodeOutputType, got {type(category)}",
374
+ context=context,
375
+ actual_type=type(category).__name__,
376
+ )
377
+
378
+
379
+ # ==============================================================================
380
+ # Message Category Detection
381
+ # ==============================================================================
382
+
383
+
384
+ def detect_message_category(
385
+ message: object,
386
+ ) -> MessageOutputCategory | None:
387
+ """Detect message category or node output type from object type or attributes.
388
+
389
+ This function attempts to determine the message category or node output type
390
+ of an object using several strategies:
391
+
392
+ 1. Check for explicit `category` attribute (EnumMessageCategory or EnumNodeOutputType)
393
+ 2. Check for explicit `message_category` or `output_type` attribute
394
+ 3. Check type name patterns (Event*, Command*, Intent*, Projection*)
395
+
396
+ Note: PROJECTION is detected as EnumNodeOutputType.PROJECTION since projections
397
+ are node output types (used by REDUCERs), not message routing categories.
398
+
399
+ Args:
400
+ message: The message object to analyze.
401
+
402
+ Returns:
403
+ The detected EnumMessageCategory or EnumNodeOutputType,
404
+ or None if category cannot be determined.
405
+
406
+ Example:
407
+ >>> class OrderCreatedEvent:
408
+ ... pass
409
+ >>> detect_message_category(OrderCreatedEvent())
410
+ EnumMessageCategory.EVENT
411
+
412
+ >>> class UserProjection:
413
+ ... output_type = EnumNodeOutputType.PROJECTION
414
+ >>> detect_message_category(UserProjection())
415
+ EnumNodeOutputType.PROJECTION
416
+ """
417
+ if message is None:
418
+ return None
419
+
420
+ # Strategy 1: Check for explicit category attribute
421
+ if hasattr(message, "category"):
422
+ category = message.category
423
+ if isinstance(category, EnumMessageCategory | EnumNodeOutputType):
424
+ return category
425
+
426
+ # Strategy 2a: Check for message_category attribute
427
+ if hasattr(message, "message_category"):
428
+ category = message.message_category
429
+ if isinstance(category, EnumMessageCategory):
430
+ return category
431
+
432
+ # Strategy 2b: Check for output_type attribute (for node outputs like projections)
433
+ if hasattr(message, "output_type"):
434
+ output_type = message.output_type
435
+ if isinstance(output_type, EnumNodeOutputType):
436
+ return output_type
437
+
438
+ # Strategy 3: Check type name patterns
439
+ type_name = type(message).__name__
440
+
441
+ # Check for common naming patterns
442
+ # Note: PROJECTION returns EnumNodeOutputType since it's a node output type
443
+ name_patterns: list[tuple[str, MessageOutputCategory]] = [
444
+ ("Event", EnumMessageCategory.EVENT),
445
+ ("Command", EnumMessageCategory.COMMAND),
446
+ ("Intent", EnumMessageCategory.INTENT),
447
+ ("Projection", EnumNodeOutputType.PROJECTION),
448
+ ]
449
+
450
+ for pattern, category in name_patterns:
451
+ # Check if type name ends with pattern (e.g., OrderCreatedEvent)
452
+ if type_name.endswith(pattern):
453
+ return category
454
+ # Check if type name starts with pattern (e.g., EventOrderCreated)
455
+ if type_name.startswith(pattern):
456
+ return category
457
+
458
+ # Could not determine category
459
+ return None
460
+
461
+
462
+ # ==============================================================================
463
+ # Runtime Shape Validator
464
+ # ==============================================================================
465
+
466
+
467
+ class RuntimeShapeValidator:
468
+ """Runtime validator for ONEX handler execution shape constraints.
469
+
470
+ This validator checks handler outputs at runtime against the ONEX 4-node
471
+ architecture execution shape rules. Each node archetype has specific
472
+ constraints on what message categories it can produce.
473
+
474
+ Attributes:
475
+ rules: Dictionary mapping node archetypes to their execution shape rules.
476
+
477
+ Thread Safety:
478
+ RuntimeShapeValidator instances are stateless after initialization.
479
+ The rules dictionary is immutable and no per-validation state is stored.
480
+ Multiple threads can safely call validate_handler_output() or
481
+ validate_and_raise() on the same validator instance concurrently.
482
+
483
+ Performance:
484
+ For repeated validation (e.g., decorated handlers in hot paths), use the
485
+ module-level singleton via `enforce_execution_shape()` decorator or the
486
+ `_default_validator` instance for optimal performance.
487
+
488
+ Creating new validator instances is cheap but unnecessary in most cases.
489
+ Create a new instance only if you need custom rules or isolation.
490
+
491
+ Example:
492
+ >>> from omnibase_infra.models.validation import (
493
+ ... ModelOutputValidationParams,
494
+ ... ModelValidateAndRaiseParams,
495
+ ... )
496
+ >>> validator = RuntimeShapeValidator()
497
+ >>>
498
+ >>> # Check if output is allowed
499
+ >>> if not validator.is_output_allowed(EnumNodeArchetype.REDUCER, EnumMessageCategory.EVENT):
500
+ ... print("Reducer cannot return events!")
501
+ >>>
502
+ >>> # Get full violation details
503
+ >>> params = ModelOutputValidationParams(
504
+ ... node_archetype=EnumNodeArchetype.REDUCER,
505
+ ... output=event_output,
506
+ ... output_category=EnumMessageCategory.EVENT,
507
+ ... )
508
+ >>> violation = validator.validate_handler_output(params)
509
+ >>> if violation:
510
+ ... print(f"Violation: {violation.format_for_ci()}")
511
+ >>>
512
+ >>> # Raise exception on violation
513
+ >>> raise_params = ModelValidateAndRaiseParams(
514
+ ... node_archetype=EnumNodeArchetype.REDUCER,
515
+ ... output=event_output,
516
+ ... output_category=EnumMessageCategory.EVENT,
517
+ ... )
518
+ >>> validator.validate_and_raise(raise_params) # Raises ExecutionShapeViolationError
519
+ """
520
+
521
+ def __init__(
522
+ self, rules: dict[EnumNodeArchetype, ModelExecutionShapeRule] | None = None
523
+ ) -> None:
524
+ """Initialize RuntimeShapeValidator.
525
+
526
+ Args:
527
+ rules: Optional custom rules dictionary. If not provided,
528
+ uses the default EXECUTION_SHAPE_RULES.
529
+ """
530
+ self.rules = rules if rules is not None else EXECUTION_SHAPE_RULES
531
+
532
+ def get_rule(self, node_archetype: EnumNodeArchetype) -> ModelExecutionShapeRule:
533
+ """Get execution shape rule for a node archetype.
534
+
535
+ Args:
536
+ node_archetype: The node archetype to get the rule for.
537
+
538
+ Returns:
539
+ The ModelExecutionShapeRule for the specified node archetype.
540
+
541
+ Raises:
542
+ KeyError: If no rule is defined for the node archetype.
543
+ """
544
+ if node_archetype not in self.rules:
545
+ raise KeyError(
546
+ f"No execution shape rule defined for: {node_archetype.value}"
547
+ )
548
+ return self.rules[node_archetype]
549
+
550
+ def _get_allowed_types_for_handler(self, node_archetype: EnumNodeArchetype) -> str:
551
+ """Get a human-readable string of allowed output types for a handler.
552
+
553
+ Used to generate helpful error messages that suggest valid alternatives
554
+ when a handler attempts to return a forbidden output type.
555
+
556
+ Args:
557
+ node_archetype: The node archetype to get allowed types for.
558
+
559
+ Returns:
560
+ A formatted string listing allowed output types (e.g., "EVENTs or COMMANDs").
561
+ """
562
+ try:
563
+ rule = self.get_rule(node_archetype)
564
+ allowed = [t.value.upper() + "s" for t in rule.allowed_return_types]
565
+ if len(allowed) == 0:
566
+ return "no specific types (check EXECUTION_SHAPE_RULES)"
567
+ if len(allowed) == 1:
568
+ return allowed[0]
569
+ if len(allowed) == 2:
570
+ return f"{allowed[0]} or {allowed[1]}"
571
+ return ", ".join(allowed[:-1]) + f", or {allowed[-1]}"
572
+ except KeyError:
573
+ return "appropriate types (check EXECUTION_SHAPE_RULES)"
574
+
575
+ def is_output_allowed(
576
+ self,
577
+ node_archetype: EnumNodeArchetype,
578
+ output_category: MessageOutputCategory,
579
+ ) -> bool:
580
+ """Check if an output category is allowed for a node archetype.
581
+
582
+ This is a quick check that returns True/False without creating
583
+ a full violation result.
584
+
585
+ Args:
586
+ node_archetype: The node archetype to check.
587
+ output_category: The message category or node output type of the output.
588
+
589
+ Returns:
590
+ True if the output category is allowed, False if forbidden.
591
+
592
+ Security Note (Intentional Fail-Open Design):
593
+ This method returns True (allowing the output) when no rule exists
594
+ for the given node archetype. This is an INTENTIONAL design decision,
595
+ not a security vulnerability:
596
+
597
+ 1. **Extensibility**: New node archetypes should work by default without
598
+ requiring immediate rule definitions. This prevents blocking valid
599
+ code during archetype evolution.
600
+
601
+ 2. **Validation vs Security Boundary**: This validator enforces
602
+ architectural constraints (ONEX 4-node patterns), NOT security
603
+ policies. It catches developer errors at build/test time, not
604
+ malicious inputs at runtime.
605
+
606
+ 3. **Defense in Depth**: Security boundaries should be implemented
607
+ at the infrastructure layer (authentication, authorization,
608
+ input validation) - not in architectural pattern validators.
609
+
610
+ 4. **Fail-Safe for Unknown Types**: Unknown node archetypes represent
611
+ future extensions or custom implementations. Blocking them would
612
+ break forward compatibility without security benefit.
613
+
614
+ If strict validation is required for security-critical contexts,
615
+ use a fail-closed wrapper or policy decorator.
616
+ """
617
+ try:
618
+ rule = self.get_rule(node_archetype)
619
+ # Convert to EnumNodeOutputType for validation
620
+ node_output_type = _to_node_output_type(output_category)
621
+ return rule.is_return_type_allowed(node_output_type)
622
+ except KeyError:
623
+ # SECURITY DESIGN: Fail-open for unknown node archetypes.
624
+ # See docstring "Security Note" for rationale.
625
+ # This is intentional - new archetypes should be allowed by default.
626
+ return True
627
+
628
+ def validate_handler_output(
629
+ self,
630
+ params: ModelOutputValidationParams,
631
+ ) -> ModelExecutionShapeViolationResult | None:
632
+ """Validate handler output against execution shape constraints.
633
+
634
+ Args:
635
+ params: Parameters encapsulating node_archetype, output, output_category,
636
+ and optional file_path and line_number for violation reporting.
637
+
638
+ Returns:
639
+ A ModelExecutionShapeViolationResult if a violation is detected,
640
+ or None if the output is valid.
641
+ """
642
+ if self.is_output_allowed(params.node_archetype, params.output_category):
643
+ return None
644
+
645
+ # Determine specific violation type.
646
+ #
647
+ # The _VIOLATION_TYPE_MAP contains explicit mappings for known forbidden
648
+ # combinations (e.g., REDUCER returning EVENT). The fallback to
649
+ # FORBIDDEN_RETURN_TYPE is used for implicitly forbidden categories
650
+ # that aren't in the handler's allow-list but don't have a specific
651
+ # violation type. Examples:
652
+ # - REDUCER returning COMMAND (not in allowed_return_types=[PROJECTION])
653
+ # - EFFECT returning INTENT (not in allowed_return_types=[EVENT, COMMAND])
654
+ #
655
+ # The generic FORBIDDEN_RETURN_TYPE is semantically appropriate for these
656
+ # cases because they represent allow-list violations rather than explicit
657
+ # architectural constraint violations.
658
+ violation_key = (params.node_archetype, params.output_category)
659
+ violation_type = _VIOLATION_TYPE_MAP.get(
660
+ violation_key,
661
+ EnumExecutionShapeViolation.FORBIDDEN_RETURN_TYPE,
662
+ )
663
+
664
+ # Build descriptive message with clear actionable guidance.
665
+ # The message distinguishes between explicit forbidden types (architectural
666
+ # constraint) and implicit forbidden types (not in allow-list).
667
+ output_type_name = type(params.output).__name__
668
+ archetype_name = params.node_archetype.value.upper()
669
+ category_name = params.output_category.value.upper()
670
+
671
+ # Check if this is a PROJECTION violation - these need educational context
672
+ # about the distinction between node output types and message categories
673
+ is_projection_violation = (
674
+ params.output_category == EnumNodeOutputType.PROJECTION
675
+ )
676
+
677
+ # Provide context-specific guidance based on whether this is an explicit
678
+ # or implicit violation
679
+ if violation_type == EnumExecutionShapeViolation.FORBIDDEN_RETURN_TYPE:
680
+ # Implicit violation: category not in allow-list
681
+ if is_projection_violation:
682
+ # Special case: PROJECTION needs educational message
683
+ message = (
684
+ f"{archetype_name} handler cannot return PROJECTION type "
685
+ f"'{output_type_name}'. PROJECTION is a node output type "
686
+ f"(EnumNodeOutputType), not a message routing category "
687
+ f"(EnumMessageCategory). Projections represent aggregated state "
688
+ f"and are only valid for REDUCER node output types."
689
+ )
690
+ else:
691
+ message = (
692
+ f"{archetype_name} handler cannot return {category_name} type "
693
+ f"'{output_type_name}'. {category_name} is not in the allowed "
694
+ f"return types for {archetype_name} handlers. "
695
+ f"Check EXECUTION_SHAPE_RULES for allowed message categories."
696
+ )
697
+ # Explicit violation: known architectural constraint
698
+ elif is_projection_violation:
699
+ # PROJECTION violations get enhanced educational message
700
+ allowed_types = self._get_allowed_types_for_handler(params.node_archetype)
701
+ message = (
702
+ f"{archetype_name} handler cannot return PROJECTION type "
703
+ f"'{output_type_name}'. PROJECTION is a node output type "
704
+ f"(EnumNodeOutputType), not a message routing category "
705
+ f"(EnumMessageCategory). Projections represent aggregated state "
706
+ f"and are only valid for REDUCER node output types. "
707
+ f"{archetype_name} handlers should return {allowed_types} instead."
708
+ )
709
+ else:
710
+ message = (
711
+ f"{archetype_name} handler cannot return {category_name} type "
712
+ f"'{output_type_name}'. This violates ONEX 4-node architecture "
713
+ f"execution shape constraints ({violation_type.value})."
714
+ )
715
+
716
+ return ModelExecutionShapeViolationResult(
717
+ violation_type=violation_type,
718
+ node_archetype=params.node_archetype,
719
+ file_path=params.file_path,
720
+ line_number=params.line_number if params.line_number > 0 else 1,
721
+ message=message,
722
+ severity=EnumValidationSeverity.ERROR,
723
+ )
724
+
725
+ def validate_and_raise(
726
+ self,
727
+ params: ModelValidateAndRaiseParams,
728
+ ) -> None:
729
+ """Validate handler output and raise exception if invalid.
730
+
731
+ This method performs the same validation as validate_handler_output,
732
+ but raises an ExecutionShapeViolationError if a violation is detected.
733
+
734
+ Args:
735
+ params: Parameters encapsulating node_archetype, output, output_category,
736
+ optional file_path and line_number for violation reporting,
737
+ and optional correlation_id for distributed tracing.
738
+
739
+ Raises:
740
+ ExecutionShapeViolationError: If the output violates execution
741
+ shape constraints for the node archetype.
742
+ """
743
+ validation_params = ModelOutputValidationParams(
744
+ node_archetype=params.node_archetype,
745
+ output=params.output,
746
+ output_category=params.output_category,
747
+ file_path=params.file_path,
748
+ line_number=params.line_number,
749
+ )
750
+ violation = self.validate_handler_output(validation_params)
751
+ if violation is not None:
752
+ raise ExecutionShapeViolationError(
753
+ violation, correlation_id=params.correlation_id
754
+ )
755
+
756
+
757
+ # ==============================================================================
758
+ # Module-Level Singleton Validator
759
+ # ==============================================================================
760
+ #
761
+ # Performance Optimization: The RuntimeShapeValidator is stateless after
762
+ # initialization (only stores a reference to EXECUTION_SHAPE_RULES which is
763
+ # a module-level constant). Creating new instances on every validation call
764
+ # is wasteful in hot paths (e.g., the @enforce_execution_shape decorator).
765
+ # Instead, we use a module-level singleton.
766
+ #
767
+ # Why a singleton is safe here:
768
+ # - The validator's rules dictionary is immutable after initialization
769
+ # - No per-validation state is stored in the validator instance
770
+ # - All validation methods are pure functions that produce new results
771
+ # - Each validation creates fresh ModelExecutionShapeViolationResult objects
772
+ #
773
+ # Thread Safety:
774
+ # - The singleton is created at module import time (before any threads)
775
+ # - All read operations on the rules dictionary are thread-safe
776
+ # - Each validation creates fresh local state (violation results)
777
+ # - No locks are needed because there's no shared mutable state
778
+ # - The @enforce_execution_shape decorator uses this singleton safely from any thread
779
+ # - Concurrent calls from multiple threads will each create independent violation
780
+ # results without interference
781
+ #
782
+ # When NOT to use the singleton:
783
+ # - If you need custom execution shape rules (create your own instance)
784
+ # - If you need to mock the validator in tests (inject or patch)
785
+ # - If you're validating in a context that requires isolation
786
+ #
787
+ # For repeated validation (e.g., decorated handlers in hot paths), the singleton
788
+ # pattern provides optimal performance without sacrificing thread safety.
789
+
790
+ _default_validator = RuntimeShapeValidator()
791
+
792
+
793
+ # ==============================================================================
794
+ # Decorator
795
+ # ==============================================================================
796
+
797
+
798
+ def enforce_execution_shape(node_archetype: EnumNodeArchetype) -> Callable[[F], F]:
799
+ """Decorator to enforce execution shape constraints at runtime.
800
+
801
+ This decorator wraps a handler function and validates its return value
802
+ against the execution shape rules for the specified node archetype.
803
+ If the return value violates the constraints, an ExecutionShapeViolationError
804
+ is raised.
805
+
806
+ The decorator attempts to detect the message category of the return value
807
+ using the `detect_message_category` function. If the category cannot be
808
+ determined, no validation is performed (fail-open behavior).
809
+
810
+ Args:
811
+ node_archetype: The node archetype that determines allowed output categories.
812
+
813
+ Returns:
814
+ A decorator function that wraps the handler with runtime validation.
815
+
816
+ Example:
817
+ >>> @enforce_execution_shape(EnumNodeArchetype.REDUCER)
818
+ ... def my_reducer(event):
819
+ ... # This is OK - reducer can return projections
820
+ ... return UserProjection(user_id=event.user_id)
821
+ >>>
822
+ >>> @enforce_execution_shape(EnumNodeArchetype.REDUCER)
823
+ ... def bad_reducer(event):
824
+ ... # This will raise ExecutionShapeViolationError
825
+ ... return UserCreatedEvent(user_id=event.user_id)
826
+
827
+ Note:
828
+ The decorator uses inspect to determine the source file and line
829
+ number of the decorated function for better error reporting.
830
+
831
+ Security Note (Intentional Fail-Open Design):
832
+ When the message category cannot be determined from the return value,
833
+ the decorator skips validation and allows the return. This is an
834
+ INTENTIONAL design decision for the following reasons:
835
+
836
+ 1. **Graceful Handling of Unknown Types**: Not all return types will
837
+ have detectable categories (e.g., primitive types, third-party
838
+ objects, custom domain objects). Blocking these would cause false
839
+ positives and break legitimate code.
840
+
841
+ 2. **Progressive Adoption**: Teams can adopt execution shape validation
842
+ incrementally. Handlers returning non-categorized types continue
843
+ working while teams add category annotations to their message types.
844
+
845
+ 3. **Validation Tool, Not Security Gate**: This decorator catches
846
+ architectural mistakes (e.g., reducer returning events), not
847
+ security threats. Unknown categories don't represent attack vectors.
848
+
849
+ 4. **Type Detection Limitations**: Category detection relies on naming
850
+ conventions and explicit attributes. Overly strict enforcement would
851
+ require all types to implement specific interfaces, which is
852
+ impractical for existing codebases.
853
+
854
+ For strict enforcement, ensure all message types either:
855
+ - Have a `category` or `message_category` attribute
856
+ - Follow naming conventions (e.g., `*Event`, `*Command`, `*Projection`)
857
+ """
858
+
859
+ def decorator(func: F) -> F:
860
+ # Get source info for better error reporting
861
+ try:
862
+ source_file = inspect.getfile(func)
863
+ source_lines = inspect.getsourcelines(func)
864
+ line_number = source_lines[1] if source_lines else 0
865
+ except (TypeError, OSError):
866
+ source_file = "<unknown>"
867
+ line_number = 0
868
+
869
+ @functools.wraps(func)
870
+ def wrapper(*args: object, **kwargs: object) -> object:
871
+ result = func(*args, **kwargs)
872
+
873
+ # Detect category of the result
874
+ output_category = detect_message_category(result)
875
+
876
+ # SECURITY DESIGN: Fail-open for undetectable message categories.
877
+ # See docstring "Security Note" for detailed rationale.
878
+ # This is intentional - unknown types shouldn't block execution.
879
+ if output_category is None:
880
+ return result
881
+
882
+ # Validate against execution shape rules
883
+ validate_params = ModelValidateAndRaiseParams(
884
+ node_archetype=node_archetype,
885
+ output=result,
886
+ output_category=output_category,
887
+ file_path=source_file,
888
+ line_number=line_number,
889
+ )
890
+ _default_validator.validate_and_raise(validate_params)
891
+
892
+ return result
893
+
894
+ # Cast wrapper to F - functools.wraps preserves the signature at runtime,
895
+ # and mypy cannot prove the equivalence, so we use an explicit cast.
896
+ return cast(F, wrapper)
897
+
898
+ return decorator
899
+
900
+
901
+ # ==============================================================================
902
+ # Module Exports
903
+ # ==============================================================================
904
+
905
+ __all__ = [
906
+ # Constants
907
+ "EXECUTION_SHAPE_RULES",
908
+ # Exception
909
+ "ExecutionShapeViolationError",
910
+ # Validator class
911
+ "RuntimeShapeValidator",
912
+ # Functions
913
+ "detect_message_category",
914
+ "enforce_execution_shape",
915
+ ]