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,907 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """
4
+ ONEX Infrastructure Contract Linter.
5
+
6
+ Validates contract.yaml files against ONEX infrastructure requirements:
7
+ - Required fields: name, node_type, contract_version, input_model, output_model
8
+ - Type consistency: input_model/output_model module references are importable
9
+ - YAML syntax validity
10
+ - Node type constraints (EFFECT_GENERIC, COMPUTE_GENERIC, REDUCER_GENERIC, ORCHESTRATOR_GENERIC)
11
+
12
+ This linter complements omnibase_core.validation.validate_contracts by adding
13
+ infrastructure-specific validation that is not covered by the base validator.
14
+
15
+ Integration with Structured Error Reporting (OMN-1091):
16
+ The linter now supports converting contract violations to structured
17
+ ModelHandlerValidationError instances with unique rule IDs, handler
18
+ identities, and remediation hints. Use ModelContractLintResult.to_handler_errors()
19
+ to convert violations to structured errors.
20
+
21
+ Rule ID Mapping:
22
+ CONTRACT-001: YAML parse error
23
+ CONTRACT-002: Missing required field
24
+ CONTRACT-003: Invalid node_type
25
+ CONTRACT-004: Invalid field type
26
+ CONTRACT-005: Import error for models
27
+ CONTRACT-006: Invalid contract_version format
28
+ CONTRACT-007: Invalid model reference
29
+ CONTRACT-008: Invalid name convention
30
+ CONTRACT-009: File not found
31
+ CONTRACT-010: Non-dict contract
32
+ CONTRACT-011: Model not found in module
33
+ CONTRACT-012: Encoding error
34
+
35
+ Usage:
36
+ from omnibase_infra.validation.contract_linter import (
37
+ ContractLinter,
38
+ lint_contracts_in_directory,
39
+ lint_contract_file,
40
+ convert_violation_to_handler_error,
41
+ )
42
+
43
+ # Lint all contracts in a directory
44
+ result = lint_contracts_in_directory("src/omnibase_infra/nodes/")
45
+
46
+ # Lint a single contract file
47
+ result = lint_contract_file("path/to/contract.yaml")
48
+
49
+ # Convert violations to structured errors
50
+ errors = result.to_handler_errors()
51
+ for error in errors:
52
+ logger.error(error.format_for_logging())
53
+
54
+ Exit Codes (for CI):
55
+ 0: All contracts valid
56
+ 1: Validation failures found
57
+ 2: Runtime error (file not found, YAML parse error, etc.)
58
+ """
59
+
60
+ import importlib
61
+ import logging
62
+ import re
63
+ from pathlib import Path
64
+ from typing import Literal
65
+ from uuid import UUID, uuid4
66
+
67
+ import yaml
68
+
69
+ from omnibase_infra.enums import EnumValidationSeverity
70
+ from omnibase_infra.models.errors import ModelHandlerValidationError
71
+ from omnibase_infra.models.handlers import ModelHandlerIdentifier
72
+ from omnibase_infra.types import PathInput
73
+ from omnibase_infra.validation.enums.enum_contract_violation_severity import (
74
+ EnumContractViolationSeverity,
75
+ )
76
+ from omnibase_infra.validation.models.model_contract_lint_result import (
77
+ ModelContractLintResult,
78
+ )
79
+ from omnibase_infra.validation.models.model_contract_violation import (
80
+ ModelContractViolation,
81
+ )
82
+
83
+ # Module-level logger
84
+ logger = logging.getLogger(__name__)
85
+
86
+
87
+ # Valid node types per ONEX 4-node architecture (omnibase_core 0.7.0+)
88
+ VALID_NODE_TYPES = frozenset(
89
+ {"EFFECT_GENERIC", "COMPUTE_GENERIC", "REDUCER_GENERIC", "ORCHESTRATOR_GENERIC"}
90
+ )
91
+
92
+
93
+ # Rule ID mapping for contract violations
94
+ class ContractRuleId:
95
+ """Rule IDs for contract validation errors.
96
+
97
+ These IDs provide unique identifiers for each type of contract validation
98
+ failure, enabling structured error tracking and remediation guidance.
99
+ """
100
+
101
+ YAML_PARSE_ERROR = "CONTRACT-001"
102
+ MISSING_REQUIRED_FIELD = "CONTRACT-002"
103
+ INVALID_NODE_TYPE = "CONTRACT-003"
104
+ INVALID_FIELD_TYPE = "CONTRACT-004"
105
+ IMPORT_ERROR = "CONTRACT-005"
106
+ INVALID_CONTRACT_VERSION = "CONTRACT-006"
107
+ INVALID_MODEL_REFERENCE = "CONTRACT-007"
108
+ INVALID_NAME_CONVENTION = "CONTRACT-008"
109
+ FILE_NOT_FOUND = "CONTRACT-009"
110
+ NON_DICT_CONTRACT = "CONTRACT-010"
111
+ MODEL_NOT_FOUND = "CONTRACT-011"
112
+ ENCODING_ERROR = "CONTRACT-012"
113
+
114
+
115
+ def convert_violation_to_handler_error(
116
+ violation: ModelContractViolation,
117
+ correlation_id: UUID | None = None,
118
+ ) -> ModelHandlerValidationError:
119
+ """Convert contract violation to structured handler validation error.
120
+
121
+ Maps ModelContractViolation to ModelHandlerValidationError with appropriate
122
+ rule IDs, handler identity, and remediation hints for structured error reporting.
123
+
124
+ Args:
125
+ violation: Contract violation to convert.
126
+ correlation_id: Optional correlation ID for distributed tracing.
127
+
128
+ Returns:
129
+ ModelHandlerValidationError with structured error information.
130
+
131
+ Example:
132
+ >>> violation = ModelContractViolation(
133
+ ... file_path="nodes/registration/contract.yaml",
134
+ ... field_path="node_type",
135
+ ... message="Invalid node_type 'INVALID'",
136
+ ... severity=EnumContractViolationSeverity.ERROR,
137
+ ... )
138
+ >>> error = convert_violation_to_handler_error(violation)
139
+ >>> error.rule_id
140
+ 'CONTRACT-003'
141
+ """
142
+ # Derive handler_id from file path (e.g., nodes/registration/contract.yaml -> registration)
143
+ file_path = violation.file_path
144
+ handler_id = _derive_handler_id_from_path(file_path)
145
+
146
+ # Create handler identifier
147
+ handler_identity = ModelHandlerIdentifier.from_handler_id(handler_id)
148
+
149
+ # Map violation to rule ID based on field_path and message
150
+ rule_id = _map_violation_to_rule_id(violation)
151
+
152
+ # Map severity
153
+ severity = (
154
+ EnumValidationSeverity.ERROR
155
+ if violation.severity == EnumContractViolationSeverity.ERROR
156
+ else EnumValidationSeverity.WARNING
157
+ )
158
+
159
+ # Use suggestion as remediation hint, or provide default
160
+ remediation_hint = (
161
+ violation.suggestion or "Review contract.yaml and fix the validation error"
162
+ )
163
+
164
+ return ModelHandlerValidationError.from_contract_error(
165
+ rule_id=rule_id,
166
+ message=violation.message,
167
+ file_path=file_path,
168
+ remediation_hint=remediation_hint,
169
+ handler_identity=handler_identity,
170
+ line_number=None, # Contract linter doesn't track line numbers currently
171
+ correlation_id=correlation_id or uuid4(),
172
+ severity=severity,
173
+ )
174
+
175
+
176
+ def _derive_handler_id_from_path(file_path: str) -> str:
177
+ """Derive handler ID from contract file path.
178
+
179
+ Extracts the node name from the contract file path to use as handler_id.
180
+ For root-level contract.yaml files without a meaningful parent directory,
181
+ falls back to using the filename stem as the handler ID.
182
+
183
+ Args:
184
+ file_path: Path to contract.yaml file.
185
+
186
+ Returns:
187
+ Derived handler ID (e.g., "registration" from "nodes/registration/contract.yaml").
188
+
189
+ Example:
190
+ >>> _derive_handler_id_from_path("nodes/registration/contract.yaml")
191
+ 'registration'
192
+ >>> _derive_handler_id_from_path("contract.yaml")
193
+ 'contract'
194
+ >>> _derive_handler_id_from_path("./contract.yaml")
195
+ 'contract'
196
+ >>> _derive_handler_id_from_path("/tmp/contract.yaml")
197
+ 'tmp'
198
+ """
199
+ # Extract parent directory name as handler ID
200
+ path = Path(file_path)
201
+ if path.name == "contract.yaml":
202
+ # Get parent directory name, but only if it's meaningful (not ".", "", or just "/")
203
+ parent_name = path.parent.name
204
+ if parent_name and parent_name not in {".", "", "/"}:
205
+ return parent_name
206
+ # Fallback to filename without extension for root-level files
207
+ return path.stem
208
+
209
+
210
+ def _map_violation_to_rule_id(violation: ModelContractViolation) -> str:
211
+ """Map contract violation to appropriate rule ID using keyword heuristics.
212
+
213
+ This function uses a decision tree based on keyword matching in the violation's
214
+ field_path and message to determine the appropriate CONTRACT-xxx rule ID.
215
+ The mapping provides unique, stable rule IDs for structured error reporting.
216
+
217
+ Mapping Logic (evaluated in order):
218
+
219
+ 1. **YAML/File-Level Errors** (no field_path):
220
+ - "not found" → CONTRACT-009 (FILE_NOT_FOUND)
221
+ - "yaml" + "parse" → CONTRACT-001 (YAML_PARSE_ERROR)
222
+ - "encoding" or "binary" → CONTRACT-012 (ENCODING_ERROR)
223
+ - "must be a yaml mapping" or "must be a dict" → CONTRACT-010 (NON_DICT_CONTRACT)
224
+
225
+ 2. **Missing Fields**:
226
+ - "missing" + "required field" → CONTRACT-002 (MISSING_REQUIRED_FIELD)
227
+
228
+ 3. **Field-Specific Errors** (based on field_path):
229
+ - field_path == "node_type":
230
+ - "invalid node_type" → CONTRACT-003 (INVALID_NODE_TYPE)
231
+ - "must be a string" → CONTRACT-004 (INVALID_FIELD_TYPE)
232
+ - field_path starts with "contract_version" → CONTRACT-006 (INVALID_CONTRACT_VERSION)
233
+ - field_path starts with "input_model" or "output_model":
234
+ - "cannot import" → CONTRACT-005 (IMPORT_ERROR)
235
+ - "not found in module" → CONTRACT-011 (MODEL_NOT_FOUND)
236
+ - Otherwise → CONTRACT-007 (INVALID_MODEL_REFERENCE)
237
+ - field_path == "name" → CONTRACT-008 (INVALID_NAME_CONVENTION)
238
+
239
+ 4. **Default Fallback**:
240
+ - CONTRACT-004 (INVALID_FIELD_TYPE) for any unmatched violations
241
+
242
+ Args:
243
+ violation: Contract violation to map.
244
+
245
+ Returns:
246
+ Rule ID string (e.g., "CONTRACT-001").
247
+
248
+ Note:
249
+ This heuristic-based approach enables automatic rule ID assignment without
250
+ requiring explicit rule IDs at violation creation time. The keyword patterns
251
+ are chosen to match the actual error messages generated by ContractLinter,
252
+ ensuring consistent and predictable rule ID assignment.
253
+
254
+ The decision tree is evaluated top-to-bottom with early returns, so more
255
+ specific patterns should be checked before general ones.
256
+ """
257
+ field_path = violation.field_path
258
+ message_lower = violation.message.lower()
259
+
260
+ # YAML/file errors
261
+ if "not found" in message_lower and not field_path:
262
+ return ContractRuleId.FILE_NOT_FOUND
263
+ if "yaml" in message_lower and "parse" in message_lower:
264
+ return ContractRuleId.YAML_PARSE_ERROR
265
+ if "encoding" in message_lower or "binary" in message_lower:
266
+ return ContractRuleId.ENCODING_ERROR
267
+ if "must be a yaml mapping" in message_lower or "must be a dict" in message_lower:
268
+ return ContractRuleId.NON_DICT_CONTRACT
269
+
270
+ # Field-specific errors
271
+ if not field_path:
272
+ return ContractRuleId.YAML_PARSE_ERROR
273
+
274
+ # Missing required fields
275
+ if "missing" in message_lower and "required field" in message_lower:
276
+ return ContractRuleId.MISSING_REQUIRED_FIELD
277
+
278
+ # Node type validation
279
+ if field_path == "node_type":
280
+ if "invalid node_type" in message_lower:
281
+ return ContractRuleId.INVALID_NODE_TYPE
282
+ if "must be a string" in message_lower:
283
+ return ContractRuleId.INVALID_FIELD_TYPE
284
+
285
+ # Contract version validation
286
+ if field_path.startswith("contract_version"):
287
+ return ContractRuleId.INVALID_CONTRACT_VERSION
288
+
289
+ # Model reference validation
290
+ if field_path.startswith(("input_model", "output_model")):
291
+ if "cannot import" in message_lower:
292
+ return ContractRuleId.IMPORT_ERROR
293
+ if "not found in module" in message_lower:
294
+ return ContractRuleId.MODEL_NOT_FOUND
295
+ return ContractRuleId.INVALID_MODEL_REFERENCE
296
+
297
+ # Name convention validation
298
+ if field_path == "name":
299
+ return ContractRuleId.INVALID_NAME_CONVENTION
300
+
301
+ # Default to invalid field type
302
+ return ContractRuleId.INVALID_FIELD_TYPE
303
+
304
+
305
+ class ContractLinter:
306
+ """
307
+ ONEX Infrastructure Contract Linter.
308
+
309
+ Validates contract.yaml files for required fields, type consistency,
310
+ and ONEX compliance. Designed for CI integration with clear exit codes.
311
+
312
+ Required Fields:
313
+ - name: Node identifier (snake_case)
314
+ - node_type: One of EFFECT_GENERIC, COMPUTE_GENERIC, REDUCER_GENERIC, ORCHESTRATOR_GENERIC
315
+ - contract_version: Semantic version dict with major, minor, patch
316
+ - input_model: Dict with name and module fields
317
+ - output_model: Dict with name and module fields
318
+
319
+ Optional but Recommended Fields:
320
+ - description: Human-readable description
321
+ - node_version: Semantic version string
322
+ - dependencies: List of dependency declarations
323
+ - consumed_events: Event topics the node subscribes to
324
+ - published_events: Event topics the node publishes to
325
+ """
326
+
327
+ def __init__(
328
+ self,
329
+ *,
330
+ check_imports: bool = True,
331
+ strict_mode: bool = False,
332
+ ):
333
+ """
334
+ Initialize the contract linter.
335
+
336
+ Args:
337
+ check_imports: Whether to verify input_model/output_model modules
338
+ are importable. Disable for faster validation when
339
+ modules may not be in the Python path.
340
+ strict_mode: If True, treat warnings as errors.
341
+ """
342
+ self.check_imports = check_imports
343
+ self.strict_mode = strict_mode
344
+
345
+ def lint_file(self, file_path: Path) -> ModelContractLintResult:
346
+ """
347
+ Lint a single contract.yaml file.
348
+
349
+ Args:
350
+ file_path: Path to the contract.yaml file.
351
+
352
+ Returns:
353
+ ModelContractLintResult with violations found.
354
+ """
355
+ violations: list[ModelContractViolation] = []
356
+ file_str = str(file_path)
357
+
358
+ # Check file exists
359
+ if not file_path.exists():
360
+ violations.append(
361
+ ModelContractViolation(
362
+ file_path=file_str,
363
+ field_path="",
364
+ message=f"Contract file not found: {file_path}",
365
+ severity=EnumContractViolationSeverity.ERROR,
366
+ )
367
+ )
368
+ return ModelContractLintResult(
369
+ is_valid=False,
370
+ violations=violations,
371
+ files_checked=1,
372
+ files_with_errors=1,
373
+ )
374
+
375
+ # Parse YAML
376
+ try:
377
+ with file_path.open("r", encoding="utf-8") as f:
378
+ content = yaml.safe_load(f)
379
+ except yaml.YAMLError as e:
380
+ violations.append(
381
+ ModelContractViolation(
382
+ file_path=file_str,
383
+ field_path="",
384
+ message=f"YAML parse error: {e}",
385
+ severity=EnumContractViolationSeverity.ERROR,
386
+ )
387
+ )
388
+ return ModelContractLintResult(
389
+ is_valid=False,
390
+ violations=violations,
391
+ files_checked=1,
392
+ files_with_errors=1,
393
+ )
394
+ except UnicodeDecodeError as e:
395
+ violations.append(
396
+ ModelContractViolation(
397
+ file_path=file_str,
398
+ field_path="",
399
+ message=f"Contract file contains binary or non-UTF-8 content: "
400
+ f"encoding error at position {e.start}-{e.end}: {e.reason}",
401
+ severity=EnumContractViolationSeverity.ERROR,
402
+ )
403
+ )
404
+ return ModelContractLintResult(
405
+ is_valid=False,
406
+ violations=violations,
407
+ files_checked=1,
408
+ files_with_errors=1,
409
+ )
410
+
411
+ if not isinstance(content, dict):
412
+ violations.append(
413
+ ModelContractViolation(
414
+ file_path=file_str,
415
+ field_path="",
416
+ message="Contract must be a YAML mapping (dict), not a scalar or list",
417
+ severity=EnumContractViolationSeverity.ERROR,
418
+ )
419
+ )
420
+ return ModelContractLintResult(
421
+ is_valid=False,
422
+ violations=violations,
423
+ files_checked=1,
424
+ files_with_errors=1,
425
+ )
426
+
427
+ # Validate required fields
428
+ violations.extend(self._validate_required_fields(file_str, content))
429
+
430
+ # Validate node_type
431
+ violations.extend(self._validate_node_type(file_str, content))
432
+
433
+ # Validate contract_version format
434
+ violations.extend(self._validate_contract_version(file_str, content))
435
+
436
+ # Validate input_model and output_model
437
+ violations.extend(
438
+ self._validate_model_reference(file_str, content, "input_model")
439
+ )
440
+ violations.extend(
441
+ self._validate_model_reference(file_str, content, "output_model")
442
+ )
443
+
444
+ # Validate naming convention (name should be snake_case)
445
+ violations.extend(self._validate_name_convention(file_str, content))
446
+
447
+ # Check for recommended fields
448
+ violations.extend(self._check_recommended_fields(file_str, content))
449
+
450
+ # Calculate result
451
+ has_errors = any(
452
+ v.severity == EnumContractViolationSeverity.ERROR for v in violations
453
+ )
454
+ if self.strict_mode:
455
+ has_errors = has_errors or any(
456
+ v.severity == EnumContractViolationSeverity.WARNING for v in violations
457
+ )
458
+
459
+ return ModelContractLintResult(
460
+ is_valid=not has_errors,
461
+ violations=violations,
462
+ files_checked=1,
463
+ files_valid=0 if has_errors else 1,
464
+ files_with_errors=1 if has_errors else 0,
465
+ )
466
+
467
+ def lint_directory(
468
+ self,
469
+ directory: Path,
470
+ *,
471
+ recursive: bool = True,
472
+ ) -> ModelContractLintResult:
473
+ """
474
+ Lint all contract.yaml files in a directory.
475
+
476
+ Args:
477
+ directory: Directory to search for contract.yaml files.
478
+ recursive: Whether to search subdirectories.
479
+
480
+ Returns:
481
+ ModelContractLintResult with aggregated violations.
482
+ """
483
+ if not directory.exists():
484
+ return ModelContractLintResult(
485
+ is_valid=False,
486
+ violations=[
487
+ ModelContractViolation(
488
+ file_path=str(directory),
489
+ field_path="",
490
+ message=f"Directory not found: {directory}",
491
+ severity=EnumContractViolationSeverity.ERROR,
492
+ )
493
+ ],
494
+ files_checked=0,
495
+ files_with_errors=0,
496
+ )
497
+
498
+ # Find all contract.yaml files
499
+ pattern = "**/contract.yaml" if recursive else "contract.yaml"
500
+ contract_files = list(directory.glob(pattern))
501
+
502
+ if not contract_files:
503
+ # No contracts found - this is informational, not an error
504
+ logger.info("No contract.yaml files found in %s", directory)
505
+ return ModelContractLintResult(
506
+ is_valid=True,
507
+ violations=[],
508
+ files_checked=0,
509
+ files_valid=0,
510
+ files_with_errors=0,
511
+ )
512
+
513
+ # Lint each file and aggregate results
514
+ all_violations: list[ModelContractViolation] = []
515
+ files_valid = 0
516
+ files_with_errors = 0
517
+
518
+ for contract_file in sorted(contract_files):
519
+ result = self.lint_file(contract_file)
520
+ all_violations.extend(result.violations)
521
+ files_valid += result.files_valid
522
+ files_with_errors += result.files_with_errors
523
+
524
+ has_errors = any(
525
+ v.severity == EnumContractViolationSeverity.ERROR for v in all_violations
526
+ )
527
+ if self.strict_mode:
528
+ has_errors = has_errors or any(
529
+ v.severity == EnumContractViolationSeverity.WARNING
530
+ for v in all_violations
531
+ )
532
+
533
+ return ModelContractLintResult(
534
+ is_valid=not has_errors,
535
+ violations=all_violations,
536
+ files_checked=len(contract_files),
537
+ files_valid=files_valid,
538
+ files_with_errors=files_with_errors,
539
+ )
540
+
541
+ def _validate_required_fields(
542
+ self,
543
+ file_path: str,
544
+ content: dict,
545
+ ) -> list[ModelContractViolation]:
546
+ """Validate that all required top-level fields are present."""
547
+ violations: list[ModelContractViolation] = []
548
+ required_fields = [
549
+ "name",
550
+ "node_type",
551
+ "contract_version",
552
+ "input_model",
553
+ "output_model",
554
+ ]
555
+
556
+ for field in required_fields:
557
+ if field not in content:
558
+ violations.append(
559
+ ModelContractViolation(
560
+ file_path=file_path,
561
+ field_path=field,
562
+ message=f"Required field '{field}' is missing",
563
+ severity=EnumContractViolationSeverity.ERROR,
564
+ suggestion=f"Add '{field}:' to your contract.yaml",
565
+ )
566
+ )
567
+
568
+ return violations
569
+
570
+ def _validate_node_type(
571
+ self,
572
+ file_path: str,
573
+ content: dict,
574
+ ) -> list[ModelContractViolation]:
575
+ """Validate node_type is one of the valid ONEX 4-node types."""
576
+ violations: list[ModelContractViolation] = []
577
+ node_type = content.get("node_type")
578
+
579
+ if node_type is None:
580
+ return violations # Already caught by required fields check
581
+
582
+ if not isinstance(node_type, str):
583
+ violations.append(
584
+ ModelContractViolation(
585
+ file_path=file_path,
586
+ field_path="node_type",
587
+ message=f"node_type must be a string, got {type(node_type).__name__}",
588
+ severity=EnumContractViolationSeverity.ERROR,
589
+ )
590
+ )
591
+ return violations
592
+
593
+ if node_type not in VALID_NODE_TYPES:
594
+ violations.append(
595
+ ModelContractViolation(
596
+ file_path=file_path,
597
+ field_path="node_type",
598
+ message=f"Invalid node_type '{node_type}'. Must be one of: {', '.join(sorted(VALID_NODE_TYPES))}",
599
+ severity=EnumContractViolationSeverity.ERROR,
600
+ suggestion=f"Change node_type to one of: {', '.join(sorted(VALID_NODE_TYPES))}",
601
+ )
602
+ )
603
+
604
+ return violations
605
+
606
+ def _validate_contract_version(
607
+ self,
608
+ file_path: str,
609
+ content: dict,
610
+ ) -> list[ModelContractViolation]:
611
+ """Validate contract_version has proper semver structure."""
612
+ violations: list[ModelContractViolation] = []
613
+ version = content.get("contract_version")
614
+
615
+ if version is None:
616
+ return violations # Already caught by required fields check
617
+
618
+ if not isinstance(version, dict):
619
+ violations.append(
620
+ ModelContractViolation(
621
+ file_path=file_path,
622
+ field_path="contract_version",
623
+ message="contract_version must be a dict with 'major', 'minor', 'patch' keys",
624
+ severity=EnumContractViolationSeverity.ERROR,
625
+ suggestion="Use format: contract_version:\\n major: 1\\n minor: 0\\n patch: 0",
626
+ )
627
+ )
628
+ return violations
629
+
630
+ for key in ["major", "minor", "patch"]:
631
+ if key not in version:
632
+ violations.append(
633
+ ModelContractViolation(
634
+ file_path=file_path,
635
+ field_path=f"contract_version.{key}",
636
+ message=f"contract_version missing required field '{key}'",
637
+ severity=EnumContractViolationSeverity.ERROR,
638
+ )
639
+ )
640
+ elif not isinstance(version[key], int):
641
+ violations.append(
642
+ ModelContractViolation(
643
+ file_path=file_path,
644
+ field_path=f"contract_version.{key}",
645
+ message=f"contract_version.{key} must be an integer, got {type(version[key]).__name__}",
646
+ severity=EnumContractViolationSeverity.ERROR,
647
+ )
648
+ )
649
+ elif version[key] < 0:
650
+ violations.append(
651
+ ModelContractViolation(
652
+ file_path=file_path,
653
+ field_path=f"contract_version.{key}",
654
+ message=f"contract_version.{key} must be non-negative, got {version[key]}",
655
+ severity=EnumContractViolationSeverity.ERROR,
656
+ )
657
+ )
658
+
659
+ return violations
660
+
661
+ def _validate_model_reference(
662
+ self,
663
+ file_path: str,
664
+ content: dict,
665
+ field_name: Literal["input_model", "output_model"],
666
+ ) -> list[ModelContractViolation]:
667
+ """Validate input_model or output_model reference structure and importability."""
668
+ violations: list[ModelContractViolation] = []
669
+ model_ref = content.get(field_name)
670
+
671
+ if model_ref is None:
672
+ return violations # Already caught by required fields check
673
+
674
+ if not isinstance(model_ref, dict):
675
+ violations.append(
676
+ ModelContractViolation(
677
+ file_path=file_path,
678
+ field_path=field_name,
679
+ message=f"{field_name} must be a dict with 'name' and 'module' keys",
680
+ severity=EnumContractViolationSeverity.ERROR,
681
+ suggestion=f"Use format: {field_name}:\\n name: ModelName\\n module: package.module",
682
+ )
683
+ )
684
+ return violations
685
+
686
+ # Check required sub-fields
687
+ for key in ["name", "module"]:
688
+ if key not in model_ref:
689
+ violations.append(
690
+ ModelContractViolation(
691
+ file_path=file_path,
692
+ field_path=f"{field_name}.{key}",
693
+ message=f"{field_name} missing required field '{key}'",
694
+ severity=EnumContractViolationSeverity.ERROR,
695
+ )
696
+ )
697
+ elif not isinstance(model_ref[key], str):
698
+ violations.append(
699
+ ModelContractViolation(
700
+ file_path=file_path,
701
+ field_path=f"{field_name}.{key}",
702
+ message=f"{field_name}.{key} must be a string",
703
+ severity=EnumContractViolationSeverity.ERROR,
704
+ )
705
+ )
706
+
707
+ # Validate model name follows ONEX naming convention (Model* prefix)
708
+ model_name = model_ref.get("name")
709
+ if isinstance(model_name, str) and not model_name.startswith("Model"):
710
+ violations.append(
711
+ ModelContractViolation(
712
+ file_path=file_path,
713
+ field_path=f"{field_name}.name",
714
+ message=f"{field_name}.name should start with 'Model' prefix per ONEX conventions",
715
+ severity=EnumContractViolationSeverity.WARNING,
716
+ suggestion=f"Rename to 'Model{model_name}'",
717
+ )
718
+ )
719
+
720
+ # Check if module is importable (optional, can be slow)
721
+ if self.check_imports:
722
+ violations.extend(
723
+ self._check_module_importable(file_path, field_name, model_ref)
724
+ )
725
+
726
+ return violations
727
+
728
+ def _check_module_importable(
729
+ self,
730
+ file_path: str,
731
+ field_name: str,
732
+ model_ref: dict,
733
+ ) -> list[ModelContractViolation]:
734
+ """Check if the model's module is importable."""
735
+ violations: list[ModelContractViolation] = []
736
+ module_name = model_ref.get("module")
737
+ class_name = model_ref.get("name")
738
+
739
+ if not isinstance(module_name, str) or not isinstance(class_name, str):
740
+ return violations # Type errors already reported
741
+
742
+ try:
743
+ module = importlib.import_module(module_name)
744
+ if not hasattr(module, class_name):
745
+ violations.append(
746
+ ModelContractViolation(
747
+ file_path=file_path,
748
+ field_path=f"{field_name}.name",
749
+ message=f"Class '{class_name}' not found in module '{module_name}'",
750
+ severity=EnumContractViolationSeverity.ERROR,
751
+ suggestion=f"Verify the class name exists in {module_name}",
752
+ )
753
+ )
754
+ except ImportError as e:
755
+ # Import failures are ERROR severity because they violate the type
756
+ # consistency guarantee documented in the module docstring: contracts
757
+ # must reference importable modules to ensure type safety.
758
+ # Use check_imports=False to skip this check in environments where
759
+ # dependencies may not be available.
760
+ violations.append(
761
+ ModelContractViolation(
762
+ file_path=file_path,
763
+ field_path=f"{field_name}.module",
764
+ message=f"Cannot import module '{module_name}': {e}",
765
+ severity=EnumContractViolationSeverity.ERROR,
766
+ suggestion="Verify module path and ensure it's installed, or use check_imports=False",
767
+ )
768
+ )
769
+
770
+ return violations
771
+
772
+ def _validate_name_convention(
773
+ self,
774
+ file_path: str,
775
+ content: dict,
776
+ ) -> list[ModelContractViolation]:
777
+ """Validate name follows snake_case convention."""
778
+ violations: list[ModelContractViolation] = []
779
+ name = content.get("name")
780
+
781
+ if name is None or not isinstance(name, str):
782
+ return violations # Already caught by required fields check
783
+
784
+ # Check snake_case pattern
785
+ if not re.match(r"^[a-z][a-z0-9_]*$", name):
786
+ violations.append(
787
+ ModelContractViolation(
788
+ file_path=file_path,
789
+ field_path="name",
790
+ message=f"Node name '{name}' should be snake_case (lowercase with underscores)",
791
+ severity=EnumContractViolationSeverity.WARNING,
792
+ suggestion="Use snake_case: e.g., 'node_registration_orchestrator'",
793
+ )
794
+ )
795
+
796
+ return violations
797
+
798
+ def _check_recommended_fields(
799
+ self,
800
+ file_path: str,
801
+ content: dict,
802
+ ) -> list[ModelContractViolation]:
803
+ """Check for recommended but optional fields."""
804
+ violations: list[ModelContractViolation] = []
805
+ recommended_fields = ["description", "node_version"]
806
+
807
+ for field in recommended_fields:
808
+ if field not in content:
809
+ violations.append(
810
+ ModelContractViolation(
811
+ file_path=file_path,
812
+ field_path=field,
813
+ message=f"Recommended field '{field}' is missing",
814
+ severity=EnumContractViolationSeverity.INFO,
815
+ suggestion=f"Consider adding '{field}:' for better documentation",
816
+ )
817
+ )
818
+
819
+ return violations
820
+
821
+
822
+ def lint_contract_file(
823
+ file_path: PathInput,
824
+ *,
825
+ check_imports: bool = True,
826
+ strict_mode: bool = False,
827
+ ) -> ModelContractLintResult:
828
+ """
829
+ Lint a single contract.yaml file.
830
+
831
+ Convenience function that creates a ContractLinter and lints the file.
832
+
833
+ Args:
834
+ file_path: Path to the contract.yaml file.
835
+ check_imports: Whether to verify model modules are importable.
836
+ strict_mode: If True, treat warnings as errors.
837
+
838
+ Returns:
839
+ ModelContractLintResult with violations found.
840
+ """
841
+ linter = ContractLinter(check_imports=check_imports, strict_mode=strict_mode)
842
+ return linter.lint_file(Path(file_path))
843
+
844
+
845
+ def lint_contracts_in_directory(
846
+ directory: PathInput,
847
+ *,
848
+ recursive: bool = True,
849
+ check_imports: bool = True,
850
+ strict_mode: bool = False,
851
+ ) -> ModelContractLintResult:
852
+ """
853
+ Lint all contract.yaml files in a directory.
854
+
855
+ Convenience function that creates a ContractLinter and lints the directory.
856
+
857
+ Args:
858
+ directory: Directory to search for contract.yaml files.
859
+ recursive: Whether to search subdirectories.
860
+ check_imports: Whether to verify model modules are importable.
861
+ strict_mode: If True, treat warnings as errors.
862
+
863
+ Returns:
864
+ ModelContractLintResult with aggregated violations.
865
+ """
866
+ linter = ContractLinter(check_imports=check_imports, strict_mode=strict_mode)
867
+ return linter.lint_directory(Path(directory), recursive=recursive)
868
+
869
+
870
+ def lint_contracts_ci(
871
+ directory: PathInput = "src/omnibase_infra/nodes/",
872
+ *,
873
+ check_imports: bool = True,
874
+ strict_mode: bool = False,
875
+ verbose: bool = False,
876
+ ) -> tuple[bool, ModelContractLintResult]:
877
+ """
878
+ Lint contracts with CI-friendly output.
879
+
880
+ Returns a tuple of (success, result) for easy integration with CI scripts.
881
+ Prints violations to stdout for CI visibility.
882
+
883
+ Args:
884
+ directory: Directory to lint.
885
+ check_imports: Whether to verify model modules are importable.
886
+ strict_mode: If True, treat warnings as errors.
887
+ verbose: If True, print all violations including INFO level.
888
+
889
+ Returns:
890
+ Tuple of (success: bool, result: ModelContractLintResult).
891
+ success is True if no errors found (and no warnings if strict_mode).
892
+ """
893
+ result = lint_contracts_in_directory(
894
+ directory,
895
+ check_imports=check_imports,
896
+ strict_mode=strict_mode,
897
+ )
898
+
899
+ # Print summary
900
+ print(str(result))
901
+
902
+ # Print violations
903
+ for violation in result.violations:
904
+ if verbose or violation.severity != EnumContractViolationSeverity.INFO:
905
+ print(f" {violation}")
906
+
907
+ return result.is_valid, result