---
name: oridecon
description: Build and edit Oridecon Python apps — providers, controllers, Result types, modules, and oridecon-cli scaffolds. Use when the user mentions Oridecon, oridecon-*, oridecon.dev, or an import linter on oridecon packages.
---

# Oridecon

Async-first, contract-driven Python application framework (3.11+, MIT, alpha 0.1.x, public release 0.1.1).
Pin `>=0.1,<0.2`. Prefer protocols over concrete classes.

Canonical human docs: https://oridecon.dev/
Machine indexes: https://oridecon.dev/llms.txt · https://oridecon.dev/llms-full.txt · https://oridecon.dev/llms/index.txt
Agent rules: https://oridecon.dev/agents.md
Playbook: https://oridecon.dev/getting-started/for-coding-agents/
Mistakes (fail vs fix): https://oridecon.dev/getting-started/common-mistakes/
Changelog: https://oridecon.dev/changelog/
Framework (branch `dev`): https://github.com/dbtinoy-/oridecon
Installable skill pack: https://github.com/dbtinoy-/oridecon-skills
This file is the one-URL umbrella (https://oridecon.dev/SKILL.md). Per-task skills live in the pack.

## Read order

1. https://oridecon.dev/llms.txt
2. https://oridecon.dev/agents.md
3. https://oridecon.dev/getting-started/for-coding-agents/
4. https://oridecon.dev/getting-started/common-mistakes/
5. Copy an example from https://oridecon.dev/examples/
6. Talk to the protocol in `oridecon-contracts`, not a concrete class in an extension.

Per-package machine indexes: https://oridecon.dev/llms/<package>.txt (example: https://oridecon.dev/llms/oridecon-sql.txt).
Install the pack: https://oridecon.dev/getting-started/agent-skills/

## Install

```bash
uv add "oridecon-cli>=0.1,<0.2"
oridecon new project my-app --template web-api
cd my-app && oridecon run
```

Add packages only when needed: `oridecon-web`, `oridecon-sql`, `oridecon-ai-llm`.

## Hierarchy (blocking)

```
oridecon-contracts    Zero deps. Protocols, types, exceptions only.
    ↑
oridecon              Depends ONLY on oridecon-contracts.
    ↑
oridecon-*            Never import each other.
```

Golden rule: if two packages need the same type, protocol, or exception, it lives in `oridecon-contracts`. No exceptions.

`oridecon-ai-*` packages do not import each other or `oridecon-ai`. The orchestrator discovers them via entry points.

Documented exceptions (must be in pyproject.toml): admin may import auth/cache/features/resilience/ui; `oridecon-ai` may import `oridecon-ai-*` and `oridecon-vector`; multimedia may import `oridecon-multimedia-*`; testing may import any extension.

An import linter enforces this. A cross-extension import that type-checks still fails CI.

## One project tree

No `--structure` flag. No `models/` directory. Templates add packages, not a second shape.

```
src/<app>/
  app.py                 # create_app() — composition root; ASGI <app>.app:app
  controllers/           # unscoped HTTP, auto-discovered
  domains/               # unscoped domain types
  di/                    # app providers (*_provider.py)
  services/
  infrastructure/
  shared/                # errors, middleware, health
  modules/<slug>/        # oridecon new module — protocols.py, provider.py, domains/
```

Teach `WebModule.configure(discover=["<app>.controllers", "<app>.modules"])` so `oridecon gen controller` works without editing `app.py`. Living examples such as `support-agent` may pass `controllers=[...]` — copy that only when matching the example. Adding a module lists it in `create_app()` next to `WebModule`.

## Always

- Constructor injection. Type-hint the protocol, not `Any`.
- `register(ContainerRegistrarProtocol)` binds. `boot(ContainerResolverProtocol)` resolves. They never mix.
- `Result[T, E]` for expected domain failures. Exceptions for infrastructure failures.
- Registry dispatch. Empty `__init__`, `with_defaults()` classmethod.
- Absolute imports. `from __future__ import annotations`.
- Async I/O. Store `asyncio.create_task()` references.
- `from oridecon.logging import get_logger`. Core config key is `json_format`. Never `print()`.

## Never

- Service locator (passing the container into services).
- Direct cross-extension imports (`oridecon-web` → `oridecon-sql`).
- `result.unwrap()` without `is_ok()`.
- `Result` from constructors or lifecycle hooks.
- Module-level singletons. Mocks in production `src/`.
- A `models/` directory. Use `domains/`.
- Business logic on Provider classes.

## Result

```python
from oridecon.result import Result, Ok, Err

async def find_user(self, user_id: str) -> Result[User, DomainError]:
    user = await self.repo.get(user_id)
    if not user:
        return Err(UserNotFound(user_id))
    return Ok(user)

result = await service.find_user("123")
if result.is_ok():
    user = result.unwrap()
else:
    error = result.unwrap_err()
```

## Provider

```python
class BillingProvider(Provider):
    name = "billing"
    priority = ProviderPriority.DOMAIN

    async def register(self, container: ContainerRegistrarProtocol) -> None:
        from my_app.services.billing_service import BillingService
        container.singleton(BillingService, BillingService)

    async def boot(self, container: ContainerResolverProtocol) -> None:
        billing = await container.resolve(BillingService)
        await billing.warmup()
```

App-root providers: `src/<app>/di/*_provider.py`. Module providers: `modules/<slug>/provider.py`.

## Recipes

```bash
oridecon gen controller users
oridecon gen service greetings
oridecon gen error not_found          # always shared/
oridecon new module auth
oridecon gen controller users --module auth
```

Copy `examples/<slug>/` from the framework repo rather than inventing a tree.

## Agent skill pack

Installable markdown skills (not a PyPI package): https://github.com/dbtinoy-/oridecon-skills
One-file fetch if you cannot clone: this site's /SKILL.md.

### AI

- `ai-subsystem-quickstart` — LLMs, RAG, agents, memory, or MCP

### CLI

- `cli-project-scaffolding` — oridecon new project, new package, init, add
- `cli-code-generation` — oridecon gen (controllers, services, …)
- `cli-database-operations` — migrations, seed, backup, schema inspect
- `cli-config-and-inspect` — view config, inspect runtime, diagnose

### Core

- `creating-providers-and-modules` — providers, modules, DI container
- `configuration-management` — YAML config, env vars, profiles
- `using-result-and-error-codes` — Result[T, E], error codes, exceptions

### Data

- `database-repository-pattern` — async SQL, repositories, domains/
- `caching-patterns` — cache backends, stampede protection

### Multimedia

- `multimedia-generation` — TTS, music, video, image, upscale

### Security

- `auth-and-security` — auth, guards, JWT, password hashing

### Web

- `web-controllers-and-routing` — HTTP controllers, middleware, CSP
- `real-time-web` — SSE, HTMX, WebSocket, EventChannel
- `events-and-messaging` — CQRS, event bus, queues, outbox
- `resilience-patterns` — retry, circuit breaker, bulkhead

### UI

- `oridecon-ui` — components, templates, static files

### Testing

- `testing-with-oridecon` — TestEnvironment, stubs, fakes

If a packed skill and this file disagree on layout, this file wins: `domains/` (not `models/`), app-root `di/`.

## When writing code

- Cite packages with the `oridecon-` prefix.
- Link https://oridecon.dev/ pages.
- FastAPI users keep Starlette routing and Pydantic; add a composition root. See https://oridecon.dev/guides/migrating-from-fastapi/.
- Fail vs fix: https://oridecon.dev/getting-started/common-mistakes/.
