omnibase_infra 0.2.9__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.
@@ -0,0 +1,545 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2025 OmniNode Team
3
+ """PostgreSQL Repository Runtime.
4
+
5
+ This module provides a generic runtime for executing repository contracts
6
+ against PostgreSQL databases. The runtime enforces safety constraints,
7
+ deterministic query ordering, and configurable operation limits.
8
+
9
+ Key Features:
10
+ - Contract-driven: All operations defined in ModelDbRepositoryContract
11
+ - Positional parameters: Uses $1, $2, ... (no named param rewriting)
12
+ - Determinism enforcement: ORDER BY injection for multi-row queries
13
+ - Limit enforcement: LIMIT injection with configurable maximum
14
+ - Operation validation: Allowlist-based operation control
15
+ - Timeout enforcement: asyncio.wait_for() for query cancellation
16
+
17
+ Usage Example:
18
+ >>> import asyncpg
19
+ >>> from omnibase_infra.runtime.db import (
20
+ ... ModelDbRepositoryContract,
21
+ ... ModelDbOperation,
22
+ ... ModelDbReturn,
23
+ ... ModelRepositoryRuntimeConfig,
24
+ ... )
25
+ >>> from omnibase_infra.runtime.db.postgres_repository_runtime import (
26
+ ... PostgresRepositoryRuntime,
27
+ ... )
28
+ >>>
29
+ >>> # Create contract
30
+ >>> contract = ModelDbRepositoryContract(
31
+ ... name="users",
32
+ ... database_ref="primary",
33
+ ... ops={
34
+ ... "find_by_id": ModelDbOperation(
35
+ ... mode="select",
36
+ ... sql="SELECT * FROM users WHERE id = $1",
37
+ ... params=["user_id"],
38
+ ... returns=ModelDbReturn(many=False),
39
+ ... ),
40
+ ... },
41
+ ... )
42
+ >>>
43
+ >>> # Create runtime (with pool)
44
+ >>> pool = await asyncpg.create_pool(...)
45
+ >>> runtime = PostgresRepositoryRuntime(pool, contract)
46
+ >>>
47
+ >>> # Execute operation
48
+ >>> user = await runtime.call("find_by_id", 123)
49
+ """
50
+
51
+ from __future__ import annotations
52
+
53
+ import asyncio
54
+ import logging
55
+ import re
56
+ import time
57
+ from typing import TYPE_CHECKING
58
+
59
+ from omnibase_infra.enums import EnumInfraTransportType
60
+ from omnibase_infra.errors.repository import (
61
+ RepositoryContractError,
62
+ RepositoryExecutionError,
63
+ RepositoryTimeoutError,
64
+ RepositoryValidationError,
65
+ )
66
+ from omnibase_infra.models.errors import ModelInfraErrorContext
67
+ from omnibase_infra.runtime.db.models import (
68
+ ModelDbOperation,
69
+ ModelDbRepositoryContract,
70
+ ModelRepositoryRuntimeConfig,
71
+ )
72
+
73
+ if TYPE_CHECKING:
74
+ import asyncpg
75
+
76
+ logger = logging.getLogger(__name__)
77
+
78
+ # =============================================================================
79
+ # SQL Clause Detection Patterns
80
+ # =============================================================================
81
+ #
82
+ # These regex patterns provide simple ORDER BY and LIMIT clause detection
83
+ # for determinism enforcement. They use word boundaries (\b) and case-insensitive
84
+ # matching to identify SQL keywords.
85
+ #
86
+ # KNOWN LIMITATIONS:
87
+ # -----------------
88
+ # These patterns use simple regex matching, NOT a full SQL parser. As such,
89
+ # they can produce false positives in certain edge cases:
90
+ #
91
+ # 1. String Literals: Patterns inside quoted strings will match:
92
+ # - SELECT description FROM items WHERE note = 'sort ORDER BY priority'
93
+ # - SELECT * FROM logs WHERE message LIKE '%LIMIT 10 reached%'
94
+ #
95
+ # 2. Subqueries: Patterns in nested queries will match the outer detection:
96
+ # - SELECT * FROM (SELECT id FROM users ORDER BY created_at LIMIT 5) sub
97
+ # - The outer query appears to have ORDER BY/LIMIT, but doesn't
98
+ #
99
+ # 3. Comments: Patterns inside SQL comments will match:
100
+ # - SELECT * FROM users -- ORDER BY id for debugging
101
+ # - SELECT * FROM users /* LIMIT 100 was here */
102
+ #
103
+ # WHY THIS IS ACCEPTABLE:
104
+ # ----------------------
105
+ # 1. Contract SQL should be simple, predictable queries. Complex queries with
106
+ # subqueries, dynamic string construction, or embedded SQL in literals
107
+ # indicate contract design that should be reconsidered.
108
+ #
109
+ # 2. This detection is defense-in-depth, not primary validation. The contract
110
+ # author has explicit control over the SQL and can always add explicit
111
+ # ORDER BY and LIMIT clauses to avoid injection entirely.
112
+ #
113
+ # 3. False positives (detecting ORDER BY/LIMIT when not present at outer level)
114
+ # are safer than false negatives. A false positive skips injection, leaving
115
+ # the query unchanged. A false negative would inject duplicate clauses.
116
+ #
117
+ # RECOMMENDATION FOR COMPLEX QUERIES:
118
+ # ----------------------------------
119
+ # If your contract requires complex SQL with subqueries or string operations
120
+ # that contain SQL keywords, explicitly include ORDER BY and LIMIT in the
121
+ # outer query. This bypasses regex detection entirely:
122
+ #
123
+ # GOOD: "SELECT * FROM (SELECT id FROM users ORDER BY id) sub ORDER BY id LIMIT 100"
124
+ # AVOID: Relying on injection for queries with embedded SQL-like strings
125
+ #
126
+ # =============================================================================
127
+ _ORDER_BY_PATTERN = re.compile(r"\bORDER\s+BY\b", re.IGNORECASE)
128
+ _LIMIT_PATTERN = re.compile(r"\bLIMIT\s+(\d+)\b", re.IGNORECASE)
129
+
130
+
131
+ class PostgresRepositoryRuntime:
132
+ """Runtime for executing repository contracts against PostgreSQL.
133
+
134
+ Executes operations defined in a ModelDbRepositoryContract with
135
+ safety constraints, determinism guarantees, and configurable limits.
136
+
137
+ Thread Safety:
138
+ This class is NOT thread-safe for concurrent modifications.
139
+ The pool itself handles connection-level concurrency.
140
+ Multiple coroutines may call() concurrently on the same runtime.
141
+
142
+ Attributes:
143
+ pool: asyncpg connection pool for database access.
144
+ contract: Repository contract defining available operations.
145
+ config: Runtime configuration for safety and behavior.
146
+
147
+ Example:
148
+ >>> pool = await asyncpg.create_pool(dsn="postgresql://...")
149
+ >>> runtime = PostgresRepositoryRuntime(pool, contract)
150
+ >>> results = await runtime.call("find_all")
151
+ """
152
+
153
+ __slots__ = ("_config", "_contract", "_pool")
154
+
155
+ def __init__(
156
+ self,
157
+ pool: asyncpg.Pool,
158
+ contract: ModelDbRepositoryContract,
159
+ config: ModelRepositoryRuntimeConfig | None = None,
160
+ ) -> None:
161
+ """Initialize the repository runtime.
162
+
163
+ Args:
164
+ pool: asyncpg connection pool for database access.
165
+ contract: Repository contract defining available operations.
166
+ config: Optional runtime configuration. If None, uses defaults.
167
+
168
+ Example:
169
+ >>> runtime = PostgresRepositoryRuntime(
170
+ ... pool=pool,
171
+ ... contract=contract,
172
+ ... config=ModelRepositoryRuntimeConfig(max_row_limit=100),
173
+ ... )
174
+ """
175
+ self._pool = pool
176
+ self._contract = contract
177
+ self._config = config or ModelRepositoryRuntimeConfig()
178
+
179
+ @property
180
+ def contract(self) -> ModelDbRepositoryContract:
181
+ """Get the repository contract."""
182
+ return self._contract
183
+
184
+ @property
185
+ def config(self) -> ModelRepositoryRuntimeConfig:
186
+ """Get the runtime configuration."""
187
+ return self._config
188
+
189
+ async def call(
190
+ self, op_name: str, *args: object
191
+ ) -> list[dict[str, object]] | dict[str, object] | None:
192
+ """Execute a named operation from the contract.
193
+
194
+ Validates the operation exists, checks allowed operations,
195
+ validates argument count, applies determinism and limit
196
+ constraints, and executes with timeout enforcement.
197
+
198
+ Args:
199
+ op_name: Operation name as defined in contract.ops.
200
+ *args: Positional arguments matching contract params order.
201
+
202
+ Returns:
203
+ For many=True: list of dicts (possibly empty)
204
+ For many=False: single dict or None if no row found
205
+
206
+ Raises:
207
+ RepositoryContractError: Operation not found, forbidden mode,
208
+ or determinism constraint violation (no PK for multi-row).
209
+ RepositoryValidationError: Argument count mismatch.
210
+ RepositoryExecutionError: Database execution error.
211
+ RepositoryTimeoutError: Query exceeded timeout.
212
+
213
+ Example:
214
+ >>> # Single row lookup
215
+ >>> user = await runtime.call("find_by_id", 123)
216
+ >>> # Multi-row query
217
+ >>> users = await runtime.call("find_by_status", "active")
218
+ """
219
+ start_time = time.monotonic()
220
+ context = self._create_error_context(op_name)
221
+
222
+ # Lookup operation in contract
223
+ operation = self._get_operation(op_name, context)
224
+
225
+ # Validate operation is allowed
226
+ self._validate_operation_allowed(operation, op_name, context)
227
+
228
+ # Validate argument count
229
+ self._validate_arg_count(operation, args, op_name, context)
230
+
231
+ # Build final SQL with determinism and limit constraints
232
+ sql = self._build_sql(operation, op_name, context)
233
+
234
+ # Execute with timeout
235
+ try:
236
+ result = await self._execute_with_timeout(
237
+ sql, args, operation, op_name, context
238
+ )
239
+ except TimeoutError as e:
240
+ timeout_seconds = self._config.timeout_ms / 1000.0
241
+ raise RepositoryTimeoutError(
242
+ f"Query '{op_name}' exceeded timeout of {timeout_seconds}s",
243
+ op_name=op_name,
244
+ table=self._get_primary_table(),
245
+ timeout_seconds=timeout_seconds,
246
+ sql_fingerprint=self._fingerprint_sql(sql),
247
+ context=context,
248
+ ) from e
249
+
250
+ # Log metrics if enabled
251
+ if self._config.emit_metrics:
252
+ elapsed_ms = (time.monotonic() - start_time) * 1000
253
+ row_count = (
254
+ len(result) if isinstance(result, list) else (1 if result else 0)
255
+ )
256
+ logger.info(
257
+ "Repository operation completed",
258
+ extra={
259
+ "op_name": op_name,
260
+ "duration_ms": round(elapsed_ms, 2),
261
+ "rows_returned": row_count,
262
+ "repository": self._contract.name,
263
+ },
264
+ )
265
+
266
+ return result
267
+
268
+ def _create_error_context(self, op_name: str) -> ModelInfraErrorContext:
269
+ """Create error context for infrastructure errors."""
270
+ return ModelInfraErrorContext.with_correlation(
271
+ transport_type=EnumInfraTransportType.DATABASE,
272
+ operation=f"repository.{op_name}",
273
+ target_name=self._contract.name,
274
+ )
275
+
276
+ def _get_operation(
277
+ self, op_name: str, context: ModelInfraErrorContext
278
+ ) -> ModelDbOperation:
279
+ """Get operation from contract, raising error if not found."""
280
+ operation = self._contract.ops.get(op_name)
281
+ if operation is None:
282
+ available_ops = list(self._contract.ops.keys())
283
+ raise RepositoryContractError(
284
+ f"Unknown operation '{op_name}' not defined in contract '{self._contract.name}'. "
285
+ f"Available operations: {available_ops}",
286
+ op_name=op_name,
287
+ table=self._get_primary_table(),
288
+ context=context,
289
+ )
290
+ return operation
291
+
292
+ def _validate_operation_allowed(
293
+ self,
294
+ operation: ModelDbOperation,
295
+ op_name: str,
296
+ context: ModelInfraErrorContext,
297
+ ) -> None:
298
+ """Validate operation mode is allowed by config.
299
+
300
+ The contract uses 'read' or 'write' modes (validated by omnibase_core
301
+ validators at contract load time to ensure SQL verb matching).
302
+ """
303
+ mode = operation.mode
304
+
305
+ # Check write operations against feature flag
306
+ if mode == "write" and not self._config.allow_write_operations:
307
+ raise RepositoryContractError(
308
+ f"Operation '{op_name}' uses 'write' mode which is disabled. "
309
+ "Set allow_write_operations=True in config to enable.",
310
+ op_name=op_name,
311
+ table=self._get_primary_table(),
312
+ context=context,
313
+ )
314
+
315
+ # Check mode against allowlist
316
+ if mode not in self._config.allowed_modes:
317
+ raise RepositoryContractError(
318
+ f"Operation mode '{mode}' for '{op_name}' is not in allowed_modes. "
319
+ f"Allowed: {set(self._config.allowed_modes)}",
320
+ op_name=op_name,
321
+ table=self._get_primary_table(),
322
+ context=context,
323
+ )
324
+
325
+ def _validate_arg_count(
326
+ self,
327
+ operation: ModelDbOperation,
328
+ args: tuple[object, ...],
329
+ op_name: str,
330
+ context: ModelInfraErrorContext,
331
+ ) -> None:
332
+ """Validate argument count matches contract params.
333
+
334
+ Contract params is a dict[str, ModelDbParam] where keys are param names.
335
+ """
336
+ param_names = list(operation.params.keys())
337
+ expected = len(param_names)
338
+ actual = len(args)
339
+ if actual != expected:
340
+ raise RepositoryValidationError(
341
+ f"Operation '{op_name}' expects {expected} argument(s) ({param_names}), "
342
+ f"but received {actual}",
343
+ op_name=op_name,
344
+ table=self._get_primary_table(),
345
+ context=context,
346
+ expected_args=expected,
347
+ actual_args=actual,
348
+ param_names=param_names,
349
+ )
350
+
351
+ def _build_sql(
352
+ self,
353
+ operation: ModelDbOperation,
354
+ op_name: str,
355
+ context: ModelInfraErrorContext,
356
+ ) -> str:
357
+ """Build final SQL with determinism and limit constraints.
358
+
359
+ Applies ORDER BY injection for multi-row queries without ORDER BY.
360
+ Applies LIMIT injection or validation based on config.
361
+
362
+ Only applies constraints to 'read' mode operations (SELECT).
363
+ """
364
+ sql = operation.sql
365
+ is_read = operation.mode == "read"
366
+ is_multi_row = operation.returns.many
367
+
368
+ # Only apply constraints to read operations
369
+ if not is_read:
370
+ return sql
371
+
372
+ # Apply determinism constraints for multi-row reads
373
+ if is_multi_row:
374
+ sql = self._inject_order_by(sql, op_name, context)
375
+
376
+ # Apply limit constraints for multi-row reads
377
+ if is_multi_row:
378
+ sql = self._inject_limit(sql, op_name, context)
379
+
380
+ return sql
381
+
382
+ def _inject_order_by(
383
+ self,
384
+ sql: str,
385
+ op_name: str,
386
+ context: ModelInfraErrorContext,
387
+ ) -> str:
388
+ """Inject ORDER BY clause for deterministic multi-row results.
389
+
390
+ Rules:
391
+ - If ORDER BY exists: no injection needed
392
+ - If no ORDER BY and PK declared: inject ORDER BY {pk}
393
+ - If no ORDER BY and no PK: HARD ERROR
394
+
395
+ Args:
396
+ sql: The SQL query to potentially modify.
397
+ op_name: Operation name for error context.
398
+ context: Error context for exception raising.
399
+
400
+ Returns:
401
+ SQL with ORDER BY clause (injected or original).
402
+
403
+ Raises:
404
+ RepositoryContractError: No ORDER BY and no primary_key_column.
405
+ """
406
+ has_order_by = bool(_ORDER_BY_PATTERN.search(sql))
407
+ if has_order_by:
408
+ return sql
409
+
410
+ # No ORDER BY - check if we can inject
411
+ pk_column = self._config.primary_key_column
412
+ if pk_column is None:
413
+ raise RepositoryContractError(
414
+ f"Multi-row query '{op_name}' has no ORDER BY clause and "
415
+ "primary_key_column is not configured. Deterministic results "
416
+ "cannot be guaranteed. Either add ORDER BY to the SQL or "
417
+ "set primary_key_column in config.",
418
+ op_name=op_name,
419
+ table=self._get_primary_table(),
420
+ sql_fingerprint=self._fingerprint_sql(sql),
421
+ context=context,
422
+ )
423
+
424
+ # Inject ORDER BY using configured order or just PK
425
+ order_by = self._config.default_order_by or pk_column
426
+ return f"{sql.rstrip().rstrip(';')} ORDER BY {order_by}"
427
+
428
+ def _inject_limit(
429
+ self,
430
+ sql: str,
431
+ op_name: str,
432
+ context: ModelInfraErrorContext,
433
+ ) -> str:
434
+ """Inject or validate LIMIT clause for multi-row results.
435
+
436
+ Rules:
437
+ - If LIMIT > max_row_limit: HARD ERROR
438
+ - If no LIMIT: inject LIMIT {max_row_limit}
439
+ - If LIMIT <= max_row_limit: OK (no change)
440
+
441
+ Args:
442
+ sql: The SQL query to potentially modify.
443
+ op_name: Operation name for error context.
444
+ context: Error context for exception raising.
445
+
446
+ Returns:
447
+ SQL with LIMIT clause (injected or original).
448
+
449
+ Raises:
450
+ RepositoryContractError: LIMIT exceeds max_row_limit.
451
+ """
452
+ max_limit = self._config.max_row_limit
453
+ limit_match = _LIMIT_PATTERN.search(sql)
454
+
455
+ if limit_match:
456
+ # Existing LIMIT - validate it
457
+ existing_limit = int(limit_match.group(1))
458
+ if existing_limit > max_limit:
459
+ raise RepositoryContractError(
460
+ f"Query '{op_name}' has LIMIT {existing_limit} which exceeds "
461
+ f"max_row_limit of {max_limit}. Reduce the LIMIT or increase "
462
+ "max_row_limit in config.",
463
+ op_name=op_name,
464
+ table=self._get_primary_table(),
465
+ sql_fingerprint=self._fingerprint_sql(sql),
466
+ context=context,
467
+ existing_limit=existing_limit,
468
+ max_row_limit=max_limit,
469
+ )
470
+ return sql
471
+
472
+ # No LIMIT - inject one
473
+ return f"{sql.rstrip().rstrip(';')} LIMIT {max_limit}"
474
+
475
+ async def _execute_with_timeout(
476
+ self,
477
+ sql: str,
478
+ args: tuple[object, ...],
479
+ operation: ModelDbOperation,
480
+ op_name: str,
481
+ context: ModelInfraErrorContext,
482
+ ) -> list[dict[str, object]] | dict[str, object] | None:
483
+ """Execute query with timeout enforcement.
484
+
485
+ Uses asyncio.wait_for() to enforce timeout.
486
+ Uses fetch() for many=True, fetchrow() for many=False.
487
+
488
+ Args:
489
+ sql: Final SQL query to execute.
490
+ args: Positional arguments for the query.
491
+ operation: Operation specification.
492
+ op_name: Operation name for error context.
493
+ context: Error context for exception raising.
494
+
495
+ Returns:
496
+ Query results as appropriate type.
497
+
498
+ Raises:
499
+ asyncio.TimeoutError: Query exceeded timeout (caught by caller).
500
+ RepositoryExecutionError: Database execution error.
501
+ """
502
+ timeout_seconds = self._config.timeout_ms / 1000.0
503
+
504
+ try:
505
+ async with self._pool.acquire() as conn:
506
+ if operation.returns.many:
507
+ # Multi-row: use fetch()
508
+ coro = conn.fetch(sql, *args)
509
+ records = await asyncio.wait_for(coro, timeout=timeout_seconds)
510
+ return [dict(record) for record in records]
511
+ else:
512
+ # Single-row: use fetchrow()
513
+ coro = conn.fetchrow(sql, *args)
514
+ record = await asyncio.wait_for(coro, timeout=timeout_seconds)
515
+ return dict(record) if record is not None else None
516
+ except TimeoutError:
517
+ # Re-raise for caller to handle
518
+ raise
519
+ except Exception as e:
520
+ # Wrap all other exceptions
521
+ raise RepositoryExecutionError(
522
+ f"Failed to execute operation '{op_name}': {e}",
523
+ op_name=op_name,
524
+ table=self._get_primary_table(),
525
+ sql_fingerprint=self._fingerprint_sql(sql),
526
+ context=context,
527
+ ) from e
528
+
529
+ def _get_primary_table(self) -> str | None:
530
+ """Get the primary table from contract for error context."""
531
+ return self._contract.tables[0] if self._contract.tables else None
532
+
533
+ def _fingerprint_sql(self, sql: str) -> str:
534
+ """Create a safe fingerprint of SQL for logging/errors.
535
+
536
+ Truncates long SQL and removes potentially sensitive values.
537
+ """
538
+ # Simple approach: truncate to reasonable length
539
+ max_len = 200
540
+ if len(sql) <= max_len:
541
+ return sql
542
+ return sql[:max_len] + "..."
543
+
544
+
545
+ __all__: list[str] = ["PostgresRepositoryRuntime"]
@@ -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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: omnibase_infra
3
- Version: 0.2.9
3
+ Version: 0.3.0
4
4
  Summary: ONEX Infrastructure - Service integration and database infrastructure tools
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -28,7 +28,7 @@ Requires-Dist: jinja2 (>=3.1.6,<4.0.0)
28
28
  Requires-Dist: jsonschema (>=4.20.0,<5.0.0)
29
29
  Requires-Dist: mcp (>=1.25.0,<2.0.0)
30
30
  Requires-Dist: neo4j (>=5.15.0,<6.0.0)
31
- Requires-Dist: omnibase-core (>=0.11.0,<0.12.0)
31
+ Requires-Dist: omnibase-core (>=0.12.0,<0.13.0)
32
32
  Requires-Dist: omnibase-spi (>=0.6.4,<0.7.0)
33
33
  Requires-Dist: opentelemetry-api (>=1.27.0,<2.0.0)
34
34
  Requires-Dist: opentelemetry-exporter-otlp (>=1.27.0,<2.0.0)
@@ -1,4 +1,4 @@
1
- omnibase_infra/__init__.py,sha256=EeYAE_QMlLbRX8X_W3kMJh4d7tODmhIA1uGh2w0Rcvg,3853
1
+ omnibase_infra/__init__.py,sha256=GaHfYUvSgKlKfO2_asrsWp0245bbZP91s5O__WZPkHI,3853
2
2
  omnibase_infra/adapters/adapter_onex_tool_execution.py,sha256=gKiRTr3pc7-DNAS9_bSmLWssOr1FDCiciwE16cQF3Ro,15377
3
3
  omnibase_infra/capabilities/__init__.py,sha256=O6qQjWNwe0ZQt5hpGMMLx4CgagdpxBJzMGVpowi8eKY,462
4
4
  omnibase_infra/capabilities/capability_inference_rules.py,sha256=2VDLhvBlDOYyi1eCQGSNB8eXf2JQ4cG9Xftsb3P2xm0,8166
@@ -58,7 +58,7 @@ omnibase_infra/enums/enum_security_rule_id.py,sha256=xMhFMpwC6P9RyCo2DAeR-DFk59m
58
58
  omnibase_infra/enums/enum_selection_strategy.py,sha256=lRrJ-s6BpehlifYp4mD2YUcY7X2nEywY2uJ9FFo5EU4,2879
59
59
  omnibase_infra/enums/enum_topic_standard.py,sha256=tuPY1Antm3PSeM5L4eLb95U-Uoh4Wi0PTOvgH_h3FEE,1196
60
60
  omnibase_infra/enums/enum_validation_severity.py,sha256=Dl6zVgIS13bA-QeNK44YJfVxUzySzbXqGs83HJTCE0M,2858
61
- omnibase_infra/errors/__init__.py,sha256=zcn-2sukSn2UKsC75jqOWyPZk9yXQ_NB6Daw3AFFhUg,6234
61
+ omnibase_infra/errors/__init__.py,sha256=2-IxVUwNrbnJdYVXDYwBqlkQDHEVG0ry6Y5CkUebQac,6939
62
62
  omnibase_infra/errors/error_architecture_violation.py,sha256=2Q6r3pqDifdBiMhZdkdImnwfJIZM_fZP1TyoHZ2aUJA,5849
63
63
  omnibase_infra/errors/error_binding_resolution.py,sha256=gZgodKaUaYHJXNpBumcI4IPgkdtIuesowWMb-UWV9Yo,5083
64
64
  omnibase_infra/errors/error_chain_propagation.py,sha256=k8A5H7lYvyGiCBqYw2gRHUjlYWMF0NGJu2mtvGQCBoo,6663
@@ -70,6 +70,8 @@ omnibase_infra/errors/error_infra.py,sha256=LizVnhvT9QyRTJu2p-KLpaOQP653XrKNrcM7
70
70
  omnibase_infra/errors/error_message_type_registry.py,sha256=2lnv0g51JdjJKNBjxWV1LCsPboApNz9gKBoNUyxZoJY,3566
71
71
  omnibase_infra/errors/error_policy_registry.py,sha256=_tOy4OvYEmS0UuntEZZipuYd7UTfEJSbACRVp-9J9Go,4400
72
72
  omnibase_infra/errors/error_vault.py,sha256=eS9wa_NWj3iVRFKz8GSkqaYW_O1DYdCQTaDDAyATgls,4686
73
+ omnibase_infra/errors/repository/__init__.py,sha256=Gn4BuBRIr5IgKaUxkOCtMI7GV3UdhbiZhIJ6iA4oJkc,2594
74
+ omnibase_infra/errors/repository/errors_repository.py,sha256=l0chIh-CWm2AUYB8PGPGvn3aaMPxhHS4ltLsCio9QtA,14865
73
75
  omnibase_infra/event_bus/__init__.py,sha256=aVcWzLBHWwwEbv5N7m2DQggnkQAjXnnk3_CfbLp_XjE,2410
74
76
  omnibase_infra/event_bus/adapters/__init__.py,sha256=FBEFQReRb-Cci-2xXMEer3pFauEOgtIZSXLnK4ByWm4,974
75
77
  omnibase_infra/event_bus/adapters/adapter_protocol_event_publisher_kafka.py,sha256=kZ53jGOiPNYuhP_EomHOKDybcoGJ28uBsCGsLDDlGsM,20379
@@ -422,7 +424,7 @@ omnibase_infra/nodes/contract_registry_reducer/models/model_payload_update_heart
422
424
  omnibase_infra/nodes/contract_registry_reducer/models/model_payload_update_topic.py,sha256=hIjvOofGdoP77WTVrxrO57lzerlBfqgPpA8Ht_ZpHfE,2316
423
425
  omnibase_infra/nodes/contract_registry_reducer/models/model_payload_upsert_contract.py,sha256=d1cFXpCl9TjuMaGfYGIggGka3nfjGtwS7heY8-zW7vg,3587
424
426
  omnibase_infra/nodes/contract_registry_reducer/node.py,sha256=hgPBU8LqCsn7USzf5pV8idfiGfNNOekhZkmJvN647iE,4761
425
- omnibase_infra/nodes/contract_registry_reducer/reducer.py,sha256=H8PD2NncsisljZdFl3MfUExG2rxq2nZaUqbZ8vJpABQ,30654
427
+ omnibase_infra/nodes/contract_registry_reducer/reducer.py,sha256=qAba8_yTAZf3It6ybDTknA-HHZPKbKVr_ThZBu3NTnU,31274
426
428
  omnibase_infra/nodes/contract_registry_reducer/registry/__init__.py,sha256=_Stta6Gviw7hTN0LNn_Dr_mpMjkNkfFoHXsS390fVEA,329
427
429
  omnibase_infra/nodes/contract_registry_reducer/registry/registry_infra_contract_registry_reducer.py,sha256=zW1EX-I704DNDqmsh4Lz6KFPV_my1ffFWCqPRMilwyE,3617
428
430
  omnibase_infra/nodes/effects/README.md,sha256=p0Go_-GuZRnp9MD7u6TX3mF2HcqEQruq4ZQmJNiAsR4,12500
@@ -634,6 +636,10 @@ omnibase_infra/runtime/contract_handler_discovery.py,sha256=1LrZHKkHcpdyaMDXxK3d
634
636
  omnibase_infra/runtime/contract_loaders/__init__.py,sha256=Ake8OEryHodK1SxmEBIuqVAH3Uw3ySSsAxqvSaDfRyY,1758
635
637
  omnibase_infra/runtime/contract_loaders/handler_routing_loader.py,sha256=bvvZIxjl3mJw9TknRBwPa9ybXXl1J6r7PFkSkdPPLYk,17313
636
638
  omnibase_infra/runtime/contract_loaders/operation_bindings_loader.py,sha256=TaOsLzdejsuIH-lZ-oY7eA_U_KMVyIc044oXU26MH6s,29808
639
+ omnibase_infra/runtime/db/__init__.py,sha256=WZLFf7XIXAefkUIiA1sg3Npw120P9zaqK6862mq7wgM,2380
640
+ omnibase_infra/runtime/db/models/__init__.py,sha256=ENQ696584GQHSvbVN85PgEo3Agij5Oo10Vz7-FoVYBE,1377
641
+ omnibase_infra/runtime/db/models/model_repository_runtime_config.py,sha256=4X231FUSe8UywlFIhb4cuyEBk2G0FiJP7-X5-f8Zop0,7826
642
+ omnibase_infra/runtime/db/postgres_repository_runtime.py,sha256=74M8qR6We7DitPwstrFosJiiWXyjBpeVsfn4IXxuo2Q,20297
637
643
  omnibase_infra/runtime/dispatch_context_enforcer.py,sha256=44McRbtsqkGTiz7dQTOtV4AmisYOlVKKhI_1n5Jwziw,16620
638
644
  omnibase_infra/runtime/emit_daemon/__init__.py,sha256=wnc8rcQCu0vO10y8uqgoEFUsBbYQsJJiKYrJoLgEhsU,3012
639
645
  omnibase_infra/runtime/emit_daemon/cli.py,sha256=KP0h3f_cfmNcH-lsVl8rWc-m4Xlhuc0yN5VnNtvNM68,26117
@@ -856,7 +862,7 @@ omnibase_infra/validation/contracts/declarative_node.validation.yaml,sha256=bV2Y
856
862
  omnibase_infra/validation/contracts/security.validation.yaml,sha256=NixKgUo7KliQr1yJBY65j2WaxJv_XKoUSCA6pB77DiQ,3858
857
863
  omnibase_infra/validation/enums/__init__.py,sha256=J4vRP14R2lHaixXCk1MH5Bzh3Vd0pZmySpN8PkqJc4c,278
858
864
  omnibase_infra/validation/enums/enum_contract_violation_severity.py,sha256=beR4vRNXtQ7ckOSOYZHn3NAacZBNTX1csG9_Y6SPd7M,414
859
- omnibase_infra/validation/infra_validators.py,sha256=5fpBbOgVhzOK8BwCzeOlVDVQoB0tldGAw3vgYCN6hNU,61255
865
+ omnibase_infra/validation/infra_validators.py,sha256=jK7b_6Sby9Fa_YTp93BQOfl1gbPbZnRq2Qjn6bUyOYU,61475
860
866
  omnibase_infra/validation/linter_contract.py,sha256=Lv6UkyXx7WFm7Yxwwt8ahXRl-QWfY980Ge7OABUcE5s,33629
861
867
  omnibase_infra/validation/mixin_any_type_classification.py,sha256=F1WoGIR_RzZpiHPOVIr-6gOLzD2qWJBnYoqPrLCIiVU,3957
862
868
  omnibase_infra/validation/mixin_any_type_exemption.py,sha256=KmKZC8znLuqOuT9vWsUjUF5Lb3aqoI3XgJLXTNNYqIU,23002
@@ -867,7 +873,7 @@ omnibase_infra/validation/models/__init__.py,sha256=p-8vUFXuk-BeJYaWXBbk5DrHq9DZ
867
873
  omnibase_infra/validation/models/model_contract_lint_result.py,sha256=Td6OH1VIV7JHPTTZN_iKLM1BQRCtxsjZIMR_DrNau-k,3343
868
874
  omnibase_infra/validation/models/model_contract_violation.py,sha256=xRYr-waBuwNVmcHS-ZqoD4g0iLzwtZiibb-Sc4BibaU,1362
869
875
  omnibase_infra/validation/service_validation_aggregator.py,sha256=pm7kvtch85hc0ajSKMZ_DPVVsBKZ7JaVYSJsQfpQHr4,14019
870
- omnibase_infra/validation/validation_exemptions.yaml,sha256=s7aTrP0p7-2ALqBcj7nYmRvFGC-8IA2Q6Si7YJhFaTQ,124328
876
+ omnibase_infra/validation/validation_exemptions.yaml,sha256=wIYYCFfi1NmB6b2lPD3G-Nyt4gO7zv3Wz11z3VsyJtk,125533
871
877
  omnibase_infra/validation/validator_any_type.py,sha256=m89Ae6ctmS920yjy6yUvARMcTMVsMnrGby9VlaLRVVw,26285
872
878
  omnibase_infra/validation/validator_chain_propagation.py,sha256=JmoYAAH9E0Z_HWh2AGG1WS5zc3lPtq46CjQmmm7IYck,35686
873
879
  omnibase_infra/validation/validator_declarative_node.py,sha256=dl8b1eZK9NpzyHZpx5_L_GAnGuaNl3HIRc_IdK1MmYo,31838
@@ -878,8 +884,8 @@ omnibase_infra/validation/validator_routing_coverage.py,sha256=51vYEi5NhU6wqohk2
878
884
  omnibase_infra/validation/validator_runtime_shape.py,sha256=9Xl37_dNDinT7nr-BoJ9fG3O5cT1_j6N-C7bojwQi3g,39033
879
885
  omnibase_infra/validation/validator_security.py,sha256=Yn_kwxBtPzEj1GzrW0OafL-bR-FgoqdeFzseQqF2_B8,20622
880
886
  omnibase_infra/validation/validator_topic_category.py,sha256=1y6STpSNIJsE2AmX5f8PVzPuOfoQmedgocSbEqOdtrM,48798
881
- omnibase_infra-0.2.9.dist-info/METADATA,sha256=1uOeeZ8daXFsr3VY4HQoXqppGSqNi1hTNA2PjQJMaLU,7554
882
- omnibase_infra-0.2.9.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
883
- omnibase_infra-0.2.9.dist-info/entry_points.txt,sha256=8jORmczvjPYrahcGRwxtuVqh8KIFOfb04GgnRnQfNsQ,166
884
- omnibase_infra-0.2.9.dist-info/licenses/LICENSE,sha256=CwYWppeN0neFHYdbbUdHbR4_PiyTYnmk6ufFWuVsL7I,1070
885
- omnibase_infra-0.2.9.dist-info/RECORD,,
887
+ omnibase_infra-0.3.0.dist-info/METADATA,sha256=0N0aDXnWUfwLdAWoj6ivITqhPj681TUwj9salQS_Ens,7554
888
+ omnibase_infra-0.3.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
889
+ omnibase_infra-0.3.0.dist-info/entry_points.txt,sha256=8jORmczvjPYrahcGRwxtuVqh8KIFOfb04GgnRnQfNsQ,166
890
+ omnibase_infra-0.3.0.dist-info/licenses/LICENSE,sha256=CwYWppeN0neFHYdbbUdHbR4_PiyTYnmk6ufFWuVsL7I,1070
891
+ omnibase_infra-0.3.0.dist-info/RECORD,,