omnibase_infra 0.2.8__py3-none-any.whl → 0.3.0__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 (88) hide show
  1. omnibase_infra/__init__.py +1 -1
  2. omnibase_infra/enums/__init__.py +4 -0
  3. omnibase_infra/enums/enum_declarative_node_violation.py +102 -0
  4. omnibase_infra/errors/__init__.py +18 -0
  5. omnibase_infra/errors/repository/__init__.py +78 -0
  6. omnibase_infra/errors/repository/errors_repository.py +424 -0
  7. omnibase_infra/event_bus/adapters/__init__.py +31 -0
  8. omnibase_infra/event_bus/adapters/adapter_protocol_event_publisher_kafka.py +517 -0
  9. omnibase_infra/mixins/mixin_async_circuit_breaker.py +113 -1
  10. omnibase_infra/models/__init__.py +9 -0
  11. omnibase_infra/models/event_bus/__init__.py +22 -0
  12. omnibase_infra/models/event_bus/model_consumer_retry_config.py +367 -0
  13. omnibase_infra/models/event_bus/model_dlq_config.py +177 -0
  14. omnibase_infra/models/event_bus/model_idempotency_config.py +131 -0
  15. omnibase_infra/models/event_bus/model_offset_policy_config.py +107 -0
  16. omnibase_infra/models/resilience/model_circuit_breaker_config.py +15 -0
  17. omnibase_infra/models/validation/__init__.py +8 -0
  18. omnibase_infra/models/validation/model_declarative_node_validation_result.py +139 -0
  19. omnibase_infra/models/validation/model_declarative_node_violation.py +169 -0
  20. omnibase_infra/nodes/architecture_validator/__init__.py +28 -7
  21. omnibase_infra/nodes/architecture_validator/constants.py +36 -0
  22. omnibase_infra/nodes/architecture_validator/handlers/__init__.py +28 -0
  23. omnibase_infra/nodes/architecture_validator/handlers/contract.yaml +120 -0
  24. omnibase_infra/nodes/architecture_validator/handlers/handler_architecture_validation.py +359 -0
  25. omnibase_infra/nodes/architecture_validator/node.py +1 -0
  26. omnibase_infra/nodes/architecture_validator/node_architecture_validator.py +48 -336
  27. omnibase_infra/nodes/contract_registry_reducer/reducer.py +12 -2
  28. omnibase_infra/nodes/node_ledger_projection_compute/__init__.py +16 -2
  29. omnibase_infra/nodes/node_ledger_projection_compute/contract.yaml +14 -4
  30. omnibase_infra/nodes/node_ledger_projection_compute/handlers/__init__.py +18 -0
  31. omnibase_infra/nodes/node_ledger_projection_compute/handlers/contract.yaml +53 -0
  32. omnibase_infra/nodes/node_ledger_projection_compute/handlers/handler_ledger_projection.py +354 -0
  33. omnibase_infra/nodes/node_ledger_projection_compute/node.py +20 -256
  34. omnibase_infra/nodes/node_registry_effect/node.py +20 -73
  35. omnibase_infra/protocols/protocol_dispatch_engine.py +90 -0
  36. omnibase_infra/runtime/__init__.py +11 -0
  37. omnibase_infra/runtime/baseline_subscriptions.py +150 -0
  38. omnibase_infra/runtime/db/__init__.py +73 -0
  39. omnibase_infra/runtime/db/models/__init__.py +41 -0
  40. omnibase_infra/runtime/db/models/model_repository_runtime_config.py +211 -0
  41. omnibase_infra/runtime/db/postgres_repository_runtime.py +545 -0
  42. omnibase_infra/runtime/event_bus_subcontract_wiring.py +455 -24
  43. omnibase_infra/runtime/kafka_contract_source.py +13 -5
  44. omnibase_infra/runtime/service_message_dispatch_engine.py +112 -0
  45. omnibase_infra/runtime/service_runtime_host_process.py +6 -11
  46. omnibase_infra/services/__init__.py +36 -0
  47. omnibase_infra/services/contract_publisher/__init__.py +95 -0
  48. omnibase_infra/services/contract_publisher/config.py +199 -0
  49. omnibase_infra/services/contract_publisher/errors.py +243 -0
  50. omnibase_infra/services/contract_publisher/models/__init__.py +28 -0
  51. omnibase_infra/services/contract_publisher/models/model_contract_error.py +67 -0
  52. omnibase_infra/services/contract_publisher/models/model_infra_error.py +62 -0
  53. omnibase_infra/services/contract_publisher/models/model_publish_result.py +112 -0
  54. omnibase_infra/services/contract_publisher/models/model_publish_stats.py +79 -0
  55. omnibase_infra/services/contract_publisher/service.py +617 -0
  56. omnibase_infra/services/contract_publisher/sources/__init__.py +52 -0
  57. omnibase_infra/services/contract_publisher/sources/model_discovered.py +155 -0
  58. omnibase_infra/services/contract_publisher/sources/protocol.py +101 -0
  59. omnibase_infra/services/contract_publisher/sources/source_composite.py +309 -0
  60. omnibase_infra/services/contract_publisher/sources/source_filesystem.py +174 -0
  61. omnibase_infra/services/contract_publisher/sources/source_package.py +221 -0
  62. omnibase_infra/services/observability/__init__.py +40 -0
  63. omnibase_infra/services/observability/agent_actions/__init__.py +64 -0
  64. omnibase_infra/services/observability/agent_actions/config.py +209 -0
  65. omnibase_infra/services/observability/agent_actions/consumer.py +1320 -0
  66. omnibase_infra/services/observability/agent_actions/models/__init__.py +87 -0
  67. omnibase_infra/services/observability/agent_actions/models/model_agent_action.py +142 -0
  68. omnibase_infra/services/observability/agent_actions/models/model_detection_failure.py +125 -0
  69. omnibase_infra/services/observability/agent_actions/models/model_envelope.py +85 -0
  70. omnibase_infra/services/observability/agent_actions/models/model_execution_log.py +159 -0
  71. omnibase_infra/services/observability/agent_actions/models/model_performance_metric.py +130 -0
  72. omnibase_infra/services/observability/agent_actions/models/model_routing_decision.py +138 -0
  73. omnibase_infra/services/observability/agent_actions/models/model_transformation_event.py +124 -0
  74. omnibase_infra/services/observability/agent_actions/tests/__init__.py +20 -0
  75. omnibase_infra/services/observability/agent_actions/tests/test_consumer.py +1154 -0
  76. omnibase_infra/services/observability/agent_actions/tests/test_models.py +645 -0
  77. omnibase_infra/services/observability/agent_actions/tests/test_writer.py +709 -0
  78. omnibase_infra/services/observability/agent_actions/writer_postgres.py +926 -0
  79. omnibase_infra/validation/__init__.py +12 -0
  80. omnibase_infra/validation/contracts/declarative_node.validation.yaml +143 -0
  81. omnibase_infra/validation/infra_validators.py +4 -1
  82. omnibase_infra/validation/validation_exemptions.yaml +111 -0
  83. omnibase_infra/validation/validator_declarative_node.py +850 -0
  84. {omnibase_infra-0.2.8.dist-info → omnibase_infra-0.3.0.dist-info}/METADATA +2 -2
  85. {omnibase_infra-0.2.8.dist-info → omnibase_infra-0.3.0.dist-info}/RECORD +88 -30
  86. {omnibase_infra-0.2.8.dist-info → omnibase_infra-0.3.0.dist-info}/WHEEL +0 -0
  87. {omnibase_infra-0.2.8.dist-info → omnibase_infra-0.3.0.dist-info}/entry_points.txt +0 -0
  88. {omnibase_infra-0.2.8.dist-info → omnibase_infra-0.3.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,359 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """Handler for architecture validation operations.
4
+
5
+ This handler processes architecture validation requests by validating nodes and
6
+ handlers against configurable architecture rules. It implements the validation
7
+ logic that was previously in NodeArchitectureValidatorCompute.
8
+
9
+ Design Pattern:
10
+ HandlerArchitectureValidation follows the ONEX handler pattern:
11
+ - Receives strongly-typed request (ModelArchitectureValidationRequest)
12
+ - Returns strongly-typed result (ModelArchitectureValidationResult)
13
+ - Manages validation rules internally
14
+ - Stateless operation (rules injected at construction)
15
+
16
+ Thread Safety:
17
+ The handler is thread-safe when used with immutable rules. Each handle()
18
+ call is independent and does not modify shared state.
19
+
20
+ Related:
21
+ - OMN-1138: Architecture Validator for omnibase_infra
22
+ - OMN-1726: Refactor to declarative pattern with contract-driven handler
23
+
24
+ Example:
25
+ >>> from omnibase_infra.nodes.architecture_validator.handlers import (
26
+ ... HandlerArchitectureValidation,
27
+ ... )
28
+ >>> from omnibase_infra.nodes.architecture_validator.models import (
29
+ ... ModelArchitectureValidationRequest,
30
+ ... )
31
+ >>>
32
+ >>> # Create handler with rules
33
+ >>> handler = HandlerArchitectureValidation(
34
+ ... rules=(no_handler_publishing_rule, no_workflow_in_reducer_rule),
35
+ ... )
36
+ >>>
37
+ >>> # Validate nodes and handlers
38
+ >>> request = ModelArchitectureValidationRequest(
39
+ ... nodes=(my_orchestrator, my_reducer),
40
+ ... handlers=(my_handler,),
41
+ ... )
42
+ >>> result = handler.handle(request)
43
+ >>> if result.valid:
44
+ ... print("All architecture rules passed")
45
+
46
+ .. versionadded:: 0.9.0
47
+ Created as part of OMN-1726 declarative refactoring.
48
+ """
49
+
50
+ from __future__ import annotations
51
+
52
+ from typing import TYPE_CHECKING
53
+
54
+ from omnibase_infra.enums import EnumInfraTransportType
55
+ from omnibase_infra.errors import ProtocolConfigurationError
56
+ from omnibase_infra.models.errors.model_infra_error_context import (
57
+ ModelInfraErrorContext,
58
+ )
59
+ from omnibase_infra.nodes.architecture_validator.constants import SUPPORTED_RULE_IDS
60
+ from omnibase_infra.nodes.architecture_validator.models import (
61
+ ModelArchitectureValidationRequest,
62
+ ModelArchitectureValidationResult,
63
+ ModelArchitectureViolation,
64
+ ModelRuleCheckResult,
65
+ )
66
+
67
+ if TYPE_CHECKING:
68
+ from omnibase_infra.nodes.architecture_validator.protocols import (
69
+ ProtocolArchitectureRule,
70
+ )
71
+
72
+ HANDLER_ID_ARCHITECTURE_VALIDATION: str = "handler-architecture-validation"
73
+
74
+ __all__ = ["HandlerArchitectureValidation", "HANDLER_ID_ARCHITECTURE_VALIDATION"]
75
+
76
+
77
+ class HandlerArchitectureValidation:
78
+ """Handler for architecture validation operations.
79
+
80
+ Validates nodes and handlers against architecture rules. This handler
81
+ encapsulates all validation logic that was previously in the compute node.
82
+
83
+ Can be called:
84
+ - At startup (direct call, pre-runtime validation)
85
+ - During runtime (via orchestrator for dynamic validation)
86
+ - From CI/CD (standalone validation in test/build pipelines)
87
+
88
+ Attributes:
89
+ _rules: Tuple of architecture rules to enforce during validation.
90
+
91
+ Thread Safety:
92
+ This handler is thread-safe when:
93
+ - Rules are stateless (recommended)
94
+ - Request objects are not shared across threads
95
+ - Each handle() call operates independently
96
+
97
+ Example:
98
+ >>> # Create handler with rules
99
+ >>> handler = HandlerArchitectureValidation(rules=rules)
100
+ >>> result = handler.handle(request)
101
+ >>> if not result:
102
+ ... from omnibase_infra.enums import EnumInfraTransportType
103
+ ... from omnibase_infra.errors import (
104
+ ... ModelInfraErrorContext,
105
+ ... ProtocolConfigurationError,
106
+ ... )
107
+ ... context = ModelInfraErrorContext.with_correlation(
108
+ ... transport_type=EnumInfraTransportType.RUNTIME,
109
+ ... operation="architecture_validation",
110
+ ... )
111
+ ... raise ProtocolConfigurationError(
112
+ ... f"Validation failed: {result.violation_count} violations",
113
+ ... context=context,
114
+ ... code="ARCHITECTURE_VALIDATION_FAILED",
115
+ ... violations=[v.to_structured_dict() for v in result.violations],
116
+ ... )
117
+
118
+ .. versionadded:: 0.9.0
119
+ Created as part of OMN-1726 declarative refactoring.
120
+ """
121
+
122
+ def __init__(
123
+ self,
124
+ rules: tuple[ProtocolArchitectureRule, ...] = (),
125
+ ) -> None:
126
+ """Initialize handler with architecture rules.
127
+
128
+ Args:
129
+ rules: Architecture rules to enforce. These should implement
130
+ ProtocolArchitectureRule. Rules from OMN-1099 validators can be
131
+ passed directly.
132
+
133
+ Raises:
134
+ ProtocolConfigurationError: If any rule has a rule_id not in
135
+ SUPPORTED_RULE_IDS. The error message includes the unsupported
136
+ rule_id and the list of supported rules for debugging.
137
+
138
+ Example:
139
+ >>> from my_rules import NoHandlerPublishingRule, NoWorkflowInReducerRule
140
+ >>>
141
+ >>> handler = HandlerArchitectureValidation(
142
+ ... rules=(NoHandlerPublishingRule(), NoWorkflowInReducerRule()),
143
+ ... )
144
+
145
+ .. versionadded:: 0.9.0
146
+ """
147
+ self._validate_rules_against_contract(rules)
148
+ self._rules = rules
149
+
150
+ @property
151
+ def handler_id(self) -> str:
152
+ """Return unique identifier for this handler.
153
+
154
+ Returns:
155
+ str: Handler identifier.
156
+
157
+ .. versionadded:: 0.9.0
158
+ """
159
+ return HANDLER_ID_ARCHITECTURE_VALIDATION
160
+
161
+ @property
162
+ def supported_operations(self) -> frozenset[str]:
163
+ """Return supported operations for this handler.
164
+
165
+ Returns:
166
+ frozenset[str]: Set of supported operation names.
167
+
168
+ .. versionadded:: 0.9.0
169
+ """
170
+ return frozenset({"architecture.validate"})
171
+
172
+ def _validate_rules_against_contract(
173
+ self,
174
+ rules: tuple[ProtocolArchitectureRule, ...],
175
+ ) -> None:
176
+ """Validate that all provided rules are in the contract's supported_rules.
177
+
178
+ This validation ensures that only rules defined in the contract's
179
+ supported_rules list can be used with this handler. Using unsupported
180
+ rules would indicate a misconfiguration or version mismatch between
181
+ the handler and the rules being passed.
182
+
183
+ Args:
184
+ rules: Tuple of architecture rules to validate against the contract.
185
+
186
+ Raises:
187
+ ProtocolConfigurationError: If any rule has a rule_id not in
188
+ SUPPORTED_RULE_IDS. The error message includes the unsupported
189
+ rule_id and the list of supported rules for debugging.
190
+ Includes ModelInfraErrorContext with RUNTIME transport type.
191
+
192
+ .. versionadded:: 0.9.0
193
+ """
194
+ for rule in rules:
195
+ if rule.rule_id not in SUPPORTED_RULE_IDS:
196
+ context = ModelInfraErrorContext.with_correlation(
197
+ transport_type=EnumInfraTransportType.RUNTIME,
198
+ operation="validate_rules_against_contract",
199
+ )
200
+ raise ProtocolConfigurationError(
201
+ f"Rule '{rule.rule_id}' is not in contract supported_rules. "
202
+ f"Supported rules: {sorted(SUPPORTED_RULE_IDS)}",
203
+ context=context,
204
+ rule_id=rule.rule_id,
205
+ supported_rules=sorted(SUPPORTED_RULE_IDS),
206
+ )
207
+
208
+ def validate_architecture(
209
+ self,
210
+ request: ModelArchitectureValidationRequest,
211
+ ) -> ModelArchitectureValidationResult:
212
+ """Validate architecture compliance.
213
+
214
+ Applies all registered rules to the nodes and handlers in the request.
215
+ Returns a result containing any violations found and summary statistics.
216
+
217
+ This is a pure transformation with no side effects:
218
+ - Same input always produces same output
219
+ - Does not modify request, rules, or external state
220
+ - Safe to call concurrently from multiple threads
221
+
222
+ Args:
223
+ request: Validation request containing:
224
+ - nodes: Nodes to validate
225
+ - handlers: Handlers to validate
226
+ - rule_ids: Optional filter for specific rules
227
+ - fail_fast: Whether to stop on first violation
228
+ - correlation_id: For distributed tracing
229
+
230
+ Returns:
231
+ ModelArchitectureValidationResult with:
232
+ - violations: All violations found (empty if validation passed)
233
+ - rules_checked: IDs of rules that were evaluated
234
+ - nodes_checked: Count of nodes validated
235
+ - handlers_checked: Count of handlers validated
236
+ - correlation_id: Propagated from request
237
+
238
+ Example:
239
+ >>> # Check all rules
240
+ >>> result = handler.handle(ModelArchitectureValidationRequest(
241
+ ... nodes=all_nodes,
242
+ ... handlers=all_handlers,
243
+ ... ))
244
+ >>> print(f"Checked {result.nodes_checked} nodes, "
245
+ ... f"{result.handlers_checked} handlers")
246
+ >>> print(f"Found {result.violation_count} violations")
247
+
248
+ >>> # Check specific rules only
249
+ >>> result = handler.handle(ModelArchitectureValidationRequest(
250
+ ... nodes=all_nodes,
251
+ ... rule_ids=("NO_HANDLER_PUBLISHING", "PURE_REDUCERS"),
252
+ ... fail_fast=True,
253
+ ... ))
254
+
255
+ .. versionadded:: 0.9.0
256
+ """
257
+ violations: list[ModelArchitectureViolation] = []
258
+ rules_to_check = self._get_rules_to_check(request.rule_ids)
259
+
260
+ # Validate nodes
261
+ for node in request.nodes:
262
+ for rule in rules_to_check:
263
+ result = rule.check(node)
264
+ if not result.passed:
265
+ violation = self._create_violation(rule, node, result)
266
+ violations.append(violation)
267
+ if request.fail_fast:
268
+ return self._build_result(violations, rules_to_check, request)
269
+
270
+ # Validate handlers
271
+ for handler in request.handlers:
272
+ for rule in rules_to_check:
273
+ result = rule.check(handler)
274
+ if not result.passed:
275
+ violation = self._create_violation(rule, handler, result)
276
+ violations.append(violation)
277
+ if request.fail_fast:
278
+ return self._build_result(violations, rules_to_check, request)
279
+
280
+ return self._build_result(violations, rules_to_check, request)
281
+
282
+ def _get_rules_to_check(
283
+ self,
284
+ rule_ids: tuple[str, ...] | None,
285
+ ) -> tuple[ProtocolArchitectureRule, ...]:
286
+ """Get rules to check based on request filter.
287
+
288
+ Args:
289
+ rule_ids: Optional tuple of rule IDs to filter by.
290
+ If None, all registered rules are returned.
291
+
292
+ Returns:
293
+ Tuple of rules to check. If rule_ids is provided, only
294
+ rules with matching IDs are included.
295
+
296
+ .. versionadded:: 0.9.0
297
+ """
298
+ if rule_ids is None:
299
+ return self._rules
300
+ return tuple(r for r in self._rules if r.rule_id in rule_ids)
301
+
302
+ def _create_violation(
303
+ self,
304
+ rule: ProtocolArchitectureRule,
305
+ target: object,
306
+ result: ModelRuleCheckResult,
307
+ ) -> ModelArchitectureViolation:
308
+ """Create violation from rule check result.
309
+
310
+ Args:
311
+ rule: The rule that was violated.
312
+ target: The node or handler that violated the rule.
313
+ result: The check result with violation details.
314
+
315
+ Returns:
316
+ ModelArchitectureViolation with full context for debugging
317
+ and remediation.
318
+
319
+ Note:
320
+ Uses getattr for target_name to handle both class types
321
+ (with __name__) and instances (fallback to str()).
322
+
323
+ .. versionadded:: 0.9.0
324
+ """
325
+ return ModelArchitectureViolation(
326
+ rule_id=rule.rule_id,
327
+ rule_name=rule.name,
328
+ severity=rule.severity,
329
+ target_type=type(target).__name__,
330
+ target_name=getattr(target, "__name__", str(target)),
331
+ message=result.message or rule.description,
332
+ details=result.details,
333
+ )
334
+
335
+ def _build_result(
336
+ self,
337
+ violations: list[ModelArchitectureViolation],
338
+ rules_checked: tuple[ProtocolArchitectureRule, ...],
339
+ request: ModelArchitectureValidationRequest,
340
+ ) -> ModelArchitectureValidationResult:
341
+ """Build final validation result.
342
+
343
+ Args:
344
+ violations: All violations found during validation.
345
+ rules_checked: Rules that were evaluated.
346
+ request: Original validation request (for counts and correlation_id).
347
+
348
+ Returns:
349
+ ModelArchitectureValidationResult with complete validation summary.
350
+
351
+ .. versionadded:: 0.9.0
352
+ """
353
+ return ModelArchitectureValidationResult(
354
+ violations=tuple(violations),
355
+ rules_checked=tuple(r.rule_id for r in rules_checked),
356
+ nodes_checked=len(request.nodes),
357
+ handlers_checked=len(request.handlers),
358
+ correlation_id=request.correlation_id,
359
+ )
@@ -69,6 +69,7 @@ if TYPE_CHECKING:
69
69
  _ValidatorFunc = Callable[[str], ModelFileValidationResult]
70
70
 
71
71
 
72
+ # ONEX_EXCLUDE: declarative_node - legacy validator with embedded validation logic (OMN-1725)
72
73
  class NodeArchitectureValidator(NodeCompute):
73
74
  """Architecture Validator - COMPUTE_GENERIC node for architecture pattern validation.
74
75