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,372 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Datetime validation and normalization utilities.
4
+
5
+ This module provides utilities for ensuring datetime values are timezone-aware
6
+ before persisting to databases. Naive datetimes (without timezone info) can cause
7
+ subtle bugs when stored in PostgreSQL's TIMESTAMPTZ columns or when compared
8
+ across different timezones.
9
+
10
+ ONEX Datetime Guidelines:
11
+ - All datetimes should be timezone-aware (preferably UTC)
12
+ - Naive datetimes trigger warnings and are auto-converted to UTC
13
+ - Use datetime.now(UTC) instead of datetime.utcnow() (deprecated in Python 3.12+)
14
+
15
+ See Also:
16
+ - PostgreSQL TIMESTAMPTZ documentation
17
+ - Python datetime best practices (PEP 495)
18
+ - ONEX infrastructure datetime conventions
19
+
20
+ Example:
21
+ >>> from datetime import datetime, UTC
22
+ >>> from omnibase_infra.utils import ensure_timezone_aware
23
+ >>>
24
+ >>> # Aware datetime passes through unchanged
25
+ >>> aware_dt = datetime.now(UTC)
26
+ >>> result = ensure_timezone_aware(aware_dt)
27
+ >>> result == aware_dt
28
+ True
29
+ >>>
30
+ >>> # Naive datetime is converted to UTC with warning
31
+ >>> naive_dt = datetime(2025, 1, 15, 12, 0, 0)
32
+ >>> result = ensure_timezone_aware(naive_dt) # Logs warning
33
+ >>> result.tzinfo is not None
34
+ True
35
+
36
+ .. versionadded:: 0.8.0
37
+ Created as part of PR #146 datetime validation improvements.
38
+ """
39
+
40
+ from __future__ import annotations
41
+
42
+ import logging
43
+ from datetime import UTC, datetime
44
+ from typing import TYPE_CHECKING
45
+ from uuid import UUID, uuid4
46
+
47
+ if TYPE_CHECKING:
48
+ from omnibase_infra.errors import ModelInfraErrorContext
49
+
50
+ logger = logging.getLogger(__name__)
51
+
52
+
53
+ def ensure_timezone_aware(
54
+ dt: datetime,
55
+ *,
56
+ assume_utc: bool = True,
57
+ warn_on_naive: bool = True,
58
+ context: str | None = None,
59
+ ) -> datetime:
60
+ """Ensure a datetime is timezone-aware, converting naive datetimes to UTC.
61
+
62
+ This function validates that datetime values have timezone information before
63
+ they are persisted to the database. Naive datetimes (those without tzinfo)
64
+ are ambiguous and can cause subtle bugs when stored in TIMESTAMPTZ columns
65
+ or compared across timezones.
66
+
67
+ Behavior:
68
+ - Timezone-aware datetimes: Passed through unchanged
69
+ - Naive datetimes with assume_utc=True: Converted to UTC with warning
70
+ - Naive datetimes with assume_utc=False: Raises ProtocolConfigurationError
71
+
72
+ Args:
73
+ dt: The datetime to validate/normalize.
74
+ assume_utc: If True (default), naive datetimes are assumed to be UTC
75
+ and converted. If False, naive datetimes raise ValueError.
76
+ warn_on_naive: If True (default), logs a warning when a naive datetime
77
+ is converted. Set to False to suppress warnings (e.g., in migration
78
+ scripts where naive datetimes are expected).
79
+ context: Optional context string for the warning message (e.g., column
80
+ name, operation type). Helps identify the source of naive datetimes.
81
+
82
+ Returns:
83
+ A timezone-aware datetime. If the input was already aware, returns
84
+ the same datetime. If naive and assume_utc=True, returns a new
85
+ datetime with UTC timezone.
86
+
87
+ Raises:
88
+ ProtocolConfigurationError: If dt is naive and assume_utc=False.
89
+
90
+ Example:
91
+ >>> from datetime import datetime, UTC, timezone
92
+ >>> from omnibase_infra.utils.util_datetime import ensure_timezone_aware
93
+ >>>
94
+ >>> # Already aware - passes through unchanged
95
+ >>> aware = datetime(2025, 1, 15, 12, 0, 0, tzinfo=UTC)
96
+ >>> ensure_timezone_aware(aware) == aware
97
+ True
98
+ >>>
99
+ >>> # Naive datetime - converted to UTC with warning
100
+ >>> naive = datetime(2025, 1, 15, 12, 0, 0)
101
+ >>> result = ensure_timezone_aware(naive, context="updated_at")
102
+ >>> result.tzinfo == UTC
103
+ True
104
+ >>>
105
+ >>> # Strict mode - raises ProtocolConfigurationError for naive datetimes
106
+ >>> ensure_timezone_aware(naive, assume_utc=False) # doctest: +ELLIPSIS
107
+ Traceback (most recent call last):
108
+ ...
109
+ omnibase_infra.errors...ProtocolConfigurationError: Naive datetime not allowed...
110
+
111
+ Warning:
112
+ Using assume_utc=True can silently mask timezone bugs in your code.
113
+ It's better to fix the source of naive datetimes than to rely on
114
+ automatic conversion. The warning log helps identify these issues.
115
+
116
+ Related:
117
+ - OMN-1170: Converting ProjectorRegistration to declarative contracts
118
+ - PR #146: Datetime validation improvements
119
+ """
120
+ # Check if datetime is already timezone-aware
121
+ if is_timezone_aware(dt):
122
+ return dt
123
+
124
+ # Handle naive datetime
125
+ if not assume_utc:
126
+ # Lazy imports to avoid circular dependency (utils -> errors -> models -> utils)
127
+ from omnibase_infra.enums import EnumInfraTransportType
128
+ from omnibase_infra.errors import (
129
+ ModelInfraErrorContext,
130
+ ProtocolConfigurationError,
131
+ )
132
+
133
+ error_context = ModelInfraErrorContext(
134
+ transport_type=EnumInfraTransportType.RUNTIME,
135
+ operation="ensure_timezone_aware",
136
+ target_name=context,
137
+ correlation_id=uuid4(),
138
+ )
139
+ raise ProtocolConfigurationError(
140
+ "Naive datetime not allowed. "
141
+ "Use timezone-aware datetime (e.g., datetime.now(UTC)).",
142
+ context=error_context,
143
+ parameter="dt",
144
+ value=dt.isoformat(),
145
+ )
146
+
147
+ # Log warning if enabled
148
+ if warn_on_naive:
149
+ context_msg = f" for '{context}'" if context else ""
150
+ logger.warning(
151
+ "Converting naive datetime to UTC%s. "
152
+ "Consider using datetime.now(UTC) instead of datetime.utcnow() or naive datetime().",
153
+ context_msg,
154
+ extra={
155
+ "naive_datetime": dt.isoformat(),
156
+ "context": context,
157
+ "action": "converted_to_utc",
158
+ },
159
+ )
160
+
161
+ # Convert naive datetime to UTC by replacing tzinfo
162
+ # Using replace() instead of astimezone() because astimezone() interprets
163
+ # naive datetimes as local time, which we don't want
164
+ return dt.replace(tzinfo=UTC)
165
+
166
+
167
+ def is_timezone_aware(dt: datetime) -> bool:
168
+ """Check if a datetime is timezone-aware.
169
+
170
+ A datetime is timezone-aware if it has a tzinfo attribute that is not None
171
+ AND returns a valid utcoffset(). Some tzinfo objects may be set but not
172
+ properly configured, so we check both conditions.
173
+
174
+ Args:
175
+ dt: The datetime to check.
176
+
177
+ Returns:
178
+ True if datetime is timezone-aware, False if naive.
179
+
180
+ Example:
181
+ >>> from datetime import datetime, UTC
182
+ >>> from omnibase_infra.utils.util_datetime import is_timezone_aware
183
+ >>>
184
+ >>> is_timezone_aware(datetime.now(UTC))
185
+ True
186
+ >>> is_timezone_aware(datetime.now()) # Naive
187
+ False
188
+ """
189
+ return dt.tzinfo is not None and dt.utcoffset() is not None
190
+
191
+
192
+ def validate_timezone_aware_with_context(
193
+ dt: datetime,
194
+ context: ModelInfraErrorContext,
195
+ *,
196
+ field_name: str = "envelope_timestamp",
197
+ ) -> datetime:
198
+ """Validate that a datetime is timezone-aware, raising ProtocolConfigurationError if not.
199
+
200
+ This is the SINGLE SOURCE OF TRUTH for handler-level timezone validation.
201
+ Use this function when you need to validate datetime values in handlers
202
+ and raise structured errors with context information.
203
+
204
+ For Pydantic field validators, use :func:`validate_timezone_aware_datetime`
205
+ from ``util_pydantic_validators.py`` instead.
206
+
207
+ Args:
208
+ dt: The datetime to validate.
209
+ context: A ModelInfraErrorContext instance for error reporting.
210
+ The context provides transport_type, operation, target_name,
211
+ and correlation_id for the error.
212
+ field_name: Name of the field being validated, used in error message.
213
+ Defaults to "envelope_timestamp".
214
+
215
+ Returns:
216
+ The validated datetime (unchanged if valid).
217
+
218
+ Raises:
219
+ ProtocolConfigurationError: If datetime is naive (no timezone info).
220
+
221
+ Example:
222
+ >>> from datetime import datetime, UTC
223
+ >>> from uuid import uuid4
224
+ >>> from omnibase_infra.enums import EnumInfraTransportType
225
+ >>> from omnibase_infra.errors import ModelInfraErrorContext
226
+ >>> from omnibase_infra.utils import validate_timezone_aware_with_context
227
+ >>>
228
+ >>> ctx = ModelInfraErrorContext(
229
+ ... transport_type=EnumInfraTransportType.RUNTIME,
230
+ ... operation="handle_event",
231
+ ... target_name="my_handler",
232
+ ... correlation_id=uuid4(),
233
+ ... )
234
+ >>>
235
+ >>> # Valid: timezone-aware datetime passes through
236
+ >>> aware = datetime.now(UTC)
237
+ >>> validate_timezone_aware_with_context(aware, ctx) == aware
238
+ True
239
+ >>>
240
+ >>> # Invalid: naive datetime raises ProtocolConfigurationError
241
+ >>> naive = datetime.now()
242
+ >>> validate_timezone_aware_with_context(naive, ctx) # doctest: +ELLIPSIS
243
+ Traceback (most recent call last):
244
+ ...
245
+ omnibase_infra.errors...ProtocolConfigurationError: envelope_timestamp must be timezone-aware...
246
+
247
+ Related:
248
+ - OMN-1181: Replace RuntimeError with structured errors
249
+ - PR #158: Consolidate duplicate validation functions
250
+
251
+ .. versionadded:: 0.9.1
252
+ Created to consolidate duplicate timezone validation in handlers.
253
+ """
254
+ if is_timezone_aware(dt):
255
+ return dt
256
+
257
+ # Lazy imports to avoid circular dependency (utils -> errors -> models -> utils)
258
+ from omnibase_infra.errors import ProtocolConfigurationError
259
+
260
+ raise ProtocolConfigurationError(
261
+ f"{field_name} must be timezone-aware. Use datetime.now(UTC) or "
262
+ "datetime(..., tzinfo=timezone.utc) instead of naive datetime.",
263
+ context=context,
264
+ parameter=field_name,
265
+ value=dt.isoformat(),
266
+ )
267
+
268
+
269
+ def warn_if_naive_datetime(
270
+ dt: datetime,
271
+ *,
272
+ field_name: str | None = None,
273
+ context: str | None = None,
274
+ correlation_id: UUID | None = None,
275
+ logger: logging.Logger | None = None,
276
+ ) -> None:
277
+ """Log a warning if the datetime is naive (lacks timezone info).
278
+
279
+ This is a WARNING-ONLY function that does not modify or convert the datetime.
280
+ Use this when you want to detect and log naive datetimes without changing
281
+ them, such as for auditing or gradual migration scenarios.
282
+
283
+ For automatic conversion of naive datetimes to UTC, use :func:`ensure_timezone_aware`
284
+ instead.
285
+
286
+ Args:
287
+ dt: The datetime to check for timezone awareness.
288
+ field_name: Optional name of the field/column containing the datetime.
289
+ Used in the warning message to identify the source.
290
+ context: Optional context string for the warning message (e.g., operation
291
+ name, handler name). Provides additional context for debugging.
292
+ correlation_id: Optional correlation ID for distributed tracing. Included
293
+ in the log extra dict when provided.
294
+ logger: Optional logger instance to use. If not provided, uses the
295
+ module-level logger (omnibase_infra.utils.util_datetime).
296
+
297
+ Returns:
298
+ None. This function only logs a warning and does not return a value.
299
+
300
+ Example:
301
+ >>> from datetime import datetime, UTC
302
+ >>> from uuid import uuid4
303
+ >>> from omnibase_infra.utils import warn_if_naive_datetime
304
+ >>>
305
+ >>> # Naive datetime triggers warning
306
+ >>> naive_dt = datetime(2025, 1, 15, 12, 0, 0)
307
+ >>> warn_if_naive_datetime(
308
+ ... naive_dt,
309
+ ... field_name="created_at",
310
+ ... context="manifest_persistence",
311
+ ... correlation_id=uuid4(),
312
+ ... ) # Logs warning
313
+ >>>
314
+ >>> # Aware datetime - no warning logged
315
+ >>> aware_dt = datetime.now(UTC)
316
+ >>> warn_if_naive_datetime(aware_dt, field_name="updated_at") # Silent
317
+
318
+ Warning:
319
+ This function is intentionally warning-only. If you need to convert naive
320
+ datetimes to UTC, use :func:`ensure_timezone_aware` with ``assume_utc=True``.
321
+ The separation allows callers to choose between:
322
+
323
+ - **warn_if_naive_datetime**: Audit/detect without modification
324
+ - **ensure_timezone_aware**: Convert with optional warning
325
+
326
+ Related:
327
+ - OMN-1340: Extract datetime warning utility
328
+ - OMN-1163: Handler manifest persistence datetime handling
329
+
330
+ .. versionadded:: 0.9.0
331
+ Extracted from handler_manifest_persistence.py for reuse across codebase.
332
+ """
333
+ # Use module logger if none provided
334
+ log = logger if logger is not None else globals()["logger"]
335
+
336
+ # Check if datetime is timezone-aware - if so, nothing to warn about
337
+ if is_timezone_aware(dt):
338
+ return
339
+
340
+ # Build context-aware message parts
341
+ location_parts: list[str] = []
342
+ if field_name:
343
+ location_parts.append(f"field '{field_name}'")
344
+ if context:
345
+ location_parts.append(f"context '{context}'")
346
+
347
+ location_str = " in ".join(location_parts) if location_parts else "datetime value"
348
+
349
+ # Build extra dict for structured logging
350
+ extra: dict[str, str | None] = {
351
+ "field_name": field_name,
352
+ "context": context,
353
+ "datetime_value": dt.isoformat(),
354
+ }
355
+ if correlation_id is not None:
356
+ extra["correlation_id"] = str(correlation_id)
357
+
358
+ log.warning(
359
+ "Naive datetime detected for %s. For accurate comparisons, use "
360
+ "timezone-aware datetimes (e.g., datetime.now(UTC)). "
361
+ "See util_datetime module docstring for timezone handling details.",
362
+ location_str,
363
+ extra=extra,
364
+ )
365
+
366
+
367
+ __all__: list[str] = [
368
+ "ensure_timezone_aware",
369
+ "is_timezone_aware",
370
+ "validate_timezone_aware_with_context",
371
+ "warn_if_naive_datetime",
372
+ ]
@@ -0,0 +1,333 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """PostgreSQL DSN validation utility.
4
+
5
+ This module provides robust DSN validation using urllib.parse instead of regex.
6
+ It handles edge cases like IPv6 addresses, URL-encoded passwords, query parameters,
7
+ and validates DSN structure comprehensively.
8
+
9
+ Security:
10
+ - Never logs credentials in error messages
11
+ - Returns [REDACTED] in error messages for sensitive values
12
+ - Validates structure without exposing DSN contents
13
+
14
+ Edge Cases Handled:
15
+ - IPv6 addresses: postgresql://user:pass@[::1]:5432/db
16
+ - URL-encoded passwords: user:p%40ssword@host (p@ssword)
17
+ - Missing components: postgresql://localhost/db (no user/pass/port)
18
+ - Query parameters: postgresql://host/db?sslmode=require
19
+ - Unix sockets: postgresql:///db?host=/var/run/postgresql
20
+ - Empty password: user:@host (different from no password)
21
+
22
+ Limitations:
23
+ - Multiple hosts (host1:5432,host2:5433) are not validated
24
+ (urllib.parse treats them as a single hostname)
25
+ - If multi-host support is needed, use a PostgreSQL-specific parser
26
+ """
27
+
28
+ from __future__ import annotations
29
+
30
+ from typing import Literal, cast
31
+ from urllib.parse import parse_qs, unquote, urlparse
32
+ from uuid import uuid4
33
+
34
+ from omnibase_infra.types import ModelParsedDSN
35
+
36
+
37
+ def _assert_postgres_scheme(scheme: str) -> Literal["postgresql", "postgres"]:
38
+ """Type-safe scheme assertion for PostgreSQL DSN schemes.
39
+
40
+ This helper enables proper type narrowing for the Literal type
41
+ using typing.cast for explicit type assertion.
42
+
43
+ Args:
44
+ scheme: The scheme string to validate
45
+
46
+ Returns:
47
+ The scheme cast to the appropriate Literal type
48
+
49
+ Raises:
50
+ ProtocolConfigurationError: If scheme is not 'postgresql' or 'postgres'.
51
+
52
+ Note:
53
+ This function should only be called AFTER validating
54
+ that scheme is one of the valid values.
55
+ """
56
+ if scheme not in ("postgresql", "postgres"):
57
+ # Lazy imports to avoid circular dependency (utils -> errors -> models -> utils)
58
+ from omnibase_infra.enums import EnumInfraTransportType
59
+ from omnibase_infra.errors import (
60
+ ModelInfraErrorContext,
61
+ ProtocolConfigurationError,
62
+ )
63
+
64
+ context = ModelInfraErrorContext(
65
+ transport_type=EnumInfraTransportType.DATABASE,
66
+ operation="validate_dsn_scheme",
67
+ target_name="dsn_validator",
68
+ correlation_id=uuid4(),
69
+ )
70
+ raise ProtocolConfigurationError(
71
+ f"Invalid scheme: expected 'postgresql' or 'postgres', got '{scheme}'",
72
+ context=context,
73
+ parameter="scheme",
74
+ value=scheme,
75
+ )
76
+ return cast(Literal["postgresql", "postgres"], scheme)
77
+
78
+
79
+ def parse_and_validate_dsn(dsn: object) -> ModelParsedDSN:
80
+ """Parse and validate PostgreSQL DSN format using urllib.parse.
81
+
82
+ This function provides comprehensive DSN validation that handles edge cases
83
+ like IPv6 addresses, URL-encoded passwords, and query parameters. It uses
84
+ urllib.parse for robust parsing instead of fragile regex patterns.
85
+
86
+ Args:
87
+ dsn: PostgreSQL connection string (any type - validated)
88
+
89
+ Returns:
90
+ ModelParsedDSN with parsed components:
91
+ - scheme: "postgresql" or "postgres" (Literal type)
92
+ - username: Username or None
93
+ - password: Password (URL-decoded) or None
94
+ - hostname: Hostname or IP address or None
95
+ - port: Port number or None
96
+ - database: Database name
97
+ - query: Dict of query parameters (str keys, str | list[str] values)
98
+
99
+ Raises:
100
+ ProtocolConfigurationError: If DSN format is invalid
101
+
102
+ Example:
103
+ >>> result = parse_and_validate_dsn("postgresql://user:pass@localhost:5432/mydb")
104
+ >>> assert result.hostname == "localhost"
105
+ >>> assert result.database == "mydb"
106
+
107
+ Security Note:
108
+ Error messages never contain the actual DSN value. Sensitive information
109
+ is replaced with [REDACTED] to prevent credential leakage in logs.
110
+ """
111
+ # Lazy imports to avoid circular dependency (utils → errors → models → utils)
112
+ from omnibase_infra.enums import EnumInfraTransportType
113
+ from omnibase_infra.errors import ModelInfraErrorContext, ProtocolConfigurationError
114
+
115
+ context = ModelInfraErrorContext(
116
+ transport_type=EnumInfraTransportType.DATABASE,
117
+ operation="validate_dsn",
118
+ target_name="dsn_validator",
119
+ correlation_id=uuid4(),
120
+ )
121
+
122
+ # Type validation
123
+ if dsn is None:
124
+ raise ProtocolConfigurationError(
125
+ "Invalid dsn: expected a string, got None",
126
+ context=context,
127
+ parameter="dsn",
128
+ value=None,
129
+ )
130
+
131
+ if not isinstance(dsn, str):
132
+ raise ProtocolConfigurationError(
133
+ f"Invalid dsn type: expected str, got {type(dsn).__name__}",
134
+ context=context,
135
+ parameter="dsn",
136
+ value=type(dsn).__name__,
137
+ )
138
+
139
+ # Empty string validation
140
+ if not dsn.strip():
141
+ raise ProtocolConfigurationError(
142
+ "Invalid dsn: expected a non-empty string, got empty string",
143
+ context=context,
144
+ parameter="dsn",
145
+ value="",
146
+ )
147
+
148
+ dsn_str = dsn.strip()
149
+
150
+ # Scheme validation (before parsing to provide clear error)
151
+ valid_prefixes = ("postgresql://", "postgres://")
152
+ if not dsn_str.startswith(valid_prefixes):
153
+ raise ProtocolConfigurationError(
154
+ f"dsn must start with one of {valid_prefixes}",
155
+ context=context,
156
+ parameter="dsn",
157
+ value="[REDACTED]", # Never log DSN contents
158
+ )
159
+
160
+ # Check for multi-host DSN format (not supported)
161
+ # Multi-host format: postgresql://host1:port1,host2:port2/db
162
+ # We check for comma after :// and before / (in the host portion)
163
+ scheme_end = dsn_str.index("://") + 3
164
+ path_start = dsn_str.find("/", scheme_end)
165
+ host_portion = (
166
+ dsn_str[scheme_end:path_start] if path_start != -1 else dsn_str[scheme_end:]
167
+ )
168
+ if "," in host_portion:
169
+ raise ProtocolConfigurationError(
170
+ "Multi-host DSNs are not supported. Use a single host or consider "
171
+ "psycopg2.conninfo_to_dict for multi-host parsing.",
172
+ context=context,
173
+ parameter="dsn",
174
+ value="[REDACTED]",
175
+ )
176
+
177
+ # Parse DSN using urllib.parse
178
+ try:
179
+ parsed = urlparse(dsn_str)
180
+ except ValueError as e:
181
+ # urlparse can raise ValueError for invalid ports, etc.
182
+ raise ProtocolConfigurationError(
183
+ f"Invalid DSN format: {e}",
184
+ context=context,
185
+ parameter="dsn",
186
+ value="[REDACTED]",
187
+ ) from e
188
+
189
+ # Validate scheme (redundant but explicit)
190
+ if parsed.scheme not in ("postgresql", "postgres"):
191
+ raise ProtocolConfigurationError(
192
+ f"Invalid scheme: expected 'postgresql' or 'postgres', got '{parsed.scheme}'",
193
+ context=context,
194
+ parameter="dsn",
195
+ value="[REDACTED]",
196
+ )
197
+
198
+ # Validate port if present
199
+ # Note: Accessing parsed.port can raise ValueError if port is invalid
200
+ try:
201
+ port = parsed.port
202
+ if port is not None:
203
+ if port < 1 or port > 65535:
204
+ raise ProtocolConfigurationError(
205
+ f"Port must be between 1 and 65535, got {port}",
206
+ context=context,
207
+ parameter="dsn.port",
208
+ value=port,
209
+ )
210
+ except ValueError as e:
211
+ # urlparse raises ValueError for invalid ports (non-numeric, out of range)
212
+ raise ProtocolConfigurationError(
213
+ f"Invalid port in DSN: {e}",
214
+ context=context,
215
+ parameter="dsn.port",
216
+ value="[REDACTED]",
217
+ ) from e
218
+
219
+ # Validate database name
220
+ # Path is "/dbname" or "///dbname" for Unix socket
221
+ # Strip leading slashes to get database name
222
+ database = parsed.path.lstrip("/") if parsed.path else ""
223
+
224
+ # Database name is required (unless using Unix socket with query param)
225
+ # For Unix sockets: postgresql:///dbname?host=/var/run/postgresql
226
+ # For network: postgresql://host/dbname
227
+ if not database:
228
+ # Check if Unix socket is specified in query params
229
+ query_params = parse_qs(parsed.query)
230
+ if "host" not in query_params:
231
+ raise ProtocolConfigurationError(
232
+ "Database name is required in DSN path (e.g., postgresql://host:5432/dbname)",
233
+ context=context,
234
+ parameter="dsn.path",
235
+ value="[REDACTED]",
236
+ )
237
+ # Unix socket case - database might be in query params or path
238
+ # Allow empty database for now (will be validated at connection time)
239
+
240
+ # Parse query parameters
241
+ query_dict = {}
242
+ if parsed.query:
243
+ # parse_qs returns lists, flatten to single values
244
+ parsed_qs = parse_qs(parsed.query)
245
+ query_dict = {k: v[0] if len(v) == 1 else v for k, v in parsed_qs.items()}
246
+
247
+ # Return parsed components
248
+ # Note: urlparse does NOT decode URL-encoded passwords, so we use unquote()
249
+ # Important: Check 'is not None' instead of truthiness to preserve empty strings
250
+ return ModelParsedDSN(
251
+ scheme=_assert_postgres_scheme(parsed.scheme),
252
+ username=unquote(parsed.username) if parsed.username is not None else None,
253
+ password=unquote(parsed.password) if parsed.password is not None else None,
254
+ hostname=parsed.hostname,
255
+ port=port,
256
+ database=database,
257
+ query=query_dict,
258
+ )
259
+
260
+
261
+ def sanitize_dsn(dsn: str) -> str:
262
+ """Sanitize DSN by removing password for safe logging.
263
+
264
+ SECURITY: This function should ONLY be used for development/debugging.
265
+ Production code should NEVER log DSN values, even sanitized ones.
266
+
267
+ Replaces the password portion of the DSN with asterisks using URL parsing
268
+ instead of regex for robustness.
269
+
270
+ Args:
271
+ dsn: Raw PostgreSQL connection string containing credentials
272
+
273
+ Returns:
274
+ Sanitized DSN with password replaced by '***'
275
+
276
+ Example:
277
+ >>> sanitize_dsn("postgresql://user:secret@host:5432/db")
278
+ 'postgresql://user:***@host:5432/db'
279
+
280
+ >>> sanitize_dsn("postgresql://user:p%40ss@host/db")
281
+ 'postgresql://user:***@host/db'
282
+
283
+ Note:
284
+ This function is intentionally NOT used in production error paths.
285
+ It exists as a utility for development/debugging only.
286
+ """
287
+ try:
288
+ parsed = urlparse(dsn)
289
+
290
+ # Rebuild DSN with password masked
291
+ # Format: scheme://[user[:password]@]host[:port]/path[?query][#fragment]
292
+ netloc = parsed.hostname or ""
293
+
294
+ # Add port if present (handle ValueError from invalid ports)
295
+ try:
296
+ port = parsed.port
297
+ if port:
298
+ netloc = f"{netloc}:{port}"
299
+ except ValueError:
300
+ # Invalid port - include raw port string from netloc
301
+ # Extract port from raw netloc if present
302
+ if ":" in (parsed.netloc or ""):
303
+ # Keep original port notation even if invalid
304
+ parts = parsed.netloc.split("@")[-1] # Get host:port part
305
+ if ":" in parts:
306
+ netloc = parts
307
+
308
+ # Add username with masked password
309
+ if parsed.username:
310
+ if parsed.password:
311
+ netloc = f"{parsed.username}:***@{netloc}"
312
+ else:
313
+ netloc = f"{parsed.username}@{netloc}"
314
+
315
+ # Reconstruct URL
316
+ sanitized = f"{parsed.scheme}://{netloc}{parsed.path}"
317
+
318
+ # Add query string if present
319
+ if parsed.query:
320
+ sanitized = f"{sanitized}?{parsed.query}"
321
+
322
+ # Add fragment if present
323
+ if parsed.fragment:
324
+ sanitized = f"{sanitized}#{parsed.fragment}"
325
+
326
+ return sanitized
327
+
328
+ except Exception:
329
+ # If parsing fails, return a safe placeholder
330
+ return "[INVALID_DSN]"
331
+
332
+
333
+ __all__: list[str] = ["ModelParsedDSN", "parse_and_validate_dsn", "sanitize_dsn"]