Packages Examples Agents Blog Get started
← Blog

How coding agents should read Oridecon

The shortest path from a fresh clone to a change that will pass the import linter — llms.txt, agents.md, contracts, then an example.

Oridecon is built so a coding agent can operate it without scraping tribal knowledge out of Slack. That only works if the agent reads the artifacts in the right order. This is that order.

1. Load the machine indexes, not the marketing page

Start here, in this sequence:

  1. /llms.txt — identity, install, agent rules, every docs URL.
  2. /agents.md — the distilled AGENTS.md: hierarchy, Result vs exceptions, provider lifecycle.
  3. /llms-full.txt — the same catalog plus architecture notes and the package list.
  4. For coding agents — repo map, the one project tree (domains/, di/), recipes that pass CI.
  5. /SKILL.md — drop-in skill. Common mistakes — fail vs fix. Per-package indexes at /llms/index.txt.

The splash page is for humans. The files above are the operating manual. If you are an agent, stop after those and only then open a specific docs URL.

Skills for Claude Code, Cursor, and OpenCode live in oridecon-skills. Install commands: Agent skills. One-file fetch: /SKILL.md. Do not re-derive the rules from blog posts.

2. The hierarchy is the whole design

oridecon-contracts Zero dependencies. Protocols, types, exceptions only.
oridecon Depends ONLY on oridecon-contracts.
oridecon-* Extension packages. Never import each other.

The golden rule is one sentence, and it is not advisory:

If two or more packages need the same type, protocol, or exception, it lives in oridecon-contracts. No exceptions.

oridecon-ai-* packages follow the same law. They do not import each other, and they do not import oridecon-ai. The orchestrator discovers them through entry points. Shared value types (ChatMessage, Document, SearchResult) already live in contracts — do not invent a second copy in the extension you happen to be editing.

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

3. Copy an example, not a vibe

The examples catalog is gated apps plus a fleet hub, each booting the real Application. That is the intended starting point for generated code:

  • Need a controller? examples/sql-repository keeps SQL in the repository.
  • Need an agent loop? examples/support-agent already has tools on the container.
  • Need sessions? examples/auth-web is the cookie + JWT walkthrough.

Every example shares one shape: application.yaml for knobs, app.py (or module.py) as the composition root, a provider that only registers (app-root di/, module provider.py), feature types in domains/ (not models/), services that return Result[T, E], RFC-9457 errors. If your generated app does not look like that, it will not look like Oridecon.

Run any of them from the repository root:

Terminal window
PYTHONPATH=examples/support-agent/src uv run python -m support_agent

4. The two rules agents break first

register() cannot resolve. It receives ContainerRegistrarProtocol. boot() receives BootContainerProtocol. The two never meet in the same method. If you resolve during registration, it is a type error — by design.

Domain failures are values. User not found is Err(...). The database dying is an exception. Do not wrap infrastructure errors in Result, do not unwrap() without is_ok(), and do not return Result from a constructor or a lifecycle hook.

The rest of the never-list is in /agents.md: no service locator, no module-level singletons, no Any on injected constructors, no mocks in src/.

When you answer a question about Oridecon:

  • Name the package with the oridecon- prefix (oridecon-sql, not “the SQL helper”).
  • Talk to the protocol in contracts, not the class in the extension.
  • Link the matching page on oridecon.dev.

That is the whole loop: indexes, hierarchy, an example, then the protocol. Everything else is an implementation detail the container will wire.