Inspecting the IR
After you define and initialize a domain, Protean can generate its Intermediate Representation (IR) -- a JSON document that captures the complete topology of your domain model: what elements exist, what shape they have, and how they connect.
The IR is useful for:
- Reviewing your domain structure at a glance
- Diffing changes between versions in source control
- Feeding downstream tools (documentation generators, diagram builders, contract validators)
- Debugging wiring issues (missing handlers, orphaned events)
Generate the IR in code
Call domain.to_ir() on an initialized domain to get a Python dict:
from protean import Domain
domain = Domain(__name__)
# ... register aggregates, commands, events, handlers ...
domain.init()
ir = domain.to_ir()
The returned dict contains the full IR. You can serialize it to JSON:
import json
print(json.dumps(ir, indent=2))
Or write it to a file for version control:
from pathlib import Path
Path("domain-ir.json").write_text(
json.dumps(ir, indent=2, sort_keys=True)
)
Generate the IR from the CLI
The protean ir show command generates the IR without writing Python:
# Full JSON output
protean ir show --domain=my_app.domain
# Human-readable summary with element counts
protean ir show --domain=my_app.domain --format=summary
See the CLI reference for all options.
Top-level structure
Every IR document has the same shape:
{
"$schema": "https://protean.dev/ir/v0.1.0/schema.json",
"ir_version": "0.1.0",
"generated_at": "2026-03-01T12:00:00Z",
"checksum": "sha256:a1b2c3...",
"domain": { },
"clusters": { },
"projections": { },
"flows": { },
"elements": { },
"diagnostics": [ ]
}
| Section | What it contains |
|---|---|
domain |
Bounded context name and global config (identity strategy, processing mode) |
clusters |
Aggregate clusters -- each aggregate with its entities, value objects, commands, events, handlers, and repositories |
projections |
Read-side projections with their projectors, queries, and query handlers |
flows |
Cross-aggregate elements: domain services, process managers, subscribers |
elements |
Flat index of all element types for quick lookup |
diagnostics |
Warnings like unhandled events (informational, does not affect validity) |
Determinism and diffing
The same domain always produces byte-identical IR JSON (excluding the
generated_at timestamp). Keys are sorted alphabetically at every level,
lists are sorted, and optional attributes with default values are omitted.
This makes the IR safe to commit to source control and diff across versions.
The checksum field (SHA-256 of the canonical JSON) provides a quick
staleness check -- if the checksum hasn't changed, the domain structure
hasn't changed.
The $schema URI
The $schema field contains a logical URI
(https://protean.dev/ir/v0.1.0/schema.json). This URI identifies the
schema version but is not a network endpoint -- the actual JSON Schema
ships with the Protean package at protean.ir.SCHEMA_PATH.
To validate an IR document programmatically:
from jsonschema import validate
from protean.ir import load_schema
schema = load_schema()
validate(instance=ir, schema=schema)
Compatibility contract for tool authors
If you are building tools that consume IR documents, follow these rules to ensure forward compatibility:
Ignore unknown keys. Every object in the IR may gain new keys in future minor versions. Your tool must skip keys it does not recognize rather than failing. This is the single most important rule for IR consumers.
Do not rely on key ordering. Keys are sorted for determinism, but your code should not depend on iteration order for correctness.
Provide defaults for missing optional keys. Optional attributes (like
description on elements or via on association fields) may be absent.
Treat missing keys as their default value.
Check ir_version. Reject documents whose major version is higher than
what your tool supports. Minor version increases are always backward
compatible -- new keys may appear, but existing keys retain their meaning.
See the IR specification for the full compatibility contract, field reference, and design decisions.