Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
aabd3b3
feat(models): replace dict[str, Any] with typed discriminated unions …
Dec 25, 2025
75c1d67
fix(models): resolve Pydantic forward reference and PR review feedbac…
Dec 25, 2025
4c2a8cc
fix(models): address PR #239 review feedback for typed payloads (OMN-…
Dec 25, 2025
de5fa83
fix(models): address PR #239 review feedback with tests and improveme…
Dec 25, 2025
a11087f
fix(models): remove all backwards compatibility and use Protocol-base…
Dec 25, 2025
7f89cd6
fix(ci): resolve linting and documentation issues for PR #239 (OMN-1008)
Dec 25, 2025
3c1b3f9
fix(models): add kind property and typed payloads for Protocol compli…
Dec 25, 2025
9657c4d
fix(models): remove all deprecations, backwards compatibility, and fi…
Dec 25, 2025
e9b5d86
Merge origin/main into feature branch
Dec 25, 2025
6d05cd3
fix(tests): update tests for typed payload architecture and fix PR #2…
Dec 25, 2025
c92af9d
fix(pr-239): address remaining PR review issues and improve code quality
Dec 26, 2025
94d128f
fix(pr-239): address final PR review issues including nitpicks
Dec 26, 2025
7a3d7e9
fix(pr-239): address all remaining PR review issues for release readi…
Dec 26, 2025
a9e3511
fix(pr-239): address release-ready PR review issues
Dec 26, 2025
ab60432
Merge origin/main into feature branch
Dec 26, 2025
98cf99d
fix: remove deprecation warning, use typed inputs
Dec 26, 2025
e5e37dd
fix(pr-239): address final release-ready review issues
Dec 26, 2025
1b01d1b
fix(pr-239): remove unused imports and fix remaining review issues
Dec 26, 2025
0c79774
fix(pr-239): address release-ready review issues
Dec 26, 2025
8710711
docs: enhance payload architecture documentation and add version pars…
Dec 26, 2025
e7bd702
Merge origin/main into feature branch
Dec 26, 2025
5d2f98a
refactor(models): address PR review - UTC timestamps, remove dict pay…
Dec 26, 2025
434be4e
feat(payload): add migration helpers, tests, and comprehensive docume…
Dec 26, 2025
f873d3f
fix(payload): resolve circular import and add discovery events to union
Dec 26, 2025
acf4c71
fix(pr-239): address release-ready review issues
Dec 26, 2025
d35b86e
merge: resolve conflicts with main branch
Dec 26, 2025
76f37bf
fix(pr-239): address CI failures and PR review issues
Dec 26, 2025
8d2950d
fix(pr-239): address remaining PR review issues
Dec 26, 2025
6015bbd
fix(pr-239): address final PR review issues and CI failure
Dec 26, 2025
57f5479
fix(pr-239): address all remaining PR review issues for release
Dec 27, 2025
07a977c
fix(pr-239): address final release-ready PR review issues
Dec 27, 2025
6c22faf
fix(pr-239): address remaining release-ready review issues
Dec 27, 2025
fd31aaf
fix(pr-239): remove unused UUID import from test file
Dec 27, 2025
d184894
fix(pr-239): address final release-ready nitpicks and test improvements
Dec 27, 2025
574d6dc
merge: resolve conflict with main branch
Dec 27, 2025
f11a512
docs(threading): add shallow immutability warning for frozen models
Dec 27, 2025
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
4 changes: 1 addition & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -551,9 +551,7 @@ Actions now include `lease_id` and `epoch` for idempotent retries, preventing du

### Migration Guide (v0.3.x to v0.4.0)

> **Estimated Migration Time**: 30-60 minutes for typical projects
>
> **Full Guide**: See [`docs/guides/MIGRATING_TO_DECLARATIVE_NODES.md`](docs/guides/MIGRATING_TO_DECLARATIVE_NODES.md) for comprehensive migration instructions with complete examples.
> **Estimated Migration Time**: 30-60 minutes for typical projects. **Full Guide**: See [`docs/guides/MIGRATING_TO_DECLARATIVE_NODES.md`](docs/guides/MIGRATING_TO_DECLARATIVE_NODES.md) for comprehensive migration instructions with complete examples.

#### Quick Migration Checklist

Expand Down
6 changes: 1 addition & 5 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
# CLAUDE.md - Omnibase Core Project Instructions

> **Version**: 0.4.0 | **Python**: 3.12+ | **Framework**: ONEX Core
>
> **No Backwards Compatibility**: Until v0.4.0 is released, breaking changes may occur between commits.
>
> **Shared Infrastructure**: See **`~/.claude/CLAUDE.md`** for common OmniNode infrastructure (PostgreSQL, Kafka/Redpanda, Docker networking, environment variables).
> **Version**: 0.4.0 | **Python**: 3.12+ | **Framework**: ONEX Core | **No Backwards Compatibility**: Until v0.4.0 is released, breaking changes may occur between commits. **Shared Infrastructure**: See **`~/.claude/CLAUDE.md`** for common OmniNode infrastructure (PostgreSQL, Kafka/Redpanda, Docker networking, environment variables).

---

Expand Down
3 changes: 0 additions & 3 deletions docs/MVP_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,6 @@ Nodes are being reorganized but the meta-model they adhere to is not defined. Wi
**Related docs**: `PROJECT_REFACTORING_PLAN.md`, `ARCHITECTURE_EVOLUTION_OVERVIEW.md`

> **SUPERSEDED (v0.4.0)**: This phase was originally planned to move legacy nodes to a `nodes/legacy/` namespace with deprecation warnings. However, after confirming there were **no existing users** of the legacy node implementations, the decision was made to **hard delete** the legacy code entirely. The issues below are retained for historical reference but are no longer applicable.
>
> **What Actually Happened**:
> - Legacy nodes (`NodeReducerLegacy`, `NodeOrchestratorLegacy`) were **never created**
> - The `nodes/legacy/` namespace was **never created**
Expand Down Expand Up @@ -1974,11 +1973,9 @@ Create documentation explaining how to interpret and fix CI purity failures. Pre
## Future Phases (Post v0.4.0)

> **IMPORTANT - Repository Boundaries**:
>
> - **Issues F.1-F.4 (Mixin Migration)**: Remain in `omnibase_core` scope - these are internal refactoring tasks
> - **Issues F.5-F.10 (Runtime Host MVP)**: **DEPRECATED** - Moved to `omnibase_infra` v0.1.0 plan. These are retained here as legacy planning context only. **Do not implement these in `omnibase_core`**
> - **Issues F.11-F.13 (Developer Tooling)**: Remain in `omnibase_core` scope - CLI tools for core development
>
> **Repository Scope Distinction**:
> - `omnibase_core`: Foundational models, protocols, base classes, and core utilities (no infrastructure dependencies)
> - `omnibase_spi`: Protocol definitions and interfaces (pure abstractions)
Expand Down
5 changes: 0 additions & 5 deletions docs/architecture/CONTRACT_DRIVEN_NODEEFFECT_V1_0.md
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,6 @@ class ModelEffectResponseHandling(BaseModel):
> response field extraction. There is NO silent fallback between engines:
> - `jsonpath`: Requires `jsonpath_ng` package. Fails fast if not installed.
> - `dotpath`: Simple `$.field.subfield` syntax. No external dependencies.
>
> Both engines reject non-primitive extraction results (lists, dicts). Only
> `str`, `int`, `float`, `bool`, and `None` are allowed. Attempting to extract
> a complex type will raise `ModelOnexError` with `EXTRACTION_ERROR`.
Expand Down Expand Up @@ -1441,17 +1440,14 @@ class EffectHandlerRegistry(BaseModel):
> # In SPI initialization (e.g., omnibase_spi/bootstrap.py)
> from omnibase_core.registry.effect_handler_registry import EffectHandlerRegistry
> from omnibase_core.enums.enum_effect_handler_type import EnumEffectHandlerType
>
> def register_effect_handlers(container: ModelONEXContainer) -> None:
> """Register all effect handlers with the registry."""
> registry = EffectHandlerRegistry()
>
> # Register SPI implementations
> registry.register(EnumEffectHandlerType.HTTP, "HttpRestAdapter")
> registry.register(EnumEffectHandlerType.DB, "DbAdapter")
> registry.register(EnumEffectHandlerType.KAFKA, "KafkaAdapter")
> registry.register(EnumEffectHandlerType.FILESYSTEM, "FilesystemHandler")
>
> # Register the registry itself for Core consumption
> container.register_service("EffectHandlerRegistry", registry)
> ```
Expand Down Expand Up @@ -2743,7 +2739,6 @@ cb_key = str(operation.correlation_id) # Stable identity
> means transient resolution failures (e.g., secrets store temporarily unavailable,
> environment not fully loaded) can be retried when allowed by the retry policy.
> If resolution consistently fails, it will exhaust retries like any other failure.

> **Operation-Level Timeout**: Each operation has an `operation_timeout_ms` field
> (default 60 seconds) that acts as a deadline for the entire operation including
> all retries. This prevents retry stacking from exceeding intended time limits.
Expand Down
1 change: 0 additions & 1 deletion docs/architecture/DECLARATIVE_IMPLEMENTATION_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
> **Date**: 2025-12-05
> **Status**: ✅ **ALL PHASES COMPLETE** - Declarative nodes are now PRIMARY implementations
> **Correlation ID**: `impl-plan-declarative-onex-2025-11-16`

> **UPDATE (v0.4.0)**: `NodeReducer` and `NodeOrchestrator` are now the **PRIMARY declarative implementations**. The "Declarative" suffix has been removed because these ARE the standard. Legacy imperative implementations have been **hard deleted** (no deprecation period, no `nodes/legacy/` namespace).

---
Expand Down
1 change: 0 additions & 1 deletion docs/architecture/DECLARATIVE_WORKFLOW_FINDINGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
> **Version**: v0.4.0
> **Correlation ID**: `doc-review-declarative-workflows-2025-11-16`
> **Status**: COMPLETED - DECLARATIVE NODES ARE NOW PRIMARY

> **UPDATE (v0.4.0)**: `NodeReducer` and `NodeOrchestrator` are now the **PRIMARY declarative implementations**. The "Declarative" suffix has been removed because these ARE the standard.

---
Expand Down
230 changes: 230 additions & 0 deletions docs/architecture/DICT_STR_ANY_PREVENTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,230 @@
# Dict[str, Any] Prevention Guide

**Last Updated**: 2025-12-26
**Status**: Active Enforcement
**Error Code**: `[explicit-any]`

---

## Breaking Change (v0.4.0)

> **CRITICAL**: `dict[str, Any]` payloads are **NO LONGER SUPPORTED** in core payload models.

As of v0.4.0, the following models **reject** `dict[str, Any]` at validation time:

| Model | Field | Required Type |
|-------|-------|---------------|
| `ModelEventPublishIntent` | `target_event_payload` | `ModelEventPayloadUnion` |
| `ModelIntent` | `payload` | `ProtocolIntentPayload` |
| `ModelAction` | `payload` | `SpecificActionPayload` |
| `ModelRuntimeDirective` | `payload` | `ModelDirectivePayload` |

**What Happens**:

```python
# This now raises ValidationError in v0.4.0+
intent = ModelEventPublishIntent(
target_event_type="node.registered",
target_event_payload={"node_id": "abc"} # ValidationError!
)
```

**Migration**: See [Migrating from dict[str, Any]](../guides/MIGRATING_FROM_DICT_ANY.md) for step-by-step migration instructions.

---

## Overview

This document describes the mypy configuration for preventing new usage of `dict[str, Any]` in the codebase. The goal is to improve type safety by requiring developers to use specific types.

## What is Enforced

The mypy option `disallow_any_explicit = True` is enabled globally. This catches:

1. **Explicit `Any` in type annotations**:

```python
# ERROR: Explicit "Any" is not allowed [explicit-any]
def process(data: dict[str, Any]) -> dict[str, Any]:
...
```

2. **`Any` as a return type**:

```python
# ERROR: Explicit "Any" is not allowed [explicit-any]
def get_value() -> Any:
...
```

3. **`Any` in class attributes**:

```python
class MyClass:
# ERROR: Explicit "Any" is not allowed [explicit-any]
data: dict[str, Any]
```

## How to Fix Violations

### Option 1: Use Specific Types (Preferred)

Replace `dict[str, Any]` with a more specific type:

```python
# Instead of dict[str, Any], use:

# 1. TypedDict for known structure
from typing import TypedDict

class UserData(TypedDict):
name: str
age: int
email: str

def process_user(data: UserData) -> UserData:
...

# 2. Specific dict types
def process_config(data: dict[str, str | int | bool]) -> dict[str, str]:
...

# 3. Pydantic models
from pydantic import BaseModel

class Config(BaseModel):
setting: str
value: int

def apply_config(config: Config) -> None:
...
```

### Option 2: Use SchemaDict or ModelSchemaValue (ONEX Standard)

For schema-related data, use the ONEX type aliases:

```python
# For dict[str, Any] replacement in schema contexts
from omnibase_core.types.type_schema_aliases import SchemaDict

def process_schema(data: SchemaDict) -> SchemaDict:
...

# For individual typed values
from omnibase_core.models.common import ModelSchemaValue

value: ModelSchemaValue = ModelSchemaValue.create_string("example")
```

### Option 3: Use @allow_dict_any Decorator (Last Resort - NOT for Payloads)

> **WARNING**: This option is **NOT available** for core payload models (`ModelEventPublishIntent`, `ModelIntent`, `ModelAction`, `ModelRuntimeDirective`). Those models **require** typed payloads as of v0.4.0.

For other code where `dict[str, Any]` is truly unavoidable (e.g., external API integration), document the justification:

```python
from omnibase_core.decorators import allow_dict_any

@allow_dict_any(reason="External API returns untyped JSON that varies by endpoint")
def fetch(self, endpoint: str) -> dict[str, Any]: # type: ignore[explicit-any]
...
```

**Note**: Even with the decorator, you still need `# type: ignore[explicit-any]` for mypy. The decorator is for documentation and validation scripts.

## Legacy Code Exemptions

The following modules have legacy exemptions and are NOT checked for `explicit-any`:

| Module | Error Count | Notes |
|--------|-------------|-------|
| `omnibase_core.models.*` | ~1685 | Primary tech debt area |
| `omnibase_core.mixins.*` | ~114 | Mixin implementations |
| `omnibase_core.utils.*` | ~52 | Utility functions |
| `omnibase_core.logging.*` | ~23 | Logging infrastructure |
| `omnibase_core.decorators.*` | ~21 | Decorator implementations |
| `omnibase_core.infrastructure.*` | ~12 | Node infrastructure |
| `omnibase_core.errors.*` | ~12 | Error handling |
| `omnibase_core.types.*` | ~11 | Type definitions |
| `omnibase_core.runtime.*` | ~11 | Runtime components |
| `omnibase_core.protocols.*` | ~10 | Protocol definitions |
| `omnibase_core.nodes.*` | ~10 | Node implementations |
| `omnibase_core.container.*` | ~9 | DI container |
| `omnibase_core.services.*` | ~5 | Service layer |
| `omnibase_core.validation.*` | Various | Validation logic |
| `omnibase_core.tools.*` | Various | Development tools |
| `tests.*` | N/A | Test code |
| `scripts.*` | N/A | Build scripts |

### Rules for Legacy Exemptions

1. **DO NOT add new modules** to the exemption list
2. When modifying files in exempted modules, **migrate away from dict[str, Any]** where possible
3. New code in exempted modules should still avoid `dict[str, Any]` (honor the intent)
4. Remove modules from exemptions once fully migrated

## Configuration Details

### mypy.ini Settings

```ini
[mypy]
# Global enforcement
disallow_any_explicit = True

# Per-module exemptions for legacy code
[mypy-omnibase_core.models.*]
disallow_any_explicit = False

# ... (see mypy.ini for full list)
```

### pyproject.toml Settings

```toml
[tool.mypy]
disallow_any_explicit = true
```

## Migration Priority

When addressing tech debt, prioritize by impact:

1. **models/** (85% of violations) - Highest ROI
2. **mixins/** (6% of violations)
3. **utils/** (3% of violations)
4. **Other modules** (6% combined)

## Related Documentation

- [Payload Type Architecture](./PAYLOAD_TYPE_ARCHITECTURE.md) - Typed payload discriminated union design
- [ModelAction Typed Payloads](./MODELACTION_TYPED_PAYLOADS.md) - Action payload implementation guide
- [Type System Architecture](./TYPE_SYSTEM.md) - Core type patterns
- [ModelSchemaValue Type Definition](../../src/omnibase_core/models/common/model_schema_value.py)
- [SchemaDict and StepOutputs Type Aliases](../../src/omnibase_core/types/type_schema_aliases.py)
- [ONEX Terminology](../standards/onex_terminology.md)

## Verification

To verify the configuration is working:

```bash
# Check that legacy modules are exempted
poetry run mypy src/omnibase_core/models/ --show-error-codes 2>&1 | grep explicit-any
# Should show: (no output or very few errors)

# Check that new code is caught
echo 'from typing import Any
def test(x: dict[str, Any]) -> Any:
pass' > /tmp/test_any.py
poetry run mypy /tmp/test_any.py --show-error-codes
# Should show: Explicit "Any" is not allowed [explicit-any]
```

## Changelog

- **2025-12-24**: Initial implementation
- Enabled `disallow_any_explicit = True` globally
- Added per-module exemptions for ~1972 legacy violations across ~1351 files
- Created documentation
Loading
Loading