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.
- omnibase_infra/__init__.py +101 -0
- omnibase_infra/cli/__init__.py +1 -0
- omnibase_infra/cli/commands.py +216 -0
- omnibase_infra/clients/__init__.py +0 -0
- omnibase_infra/contracts/handlers/filesystem/handler_contract.yaml +261 -0
- omnibase_infra/contracts/handlers/mcp/handler_contract.yaml +138 -0
- omnibase_infra/decorators/__init__.py +29 -0
- omnibase_infra/decorators/allow_any.py +109 -0
- omnibase_infra/dlq/__init__.py +90 -0
- omnibase_infra/dlq/constants_dlq.py +57 -0
- omnibase_infra/dlq/models/__init__.py +26 -0
- omnibase_infra/dlq/models/enum_replay_status.py +37 -0
- omnibase_infra/dlq/models/model_dlq_replay_record.py +135 -0
- omnibase_infra/dlq/models/model_dlq_tracking_config.py +184 -0
- omnibase_infra/dlq/service_dlq_tracking.py +611 -0
- omnibase_infra/enums/__init__.py +123 -0
- omnibase_infra/enums/enum_any_type_violation.py +104 -0
- omnibase_infra/enums/enum_backend_type.py +27 -0
- omnibase_infra/enums/enum_capture_outcome.py +42 -0
- omnibase_infra/enums/enum_capture_state.py +88 -0
- omnibase_infra/enums/enum_chain_violation_type.py +119 -0
- omnibase_infra/enums/enum_circuit_state.py +51 -0
- omnibase_infra/enums/enum_confirmation_event_type.py +27 -0
- omnibase_infra/enums/enum_contract_type.py +84 -0
- omnibase_infra/enums/enum_dedupe_strategy.py +46 -0
- omnibase_infra/enums/enum_dispatch_status.py +191 -0
- omnibase_infra/enums/enum_environment.py +46 -0
- omnibase_infra/enums/enum_execution_shape_violation.py +103 -0
- omnibase_infra/enums/enum_handler_error_type.py +101 -0
- omnibase_infra/enums/enum_handler_loader_error.py +178 -0
- omnibase_infra/enums/enum_handler_source_type.py +87 -0
- omnibase_infra/enums/enum_handler_type.py +77 -0
- omnibase_infra/enums/enum_handler_type_category.py +61 -0
- omnibase_infra/enums/enum_infra_transport_type.py +73 -0
- omnibase_infra/enums/enum_introspection_reason.py +154 -0
- omnibase_infra/enums/enum_message_category.py +213 -0
- omnibase_infra/enums/enum_node_archetype.py +74 -0
- omnibase_infra/enums/enum_node_output_type.py +185 -0
- omnibase_infra/enums/enum_non_retryable_error_category.py +224 -0
- omnibase_infra/enums/enum_policy_type.py +32 -0
- omnibase_infra/enums/enum_registration_state.py +261 -0
- omnibase_infra/enums/enum_registration_status.py +33 -0
- omnibase_infra/enums/enum_registry_response_status.py +28 -0
- omnibase_infra/enums/enum_response_status.py +26 -0
- omnibase_infra/enums/enum_retry_error_category.py +98 -0
- omnibase_infra/enums/enum_security_rule_id.py +103 -0
- omnibase_infra/enums/enum_selection_strategy.py +91 -0
- omnibase_infra/enums/enum_topic_standard.py +42 -0
- omnibase_infra/enums/enum_validation_severity.py +78 -0
- omnibase_infra/errors/__init__.py +156 -0
- omnibase_infra/errors/error_architecture_violation.py +152 -0
- omnibase_infra/errors/error_chain_propagation.py +188 -0
- omnibase_infra/errors/error_compute_registry.py +92 -0
- omnibase_infra/errors/error_consul.py +132 -0
- omnibase_infra/errors/error_container_wiring.py +243 -0
- omnibase_infra/errors/error_event_bus_registry.py +102 -0
- omnibase_infra/errors/error_infra.py +608 -0
- omnibase_infra/errors/error_message_type_registry.py +101 -0
- omnibase_infra/errors/error_policy_registry.py +112 -0
- omnibase_infra/errors/error_vault.py +123 -0
- omnibase_infra/event_bus/__init__.py +72 -0
- omnibase_infra/event_bus/configs/kafka_event_bus_config.yaml +86 -0
- omnibase_infra/event_bus/event_bus_inmemory.py +743 -0
- omnibase_infra/event_bus/event_bus_kafka.py +1658 -0
- omnibase_infra/event_bus/mixin_kafka_broadcast.py +184 -0
- omnibase_infra/event_bus/mixin_kafka_dlq.py +765 -0
- omnibase_infra/event_bus/models/__init__.py +29 -0
- omnibase_infra/event_bus/models/config/__init__.py +20 -0
- omnibase_infra/event_bus/models/config/model_kafka_event_bus_config.py +725 -0
- omnibase_infra/event_bus/models/model_dlq_event.py +206 -0
- omnibase_infra/event_bus/models/model_dlq_metrics.py +304 -0
- omnibase_infra/event_bus/models/model_event_headers.py +115 -0
- omnibase_infra/event_bus/models/model_event_message.py +60 -0
- omnibase_infra/event_bus/topic_constants.py +376 -0
- omnibase_infra/handlers/__init__.py +75 -0
- omnibase_infra/handlers/filesystem/__init__.py +48 -0
- omnibase_infra/handlers/filesystem/enum_file_system_operation.py +35 -0
- omnibase_infra/handlers/filesystem/model_file_system_request.py +298 -0
- omnibase_infra/handlers/filesystem/model_file_system_result.py +166 -0
- omnibase_infra/handlers/handler_consul.py +787 -0
- omnibase_infra/handlers/handler_db.py +1039 -0
- omnibase_infra/handlers/handler_filesystem.py +1478 -0
- omnibase_infra/handlers/handler_graph.py +1154 -0
- omnibase_infra/handlers/handler_http.py +920 -0
- omnibase_infra/handlers/handler_manifest_persistence.contract.yaml +184 -0
- omnibase_infra/handlers/handler_manifest_persistence.py +1539 -0
- omnibase_infra/handlers/handler_mcp.py +748 -0
- omnibase_infra/handlers/handler_qdrant.py +1076 -0
- omnibase_infra/handlers/handler_vault.py +422 -0
- omnibase_infra/handlers/mcp/__init__.py +19 -0
- omnibase_infra/handlers/mcp/adapter_onex_to_mcp.py +446 -0
- omnibase_infra/handlers/mcp/protocols.py +178 -0
- omnibase_infra/handlers/mcp/transport_streamable_http.py +352 -0
- omnibase_infra/handlers/mixins/__init__.py +42 -0
- omnibase_infra/handlers/mixins/mixin_consul_initialization.py +349 -0
- omnibase_infra/handlers/mixins/mixin_consul_kv.py +337 -0
- omnibase_infra/handlers/mixins/mixin_consul_service.py +277 -0
- omnibase_infra/handlers/mixins/mixin_vault_initialization.py +338 -0
- omnibase_infra/handlers/mixins/mixin_vault_retry.py +412 -0
- omnibase_infra/handlers/mixins/mixin_vault_secrets.py +450 -0
- omnibase_infra/handlers/mixins/mixin_vault_token.py +365 -0
- omnibase_infra/handlers/models/__init__.py +286 -0
- omnibase_infra/handlers/models/consul/__init__.py +81 -0
- omnibase_infra/handlers/models/consul/enum_consul_operation_type.py +57 -0
- omnibase_infra/handlers/models/consul/model_consul_deregister_payload.py +51 -0
- omnibase_infra/handlers/models/consul/model_consul_handler_config.py +153 -0
- omnibase_infra/handlers/models/consul/model_consul_handler_payload.py +89 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_get_found_payload.py +55 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_get_not_found_payload.py +49 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_get_recurse_payload.py +50 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_item.py +33 -0
- omnibase_infra/handlers/models/consul/model_consul_kv_put_payload.py +41 -0
- omnibase_infra/handlers/models/consul/model_consul_register_payload.py +53 -0
- omnibase_infra/handlers/models/consul/model_consul_retry_config.py +66 -0
- omnibase_infra/handlers/models/consul/model_payload_consul.py +66 -0
- omnibase_infra/handlers/models/consul/registry_payload_consul.py +214 -0
- omnibase_infra/handlers/models/graph/__init__.py +35 -0
- omnibase_infra/handlers/models/graph/enum_graph_operation_type.py +20 -0
- omnibase_infra/handlers/models/graph/model_graph_execute_payload.py +38 -0
- omnibase_infra/handlers/models/graph/model_graph_handler_config.py +54 -0
- omnibase_infra/handlers/models/graph/model_graph_handler_payload.py +44 -0
- omnibase_infra/handlers/models/graph/model_graph_query_payload.py +40 -0
- omnibase_infra/handlers/models/graph/model_graph_record.py +22 -0
- omnibase_infra/handlers/models/http/__init__.py +50 -0
- omnibase_infra/handlers/models/http/enum_http_operation_type.py +29 -0
- omnibase_infra/handlers/models/http/model_http_body_content.py +45 -0
- omnibase_infra/handlers/models/http/model_http_get_payload.py +88 -0
- omnibase_infra/handlers/models/http/model_http_handler_payload.py +90 -0
- omnibase_infra/handlers/models/http/model_http_post_payload.py +88 -0
- omnibase_infra/handlers/models/http/model_payload_http.py +66 -0
- omnibase_infra/handlers/models/http/registry_payload_http.py +212 -0
- omnibase_infra/handlers/models/mcp/__init__.py +23 -0
- omnibase_infra/handlers/models/mcp/enum_mcp_operation_type.py +24 -0
- omnibase_infra/handlers/models/mcp/model_mcp_handler_config.py +40 -0
- omnibase_infra/handlers/models/mcp/model_mcp_tool_call.py +32 -0
- omnibase_infra/handlers/models/mcp/model_mcp_tool_result.py +45 -0
- omnibase_infra/handlers/models/model_consul_handler_response.py +96 -0
- omnibase_infra/handlers/models/model_db_describe_response.py +83 -0
- omnibase_infra/handlers/models/model_db_query_payload.py +95 -0
- omnibase_infra/handlers/models/model_db_query_response.py +60 -0
- omnibase_infra/handlers/models/model_filesystem_config.py +98 -0
- omnibase_infra/handlers/models/model_filesystem_delete_payload.py +54 -0
- omnibase_infra/handlers/models/model_filesystem_delete_result.py +77 -0
- omnibase_infra/handlers/models/model_filesystem_directory_entry.py +75 -0
- omnibase_infra/handlers/models/model_filesystem_ensure_directory_payload.py +54 -0
- omnibase_infra/handlers/models/model_filesystem_ensure_directory_result.py +60 -0
- omnibase_infra/handlers/models/model_filesystem_list_directory_payload.py +60 -0
- omnibase_infra/handlers/models/model_filesystem_list_directory_result.py +68 -0
- omnibase_infra/handlers/models/model_filesystem_read_payload.py +62 -0
- omnibase_infra/handlers/models/model_filesystem_read_result.py +61 -0
- omnibase_infra/handlers/models/model_filesystem_write_payload.py +70 -0
- omnibase_infra/handlers/models/model_filesystem_write_result.py +55 -0
- omnibase_infra/handlers/models/model_graph_handler_response.py +98 -0
- omnibase_infra/handlers/models/model_handler_response.py +103 -0
- omnibase_infra/handlers/models/model_http_handler_response.py +101 -0
- omnibase_infra/handlers/models/model_manifest_metadata.py +75 -0
- omnibase_infra/handlers/models/model_manifest_persistence_config.py +62 -0
- omnibase_infra/handlers/models/model_manifest_query_payload.py +90 -0
- omnibase_infra/handlers/models/model_manifest_query_result.py +97 -0
- omnibase_infra/handlers/models/model_manifest_retrieve_payload.py +44 -0
- omnibase_infra/handlers/models/model_manifest_retrieve_result.py +98 -0
- omnibase_infra/handlers/models/model_manifest_store_payload.py +47 -0
- omnibase_infra/handlers/models/model_manifest_store_result.py +67 -0
- omnibase_infra/handlers/models/model_operation_context.py +187 -0
- omnibase_infra/handlers/models/model_qdrant_handler_response.py +98 -0
- omnibase_infra/handlers/models/model_retry_state.py +162 -0
- omnibase_infra/handlers/models/model_vault_handler_response.py +98 -0
- omnibase_infra/handlers/models/qdrant/__init__.py +44 -0
- omnibase_infra/handlers/models/qdrant/enum_qdrant_operation_type.py +26 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_collection_payload.py +42 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_delete_payload.py +36 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_handler_config.py +42 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_handler_payload.py +54 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_search_payload.py +42 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_search_result.py +30 -0
- omnibase_infra/handlers/models/qdrant/model_qdrant_upsert_payload.py +36 -0
- omnibase_infra/handlers/models/vault/__init__.py +69 -0
- omnibase_infra/handlers/models/vault/enum_vault_operation_type.py +35 -0
- omnibase_infra/handlers/models/vault/model_payload_vault.py +66 -0
- omnibase_infra/handlers/models/vault/model_vault_delete_payload.py +57 -0
- omnibase_infra/handlers/models/vault/model_vault_handler_config.py +148 -0
- omnibase_infra/handlers/models/vault/model_vault_handler_payload.py +101 -0
- omnibase_infra/handlers/models/vault/model_vault_list_payload.py +58 -0
- omnibase_infra/handlers/models/vault/model_vault_renew_token_payload.py +67 -0
- omnibase_infra/handlers/models/vault/model_vault_retry_config.py +66 -0
- omnibase_infra/handlers/models/vault/model_vault_secret_payload.py +106 -0
- omnibase_infra/handlers/models/vault/model_vault_write_payload.py +66 -0
- omnibase_infra/handlers/models/vault/registry_payload_vault.py +213 -0
- omnibase_infra/handlers/registration_storage/__init__.py +43 -0
- omnibase_infra/handlers/registration_storage/handler_registration_storage_mock.py +392 -0
- omnibase_infra/handlers/registration_storage/handler_registration_storage_postgres.py +915 -0
- omnibase_infra/handlers/registration_storage/models/__init__.py +23 -0
- omnibase_infra/handlers/registration_storage/models/model_delete_registration_request.py +58 -0
- omnibase_infra/handlers/registration_storage/models/model_update_registration_request.py +73 -0
- omnibase_infra/handlers/registration_storage/protocol_registration_persistence.py +191 -0
- omnibase_infra/handlers/service_discovery/__init__.py +43 -0
- omnibase_infra/handlers/service_discovery/handler_service_discovery_consul.py +747 -0
- omnibase_infra/handlers/service_discovery/handler_service_discovery_mock.py +258 -0
- omnibase_infra/handlers/service_discovery/models/__init__.py +22 -0
- omnibase_infra/handlers/service_discovery/models/model_discovery_result.py +64 -0
- omnibase_infra/handlers/service_discovery/models/model_registration_result.py +138 -0
- omnibase_infra/handlers/service_discovery/models/model_service_info.py +99 -0
- omnibase_infra/handlers/service_discovery/protocol_discovery_operations.py +170 -0
- omnibase_infra/idempotency/__init__.py +94 -0
- omnibase_infra/idempotency/models/__init__.py +43 -0
- omnibase_infra/idempotency/models/model_idempotency_check_result.py +85 -0
- omnibase_infra/idempotency/models/model_idempotency_guard_config.py +130 -0
- omnibase_infra/idempotency/models/model_idempotency_record.py +86 -0
- omnibase_infra/idempotency/models/model_idempotency_store_health_check_result.py +81 -0
- omnibase_infra/idempotency/models/model_idempotency_store_metrics.py +140 -0
- omnibase_infra/idempotency/models/model_postgres_idempotency_store_config.py +299 -0
- omnibase_infra/idempotency/protocol_idempotency_store.py +184 -0
- omnibase_infra/idempotency/store_inmemory.py +265 -0
- omnibase_infra/idempotency/store_postgres.py +923 -0
- omnibase_infra/infrastructure/__init__.py +0 -0
- omnibase_infra/mixins/__init__.py +71 -0
- omnibase_infra/mixins/mixin_async_circuit_breaker.py +655 -0
- omnibase_infra/mixins/mixin_dict_like_accessors.py +146 -0
- omnibase_infra/mixins/mixin_envelope_extraction.py +119 -0
- omnibase_infra/mixins/mixin_node_introspection.py +2465 -0
- omnibase_infra/mixins/mixin_retry_execution.py +386 -0
- omnibase_infra/mixins/protocol_circuit_breaker_aware.py +133 -0
- omnibase_infra/models/__init__.py +136 -0
- omnibase_infra/models/corpus/__init__.py +17 -0
- omnibase_infra/models/corpus/model_capture_config.py +133 -0
- omnibase_infra/models/corpus/model_capture_result.py +86 -0
- omnibase_infra/models/discovery/__init__.py +42 -0
- omnibase_infra/models/discovery/model_dependency_spec.py +319 -0
- omnibase_infra/models/discovery/model_discovered_capabilities.py +50 -0
- omnibase_infra/models/discovery/model_introspection_config.py +311 -0
- omnibase_infra/models/discovery/model_introspection_performance_metrics.py +169 -0
- omnibase_infra/models/discovery/model_introspection_task_config.py +116 -0
- omnibase_infra/models/dispatch/__init__.py +147 -0
- omnibase_infra/models/dispatch/model_dispatch_context.py +439 -0
- omnibase_infra/models/dispatch/model_dispatch_error.py +336 -0
- omnibase_infra/models/dispatch/model_dispatch_log_context.py +400 -0
- omnibase_infra/models/dispatch/model_dispatch_metadata.py +228 -0
- omnibase_infra/models/dispatch/model_dispatch_metrics.py +496 -0
- omnibase_infra/models/dispatch/model_dispatch_outcome.py +317 -0
- omnibase_infra/models/dispatch/model_dispatch_outputs.py +231 -0
- omnibase_infra/models/dispatch/model_dispatch_result.py +436 -0
- omnibase_infra/models/dispatch/model_dispatch_route.py +279 -0
- omnibase_infra/models/dispatch/model_dispatcher_metrics.py +275 -0
- omnibase_infra/models/dispatch/model_dispatcher_registration.py +352 -0
- omnibase_infra/models/dispatch/model_parsed_topic.py +135 -0
- omnibase_infra/models/dispatch/model_topic_parser.py +725 -0
- omnibase_infra/models/dispatch/model_tracing_context.py +285 -0
- omnibase_infra/models/errors/__init__.py +45 -0
- omnibase_infra/models/errors/model_handler_validation_error.py +594 -0
- omnibase_infra/models/errors/model_infra_error_context.py +99 -0
- omnibase_infra/models/errors/model_message_type_registry_error_context.py +71 -0
- omnibase_infra/models/errors/model_timeout_error_context.py +110 -0
- omnibase_infra/models/handlers/__init__.py +37 -0
- omnibase_infra/models/handlers/model_contract_discovery_result.py +80 -0
- omnibase_infra/models/handlers/model_handler_descriptor.py +185 -0
- omnibase_infra/models/handlers/model_handler_identifier.py +215 -0
- omnibase_infra/models/health/__init__.py +9 -0
- omnibase_infra/models/health/model_health_check_result.py +40 -0
- omnibase_infra/models/lifecycle/__init__.py +39 -0
- omnibase_infra/models/logging/__init__.py +51 -0
- omnibase_infra/models/logging/model_log_context.py +756 -0
- omnibase_infra/models/model_retry_error_classification.py +78 -0
- omnibase_infra/models/projection/__init__.py +43 -0
- omnibase_infra/models/projection/model_capability_fields.py +112 -0
- omnibase_infra/models/projection/model_registration_projection.py +434 -0
- omnibase_infra/models/projection/model_registration_snapshot.py +322 -0
- omnibase_infra/models/projection/model_sequence_info.py +182 -0
- omnibase_infra/models/projection/model_snapshot_topic_config.py +590 -0
- omnibase_infra/models/projectors/__init__.py +41 -0
- omnibase_infra/models/projectors/model_projector_column.py +289 -0
- omnibase_infra/models/projectors/model_projector_discovery_result.py +65 -0
- omnibase_infra/models/projectors/model_projector_index.py +270 -0
- omnibase_infra/models/projectors/model_projector_schema.py +415 -0
- omnibase_infra/models/projectors/model_projector_validation_error.py +63 -0
- omnibase_infra/models/projectors/util_sql_identifiers.py +115 -0
- omnibase_infra/models/registration/__init__.py +59 -0
- omnibase_infra/models/registration/commands/__init__.py +15 -0
- omnibase_infra/models/registration/commands/model_node_registration_acked.py +108 -0
- omnibase_infra/models/registration/events/__init__.py +56 -0
- omnibase_infra/models/registration/events/model_node_became_active.py +103 -0
- omnibase_infra/models/registration/events/model_node_liveness_expired.py +103 -0
- omnibase_infra/models/registration/events/model_node_registration_accepted.py +98 -0
- omnibase_infra/models/registration/events/model_node_registration_ack_received.py +98 -0
- omnibase_infra/models/registration/events/model_node_registration_ack_timed_out.py +112 -0
- omnibase_infra/models/registration/events/model_node_registration_initiated.py +107 -0
- omnibase_infra/models/registration/events/model_node_registration_rejected.py +104 -0
- omnibase_infra/models/registration/model_introspection_metrics.py +253 -0
- omnibase_infra/models/registration/model_node_capabilities.py +179 -0
- omnibase_infra/models/registration/model_node_heartbeat_event.py +126 -0
- omnibase_infra/models/registration/model_node_introspection_event.py +175 -0
- omnibase_infra/models/registration/model_node_metadata.py +79 -0
- omnibase_infra/models/registration/model_node_registration.py +162 -0
- omnibase_infra/models/registration/model_node_registration_record.py +162 -0
- omnibase_infra/models/registry/__init__.py +29 -0
- omnibase_infra/models/registry/model_domain_constraint.py +202 -0
- omnibase_infra/models/registry/model_message_type_entry.py +271 -0
- omnibase_infra/models/resilience/__init__.py +9 -0
- omnibase_infra/models/resilience/model_circuit_breaker_config.py +227 -0
- omnibase_infra/models/routing/__init__.py +25 -0
- omnibase_infra/models/routing/model_routing_entry.py +52 -0
- omnibase_infra/models/routing/model_routing_subcontract.py +70 -0
- omnibase_infra/models/runtime/__init__.py +40 -0
- omnibase_infra/models/runtime/model_contract_security_config.py +41 -0
- omnibase_infra/models/runtime/model_discovery_error.py +81 -0
- omnibase_infra/models/runtime/model_discovery_result.py +162 -0
- omnibase_infra/models/runtime/model_discovery_warning.py +74 -0
- omnibase_infra/models/runtime/model_failed_plugin_load.py +63 -0
- omnibase_infra/models/runtime/model_handler_contract.py +280 -0
- omnibase_infra/models/runtime/model_loaded_handler.py +120 -0
- omnibase_infra/models/runtime/model_plugin_load_context.py +93 -0
- omnibase_infra/models/runtime/model_plugin_load_summary.py +124 -0
- omnibase_infra/models/security/__init__.py +50 -0
- omnibase_infra/models/security/classification_levels.py +99 -0
- omnibase_infra/models/security/model_environment_policy.py +145 -0
- omnibase_infra/models/security/model_handler_security_policy.py +107 -0
- omnibase_infra/models/security/model_security_error.py +81 -0
- omnibase_infra/models/security/model_security_validation_result.py +328 -0
- omnibase_infra/models/security/model_security_warning.py +67 -0
- omnibase_infra/models/snapshot/__init__.py +27 -0
- omnibase_infra/models/snapshot/model_field_change.py +65 -0
- omnibase_infra/models/snapshot/model_snapshot.py +270 -0
- omnibase_infra/models/snapshot/model_snapshot_diff.py +203 -0
- omnibase_infra/models/snapshot/model_subject_ref.py +81 -0
- omnibase_infra/models/types/__init__.py +71 -0
- omnibase_infra/models/validation/__init__.py +89 -0
- omnibase_infra/models/validation/model_any_type_validation_result.py +118 -0
- omnibase_infra/models/validation/model_any_type_violation.py +141 -0
- omnibase_infra/models/validation/model_category_match_result.py +345 -0
- omnibase_infra/models/validation/model_chain_violation.py +166 -0
- omnibase_infra/models/validation/model_coverage_metrics.py +316 -0
- omnibase_infra/models/validation/model_execution_shape_rule.py +159 -0
- omnibase_infra/models/validation/model_execution_shape_validation.py +208 -0
- omnibase_infra/models/validation/model_execution_shape_validation_result.py +294 -0
- omnibase_infra/models/validation/model_execution_shape_violation.py +122 -0
- omnibase_infra/models/validation/model_localhandler_validation_result.py +139 -0
- omnibase_infra/models/validation/model_localhandler_violation.py +100 -0
- omnibase_infra/models/validation/model_output_validation_params.py +74 -0
- omnibase_infra/models/validation/model_validate_and_raise_params.py +84 -0
- omnibase_infra/models/validation/model_validation_error_params.py +84 -0
- omnibase_infra/models/validation/model_validation_outcome.py +287 -0
- omnibase_infra/nodes/__init__.py +48 -0
- omnibase_infra/nodes/architecture_validator/__init__.py +79 -0
- omnibase_infra/nodes/architecture_validator/contract.yaml +252 -0
- omnibase_infra/nodes/architecture_validator/contract_architecture_validator.yaml +208 -0
- omnibase_infra/nodes/architecture_validator/mixins/__init__.py +16 -0
- omnibase_infra/nodes/architecture_validator/mixins/mixin_file_path_rule.py +92 -0
- omnibase_infra/nodes/architecture_validator/models/__init__.py +36 -0
- omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_request.py +56 -0
- omnibase_infra/nodes/architecture_validator/models/model_architecture_validation_result.py +311 -0
- omnibase_infra/nodes/architecture_validator/models/model_architecture_violation.py +163 -0
- omnibase_infra/nodes/architecture_validator/models/model_rule_check_result.py +265 -0
- omnibase_infra/nodes/architecture_validator/models/model_validation_request.py +105 -0
- omnibase_infra/nodes/architecture_validator/models/model_validation_result.py +314 -0
- omnibase_infra/nodes/architecture_validator/node.py +262 -0
- omnibase_infra/nodes/architecture_validator/node_architecture_validator.py +383 -0
- omnibase_infra/nodes/architecture_validator/protocols/__init__.py +9 -0
- omnibase_infra/nodes/architecture_validator/protocols/protocol_architecture_rule.py +225 -0
- omnibase_infra/nodes/architecture_validator/registry/__init__.py +28 -0
- omnibase_infra/nodes/architecture_validator/registry/registry_infra_architecture_validator.py +99 -0
- omnibase_infra/nodes/architecture_validator/validators/__init__.py +104 -0
- omnibase_infra/nodes/architecture_validator/validators/validator_no_direct_dispatch.py +422 -0
- omnibase_infra/nodes/architecture_validator/validators/validator_no_handler_publishing.py +481 -0
- omnibase_infra/nodes/architecture_validator/validators/validator_no_orchestrator_fsm.py +491 -0
- omnibase_infra/nodes/effects/README.md +358 -0
- omnibase_infra/nodes/effects/__init__.py +26 -0
- omnibase_infra/nodes/effects/contract.yaml +172 -0
- omnibase_infra/nodes/effects/models/__init__.py +32 -0
- omnibase_infra/nodes/effects/models/model_backend_result.py +190 -0
- omnibase_infra/nodes/effects/models/model_effect_idempotency_config.py +92 -0
- omnibase_infra/nodes/effects/models/model_registry_request.py +132 -0
- omnibase_infra/nodes/effects/models/model_registry_response.py +263 -0
- omnibase_infra/nodes/effects/protocol_consul_client.py +89 -0
- omnibase_infra/nodes/effects/protocol_effect_idempotency_store.py +143 -0
- omnibase_infra/nodes/effects/protocol_postgres_adapter.py +96 -0
- omnibase_infra/nodes/effects/registry_effect.py +525 -0
- omnibase_infra/nodes/effects/store_effect_idempotency_inmemory.py +425 -0
- omnibase_infra/nodes/node_registration_orchestrator/README.md +542 -0
- omnibase_infra/nodes/node_registration_orchestrator/__init__.py +120 -0
- omnibase_infra/nodes/node_registration_orchestrator/contract.yaml +475 -0
- omnibase_infra/nodes/node_registration_orchestrator/dispatchers/__init__.py +53 -0
- omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_introspected.py +376 -0
- omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_node_registration_acked.py +376 -0
- omnibase_infra/nodes/node_registration_orchestrator/dispatchers/dispatcher_runtime_tick.py +373 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/__init__.py +62 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_heartbeat.py +376 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_introspected.py +609 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_node_registration_acked.py +458 -0
- omnibase_infra/nodes/node_registration_orchestrator/handlers/handler_runtime_tick.py +364 -0
- omnibase_infra/nodes/node_registration_orchestrator/introspection_event_router.py +544 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/__init__.py +75 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_intent_payload.py +194 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_consul_registration_intent.py +67 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_intent_execution_result.py +50 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_node_liveness_expired.py +107 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_config.py +67 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_input.py +41 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_orchestrator_output.py +166 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_intent_payload.py +235 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_postgres_upsert_intent.py +68 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_execution_result.py +384 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_reducer_state.py +60 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_registration_intent.py +177 -0
- omnibase_infra/nodes/node_registration_orchestrator/models/model_registry_intent.py +247 -0
- omnibase_infra/nodes/node_registration_orchestrator/node.py +195 -0
- omnibase_infra/nodes/node_registration_orchestrator/plugin.py +909 -0
- omnibase_infra/nodes/node_registration_orchestrator/protocols.py +439 -0
- omnibase_infra/nodes/node_registration_orchestrator/registry/__init__.py +41 -0
- omnibase_infra/nodes/node_registration_orchestrator/registry/registry_infra_node_registration_orchestrator.py +525 -0
- omnibase_infra/nodes/node_registration_orchestrator/timeout_coordinator.py +392 -0
- omnibase_infra/nodes/node_registration_orchestrator/wiring.py +742 -0
- omnibase_infra/nodes/node_registration_reducer/__init__.py +15 -0
- omnibase_infra/nodes/node_registration_reducer/contract.yaml +301 -0
- omnibase_infra/nodes/node_registration_reducer/models/__init__.py +38 -0
- omnibase_infra/nodes/node_registration_reducer/models/model_validation_result.py +113 -0
- omnibase_infra/nodes/node_registration_reducer/node.py +139 -0
- omnibase_infra/nodes/node_registration_reducer/registry/__init__.py +9 -0
- omnibase_infra/nodes/node_registration_reducer/registry/registry_infra_node_registration_reducer.py +79 -0
- omnibase_infra/nodes/node_registration_storage_effect/__init__.py +41 -0
- omnibase_infra/nodes/node_registration_storage_effect/contract.yaml +225 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/__init__.py +44 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_delete_result.py +132 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_record.py +199 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_registration_update.py +155 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_details.py +123 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_health_check_result.py +117 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_query.py +100 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_storage_result.py +136 -0
- omnibase_infra/nodes/node_registration_storage_effect/models/model_upsert_result.py +127 -0
- omnibase_infra/nodes/node_registration_storage_effect/node.py +109 -0
- omnibase_infra/nodes/node_registration_storage_effect/protocols/__init__.py +22 -0
- omnibase_infra/nodes/node_registration_storage_effect/protocols/protocol_registration_persistence.py +333 -0
- omnibase_infra/nodes/node_registration_storage_effect/registry/__init__.py +23 -0
- omnibase_infra/nodes/node_registration_storage_effect/registry/registry_infra_registration_storage.py +194 -0
- omnibase_infra/nodes/node_registry_effect/__init__.py +85 -0
- omnibase_infra/nodes/node_registry_effect/contract.yaml +682 -0
- omnibase_infra/nodes/node_registry_effect/handlers/__init__.py +70 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_deregister.py +211 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_consul_register.py +212 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_partial_retry.py +416 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_deactivate.py +215 -0
- omnibase_infra/nodes/node_registry_effect/handlers/handler_postgres_upsert.py +208 -0
- omnibase_infra/nodes/node_registry_effect/models/__init__.py +43 -0
- omnibase_infra/nodes/node_registry_effect/models/model_partial_retry_request.py +92 -0
- omnibase_infra/nodes/node_registry_effect/node.py +165 -0
- omnibase_infra/nodes/node_registry_effect/registry/__init__.py +27 -0
- omnibase_infra/nodes/node_registry_effect/registry/registry_infra_registry_effect.py +196 -0
- omnibase_infra/nodes/node_service_discovery_effect/__init__.py +111 -0
- omnibase_infra/nodes/node_service_discovery_effect/contract.yaml +246 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/__init__.py +67 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/enum_health_status.py +72 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/enum_service_discovery_operation.py +58 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_query.py +99 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_discovery_result.py +98 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_health_check_config.py +121 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_query_metadata.py +63 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_registration_result.py +130 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_details.py +111 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_service_discovery_health_check_result.py +119 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_service_info.py +106 -0
- omnibase_infra/nodes/node_service_discovery_effect/models/model_service_registration.py +121 -0
- omnibase_infra/nodes/node_service_discovery_effect/node.py +111 -0
- omnibase_infra/nodes/node_service_discovery_effect/protocols/__init__.py +14 -0
- omnibase_infra/nodes/node_service_discovery_effect/protocols/protocol_discovery_operations.py +279 -0
- omnibase_infra/nodes/node_service_discovery_effect/registry/__init__.py +13 -0
- omnibase_infra/nodes/node_service_discovery_effect/registry/registry_infra_service_discovery.py +214 -0
- omnibase_infra/nodes/reducers/__init__.py +30 -0
- omnibase_infra/nodes/reducers/models/__init__.py +32 -0
- omnibase_infra/nodes/reducers/models/model_payload_consul_register.py +76 -0
- omnibase_infra/nodes/reducers/models/model_payload_postgres_upsert_registration.py +60 -0
- omnibase_infra/nodes/reducers/models/model_registration_confirmation.py +166 -0
- omnibase_infra/nodes/reducers/models/model_registration_state.py +433 -0
- omnibase_infra/nodes/reducers/registration_reducer.py +1137 -0
- omnibase_infra/observability/__init__.py +143 -0
- omnibase_infra/observability/constants_metrics.py +91 -0
- omnibase_infra/observability/factory_observability_sink.py +525 -0
- omnibase_infra/observability/handlers/__init__.py +118 -0
- omnibase_infra/observability/handlers/handler_logging_structured.py +967 -0
- omnibase_infra/observability/handlers/handler_metrics_prometheus.py +1120 -0
- omnibase_infra/observability/handlers/model_logging_handler_config.py +71 -0
- omnibase_infra/observability/handlers/model_logging_handler_response.py +77 -0
- omnibase_infra/observability/handlers/model_metrics_handler_config.py +172 -0
- omnibase_infra/observability/handlers/model_metrics_handler_payload.py +135 -0
- omnibase_infra/observability/handlers/model_metrics_handler_response.py +101 -0
- omnibase_infra/observability/hooks/__init__.py +74 -0
- omnibase_infra/observability/hooks/hook_observability.py +1223 -0
- omnibase_infra/observability/models/__init__.py +30 -0
- omnibase_infra/observability/models/enum_required_log_context_key.py +77 -0
- omnibase_infra/observability/models/model_buffered_log_entry.py +117 -0
- omnibase_infra/observability/models/model_logging_sink_config.py +73 -0
- omnibase_infra/observability/models/model_metrics_sink_config.py +156 -0
- omnibase_infra/observability/sinks/__init__.py +69 -0
- omnibase_infra/observability/sinks/sink_logging_structured.py +809 -0
- omnibase_infra/observability/sinks/sink_metrics_prometheus.py +710 -0
- omnibase_infra/plugins/__init__.py +27 -0
- omnibase_infra/plugins/examples/__init__.py +28 -0
- omnibase_infra/plugins/examples/plugin_json_normalizer.py +271 -0
- omnibase_infra/plugins/examples/plugin_json_normalizer_error_handling.py +210 -0
- omnibase_infra/plugins/models/__init__.py +21 -0
- omnibase_infra/plugins/models/model_plugin_context.py +76 -0
- omnibase_infra/plugins/models/model_plugin_input_data.py +58 -0
- omnibase_infra/plugins/models/model_plugin_output_data.py +62 -0
- omnibase_infra/plugins/plugin_compute_base.py +435 -0
- omnibase_infra/projectors/__init__.py +30 -0
- omnibase_infra/projectors/contracts/__init__.py +63 -0
- omnibase_infra/projectors/contracts/registration_projector.yaml +370 -0
- omnibase_infra/projectors/projection_reader_registration.py +1559 -0
- omnibase_infra/projectors/snapshot_publisher_registration.py +1329 -0
- omnibase_infra/protocols/__init__.py +99 -0
- omnibase_infra/protocols/protocol_capability_projection.py +253 -0
- omnibase_infra/protocols/protocol_capability_query.py +251 -0
- omnibase_infra/protocols/protocol_event_bus_like.py +127 -0
- omnibase_infra/protocols/protocol_event_projector.py +96 -0
- omnibase_infra/protocols/protocol_idempotency_store.py +142 -0
- omnibase_infra/protocols/protocol_message_dispatcher.py +247 -0
- omnibase_infra/protocols/protocol_message_type_registry.py +306 -0
- omnibase_infra/protocols/protocol_plugin_compute.py +368 -0
- omnibase_infra/protocols/protocol_projector_schema_validator.py +82 -0
- omnibase_infra/protocols/protocol_registry_metrics.py +215 -0
- omnibase_infra/protocols/protocol_snapshot_publisher.py +396 -0
- omnibase_infra/protocols/protocol_snapshot_store.py +567 -0
- omnibase_infra/runtime/__init__.py +296 -0
- omnibase_infra/runtime/binding_config_resolver.py +2706 -0
- omnibase_infra/runtime/chain_aware_dispatch.py +467 -0
- omnibase_infra/runtime/contract_handler_discovery.py +582 -0
- omnibase_infra/runtime/contract_loaders/__init__.py +42 -0
- omnibase_infra/runtime/contract_loaders/handler_routing_loader.py +464 -0
- omnibase_infra/runtime/dispatch_context_enforcer.py +427 -0
- omnibase_infra/runtime/enums/__init__.py +18 -0
- omnibase_infra/runtime/enums/enum_config_ref_scheme.py +33 -0
- omnibase_infra/runtime/enums/enum_scheduler_status.py +170 -0
- omnibase_infra/runtime/envelope_validator.py +179 -0
- omnibase_infra/runtime/handler_contract_source.py +669 -0
- omnibase_infra/runtime/handler_plugin_loader.py +2029 -0
- omnibase_infra/runtime/handler_registry.py +321 -0
- omnibase_infra/runtime/invocation_security_enforcer.py +427 -0
- omnibase_infra/runtime/kernel.py +40 -0
- omnibase_infra/runtime/mixin_policy_validation.py +522 -0
- omnibase_infra/runtime/mixin_semver_cache.py +378 -0
- omnibase_infra/runtime/mixins/__init__.py +17 -0
- omnibase_infra/runtime/mixins/mixin_projector_sql_operations.py +757 -0
- omnibase_infra/runtime/models/__init__.py +192 -0
- omnibase_infra/runtime/models/model_batch_lifecycle_result.py +217 -0
- omnibase_infra/runtime/models/model_binding_config.py +168 -0
- omnibase_infra/runtime/models/model_binding_config_cache_stats.py +135 -0
- omnibase_infra/runtime/models/model_binding_config_resolver_config.py +329 -0
- omnibase_infra/runtime/models/model_cached_secret.py +138 -0
- omnibase_infra/runtime/models/model_compute_key.py +138 -0
- omnibase_infra/runtime/models/model_compute_registration.py +97 -0
- omnibase_infra/runtime/models/model_config_cache_entry.py +61 -0
- omnibase_infra/runtime/models/model_config_ref.py +331 -0
- omnibase_infra/runtime/models/model_config_ref_parse_result.py +125 -0
- omnibase_infra/runtime/models/model_domain_plugin_config.py +92 -0
- omnibase_infra/runtime/models/model_domain_plugin_result.py +270 -0
- omnibase_infra/runtime/models/model_duplicate_response.py +54 -0
- omnibase_infra/runtime/models/model_enabled_protocols_config.py +61 -0
- omnibase_infra/runtime/models/model_event_bus_config.py +54 -0
- omnibase_infra/runtime/models/model_failed_component.py +55 -0
- omnibase_infra/runtime/models/model_health_check_response.py +168 -0
- omnibase_infra/runtime/models/model_health_check_result.py +228 -0
- omnibase_infra/runtime/models/model_lifecycle_result.py +245 -0
- omnibase_infra/runtime/models/model_logging_config.py +42 -0
- omnibase_infra/runtime/models/model_optional_correlation_id.py +167 -0
- omnibase_infra/runtime/models/model_optional_string.py +94 -0
- omnibase_infra/runtime/models/model_optional_uuid.py +110 -0
- omnibase_infra/runtime/models/model_policy_context.py +100 -0
- omnibase_infra/runtime/models/model_policy_key.py +138 -0
- omnibase_infra/runtime/models/model_policy_registration.py +139 -0
- omnibase_infra/runtime/models/model_policy_result.py +103 -0
- omnibase_infra/runtime/models/model_policy_type_filter.py +157 -0
- omnibase_infra/runtime/models/model_projector_plugin_loader_config.py +47 -0
- omnibase_infra/runtime/models/model_protocol_registration_config.py +65 -0
- omnibase_infra/runtime/models/model_retry_policy.py +105 -0
- omnibase_infra/runtime/models/model_runtime_config.py +150 -0
- omnibase_infra/runtime/models/model_runtime_scheduler_config.py +624 -0
- omnibase_infra/runtime/models/model_runtime_scheduler_metrics.py +233 -0
- omnibase_infra/runtime/models/model_runtime_tick.py +193 -0
- omnibase_infra/runtime/models/model_secret_cache_stats.py +82 -0
- omnibase_infra/runtime/models/model_secret_mapping.py +63 -0
- omnibase_infra/runtime/models/model_secret_resolver_config.py +107 -0
- omnibase_infra/runtime/models/model_secret_resolver_metrics.py +111 -0
- omnibase_infra/runtime/models/model_secret_source_info.py +72 -0
- omnibase_infra/runtime/models/model_secret_source_spec.py +66 -0
- omnibase_infra/runtime/models/model_shutdown_batch_result.py +75 -0
- omnibase_infra/runtime/models/model_shutdown_config.py +94 -0
- omnibase_infra/runtime/projector_plugin_loader.py +1462 -0
- omnibase_infra/runtime/projector_schema_manager.py +565 -0
- omnibase_infra/runtime/projector_shell.py +1102 -0
- omnibase_infra/runtime/protocol_contract_descriptor.py +92 -0
- omnibase_infra/runtime/protocol_contract_source.py +92 -0
- omnibase_infra/runtime/protocol_domain_plugin.py +474 -0
- omnibase_infra/runtime/protocol_handler_discovery.py +221 -0
- omnibase_infra/runtime/protocol_handler_plugin_loader.py +327 -0
- omnibase_infra/runtime/protocol_lifecycle_executor.py +435 -0
- omnibase_infra/runtime/protocol_policy.py +366 -0
- omnibase_infra/runtime/protocols/__init__.py +27 -0
- omnibase_infra/runtime/protocols/protocol_runtime_scheduler.py +468 -0
- omnibase_infra/runtime/registry/__init__.py +93 -0
- omnibase_infra/runtime/registry/mixin_message_type_query.py +326 -0
- omnibase_infra/runtime/registry/mixin_message_type_registration.py +354 -0
- omnibase_infra/runtime/registry/registry_event_bus_binding.py +268 -0
- omnibase_infra/runtime/registry/registry_message_type.py +542 -0
- omnibase_infra/runtime/registry/registry_protocol_binding.py +444 -0
- omnibase_infra/runtime/registry_compute.py +1143 -0
- omnibase_infra/runtime/registry_dispatcher.py +678 -0
- omnibase_infra/runtime/registry_policy.py +1502 -0
- omnibase_infra/runtime/runtime_scheduler.py +1070 -0
- omnibase_infra/runtime/secret_resolver.py +2110 -0
- omnibase_infra/runtime/security_metadata_validator.py +776 -0
- omnibase_infra/runtime/service_kernel.py +1573 -0
- omnibase_infra/runtime/service_message_dispatch_engine.py +1805 -0
- omnibase_infra/runtime/service_runtime_host_process.py +2260 -0
- omnibase_infra/runtime/util_container_wiring.py +1123 -0
- omnibase_infra/runtime/util_validation.py +314 -0
- omnibase_infra/runtime/util_version.py +98 -0
- omnibase_infra/runtime/util_wiring.py +566 -0
- omnibase_infra/schemas/schema_registration_projection.sql +320 -0
- omnibase_infra/services/__init__.py +68 -0
- omnibase_infra/services/corpus_capture.py +678 -0
- omnibase_infra/services/service_capability_query.py +945 -0
- omnibase_infra/services/service_health.py +897 -0
- omnibase_infra/services/service_node_selector.py +530 -0
- omnibase_infra/services/service_timeout_emitter.py +682 -0
- omnibase_infra/services/service_timeout_scanner.py +390 -0
- omnibase_infra/services/snapshot/__init__.py +31 -0
- omnibase_infra/services/snapshot/service_snapshot.py +647 -0
- omnibase_infra/services/snapshot/store_inmemory.py +637 -0
- omnibase_infra/services/snapshot/store_postgres.py +1279 -0
- omnibase_infra/shared/__init__.py +8 -0
- omnibase_infra/testing/__init__.py +10 -0
- omnibase_infra/testing/utils.py +23 -0
- omnibase_infra/types/__init__.py +48 -0
- omnibase_infra/types/type_cache_info.py +49 -0
- omnibase_infra/types/type_dsn.py +173 -0
- omnibase_infra/types/type_infra_aliases.py +60 -0
- omnibase_infra/types/typed_dict/__init__.py +21 -0
- omnibase_infra/types/typed_dict/typed_dict_introspection_cache.py +128 -0
- omnibase_infra/types/typed_dict/typed_dict_performance_metrics_cache.py +140 -0
- omnibase_infra/types/typed_dict_capabilities.py +64 -0
- omnibase_infra/utils/__init__.py +89 -0
- omnibase_infra/utils/correlation.py +208 -0
- omnibase_infra/utils/util_datetime.py +372 -0
- omnibase_infra/utils/util_dsn_validation.py +333 -0
- omnibase_infra/utils/util_env_parsing.py +264 -0
- omnibase_infra/utils/util_error_sanitization.py +457 -0
- omnibase_infra/utils/util_pydantic_validators.py +477 -0
- omnibase_infra/utils/util_semver.py +233 -0
- omnibase_infra/validation/__init__.py +307 -0
- omnibase_infra/validation/enums/__init__.py +11 -0
- omnibase_infra/validation/enums/enum_contract_violation_severity.py +13 -0
- omnibase_infra/validation/infra_validators.py +1486 -0
- omnibase_infra/validation/linter_contract.py +907 -0
- omnibase_infra/validation/mixin_any_type_classification.py +120 -0
- omnibase_infra/validation/mixin_any_type_exemption.py +580 -0
- omnibase_infra/validation/mixin_any_type_reporting.py +106 -0
- omnibase_infra/validation/mixin_execution_shape_violation_checks.py +596 -0
- omnibase_infra/validation/mixin_node_archetype_detection.py +254 -0
- omnibase_infra/validation/models/__init__.py +15 -0
- omnibase_infra/validation/models/model_contract_lint_result.py +101 -0
- omnibase_infra/validation/models/model_contract_violation.py +41 -0
- omnibase_infra/validation/service_validation_aggregator.py +395 -0
- omnibase_infra/validation/validation_exemptions.yaml +1710 -0
- omnibase_infra/validation/validator_any_type.py +715 -0
- omnibase_infra/validation/validator_chain_propagation.py +839 -0
- omnibase_infra/validation/validator_execution_shape.py +465 -0
- omnibase_infra/validation/validator_localhandler.py +261 -0
- omnibase_infra/validation/validator_registration_security.py +410 -0
- omnibase_infra/validation/validator_routing_coverage.py +1020 -0
- omnibase_infra/validation/validator_runtime_shape.py +915 -0
- omnibase_infra/validation/validator_security.py +410 -0
- omnibase_infra/validation/validator_topic_category.py +1152 -0
- omnibase_infra-0.2.1.dist-info/METADATA +197 -0
- omnibase_infra-0.2.1.dist-info/RECORD +675 -0
- omnibase_infra-0.2.1.dist-info/WHEEL +4 -0
- omnibase_infra-0.2.1.dist-info/entry_points.txt +4 -0
- omnibase_infra-0.2.1.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 OmniNode Team
|
|
3
|
+
"""Metrics model for idempotency store observability.
|
|
4
|
+
|
|
5
|
+
This module provides a Pydantic model for tracking operational metrics
|
|
6
|
+
of the idempotency store, enabling monitoring of:
|
|
7
|
+
- Duplicate detection rate (duplicates / total checks)
|
|
8
|
+
- Store error rate (failed checks / total checks)
|
|
9
|
+
- Cleanup effectiveness (records deleted per run)
|
|
10
|
+
|
|
11
|
+
Example:
|
|
12
|
+
>>> from omnibase_infra.idempotency.models import ModelIdempotencyStoreMetrics
|
|
13
|
+
>>>
|
|
14
|
+
>>> metrics = ModelIdempotencyStoreMetrics(
|
|
15
|
+
... total_checks=1000,
|
|
16
|
+
... duplicate_count=50,
|
|
17
|
+
... error_count=5,
|
|
18
|
+
... )
|
|
19
|
+
>>> print(f"Duplicate rate: {metrics.duplicate_rate:.2%}")
|
|
20
|
+
Duplicate rate: 5.00%
|
|
21
|
+
>>> print(f"Error rate: {metrics.error_rate:.2%}")
|
|
22
|
+
Error rate: 0.50%
|
|
23
|
+
"""
|
|
24
|
+
|
|
25
|
+
from __future__ import annotations
|
|
26
|
+
|
|
27
|
+
from datetime import datetime
|
|
28
|
+
|
|
29
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class ModelIdempotencyStoreMetrics(BaseModel):
|
|
33
|
+
"""Metrics for idempotency store observability.
|
|
34
|
+
|
|
35
|
+
Tracks operational statistics for monitoring store health and performance.
|
|
36
|
+
All counters are monotonically increasing over the lifetime of the store
|
|
37
|
+
instance, except for last_cleanup_deleted which is reset each cleanup.
|
|
38
|
+
|
|
39
|
+
Mutability Note:
|
|
40
|
+
This model is intentionally mutable (frozen=False) to allow the
|
|
41
|
+
idempotency store to update metrics internally during operation.
|
|
42
|
+
External consumers should use the store's get_metrics() method,
|
|
43
|
+
which returns a copy of the metrics to prevent unintended mutation
|
|
44
|
+
from external code. This design ensures:
|
|
45
|
+
|
|
46
|
+
- Internal updates are efficient (no copy on each increment)
|
|
47
|
+
- External access is safe (isolated copies)
|
|
48
|
+
- Metrics remain consistent during reads
|
|
49
|
+
|
|
50
|
+
Attributes:
|
|
51
|
+
total_checks: Total number of check_and_record calls.
|
|
52
|
+
duplicate_count: Number of duplicates detected (check_and_record returned False).
|
|
53
|
+
error_count: Number of failed check operations (exceptions raised).
|
|
54
|
+
total_cleanup_deleted: Total records cleaned up across all cleanup runs.
|
|
55
|
+
last_cleanup_deleted: Records deleted in the most recent cleanup run.
|
|
56
|
+
last_cleanup_at: Timestamp of the most recent cleanup run.
|
|
57
|
+
"""
|
|
58
|
+
|
|
59
|
+
# Explicitly mutable for internal metric updates.
|
|
60
|
+
# External consumers receive copies via get_metrics() to prevent unintended mutation.
|
|
61
|
+
model_config = ConfigDict(frozen=False, extra="forbid")
|
|
62
|
+
|
|
63
|
+
total_checks: int = Field(
|
|
64
|
+
default=0,
|
|
65
|
+
ge=0,
|
|
66
|
+
description="Total check_and_record calls",
|
|
67
|
+
)
|
|
68
|
+
duplicate_count: int = Field(
|
|
69
|
+
default=0,
|
|
70
|
+
ge=0,
|
|
71
|
+
description="Number of duplicates detected",
|
|
72
|
+
)
|
|
73
|
+
error_count: int = Field(
|
|
74
|
+
default=0,
|
|
75
|
+
ge=0,
|
|
76
|
+
description="Number of failed checks",
|
|
77
|
+
)
|
|
78
|
+
total_cleanup_deleted: int = Field(
|
|
79
|
+
default=0,
|
|
80
|
+
ge=0,
|
|
81
|
+
description="Total records cleaned up across all runs",
|
|
82
|
+
)
|
|
83
|
+
last_cleanup_deleted: int = Field(
|
|
84
|
+
default=0,
|
|
85
|
+
ge=0,
|
|
86
|
+
description="Records deleted in last cleanup",
|
|
87
|
+
)
|
|
88
|
+
last_cleanup_at: datetime | None = Field(
|
|
89
|
+
default=None,
|
|
90
|
+
description="Timestamp of last cleanup run",
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
@property
|
|
94
|
+
def duplicate_rate(self) -> float:
|
|
95
|
+
"""Calculate duplicate detection rate.
|
|
96
|
+
|
|
97
|
+
Returns:
|
|
98
|
+
Ratio of duplicates to total checks (0.0 to 1.0).
|
|
99
|
+
Returns 0.0 if no checks have been made.
|
|
100
|
+
"""
|
|
101
|
+
if self.total_checks == 0:
|
|
102
|
+
return 0.0
|
|
103
|
+
return self.duplicate_count / self.total_checks
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def error_rate(self) -> float:
|
|
107
|
+
"""Calculate error rate.
|
|
108
|
+
|
|
109
|
+
Returns:
|
|
110
|
+
Ratio of errors to total checks (0.0 to 1.0).
|
|
111
|
+
Returns 0.0 if no checks have been made.
|
|
112
|
+
"""
|
|
113
|
+
if self.total_checks == 0:
|
|
114
|
+
return 0.0
|
|
115
|
+
return self.error_count / self.total_checks
|
|
116
|
+
|
|
117
|
+
@property
|
|
118
|
+
def success_count(self) -> int:
|
|
119
|
+
"""Calculate number of successful new message recordings.
|
|
120
|
+
|
|
121
|
+
Returns:
|
|
122
|
+
Number of check_and_record calls that returned True (new messages).
|
|
123
|
+
Clamped to 0 if the calculation would yield a negative value.
|
|
124
|
+
"""
|
|
125
|
+
return max(0, self.total_checks - self.duplicate_count - self.error_count)
|
|
126
|
+
|
|
127
|
+
@property
|
|
128
|
+
def success_rate(self) -> float:
|
|
129
|
+
"""Calculate success rate (new messages recorded / total checks).
|
|
130
|
+
|
|
131
|
+
Returns:
|
|
132
|
+
Ratio of successful new recordings to total checks (0.0 to 1.0).
|
|
133
|
+
Returns 0.0 if no checks have been made.
|
|
134
|
+
"""
|
|
135
|
+
if self.total_checks == 0:
|
|
136
|
+
return 0.0
|
|
137
|
+
return self.success_count / self.total_checks
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
__all__: list[str] = ["ModelIdempotencyStoreMetrics"]
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 OmniNode Team
|
|
3
|
+
"""PostgreSQL Idempotency Store Configuration Model.
|
|
4
|
+
|
|
5
|
+
This module provides the Pydantic configuration model for the PostgreSQL-based
|
|
6
|
+
idempotency store, including connection pooling, TTL, and cleanup settings.
|
|
7
|
+
|
|
8
|
+
Security Note:
|
|
9
|
+
The dsn field may contain credentials. Use environment variables for
|
|
10
|
+
sensitive values and ensure connection strings are not logged.
|
|
11
|
+
|
|
12
|
+
Environment Variables:
|
|
13
|
+
ONEX_IDEMPOTENCY_TTL_SECONDS: TTL for idempotency records (default: 86400)
|
|
14
|
+
ONEX_IDEMPOTENCY_CLEANUP_INTERVAL: Cleanup interval in seconds (default: 3600)
|
|
15
|
+
ONEX_IDEMPOTENCY_BATCH_SIZE: Records per cleanup batch (default: 10000)
|
|
16
|
+
ONEX_IDEMPOTENCY_POOL_MIN_SIZE: Minimum pool connections (default: 1)
|
|
17
|
+
ONEX_IDEMPOTENCY_POOL_MAX_SIZE: Maximum pool connections (default: 5)
|
|
18
|
+
ONEX_IDEMPOTENCY_COMMAND_TIMEOUT: Command timeout in seconds (default: 30.0)
|
|
19
|
+
ONEX_IDEMPOTENCY_CLOCK_SKEW_TOLERANCE: Clock skew tolerance in seconds (default: 60)
|
|
20
|
+
ONEX_IDEMPOTENCY_CLEANUP_MAX_ITERATIONS: Max cleanup iterations (default: 100)
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
from pydantic import BaseModel, ConfigDict, Field, ValidationInfo, field_validator
|
|
26
|
+
|
|
27
|
+
from omnibase_infra.enums import EnumInfraTransportType
|
|
28
|
+
from omnibase_infra.utils import validate_pool_sizes_constraint
|
|
29
|
+
from omnibase_infra.utils.util_env_parsing import parse_env_float, parse_env_int
|
|
30
|
+
|
|
31
|
+
# Module-level defaults from environment variables
|
|
32
|
+
# These allow runtime configuration without code changes
|
|
33
|
+
|
|
34
|
+
_DEFAULT_TTL_SECONDS = parse_env_int(
|
|
35
|
+
"ONEX_IDEMPOTENCY_TTL_SECONDS",
|
|
36
|
+
86400,
|
|
37
|
+
transport_type=EnumInfraTransportType.DATABASE,
|
|
38
|
+
service_name="postgres_idempotency_store",
|
|
39
|
+
min_value=60, # Minimum 1 minute
|
|
40
|
+
max_value=2592000, # Maximum 30 days
|
|
41
|
+
)
|
|
42
|
+
_DEFAULT_CLEANUP_INTERVAL = parse_env_int(
|
|
43
|
+
"ONEX_IDEMPOTENCY_CLEANUP_INTERVAL",
|
|
44
|
+
3600,
|
|
45
|
+
transport_type=EnumInfraTransportType.DATABASE,
|
|
46
|
+
service_name="postgres_idempotency_store",
|
|
47
|
+
min_value=60, # Minimum 1 minute
|
|
48
|
+
max_value=86400, # Maximum 24 hours
|
|
49
|
+
)
|
|
50
|
+
_DEFAULT_BATCH_SIZE = parse_env_int(
|
|
51
|
+
"ONEX_IDEMPOTENCY_BATCH_SIZE",
|
|
52
|
+
10000,
|
|
53
|
+
transport_type=EnumInfraTransportType.DATABASE,
|
|
54
|
+
service_name="postgres_idempotency_store",
|
|
55
|
+
min_value=100, # Minimum batch size
|
|
56
|
+
max_value=100000, # Maximum batch size
|
|
57
|
+
)
|
|
58
|
+
_DEFAULT_POOL_MIN_SIZE = parse_env_int(
|
|
59
|
+
"ONEX_IDEMPOTENCY_POOL_MIN_SIZE",
|
|
60
|
+
1,
|
|
61
|
+
transport_type=EnumInfraTransportType.DATABASE,
|
|
62
|
+
service_name="postgres_idempotency_store",
|
|
63
|
+
min_value=1, # Minimum 1 connection
|
|
64
|
+
max_value=100, # Maximum pool size
|
|
65
|
+
)
|
|
66
|
+
_DEFAULT_POOL_MAX_SIZE = parse_env_int(
|
|
67
|
+
"ONEX_IDEMPOTENCY_POOL_MAX_SIZE",
|
|
68
|
+
5,
|
|
69
|
+
transport_type=EnumInfraTransportType.DATABASE,
|
|
70
|
+
service_name="postgres_idempotency_store",
|
|
71
|
+
min_value=1, # Minimum 1 connection
|
|
72
|
+
max_value=100, # Maximum pool size
|
|
73
|
+
)
|
|
74
|
+
_DEFAULT_COMMAND_TIMEOUT = parse_env_float(
|
|
75
|
+
"ONEX_IDEMPOTENCY_COMMAND_TIMEOUT",
|
|
76
|
+
30.0,
|
|
77
|
+
transport_type=EnumInfraTransportType.DATABASE,
|
|
78
|
+
service_name="postgres_idempotency_store",
|
|
79
|
+
min_value=1.0, # Minimum 1 second
|
|
80
|
+
max_value=300.0, # Maximum 5 minutes
|
|
81
|
+
)
|
|
82
|
+
_DEFAULT_CLOCK_SKEW_TOLERANCE = parse_env_int(
|
|
83
|
+
"ONEX_IDEMPOTENCY_CLOCK_SKEW_TOLERANCE",
|
|
84
|
+
60,
|
|
85
|
+
transport_type=EnumInfraTransportType.DATABASE,
|
|
86
|
+
service_name="postgres_idempotency_store",
|
|
87
|
+
min_value=0, # Can disable tolerance
|
|
88
|
+
max_value=3600, # Maximum 1 hour
|
|
89
|
+
)
|
|
90
|
+
_DEFAULT_CLEANUP_MAX_ITERATIONS = parse_env_int(
|
|
91
|
+
"ONEX_IDEMPOTENCY_CLEANUP_MAX_ITERATIONS",
|
|
92
|
+
100,
|
|
93
|
+
transport_type=EnumInfraTransportType.DATABASE,
|
|
94
|
+
service_name="postgres_idempotency_store",
|
|
95
|
+
min_value=1, # Minimum 1 iteration
|
|
96
|
+
max_value=1000, # Maximum iterations
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
class ModelPostgresIdempotencyStoreConfig(BaseModel):
|
|
101
|
+
"""Configuration for PostgreSQL-based idempotency store.
|
|
102
|
+
|
|
103
|
+
This model defines all configuration options for the PostgreSQL
|
|
104
|
+
idempotency store, including connection settings, pooling parameters,
|
|
105
|
+
and TTL-based cleanup configuration.
|
|
106
|
+
|
|
107
|
+
Security Policy:
|
|
108
|
+
- DSN may contain credentials - use environment variables
|
|
109
|
+
- Never log the full DSN value
|
|
110
|
+
- Use SSL in production environments
|
|
111
|
+
|
|
112
|
+
Attributes:
|
|
113
|
+
dsn: PostgreSQL connection string (e.g., "postgresql://user:pass@host:5432/db").
|
|
114
|
+
Should be provided via environment variable for security.
|
|
115
|
+
table_name: Name of the idempotency records table.
|
|
116
|
+
Default: "idempotency_records".
|
|
117
|
+
pool_min_size: Minimum number of connections in the pool.
|
|
118
|
+
Default: 1.
|
|
119
|
+
pool_max_size: Maximum number of connections in the pool.
|
|
120
|
+
Default: 5.
|
|
121
|
+
command_timeout: Timeout for database commands in seconds.
|
|
122
|
+
Default: 30.0.
|
|
123
|
+
ttl_seconds: Time-to-live for idempotency records in seconds.
|
|
124
|
+
Records older than this will be cleaned up. Default: 86400 (24 hours).
|
|
125
|
+
auto_cleanup: Whether to automatically clean up expired records.
|
|
126
|
+
Default: True.
|
|
127
|
+
cleanup_interval_seconds: Interval between cleanup runs in seconds.
|
|
128
|
+
Default: 3600 (1 hour).
|
|
129
|
+
clock_skew_tolerance_seconds: Buffer added to TTL during cleanup to prevent
|
|
130
|
+
premature deletion due to clock skew between distributed nodes.
|
|
131
|
+
Default: 60 (1 minute).
|
|
132
|
+
cleanup_batch_size: Number of records to delete per batch during cleanup.
|
|
133
|
+
Batched deletion reduces lock contention. Default: 10000.
|
|
134
|
+
cleanup_max_iterations: Maximum number of batch iterations during cleanup.
|
|
135
|
+
Prevents runaway loops. Default: 100.
|
|
136
|
+
|
|
137
|
+
Example:
|
|
138
|
+
>>> config = ModelPostgresIdempotencyStoreConfig(
|
|
139
|
+
... dsn="postgresql://user:pass@localhost:5432/mydb",
|
|
140
|
+
... table_name="idempotency_records",
|
|
141
|
+
... pool_max_size=10,
|
|
142
|
+
... ttl_seconds=172800, # 48 hours
|
|
143
|
+
... )
|
|
144
|
+
>>> print(config.table_name)
|
|
145
|
+
idempotency_records
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
model_config = ConfigDict(
|
|
149
|
+
frozen=True,
|
|
150
|
+
extra="forbid",
|
|
151
|
+
from_attributes=True,
|
|
152
|
+
)
|
|
153
|
+
|
|
154
|
+
dsn: str = Field(
|
|
155
|
+
description="PostgreSQL connection string (e.g., 'postgresql://user:pass@host:5432/db')",
|
|
156
|
+
min_length=1,
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
@field_validator("dsn", mode="before")
|
|
160
|
+
@classmethod
|
|
161
|
+
def validate_dsn(cls, v: object) -> str:
|
|
162
|
+
"""Validate PostgreSQL DSN format using robust parser.
|
|
163
|
+
|
|
164
|
+
This validator uses urllib.parse for comprehensive DSN validation,
|
|
165
|
+
handling edge cases like IPv6 addresses, URL-encoded passwords,
|
|
166
|
+
and query parameters.
|
|
167
|
+
|
|
168
|
+
Edge cases validated:
|
|
169
|
+
- IPv6 addresses: postgresql://user:pass@[::1]:5432/db
|
|
170
|
+
- URL-encoded passwords: user:p%40ssword@host (p@ssword)
|
|
171
|
+
- Query parameters: postgresql://host/db?sslmode=require
|
|
172
|
+
- Missing components: postgresql://localhost/db (no user/pass/port)
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
v: DSN value (any type before Pydantic conversion)
|
|
176
|
+
|
|
177
|
+
Returns:
|
|
178
|
+
Validated DSN string
|
|
179
|
+
|
|
180
|
+
Raises:
|
|
181
|
+
ProtocolConfigurationError: If DSN format is invalid
|
|
182
|
+
"""
|
|
183
|
+
from omnibase_infra.utils.util_dsn_validation import parse_and_validate_dsn
|
|
184
|
+
|
|
185
|
+
# parse_and_validate_dsn handles all validation and error context
|
|
186
|
+
# It will raise ProtocolConfigurationError with proper context if invalid
|
|
187
|
+
parse_and_validate_dsn(v)
|
|
188
|
+
|
|
189
|
+
# If validation passes, return the stripped string
|
|
190
|
+
return v.strip() if isinstance(v, str) else str(v)
|
|
191
|
+
|
|
192
|
+
table_name: str = Field(
|
|
193
|
+
default="idempotency_records",
|
|
194
|
+
description="Name of the idempotency records table",
|
|
195
|
+
min_length=1,
|
|
196
|
+
max_length=63, # PostgreSQL identifier limit
|
|
197
|
+
pattern=r"^[a-zA-Z_][a-zA-Z0-9_]*$",
|
|
198
|
+
)
|
|
199
|
+
pool_min_size: int = Field(
|
|
200
|
+
default=_DEFAULT_POOL_MIN_SIZE,
|
|
201
|
+
description=(
|
|
202
|
+
"Minimum number of connections in the pool "
|
|
203
|
+
"(env: ONEX_IDEMPOTENCY_POOL_MIN_SIZE)"
|
|
204
|
+
),
|
|
205
|
+
ge=1,
|
|
206
|
+
le=100,
|
|
207
|
+
)
|
|
208
|
+
pool_max_size: int = Field(
|
|
209
|
+
default=_DEFAULT_POOL_MAX_SIZE,
|
|
210
|
+
description=(
|
|
211
|
+
"Maximum number of connections in the pool "
|
|
212
|
+
"(env: ONEX_IDEMPOTENCY_POOL_MAX_SIZE)"
|
|
213
|
+
),
|
|
214
|
+
ge=1,
|
|
215
|
+
le=100,
|
|
216
|
+
)
|
|
217
|
+
command_timeout: float = Field(
|
|
218
|
+
default=_DEFAULT_COMMAND_TIMEOUT,
|
|
219
|
+
description=(
|
|
220
|
+
"Timeout for database commands in seconds "
|
|
221
|
+
"(env: ONEX_IDEMPOTENCY_COMMAND_TIMEOUT)"
|
|
222
|
+
),
|
|
223
|
+
ge=1.0,
|
|
224
|
+
le=300.0,
|
|
225
|
+
)
|
|
226
|
+
ttl_seconds: int = Field(
|
|
227
|
+
default=_DEFAULT_TTL_SECONDS,
|
|
228
|
+
description=(
|
|
229
|
+
"Time-to-live for idempotency records in seconds "
|
|
230
|
+
"(env: ONEX_IDEMPOTENCY_TTL_SECONDS)"
|
|
231
|
+
),
|
|
232
|
+
ge=60, # Minimum 1 minute
|
|
233
|
+
le=2592000, # Maximum 30 days
|
|
234
|
+
)
|
|
235
|
+
auto_cleanup: bool = Field(
|
|
236
|
+
default=True,
|
|
237
|
+
description="Whether to automatically clean up expired records",
|
|
238
|
+
)
|
|
239
|
+
cleanup_interval_seconds: int = Field(
|
|
240
|
+
default=_DEFAULT_CLEANUP_INTERVAL,
|
|
241
|
+
description=(
|
|
242
|
+
"Interval between cleanup runs in seconds "
|
|
243
|
+
"(env: ONEX_IDEMPOTENCY_CLEANUP_INTERVAL)"
|
|
244
|
+
),
|
|
245
|
+
ge=60, # Minimum 1 minute
|
|
246
|
+
le=86400, # Maximum 24 hours
|
|
247
|
+
)
|
|
248
|
+
clock_skew_tolerance_seconds: int = Field(
|
|
249
|
+
default=_DEFAULT_CLOCK_SKEW_TOLERANCE,
|
|
250
|
+
description=(
|
|
251
|
+
"Buffer added to TTL during cleanup to prevent premature deletion due to "
|
|
252
|
+
"clock skew between distributed nodes (env: ONEX_IDEMPOTENCY_CLOCK_SKEW_TOLERANCE). "
|
|
253
|
+
"In distributed systems, nodes may have slightly different system times. "
|
|
254
|
+
"This tolerance ensures records are not cleaned up before all nodes "
|
|
255
|
+
"consider them expired. Recommended: Use NTP synchronization in production "
|
|
256
|
+
"and set this to at least the maximum expected clock drift between nodes."
|
|
257
|
+
),
|
|
258
|
+
ge=0, # Can be 0 to disable tolerance
|
|
259
|
+
le=3600, # Maximum 1 hour tolerance
|
|
260
|
+
)
|
|
261
|
+
cleanup_batch_size: int = Field(
|
|
262
|
+
default=_DEFAULT_BATCH_SIZE,
|
|
263
|
+
description=(
|
|
264
|
+
"Number of records to delete per batch during cleanup (env: ONEX_IDEMPOTENCY_BATCH_SIZE). "
|
|
265
|
+
"Batched deletion reduces lock contention on high-volume tables by "
|
|
266
|
+
"breaking large deletes into smaller transactions, allowing other "
|
|
267
|
+
"operations to interleave and preventing long-running locks."
|
|
268
|
+
),
|
|
269
|
+
ge=100, # Minimum batch size
|
|
270
|
+
le=100000, # Maximum batch size
|
|
271
|
+
)
|
|
272
|
+
cleanup_max_iterations: int = Field(
|
|
273
|
+
default=_DEFAULT_CLEANUP_MAX_ITERATIONS,
|
|
274
|
+
description=(
|
|
275
|
+
"Maximum number of batch iterations during cleanup "
|
|
276
|
+
"(env: ONEX_IDEMPOTENCY_CLEANUP_MAX_ITERATIONS). "
|
|
277
|
+
"Prevents runaway cleanup loops in extreme cases. "
|
|
278
|
+
"Total max records deleted = cleanup_batch_size * cleanup_max_iterations."
|
|
279
|
+
),
|
|
280
|
+
ge=1,
|
|
281
|
+
le=1000,
|
|
282
|
+
)
|
|
283
|
+
|
|
284
|
+
@field_validator("pool_max_size", mode="after")
|
|
285
|
+
@classmethod
|
|
286
|
+
def validate_pool_sizes(cls, v: int, info: ValidationInfo) -> int:
|
|
287
|
+
"""Validate that pool_max_size >= pool_min_size.
|
|
288
|
+
|
|
289
|
+
Delegates to shared utility for consistent validation across all config models.
|
|
290
|
+
"""
|
|
291
|
+
if info.data:
|
|
292
|
+
pool_min_size = info.data.get("pool_min_size", 1)
|
|
293
|
+
return validate_pool_sizes_constraint(
|
|
294
|
+
v, pool_min_size, target_name="postgres_idempotency_store"
|
|
295
|
+
)
|
|
296
|
+
return v
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
__all__: list[str] = ["ModelPostgresIdempotencyStoreConfig"]
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# SPDX-License-Identifier: MIT
|
|
2
|
+
# Copyright (c) 2025 OmniNode Team
|
|
3
|
+
"""Protocol definition for Idempotency Store.
|
|
4
|
+
|
|
5
|
+
This module defines the ProtocolIdempotencyStore protocol that all idempotency
|
|
6
|
+
store implementations must follow. The protocol defines the contract for
|
|
7
|
+
message deduplication in distributed systems.
|
|
8
|
+
|
|
9
|
+
Migration Note:
|
|
10
|
+
This protocol is defined locally in omnibase_infra because it is not
|
|
11
|
+
available in omnibase_spi versions 0.4.0/0.4.1. This is a TEMPORARY
|
|
12
|
+
definition that should be migrated to omnibase_spi in a future release.
|
|
13
|
+
|
|
14
|
+
Migration Path (OMN-1000):
|
|
15
|
+
1. When omnibase_spi 0.5.0+ is released with ProtocolIdempotencyStore,
|
|
16
|
+
update pyproject.toml to require the new version
|
|
17
|
+
2. Update imports in StoreIdempotencyInmemory and StoreIdempotencyPostgres
|
|
18
|
+
to use: `from omnibase_spi.protocols import ProtocolIdempotencyStore`
|
|
19
|
+
3. Remove this local protocol definition
|
|
20
|
+
4. Run tests to verify compatibility
|
|
21
|
+
|
|
22
|
+
The protocol contract is intentionally designed to match the expected
|
|
23
|
+
omnibase_spi interface to ensure a smooth migration.
|
|
24
|
+
|
|
25
|
+
Protocol Methods:
|
|
26
|
+
- check_and_record: Atomically check if message was processed and record if not
|
|
27
|
+
- is_processed: Check if a message was already processed (read-only)
|
|
28
|
+
- mark_processed: Mark a message as processed (upsert)
|
|
29
|
+
- cleanup_expired: Remove entries older than TTL
|
|
30
|
+
|
|
31
|
+
Implementations:
|
|
32
|
+
- StoreIdempotencyInmemory: In-memory store for testing (OMN-945)
|
|
33
|
+
- StoreIdempotencyPostgres: Production PostgreSQL store (OMN-945)
|
|
34
|
+
|
|
35
|
+
Security Considerations:
|
|
36
|
+
- Concurrency Safety: All implementations MUST be safe for concurrent access.
|
|
37
|
+
Multiple coroutines may call check_and_record simultaneously with the
|
|
38
|
+
same message_id. Implementations must use appropriate synchronization
|
|
39
|
+
(e.g., asyncio.Lock for in-memory, database transactions for PostgreSQL).
|
|
40
|
+
|
|
41
|
+
Note: This is coroutine-safe for asyncio concurrent access, not thread-safe.
|
|
42
|
+
For multi-threaded access, additional synchronization would be required.
|
|
43
|
+
|
|
44
|
+
- Atomicity: The check_and_record method MUST provide atomic check-and-set
|
|
45
|
+
semantics. When multiple callers race with the same (domain, message_id),
|
|
46
|
+
exactly ONE caller must receive True. This prevents duplicate processing
|
|
47
|
+
in concurrent scenarios.
|
|
48
|
+
|
|
49
|
+
- Domain Isolation: Messages are namespaced by domain to prevent cross-tenant
|
|
50
|
+
conflicts. The (domain, message_id) tuple forms the unique key. Different
|
|
51
|
+
domains can safely use the same message_id without collision. This is
|
|
52
|
+
critical for multi-tenant deployments where tenant data must be isolated.
|
|
53
|
+
|
|
54
|
+
- Correlation ID Usage: The correlation_id parameter is used ONLY for
|
|
55
|
+
distributed tracing and observability. It is NOT used for authentication
|
|
56
|
+
or authorization. Security-sensitive operations must implement their own
|
|
57
|
+
authentication layer; do not rely on correlation_id for access control.
|
|
58
|
+
|
|
59
|
+
- Input Validation: Implementations should validate that message_id is a
|
|
60
|
+
valid UUID. Domain names should be sanitized if used in storage backends
|
|
61
|
+
(e.g., as part of database keys or Redis key prefixes).
|
|
62
|
+
"""
|
|
63
|
+
|
|
64
|
+
from __future__ import annotations
|
|
65
|
+
|
|
66
|
+
from datetime import datetime
|
|
67
|
+
from typing import Protocol, runtime_checkable
|
|
68
|
+
from uuid import UUID
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
@runtime_checkable
|
|
72
|
+
class ProtocolIdempotencyStore(Protocol):
|
|
73
|
+
"""Protocol for idempotency store implementations.
|
|
74
|
+
|
|
75
|
+
Defines the contract for message deduplication stores that track processed
|
|
76
|
+
messages and prevent duplicate processing in distributed systems.
|
|
77
|
+
|
|
78
|
+
All implementations must provide atomic check-and-record semantics to
|
|
79
|
+
ensure exactly-once processing guarantees.
|
|
80
|
+
|
|
81
|
+
Key Properties:
|
|
82
|
+
- Coroutine-safe: All operations must be safe for concurrent async access
|
|
83
|
+
- Atomic: check_and_record must provide atomic check-and-set semantics
|
|
84
|
+
- Domain-isolated: Messages can be namespaced by domain for isolated deduplication
|
|
85
|
+
|
|
86
|
+
Example:
|
|
87
|
+
>>> store: ProtocolIdempotencyStore = StoreIdempotencyInmemory()
|
|
88
|
+
>>> message_id = uuid4()
|
|
89
|
+
>>> is_new = await store.check_and_record(message_id, domain="orders")
|
|
90
|
+
>>> if is_new:
|
|
91
|
+
... # Process the message
|
|
92
|
+
... pass
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
async def check_and_record(
|
|
96
|
+
self,
|
|
97
|
+
message_id: UUID,
|
|
98
|
+
domain: str | None = None,
|
|
99
|
+
correlation_id: UUID | None = None,
|
|
100
|
+
) -> bool:
|
|
101
|
+
"""Atomically check if message was processed and record if not.
|
|
102
|
+
|
|
103
|
+
This is the primary idempotency operation. It must be atomic to ensure
|
|
104
|
+
that when multiple coroutines call this method simultaneously with the
|
|
105
|
+
same (domain, message_id), exactly ONE caller receives True.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
message_id: Unique identifier for the message.
|
|
109
|
+
domain: Optional domain namespace for isolated deduplication.
|
|
110
|
+
Messages with the same message_id but different domains are
|
|
111
|
+
treated as distinct messages.
|
|
112
|
+
correlation_id: Optional correlation ID for distributed tracing.
|
|
113
|
+
Stored with the record for observability purposes.
|
|
114
|
+
|
|
115
|
+
Returns:
|
|
116
|
+
True if message is new (should be processed).
|
|
117
|
+
False if message is duplicate (should be skipped).
|
|
118
|
+
"""
|
|
119
|
+
...
|
|
120
|
+
|
|
121
|
+
async def is_processed(
|
|
122
|
+
self,
|
|
123
|
+
message_id: UUID,
|
|
124
|
+
domain: str | None = None,
|
|
125
|
+
) -> bool:
|
|
126
|
+
"""Check if a message was already processed.
|
|
127
|
+
|
|
128
|
+
Read-only check that does not modify the store. Useful for querying
|
|
129
|
+
message status without affecting the idempotency state.
|
|
130
|
+
|
|
131
|
+
Args:
|
|
132
|
+
message_id: Unique identifier for the message.
|
|
133
|
+
domain: Optional domain namespace.
|
|
134
|
+
|
|
135
|
+
Returns:
|
|
136
|
+
True if the message has been processed.
|
|
137
|
+
False if the message has not been processed.
|
|
138
|
+
"""
|
|
139
|
+
...
|
|
140
|
+
|
|
141
|
+
async def mark_processed(
|
|
142
|
+
self,
|
|
143
|
+
message_id: UUID,
|
|
144
|
+
domain: str | None = None,
|
|
145
|
+
correlation_id: UUID | None = None,
|
|
146
|
+
processed_at: datetime | None = None,
|
|
147
|
+
) -> None:
|
|
148
|
+
"""Mark a message as processed.
|
|
149
|
+
|
|
150
|
+
Records a message as processed without checking if it already exists.
|
|
151
|
+
If the record already exists, updates it with the new values.
|
|
152
|
+
|
|
153
|
+
This is an upsert operation - it will create a new record if one
|
|
154
|
+
doesn't exist, or update the existing record if it does.
|
|
155
|
+
|
|
156
|
+
Args:
|
|
157
|
+
message_id: Unique identifier for the message.
|
|
158
|
+
domain: Optional domain namespace for isolated deduplication.
|
|
159
|
+
correlation_id: Optional correlation ID for tracing.
|
|
160
|
+
processed_at: Optional timestamp of when processing occurred.
|
|
161
|
+
If None, implementations should use the current UTC time.
|
|
162
|
+
"""
|
|
163
|
+
...
|
|
164
|
+
|
|
165
|
+
async def cleanup_expired(
|
|
166
|
+
self,
|
|
167
|
+
ttl_seconds: int,
|
|
168
|
+
) -> int:
|
|
169
|
+
"""Remove entries older than TTL.
|
|
170
|
+
|
|
171
|
+
Cleans up old idempotency records based on their processed_at timestamp.
|
|
172
|
+
This prevents unbounded storage growth.
|
|
173
|
+
|
|
174
|
+
Args:
|
|
175
|
+
ttl_seconds: Time-to-live in seconds. Records older than this
|
|
176
|
+
value (based on processed_at timestamp) are removed.
|
|
177
|
+
|
|
178
|
+
Returns:
|
|
179
|
+
Number of entries removed.
|
|
180
|
+
"""
|
|
181
|
+
...
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
__all__ = ["ProtocolIdempotencyStore"]
|