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
@@ -160,6 +160,14 @@ from omnibase_infra.validation.validator_chain_propagation import (
160
160
  validate_message_chain,
161
161
  )
162
162
 
163
+ # Declarative node validation for ONEX architecture (OMN-1725)
164
+ from omnibase_infra.validation.validator_declarative_node import (
165
+ ValidatorDeclarativeNode,
166
+ validate_declarative_node_in_file,
167
+ validate_declarative_nodes,
168
+ validate_declarative_nodes_ci,
169
+ )
170
+
163
171
  # AST-based execution shape validation for CI gate (OMN-958)
164
172
  # NOTE: EXECUTION_SHAPE_RULES is defined ONLY in validator_execution_shape.py
165
173
  # (the canonical single source of truth). This import re-exports it for public API
@@ -255,6 +263,7 @@ __all__: list[str] = [
255
263
  "ModelModuleImportResult", # Module import result (from omnibase_core)
256
264
  # Validators
257
265
  "AnyTypeDetector", # Any type AST detector (OMN-1276)
266
+ "ValidatorDeclarativeNode", # Declarative node validator (OMN-1725)
258
267
  "ChainPropagationValidator", # Chain propagation validator (OMN-951)
259
268
  "CircularImportValidator", # Circular import validator
260
269
  "ContractLinter", # Contract linter (PR #57)
@@ -285,6 +294,9 @@ __all__: list[str] = [
285
294
  "validate_any_types_in_file", # Any type file validation (OMN-1276)
286
295
  "validate_architecture", # Re-export from omnibase_core
287
296
  "validate_contracts", # Re-export from omnibase_core
297
+ "validate_declarative_node_in_file", # Declarative node file validation (OMN-1725)
298
+ "validate_declarative_nodes", # Declarative node validation (OMN-1725)
299
+ "validate_declarative_nodes_ci", # Declarative node CI validation (OMN-1725)
288
300
  "validate_execution_shapes", # Execution shape validation
289
301
  "validate_execution_shapes_ci", # CI shape validation
290
302
  "validate_handler_registration", # Handler registration validation (OMN-1098)
@@ -0,0 +1,143 @@
1
+ contract_kind: validation_subcontract
2
+ validation:
3
+ version:
4
+ major: 1
5
+ minor: 0
6
+ patch: 0
7
+ validator_id: declarative_node
8
+ validator_name: ONEX Declarative Node Validator
9
+ validator_description: |
10
+ Validates node.py files follow the ONEX declarative pattern where all behavior
11
+ is defined in contract.yaml rather than custom Python logic.
12
+
13
+ This validator performs static AST analysis to detect imperative patterns:
14
+ - Custom methods beyond __init__ (behavior should be in contract)
15
+ - @property decorators (state should be in models)
16
+ - Custom logic in __init__ beyond super().__init__(container)
17
+ - Instance variable assignments (state belongs in container/models)
18
+ - Class-level variable assignments (configuration belongs in contract)
19
+
20
+ Declarative nodes extend base classes from omnibase_core.nodes and delegate
21
+ all behavior to handler routing defined in contract.yaml.
22
+
23
+ Part of ONEX architecture: Declarative nodes, contract-driven behavior.
24
+ target_patterns:
25
+ - "**/node.py"
26
+ - "node.py"
27
+ exclude_patterns:
28
+ - "**/node_modules/**"
29
+ - "**/.git/**"
30
+ - "**/venv/**"
31
+ - "**/.venv/**"
32
+ - "**/__pycache__/**"
33
+ - "**/archived/**"
34
+ - "**/tests/**"
35
+ - "**/*_test.py"
36
+ - "**/test_*.py"
37
+ - "**/conftest.py"
38
+ rules:
39
+ - rule_id: DECL-001
40
+ name: no_custom_methods
41
+ description: |
42
+ Node classes must not have custom methods (except __init__).
43
+ All behavior should be defined in contract.yaml via handler_routing.
44
+ Custom methods indicate imperative logic that belongs in handlers.
45
+ severity: error
46
+ enabled: true
47
+ parameters:
48
+ allowed_methods:
49
+ - "__init__"
50
+ base_class_patterns:
51
+ - "^Node.*Effect$"
52
+ - "^Node.*Compute$"
53
+ - "^Node.*Reducer$"
54
+ - "^Node.*Orchestrator$"
55
+ - "^NodeEffect$"
56
+ - "^NodeCompute$"
57
+ - "^NodeReducer$"
58
+ - "^NodeOrchestrator$"
59
+ - rule_id: DECL-002
60
+ name: no_custom_properties
61
+ description: |
62
+ Node classes must not have @property decorators.
63
+ State access should be through container injection or models.
64
+ Properties indicate node-level state that should be in the container.
65
+ severity: error
66
+ enabled: true
67
+ parameters:
68
+ forbidden_decorators:
69
+ - "property"
70
+ - "cached_property"
71
+ - rule_id: DECL-003
72
+ name: no_init_custom_logic
73
+ description: |
74
+ __init__ must only call super().__init__(container).
75
+ No additional logic, assignments, or method calls allowed.
76
+ All initialization should happen through container dependency injection.
77
+ severity: error
78
+ enabled: true
79
+ parameters:
80
+ required_pattern: "super().__init__(container)"
81
+ max_statements: 1
82
+ allowed_statements:
83
+ - "super().__init__"
84
+ - rule_id: DECL-004
85
+ name: no_instance_variables
86
+ description: |
87
+ Node classes must not create instance variables (self.x = ...).
88
+ State should be managed through the container, not node-level attributes.
89
+ Instance variables indicate imperative state management.
90
+ severity: error
91
+ enabled: true
92
+ parameters:
93
+ allow_in_init: false
94
+ forbidden_patterns:
95
+ - "^self\\.[a-z_][a-z0-9_]*\\s*="
96
+ - rule_id: DECL-005
97
+ name: no_class_variables
98
+ description: |
99
+ Node classes must not have class-level variable assignments.
100
+ Configuration should be in contract.yaml, not hardcoded in Python.
101
+ Class variables indicate configuration that belongs in contracts.
102
+ severity: error
103
+ enabled: true
104
+ parameters:
105
+ allowed_class_attributes:
106
+ - "__slots__"
107
+ - "__doc__"
108
+ forbidden_patterns:
109
+ - "^[A-Z_][A-Z0-9_]*\\s*="
110
+ - "^[a-z_][a-z0-9_]*\\s*="
111
+ - rule_id: DECL-006
112
+ name: syntax_error
113
+ description: |
114
+ File has Python syntax error and cannot be validated.
115
+ Fix the syntax error before validation can proceed.
116
+ severity: error
117
+ enabled: true
118
+ - rule_id: DECL-007
119
+ name: no_node_class
120
+ description: |
121
+ File is named node.py but does not contain a Node class.
122
+ Either add a Node class or rename the file.
123
+ severity: warning
124
+ enabled: true
125
+ # ============================================================================
126
+ # LINE-BASED SUPPRESSION
127
+ # ============================================================================
128
+ # Use ONEX_EXCLUDE to exempt imperative nodes that are intentionally non-declarative.
129
+ # Place the comment on the line before or same line as the class definition.
130
+ #
131
+ # Usage example:
132
+ # # ONEX_EXCLUDE: declarative_node - legacy node with embedded logic (OMN-XXXX)
133
+ # class MyLegacyNode(NodeEffect):
134
+ # def custom_method(self): ...
135
+ # ============================================================================
136
+ suppression_comments:
137
+ - "# ONEX_EXCLUDE: declarative_node"
138
+ - "# ONEX_EXCLUDE: declarative"
139
+ severity_default: error
140
+ fail_on_error: true
141
+ fail_on_warning: false
142
+ max_violations: 0
143
+ parallel_execution: true
@@ -446,7 +446,10 @@ INFRA_NODES_PATH = "src/omnibase_infra/nodes/"
446
446
  # - 115 (2026-01-29): OMN-1653 contract registry reducer (+2 unions)
447
447
  # ContractRegistryEvent: 4-type union for event routing
448
448
  # contract_yaml: dict | str for flexible YAML handling
449
- INFRA_MAX_UNIONS = 115
449
+ # - 117 (2026-02-01): OMN-1783 PostgresRepositoryRuntime (+2 unions)
450
+ # call() return type: list[dict] | dict | None
451
+ # _execute_with_timeout() return type: list[dict] | dict | None
452
+ INFRA_MAX_UNIONS = 117
450
453
 
451
454
  # Maximum allowed architecture violations in infrastructure code.
452
455
  # Set to 0 (strict enforcement) to ensure one-model-per-file principle is always followed.
@@ -132,6 +132,24 @@ pattern_exemptions:
132
132
  - CLAUDE.md (Accepted Pattern Exceptions - EventBusKafka Complexity)
133
133
  ticket: OMN-1305
134
134
  # ==========================================================================
135
+ # PostgresRepositoryRuntime Exemptions (OMN-1783)
136
+ # ==========================================================================
137
+ # Contract-driven database runtime with cohesive methods for query execution.
138
+ # All methods serve the same purpose: executing repository contract operations.
139
+ # Public: call(), contract (property), config (property)
140
+ # Private: _create_error_context, _get_operation, _validate_operation_allowed,
141
+ # _validate_arg_count, _build_sql, _inject_order_by, _inject_limit,
142
+ # _execute_with_timeout, _get_primary_table, _fingerprint_sql
143
+ - file_pattern: 'postgres_repository_runtime\.py'
144
+ class_pattern: "Class 'PostgresRepositoryRuntime'"
145
+ violation_pattern: 'has \d+ methods'
146
+ reason: >
147
+ Cohesive runtime class with single responsibility: executing repository contract operations. Methods are logically grouped: validation (3), SQL building (3), execution (1), and helpers (3). Breaking into smaller classes would reduce cohesion and complicate the simple contract-driven execution flow.
148
+
149
+ documentation:
150
+ - OMN-1783 PR description
151
+ ticket: OMN-1783
152
+ # ==========================================================================
135
153
  # Protocol Plugin Architecture Exemptions
136
154
  # ==========================================================================
137
155
  # The 'execute' method name is a standard plugin architecture pattern.
@@ -982,6 +1000,23 @@ pattern_exemptions:
982
1000
  documentation:
983
1001
  - CLAUDE.md (Circuit Breaker Pattern section)
984
1002
  ticket: OMN-1004
1003
+ # ==========================================================================
1004
+ # MixinAsyncCircuitBreaker - _init_circuit_breaker parameter count (OMN-1743)
1005
+ # ==========================================================================
1006
+ # Circuit breaker initialization requires multiple configuration parameters
1007
+ # for proper resilience behavior: threshold, reset_timeout, service_name,
1008
+ # transport_type, and half_open_successes. These are standard circuit breaker
1009
+ # configuration parameters that belong together for proper initialization.
1010
+ - file_pattern: 'mixin_async_circuit_breaker\.py'
1011
+ method_pattern: "Function '_init_circuit_breaker'"
1012
+ violation_pattern: 'has \d+ parameters'
1013
+ reason: >
1014
+ Circuit breaker initialization requires cohesive configuration parameters: threshold (failures before open), reset_timeout (seconds before half-open), service_name (for error context), transport_type (for error codes), and half_open_successes (for close validation). These parameters define the complete circuit breaker behavior and cannot be split without losing cohesion. Alternative is ModelCircuitBreakerConfig but direct parameters preferred for mixin flexibility.
1015
+
1016
+ documentation:
1017
+ - docs/patterns/circuit_breaker_implementation.md
1018
+ - CLAUDE.md (Circuit Breaker Pattern section)
1019
+ ticket: OMN-1743
985
1020
  # ModelOperationContext - operation_name is an operation identifier string
986
1021
  - file_pattern: 'model_operation_context\.py'
987
1022
  violation_pattern: "Field 'operation_name' might reference an entity"
@@ -1919,6 +1954,82 @@ pattern_exemptions:
1919
1954
  documentation:
1920
1955
  - CLAUDE.md (Contract-Driven - node_name conventions)
1921
1956
  ticket: OMN-1653
1957
+ # ==========================================================================
1958
+ # ModelDeclarativeNodeViolation Field Exemptions (OMN-1725)
1959
+ # ==========================================================================
1960
+ # node_class_name and method_name are descriptive strings providing context
1961
+ # about where a violation occurred, not entity references requiring ID + display_name.
1962
+ - file_pattern: 'model_declarative_node_violation\.py'
1963
+ violation_pattern: "Field 'node_class_name' might reference an entity"
1964
+ reason: >
1965
+ node_class_name is a descriptive string showing which node class contains the violation (e.g., "NodeRegistrationOrchestrator"). It provides human-readable context for error messages and CI output, not an entity reference requiring ID + display_name pattern.
1966
+
1967
+ documentation:
1968
+ - CLAUDE.md (Declarative Nodes)
1969
+ ticket: OMN-1725
1970
+ - file_pattern: 'model_declarative_node_violation\.py'
1971
+ violation_pattern: "Field 'method_name' might reference an entity"
1972
+ reason: >
1973
+ method_name is a descriptive string showing which method/property triggered the violation (e.g., "compute", "__bool__"). It provides human-readable context for debugging and does not require ID + display_name pattern.
1974
+
1975
+ documentation:
1976
+ - CLAUDE.md (Declarative Nodes)
1977
+ ticket: OMN-1725
1978
+ # ==========================================================================
1979
+ # Observability Consumer Model Exemptions (OMN-1743)
1980
+ # ==========================================================================
1981
+ # These models consume EXTERNAL Kafka events from omniclaude producers.
1982
+ # The field types are dictated by the producer schema, not our internal design.
1983
+ # Using entity references (_id + _name) or enums would break compatibility
1984
+ # with the existing event producers.
1985
+ - file_pattern: 'services/observability/agent_actions/models/model_agent_action\.py'
1986
+ violation_pattern: "Field 'agent_name' might reference an entity"
1987
+ reason: >
1988
+ External observability event payload. The agent_name field comes from Kafka events produced by omniclaude. Using ID + display_name pattern would break compatibility with existing producers.
1989
+
1990
+ documentation:
1991
+ - docs/plans/OMN-1743-migration-plan.md
1992
+ ticket: OMN-1743
1993
+ - file_pattern: 'services/observability/agent_actions/models/model_agent_action\.py'
1994
+ violation_pattern: "Field 'action_name' might reference an entity"
1995
+ reason: >
1996
+ External observability event payload. The action_name field comes from Kafka events produced by omniclaude. Using ID + display_name pattern would break compatibility with existing producers.
1997
+
1998
+ documentation:
1999
+ - docs/plans/OMN-1743-migration-plan.md
2000
+ ticket: OMN-1743
2001
+ - file_pattern: 'services/observability/agent_actions/models/model_execution_log\.py'
2002
+ violation_pattern: "Field 'agent_name' might reference an entity"
2003
+ reason: >
2004
+ External observability event payload. The agent_name field comes from Kafka events produced by omniclaude. Using ID + display_name pattern would break compatibility with existing producers.
2005
+
2006
+ documentation:
2007
+ - docs/plans/OMN-1743-migration-plan.md
2008
+ ticket: OMN-1743
2009
+ - file_pattern: 'services/observability/agent_actions/models/model_execution_log\.py'
2010
+ violation_pattern: "Field 'status' should use Enum"
2011
+ reason: >
2012
+ External observability event payload. The status field values (started, running, completed, failed) are defined by omniclaude producer. Converting to enum would break compatibility.
2013
+
2014
+ documentation:
2015
+ - docs/plans/OMN-1743-migration-plan.md
2016
+ ticket: OMN-1743
2017
+ - file_pattern: 'services/observability/agent_actions/models/model_envelope\.py'
2018
+ violation_pattern: "Field 'producer_id' should use UUID"
2019
+ reason: >
2020
+ External service identifier string (e.g., 'omniclaude', 'archon-intelligence'). It is NOT an internal entity UUID but a producer service name.
2021
+
2022
+ documentation:
2023
+ - docs/plans/OMN-1743-migration-plan.md
2024
+ ticket: OMN-1743
2025
+ - file_pattern: 'services/observability/agent_actions/models/model_performance_metric\.py'
2026
+ violation_pattern: "Field 'metric_name' might reference an entity"
2027
+ reason: >
2028
+ External observability event payload. The metric_name field comes from Kafka events produced by omniclaude. Using ID + display_name pattern would break compatibility.
2029
+
2030
+ documentation:
2031
+ - docs/plans/OMN-1743-migration-plan.md
2032
+ ticket: OMN-1743
1922
2033
  # Architecture validator exemptions
1923
2034
  # These handle one-model-per-file violations for domain-grouped protocols
1924
2035
  architecture_exemptions: