omnibase_infra 0.2.7__py3-none-any.whl → 0.2.9__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 (79) 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/event_bus/adapters/__init__.py +31 -0
  5. omnibase_infra/event_bus/adapters/adapter_protocol_event_publisher_kafka.py +517 -0
  6. omnibase_infra/mixins/mixin_async_circuit_breaker.py +113 -1
  7. omnibase_infra/models/__init__.py +9 -0
  8. omnibase_infra/models/event_bus/__init__.py +22 -0
  9. omnibase_infra/models/event_bus/model_consumer_retry_config.py +367 -0
  10. omnibase_infra/models/event_bus/model_dlq_config.py +177 -0
  11. omnibase_infra/models/event_bus/model_idempotency_config.py +131 -0
  12. omnibase_infra/models/event_bus/model_offset_policy_config.py +107 -0
  13. omnibase_infra/models/resilience/model_circuit_breaker_config.py +15 -0
  14. omnibase_infra/models/validation/__init__.py +8 -0
  15. omnibase_infra/models/validation/model_declarative_node_validation_result.py +139 -0
  16. omnibase_infra/models/validation/model_declarative_node_violation.py +169 -0
  17. omnibase_infra/nodes/architecture_validator/__init__.py +28 -7
  18. omnibase_infra/nodes/architecture_validator/constants.py +36 -0
  19. omnibase_infra/nodes/architecture_validator/handlers/__init__.py +28 -0
  20. omnibase_infra/nodes/architecture_validator/handlers/contract.yaml +120 -0
  21. omnibase_infra/nodes/architecture_validator/handlers/handler_architecture_validation.py +359 -0
  22. omnibase_infra/nodes/architecture_validator/node.py +1 -0
  23. omnibase_infra/nodes/architecture_validator/node_architecture_validator.py +48 -336
  24. omnibase_infra/nodes/node_ledger_projection_compute/__init__.py +16 -2
  25. omnibase_infra/nodes/node_ledger_projection_compute/contract.yaml +14 -4
  26. omnibase_infra/nodes/node_ledger_projection_compute/handlers/__init__.py +18 -0
  27. omnibase_infra/nodes/node_ledger_projection_compute/handlers/contract.yaml +53 -0
  28. omnibase_infra/nodes/node_ledger_projection_compute/handlers/handler_ledger_projection.py +354 -0
  29. omnibase_infra/nodes/node_ledger_projection_compute/node.py +20 -256
  30. omnibase_infra/nodes/node_registry_effect/node.py +20 -73
  31. omnibase_infra/protocols/protocol_dispatch_engine.py +90 -0
  32. omnibase_infra/runtime/__init__.py +11 -0
  33. omnibase_infra/runtime/baseline_subscriptions.py +150 -0
  34. omnibase_infra/runtime/event_bus_subcontract_wiring.py +455 -24
  35. omnibase_infra/runtime/kafka_contract_source.py +13 -5
  36. omnibase_infra/runtime/service_message_dispatch_engine.py +112 -0
  37. omnibase_infra/runtime/service_runtime_host_process.py +6 -11
  38. omnibase_infra/services/__init__.py +36 -0
  39. omnibase_infra/services/contract_publisher/__init__.py +95 -0
  40. omnibase_infra/services/contract_publisher/config.py +199 -0
  41. omnibase_infra/services/contract_publisher/errors.py +243 -0
  42. omnibase_infra/services/contract_publisher/models/__init__.py +28 -0
  43. omnibase_infra/services/contract_publisher/models/model_contract_error.py +67 -0
  44. omnibase_infra/services/contract_publisher/models/model_infra_error.py +62 -0
  45. omnibase_infra/services/contract_publisher/models/model_publish_result.py +112 -0
  46. omnibase_infra/services/contract_publisher/models/model_publish_stats.py +79 -0
  47. omnibase_infra/services/contract_publisher/service.py +617 -0
  48. omnibase_infra/services/contract_publisher/sources/__init__.py +52 -0
  49. omnibase_infra/services/contract_publisher/sources/model_discovered.py +155 -0
  50. omnibase_infra/services/contract_publisher/sources/protocol.py +101 -0
  51. omnibase_infra/services/contract_publisher/sources/source_composite.py +309 -0
  52. omnibase_infra/services/contract_publisher/sources/source_filesystem.py +174 -0
  53. omnibase_infra/services/contract_publisher/sources/source_package.py +221 -0
  54. omnibase_infra/services/observability/__init__.py +40 -0
  55. omnibase_infra/services/observability/agent_actions/__init__.py +64 -0
  56. omnibase_infra/services/observability/agent_actions/config.py +209 -0
  57. omnibase_infra/services/observability/agent_actions/consumer.py +1320 -0
  58. omnibase_infra/services/observability/agent_actions/models/__init__.py +87 -0
  59. omnibase_infra/services/observability/agent_actions/models/model_agent_action.py +142 -0
  60. omnibase_infra/services/observability/agent_actions/models/model_detection_failure.py +125 -0
  61. omnibase_infra/services/observability/agent_actions/models/model_envelope.py +85 -0
  62. omnibase_infra/services/observability/agent_actions/models/model_execution_log.py +159 -0
  63. omnibase_infra/services/observability/agent_actions/models/model_performance_metric.py +130 -0
  64. omnibase_infra/services/observability/agent_actions/models/model_routing_decision.py +138 -0
  65. omnibase_infra/services/observability/agent_actions/models/model_transformation_event.py +124 -0
  66. omnibase_infra/services/observability/agent_actions/tests/__init__.py +20 -0
  67. omnibase_infra/services/observability/agent_actions/tests/test_consumer.py +1154 -0
  68. omnibase_infra/services/observability/agent_actions/tests/test_models.py +645 -0
  69. omnibase_infra/services/observability/agent_actions/tests/test_writer.py +709 -0
  70. omnibase_infra/services/observability/agent_actions/writer_postgres.py +926 -0
  71. omnibase_infra/validation/__init__.py +12 -0
  72. omnibase_infra/validation/contracts/declarative_node.validation.yaml +143 -0
  73. omnibase_infra/validation/validation_exemptions.yaml +93 -0
  74. omnibase_infra/validation/validator_declarative_node.py +850 -0
  75. {omnibase_infra-0.2.7.dist-info → omnibase_infra-0.2.9.dist-info}/METADATA +3 -3
  76. {omnibase_infra-0.2.7.dist-info → omnibase_infra-0.2.9.dist-info}/RECORD +79 -27
  77. {omnibase_infra-0.2.7.dist-info → omnibase_infra-0.2.9.dist-info}/WHEEL +0 -0
  78. {omnibase_infra-0.2.7.dist-info → omnibase_infra-0.2.9.dist-info}/entry_points.txt +0 -0
  79. {omnibase_infra-0.2.7.dist-info → omnibase_infra-0.2.9.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
@@ -982,6 +982,23 @@ pattern_exemptions:
982
982
  documentation:
983
983
  - CLAUDE.md (Circuit Breaker Pattern section)
984
984
  ticket: OMN-1004
985
+ # ==========================================================================
986
+ # MixinAsyncCircuitBreaker - _init_circuit_breaker parameter count (OMN-1743)
987
+ # ==========================================================================
988
+ # Circuit breaker initialization requires multiple configuration parameters
989
+ # for proper resilience behavior: threshold, reset_timeout, service_name,
990
+ # transport_type, and half_open_successes. These are standard circuit breaker
991
+ # configuration parameters that belong together for proper initialization.
992
+ - file_pattern: 'mixin_async_circuit_breaker\.py'
993
+ method_pattern: "Function '_init_circuit_breaker'"
994
+ violation_pattern: 'has \d+ parameters'
995
+ reason: >
996
+ 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.
997
+
998
+ documentation:
999
+ - docs/patterns/circuit_breaker_implementation.md
1000
+ - CLAUDE.md (Circuit Breaker Pattern section)
1001
+ ticket: OMN-1743
985
1002
  # ModelOperationContext - operation_name is an operation identifier string
986
1003
  - file_pattern: 'model_operation_context\.py'
987
1004
  violation_pattern: "Field 'operation_name' might reference an entity"
@@ -1919,6 +1936,82 @@ pattern_exemptions:
1919
1936
  documentation:
1920
1937
  - CLAUDE.md (Contract-Driven - node_name conventions)
1921
1938
  ticket: OMN-1653
1939
+ # ==========================================================================
1940
+ # ModelDeclarativeNodeViolation Field Exemptions (OMN-1725)
1941
+ # ==========================================================================
1942
+ # node_class_name and method_name are descriptive strings providing context
1943
+ # about where a violation occurred, not entity references requiring ID + display_name.
1944
+ - file_pattern: 'model_declarative_node_violation\.py'
1945
+ violation_pattern: "Field 'node_class_name' might reference an entity"
1946
+ reason: >
1947
+ 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.
1948
+
1949
+ documentation:
1950
+ - CLAUDE.md (Declarative Nodes)
1951
+ ticket: OMN-1725
1952
+ - file_pattern: 'model_declarative_node_violation\.py'
1953
+ violation_pattern: "Field 'method_name' might reference an entity"
1954
+ reason: >
1955
+ 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.
1956
+
1957
+ documentation:
1958
+ - CLAUDE.md (Declarative Nodes)
1959
+ ticket: OMN-1725
1960
+ # ==========================================================================
1961
+ # Observability Consumer Model Exemptions (OMN-1743)
1962
+ # ==========================================================================
1963
+ # These models consume EXTERNAL Kafka events from omniclaude producers.
1964
+ # The field types are dictated by the producer schema, not our internal design.
1965
+ # Using entity references (_id + _name) or enums would break compatibility
1966
+ # with the existing event producers.
1967
+ - file_pattern: 'services/observability/agent_actions/models/model_agent_action\.py'
1968
+ violation_pattern: "Field 'agent_name' might reference an entity"
1969
+ reason: >
1970
+ 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.
1971
+
1972
+ documentation:
1973
+ - docs/plans/OMN-1743-migration-plan.md
1974
+ ticket: OMN-1743
1975
+ - file_pattern: 'services/observability/agent_actions/models/model_agent_action\.py'
1976
+ violation_pattern: "Field 'action_name' might reference an entity"
1977
+ reason: >
1978
+ 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.
1979
+
1980
+ documentation:
1981
+ - docs/plans/OMN-1743-migration-plan.md
1982
+ ticket: OMN-1743
1983
+ - file_pattern: 'services/observability/agent_actions/models/model_execution_log\.py'
1984
+ violation_pattern: "Field 'agent_name' might reference an entity"
1985
+ reason: >
1986
+ 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.
1987
+
1988
+ documentation:
1989
+ - docs/plans/OMN-1743-migration-plan.md
1990
+ ticket: OMN-1743
1991
+ - file_pattern: 'services/observability/agent_actions/models/model_execution_log\.py'
1992
+ violation_pattern: "Field 'status' should use Enum"
1993
+ reason: >
1994
+ External observability event payload. The status field values (started, running, completed, failed) are defined by omniclaude producer. Converting to enum would break compatibility.
1995
+
1996
+ documentation:
1997
+ - docs/plans/OMN-1743-migration-plan.md
1998
+ ticket: OMN-1743
1999
+ - file_pattern: 'services/observability/agent_actions/models/model_envelope\.py'
2000
+ violation_pattern: "Field 'producer_id' should use UUID"
2001
+ reason: >
2002
+ External service identifier string (e.g., 'omniclaude', 'archon-intelligence'). It is NOT an internal entity UUID but a producer service name.
2003
+
2004
+ documentation:
2005
+ - docs/plans/OMN-1743-migration-plan.md
2006
+ ticket: OMN-1743
2007
+ - file_pattern: 'services/observability/agent_actions/models/model_performance_metric\.py'
2008
+ violation_pattern: "Field 'metric_name' might reference an entity"
2009
+ reason: >
2010
+ External observability event payload. The metric_name field comes from Kafka events produced by omniclaude. Using ID + display_name pattern would break compatibility.
2011
+
2012
+ documentation:
2013
+ - docs/plans/OMN-1743-migration-plan.md
2014
+ ticket: OMN-1743
1922
2015
  # Architecture validator exemptions
1923
2016
  # These handle one-model-per-file violations for domain-grouped protocols
1924
2017
  architecture_exemptions: