Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
c846c50
feat(models): add ModelContractPatch and patch validation system (OMN…
jonahgabriel Dec 30, 2025
d53ca60
feat(contracts): enhance patch validation and add helper methods (OMN…
jonahgabriel Dec 30, 2025
6e56442
refactor(models): rename ModelHandlerDescriptor to ModelHandlerBehavi…
jonahgabriel Dec 30, 2025
db991d5
chore(validation): add ContractPatchValidator to naming exemptions (O…
jonahgabriel Dec 30, 2025
59244d5
fix(contracts): address PR review feedback for patch validation (OMN-…
jonahgabriel Dec 30, 2025
4faceda
fix(contracts): address PR #289 review feedback (OMN-1126)
jonahgabriel Dec 30, 2025
dadf401
Merge branch 'main' into jonah/omn-1126-modelcontractpatch-patch-vali…
jonahgabriel Dec 30, 2025
25757cd
feat(manifest): add execution manifest generation for pipeline observ…
Dec 30, 2025
b97c19a
fix(contracts): fix CI failure and address remaining PR #289 feedback…
jonahgabriel Dec 30, 2025
69f6403
fix(mixins): remove backwards compatibility and extract ProtocolFromE…
Dec 30, 2025
4a7c9f2
fix(contracts): address all PR #289 feedback for release readiness (O…
jonahgabriel Dec 30, 2025
15a4d51
fix(manifest): address PR review feedback for manifest generation
Dec 30, 2025
002a190
fix(manifest): address additional PR review feedback
Dec 31, 2025
69320e3
fix(contracts): address final PR #289 nitpicks and polish for release…
jonahgabriel Dec 31, 2025
f886793
fix(manifest): address PR review feedback for release readiness
Dec 31, 2025
f8ee9e3
fix(contracts): fix CI failures and address remaining PR #289 feedbac…
jonahgabriel Dec 31, 2025
1ec1a7f
fix(manifest): address final PR review items for release readiness
Dec 31, 2025
39e97db
Merge branch 'main' into jonah/omn-1113-beta-manifest-generation-obse…
Dec 31, 2025
52b728a
fix(contracts): fix CI test failures and final PR #289 polish (OMN-1126)
jonahgabriel Dec 31, 2025
3476b30
fix(manifest): address all PR review feedback and pre-commit violations
Dec 31, 2025
1372f98
fix(manifest): address PR review feedback and fix CI mypy errors
Dec 31, 2025
5a86ae2
fix(manifest): address PR #294 review feedback
Dec 31, 2025
bf7c3e8
feat(models): add ModelProjectorContract and schema models (OMN-1166)
Jan 1, 2026
204f3ce
refactor(contracts): DRY up duplicate detection in ContractPatchValid…
jonahgabriel Jan 1, 2026
3de833a
Merge branch 'jonah/omn-1126-modelcontractpatch-patch-validation' int…
jonahgabriel Jan 1, 2026
648bf2b
Merge branch 'jonah/omn-1166-modelprojectorcontract-schema-models' in…
Jan 1, 2026
d2ed3f1
Merge branch 'jonah/omn-1113-beta-manifest-generation-observability' …
jonahgabriel Jan 1, 2026
290434c
docs(contracts): add handler contract guide with ID prefix convention
Jan 1, 2026
605fd88
fix(manifest): add EnumExecutionStatus classmethods and delegate from…
Jan 1, 2026
ea8787b
feat(security): add module allowlist for dynamic import resolution (O…
jonahgabriel Jan 1, 2026
103453a
refactor(contracts): improve code quality and maintainability (OMN-1126)
jonahgabriel Jan 1, 2026
0105041
fix: resolve all pre-commit hook violations
Jan 1, 2026
077d146
Merge branch 'main' into jonah/omn-1113-beta-manifest-generation-obse…
Jan 1, 2026
bf8ec13
Merge jonah/omn-1113-beta-manifest-generation-observability into OMN-…
jonahgabriel Jan 1, 2026
9e1ddf1
fix: resolve pre-push hook failures from merged branch (OMN-1126)
jonahgabriel Jan 1, 2026
061223c
fix: address all PR #289 review feedback (OMN-1126)
jonahgabriel Jan 1, 2026
46a513d
style: fix ruff formatting in test files (OMN-1126)
jonahgabriel Jan 1, 2026
80aabad
Merge branch 'main' into jonah/omn-1126-modelcontractpatch-patch-vali…
jonahgabriel Jan 1, 2026
1ab7909
fix: skip tests with circular import in ModelProviderDescriptor (OMN-…
jonahgabriel Jan 2, 2026
b78e392
fix: resolve CI failures and PR #289 review feedback (OMN-1126)
jonahgabriel Jan 2, 2026
820e870
fix: update import path for ModelToolSecuritySummary (OMN-1126)
jonahgabriel Jan 2, 2026
b8af310
docs: improve documentation and add security allowlist for PR #289 fe…
jonahgabriel Jan 2, 2026
c4f2cd7
Merge branch 'main' into jonah/omn-1126-modelcontractpatch-patch-vali…
jonahgabriel Jan 2, 2026
a157f2b
fix: address PR #289 review feedback - validation, security, and docs…
jonahgabriel Jan 2, 2026
3537fa6
fix: address PR review feedback - scoring docs, logging cleanup, test…
jonahgabriel Jan 2, 2026
4f844bc
Merge branch 'main' into jonah/omn-1126-modelcontractpatch-patch-vali…
jonahgabriel Jan 2, 2026
b52e8d3
style: fix end-of-file in schema file
jonahgabriel Jan 2, 2026
604f78a
fix: correct security allowlist test assertions (OMN-1126)
jonahgabriel Jan 2, 2026
b33b028
Merge branch 'main' into jonah/omn-1126-modelcontractpatch-patch-vali…
jonahgabriel Jan 3, 2026
e343fa0
fix: resolve CI test failures and PR review issues (OMN-1126)
jonahgabriel Jan 3, 2026
c0cf00e
Merge remote-tracking branch 'origin/main' into jonah/omn-1126-modelc…
jonahgabriel Jan 3, 2026
cfa6b84
fix: address remaining PR #289 review feedback (OMN-1126)
jonahgabriel Jan 3, 2026
de99bad
fix: address final PR #289 review feedback (OMN-1126)
jonahgabriel Jan 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 21 additions & 19 deletions docs/guides/CONTRACT_PATCHING_GUIDE.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Contract Patching Guide

**Version**: 1.0.1
**Last Updated**: 2025-12-31
**Version**: 1.0.2
**Last Updated**: 2026-01-03
**Status**: Comprehensive Reference

> **New in v0.4.0**: Contract patches provide a declarative way to extend base contracts produced by profile factories. This guide explains the patching system architecture, model reference, and end-to-end usage examples.
Expand Down Expand Up @@ -205,7 +205,7 @@ Partial behavior overrides for handler settings. This model is used in the `desc
```python
from omnibase_core.models.contracts.model_descriptor_patch import ModelDescriptorPatch

behavior = ModelDescriptorPatch(
descriptor = ModelDescriptorPatch(
purity="pure", # "pure" | "side_effecting"
idempotent=True, # Safe to retry?
timeout_ms=30000, # Max execution time
Expand Down Expand Up @@ -574,7 +574,7 @@ patch = ModelContractPatch(
),
)

# Verify descriptor overrides
# Verify behavior overrides
assert patch.descriptor.timeout_ms == 60000
assert patch.descriptor.retry_policy.max_retries == 5
```
Expand Down Expand Up @@ -784,31 +784,33 @@ These run when you call `validator.validate(patch)`:

| Check | Severity | Error Code |
|-------|----------|------------|
| Duplicate handlers in `handlers__add` | Error | `DUPLICATE_LIST_ENTRIES` |
| Duplicate dependencies in `dependencies__add` | Error | `DUPLICATE_LIST_ENTRIES` |
| Duplicate capabilities in `capability_outputs__add` | Error | `DUPLICATE_LIST_ENTRIES` |
| Duplicate inputs in `capability_inputs__add` | Error | `DUPLICATE_LIST_ENTRIES` |
| Empty behavior patch (no overrides) | Warning | `EMPTY_DESCRIPTOR_PATCH` |
| `purity="pure"` with `idempotent=False` | Warning | `PURITY_IDEMPOTENT_MISMATCH` |
| Duplicate handlers in `handlers__add` | Error | `CONTRACT_PATCH_DUPLICATE_LIST_ENTRIES` |
| Duplicate dependencies in `dependencies__add` | Error | `CONTRACT_PATCH_DUPLICATE_LIST_ENTRIES` |
| Duplicate capabilities in `capability_outputs__add` | Error | `CONTRACT_PATCH_DUPLICATE_LIST_ENTRIES` |
| Duplicate inputs in `capability_inputs__add` | Error | `CONTRACT_PATCH_DUPLICATE_LIST_ENTRIES` |
| Duplicate events in `consumed_events__add` | Error | `CONTRACT_PATCH_DUPLICATE_LIST_ENTRIES` |
| Empty behavior patch (no overrides) | Info | `CONTRACT_PATCH_EMPTY_DESCRIPTOR` |
| `purity="pure"` with `idempotent=False` | Warning | `CONTRACT_PATCH_PURITY_IDEMPOTENT_MISMATCH` |
| New contract identity declared | Info | `CONTRACT_PATCH_NEW_IDENTITY` |

#### 3. Format Validation (Warnings)

| Check | Description | Error Code |
|-------|-------------|------------|
| Profile Name | Should be lowercase_with_underscores | `NON_STANDARD_PROFILE_NAME` |
| Version Format | Should contain digits (semver) | `NON_STANDARD_VERSION_FORMAT` |
| Profile Name | Should be lowercase_with_underscores | `CONTRACT_PATCH_NON_STANDARD_PROFILE_NAME` |
| Version Format | Should contain digits (semver) | `CONTRACT_PATCH_NON_STANDARD_VERSION_FORMAT` |

#### 4. File Validation Error Codes

When using `validate_file()`:

| Condition | Error Code |
|-----------|------------|
| File does not exist | `FILE_NOT_FOUND` |
| Cannot read file | `FILE_READ_ERROR` |
| Non-.yaml/.yml extension | `UNEXPECTED_EXTENSION` (warning) |
| YAML parsing or validation error | `YAML_VALIDATION_ERROR` |
| Pydantic validation error | `PYDANTIC_VALIDATION_ERROR` |
| File does not exist | `CONTRACT_PATCH_FILE_NOT_FOUND` |
| Cannot read file | `CONTRACT_PATCH_FILE_READ_ERROR` |
| Non-.yaml/.yml extension | `CONTRACT_PATCH_UNEXPECTED_EXTENSION` (warning) |
| YAML parsing or validation error | `CONTRACT_PATCH_YAML_VALIDATION_ERROR` |
| Pydantic validation error | `CONTRACT_PATCH_PYDANTIC_VALIDATION_ERROR` |

### What Is NOT Validated (Deferred)

Expand Down Expand Up @@ -1028,6 +1030,6 @@ patch = ModelContractPatch(

---

**Last Updated**: 2025-12-31
**Version**: 1.0.1
**Last Updated**: 2026-01-03
**Version**: 1.0.2
**Maintainer**: ONEX Framework Team
6 changes: 3 additions & 3 deletions scripts/validation/validate-string-versions.py
Original file line number Diff line number Diff line change
Expand Up @@ -615,7 +615,7 @@ def validate_python_file(self, python_path: Path) -> bool:
try:
tree = ast.parse(content, filename=str(python_path))
# Pass source lines to enable inline comment bypass checking
source_lines = content.split("\n")
source_lines = content.splitlines()
ast_validator = PythonASTValidator(str(python_path), source_lines)
Comment thread
coderabbitai[bot] marked this conversation as resolved.
ast_validator.visit(tree)

Expand All @@ -642,7 +642,7 @@ def _validate_python_version_declarations(
errors: list[str],
) -> None:
"""Check Python content for hardcoded __version__ declarations."""
lines = content.split("\n")
lines = content.splitlines()

# Track bypass comments
bypass_patterns = [
Expand Down Expand Up @@ -805,7 +805,7 @@ def _validate_yaml_content_ast(
errors: list[str],
) -> None:
"""Use AST-like parsing to detect string versions in YAML content."""
lines = content.split("\n")
lines = content.splitlines()

version_field_patterns = [
"version:",
Expand Down
4 changes: 4 additions & 0 deletions src/omnibase_core/enums/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@

# Parameter and return type enums
from .enum_parameter_type import EnumParameterType

# Patch validation error codes (OMN-1126)
from .enum_patch_validation_error_code import EnumPatchValidationErrorCode
from .enum_query_parameter_transformation_type import (
EnumQueryParameterTransformationType,
)
Expand Down Expand Up @@ -283,6 +286,7 @@
"EnumCLIExitCode",
"EnumOnexErrorCode",
"EnumCoreErrorCode",
"EnumPatchValidationErrorCode",
"EnumRegistryErrorCode",
"CORE_ERROR_CODE_TO_EXIT_CODE",
"get_core_error_description",
Expand Down
3 changes: 2 additions & 1 deletion src/omnibase_core/enums/enum_likelihood.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,9 @@ def from_probability(cls, probability: float) -> EnumLikelihood:
from omnibase_core.errors import ModelOnexError

raise ModelOnexError(
f"probability must be between 0.0 and 1.0, got {probability}",
message=f"probability must be between 0.0 and 1.0, got {probability}",
error_code=EnumCoreErrorCode.VALIDATION_ERROR,
probability=probability,
)
if probability <= 0.0:
return cls.IMPOSSIBLE
Expand Down
102 changes: 102 additions & 0 deletions src/omnibase_core/enums/enum_patch_validation_error_code.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# SPDX-FileCopyrightText: 2025 OmniNode Team <info@omninode.ai>
#
# SPDX-License-Identifier: Apache-2.0
"""Patch validation error codes for contract patch validation.

These error codes are used by ContractPatchValidator to categorize
validation issues in contract patches. They provide type-safe
identification of validation errors and warnings.

Error Code Categories:
- List Operations: Duplicate detection within add lists
- Descriptor/Behavior: Behavior patch consistency issues
- Identity: Contract identity field issues
- Profile: Profile reference format issues
- File I/O: File access and parsing issues
- Validation: General validation errors

Related:
- OMN-1126: ModelContractPatch & Patch Validation
- ContractPatchValidator: The validator that uses these codes

.. versionadded:: 0.4.0
"""

from enum import Enum


class EnumPatchValidationErrorCode(str, Enum):
"""Error codes for contract patch validation.

These codes categorize the types of issues that can be detected
during contract patch validation. They are used in validation
results to provide machine-readable issue identification.

All error codes follow the CONTRACT_PATCH_* prefix convention for
consistent categorization and type-safe identification per PR #289.

Attributes:
CONTRACT_PATCH_DUPLICATE_LIST_ENTRIES: Duplicate items within an add list
CONTRACT_PATCH_EMPTY_DESCRIPTOR: Behavior patch with no overrides
CONTRACT_PATCH_PURITY_IDEMPOTENT_MISMATCH: Conflicting purity/idempotent settings
CONTRACT_PATCH_NEW_IDENTITY: Informational - new contract identity declared
CONTRACT_PATCH_NON_STANDARD_PROFILE_NAME: Profile name doesn't follow conventions
CONTRACT_PATCH_NON_STANDARD_VERSION_FORMAT: Version string format is non-standard
CONTRACT_PATCH_FILE_NOT_FOUND: File does not exist
CONTRACT_PATCH_FILE_READ_ERROR: File could not be read
CONTRACT_PATCH_UNEXPECTED_EXTENSION: File has unexpected extension
CONTRACT_PATCH_YAML_VALIDATION_ERROR: YAML parsing or validation error
CONTRACT_PATCH_PYDANTIC_VALIDATION_ERROR: Pydantic model validation error

Example:
>>> from omnibase_core.enums import EnumPatchValidationErrorCode
>>> code = EnumPatchValidationErrorCode.CONTRACT_PATCH_DUPLICATE_LIST_ENTRIES
>>> result.add_error("Duplicate handler found", code=code.value)
"""

# List operation errors
CONTRACT_PATCH_DUPLICATE_LIST_ENTRIES = "CONTRACT_PATCH_DUPLICATE_LIST_ENTRIES"
"""Duplicate items found within an add list (e.g., handlers__add)."""

# Descriptor/Behavior errors
CONTRACT_PATCH_EMPTY_DESCRIPTOR = "CONTRACT_PATCH_EMPTY_DESCRIPTOR"
"""Behavior patch (descriptor field) is present but has no overrides."""

CONTRACT_PATCH_PURITY_IDEMPOTENT_MISMATCH = (
"CONTRACT_PATCH_PURITY_IDEMPOTENT_MISMATCH"
)
"""Conflicting purity='pure' with idempotent=False settings."""

# Identity errors
CONTRACT_PATCH_NEW_IDENTITY = "CONTRACT_PATCH_NEW_IDENTITY"
"""Informational: Patch declares a new contract identity (name + version)."""

# Profile reference errors
CONTRACT_PATCH_NON_STANDARD_PROFILE_NAME = (
"CONTRACT_PATCH_NON_STANDARD_PROFILE_NAME"
)
"""Profile name doesn't follow lowercase_with_underscores convention."""

CONTRACT_PATCH_NON_STANDARD_VERSION_FORMAT = (
"CONTRACT_PATCH_NON_STANDARD_VERSION_FORMAT"
)
"""Version string format is non-standard (expected semver-like)."""

# File I/O errors
CONTRACT_PATCH_FILE_NOT_FOUND = "CONTRACT_PATCH_FILE_NOT_FOUND"
"""The specified file does not exist."""

CONTRACT_PATCH_FILE_READ_ERROR = "CONTRACT_PATCH_FILE_READ_ERROR"
"""The file could not be read (I/O error)."""

CONTRACT_PATCH_UNEXPECTED_EXTENSION = "CONTRACT_PATCH_UNEXPECTED_EXTENSION"
"""File has unexpected extension (expected .yaml or .yml)."""

# Validation errors
CONTRACT_PATCH_YAML_VALIDATION_ERROR = "CONTRACT_PATCH_YAML_VALIDATION_ERROR"
"""YAML parsing or validation error occurred."""

CONTRACT_PATCH_PYDANTIC_VALIDATION_ERROR = (
"CONTRACT_PATCH_PYDANTIC_VALIDATION_ERROR"
)
"""Pydantic model validation error occurred."""
Loading