Overview

This page explains the internal workings of Ometeotl/ometeotl_core at three depth levels.

For API-level details, use Class Reference.

04/25/26 - major architectural overhaul: Local tests reveal the current architecture is too abstract for any practical implementation. It has been decided to :

  • to keep the current code in a core module ometeotl_core, which is intended to remain abstract;
  • to add a primary layer of specialization ometeotl_foundations, including :
    • spatial: primary layer of spatial implementation of ometeotl_core;
    • networks: primary layer of graph theory implementation of ometeotl_core
  • to add, lastly, an adapter layer ometeotl_adapters, which implements each specialization layer with a reputable library.

Beginner View

Ometeotl/ometeotl_core is a modeling library where everything starts from a generic object, then becomes more specific.

  • ModelObject is the universal base container.
  • GenericObject adds practical metadata such as labels, tags, and profiles.
  • Actor, Resource, Space, and Action represent core domain entities.
  • World is the top-level container that organizes spaces, objects, and their relations.

The library tracks where objects exist with:

Each actor can have a subjective, possibly imperfect view of the world:

Actors may also form explicit composite hierarchies and abstraction layers:

  • Actor supports explicit component relations for composite actors and helper utilities for hierarchy traversal and cycle checks
  • Space can be marked is_abstract to represent conceptual or analytical spaces alongside canonical spaces
  • Perception can carry perceived component links, keeping composition knowledge in the epistemic layer when needed

Candidate actions can then be projected from that perceived state into explicit future-facing strategy artifacts:

  • DefaultProjectionTool derives projection assumptions and successor perceived states
  • ProjectedPerceptionState stores the projected successor perception for one action
  • StrategyNode anchors one action to one input perception and one projected successor perceived state
  • Strategy groups nodes into a linear or branching perception-driven tree

Teleology and utility/ranking are now implemented as model and game extensions:

For server-authoritative setups, mutations can be routed through:

Intermediate View

The implemented pipeline follows this flow:

  1. Build domain entities from ModelObject-derived classes such as Actor, Resource, Space, and Action.
  2. Register objects in WorldModelRegistry through World.
  3. Place object-space memberships in SpaceObjectGraph.
  4. Add space-to-space edges in SpaceRelationGraph.
  5. Serialize deterministically with to_dict() methods (canonical sorting for stable diffs).
  6. Rebuild canonical objects with from_dict() methods.
  7. Generate actor-relative snapshots via Sensor into Perception.
  8. Derive first-order projection assumptions and projected successor perceived states from candidate actions, one Perception, and available resources through DefaultProjectionTool.
  9. Build a perception-driven Strategy with build_linear_strategy(…) or build_branching_strategy(…).
  10. Validate payloads/objects with the staged validation pipeline in ometeotl_core.validation (syntactic, structural, temporal, spatial, admissibility, epistemic, completeness), using policy profiles (observe_only, enforce_structure, enforce_domain) when needed.
  11. Export a world to canonical JSON or YAML via ometeotl_core.io (world_to_json, world_to_yaml, write_world_json, write_world_yaml).
  12. Re-import a world from JSON or YAML with validated reconstruction via world_from_json / world_from_yaml, which runs syntactic then structural validation before calling World.from_dict.
  13. Optionally enforce command gating with AuthorityCommandHandler.
  14. Represent actor objectives with Goal and optionally decompose them with GoalDecompositionTree.
  15. Link Strategy to a goal and evaluate admissibility with GoalAdmissibilityChecker.
  16. Evaluate strategy outcomes with a UtilityFunction implementation and rank with StrategyRanker.

Operationally, World composes three independent graphs/registries:

This separation prevents layer mixing and aligns with the architecture constraints in specs_EN.md.

Test Layout

The test suite follows the same layer separation as the source tree:

  • tests/ometeotl_core/model/: tests for ometeotl_core.model.*
  • tests/ometeotl_core/generic/: tests for ometeotl_core.generic.*
  • tests/ometeotl_core/validation/: tests for ometeotl_core.validation.*
  • tests/ometeotl_core/game/: tests for ometeotl_core.game.*
  • tests/ometeotl_core/io/: tests for ometeotl_core.io.*

Within each layer folder, tests are split by module using one file per module (test_<module>.py).

Run the complete suite from the repository root in one command:

  • pytest

Expert View

At expert level, the core implementation can be read as a set of deterministic state-transition boundaries.

1. Canonical object schema boundary

Every serializable entity normalizes to canonical JSON dictionaries:

Deterministic ordering is enforced by canonical sort helpers and sorted list serialization, making snapshots stable for audit/diff workflows.

2. Ontology boundary vs epistemic boundary

The ontology layer is World, SpaceObjectGraph, SpaceRelationGraph, and WorldModelRegistry.

The epistemic layer is Perception, PerceivedSpace, PerceivedMembership, and PerceivedRelation, created by Sensor through composable CoverageRule and NoiseRule.

Perceived actor composition is represented explicitly through PerceivedComponentLink, which lets perceived hierarchies diverge from ontological hierarchies without mixing layers.

This realizes reality/perception dissociation from the spec: decisions can be based on perceived states, not only ontological states.

3. Authority boundary

When authority mode is enabled in World, direct mutations require a token.

AuthorityCommandHandler provides a single command path that enforces:

  • command allowlisting
  • command id deduplication
  • actor existence checks
  • strictly increasing sequence checks per actor
  • bounded in-memory tracking for processed ids and sequence history
  • immutable audit traces with AuditEntry
  • staged validation with configurable hardening profiles (observe_only, enforce_structure, enforce_domain)
  • structured validation summaries attached to command results and audit entries

4. Extensibility seam

Primary extension seams are intentionally abstract and composable:

5. Runtime wiring

RuntimeContext plus build_runtime(...) provide explicit mode selection:

  • local mode: direct world mutation APIs
  • server-authoritative mode: command-gated mutation via AuthorityCommandHandler

When server-authoritative mode is enabled, runtime also wires validation policy options (validation_soft_gate, validation_policy_profile, validation_stage_mode_overrides, validation_block_on_error, validation_completeness_level) through to the authority boundary.

This keeps local testing ergonomics while preserving an enforceable server boundary for multi-client systems.

6. First-order projection seam

DefaultProjectionTool is intentionally separate from the strategy model layer.

It consumes Action, Perception, and Resource inputs and emits ProjectionAssumption collections grouped as ActionProjection or ProjectionBatch, together with a ProjectedPerceptionState representing the successor perceived state for that action.

This keeps first-order projection focused on assumption building plus successor-state derivation, while leaving later strategy-node construction and branching as a separate concern.

7. Strategy chaining seam

The strategy layer is implemented in Strategy, StrategyNode, StrategyOutcomeBranch, and StrategyBuildStep.

The important rule is that a strategy node is anchored to:

  • one action id
  • one source perception id
  • one projected successor perceived state

validate_tree() enforces that a child node must consume the parent node’s projected successor perception when a branch links the two nodes.

This makes strategy hops explicitly perception-driven rather than action-list driven.

8. Builder seam

Two minimal builders exist today in src/ometeotl_core/model/strategies.py:

  • build_linear_strategy(...) for ordered action sequences
  • build_branching_strategy(...) for recursive action trees built from StrategyBuildStep

Both builders project each action from the currently active perceived state and pass the resulting successor perceived state to the next node or subtree.

The current implementation intentionally keeps one projected successor perceived state per node. Future support for one-action-to-many-outcomes branching is tracked as a TODO in the strategy layer, with the preferred direction being branch-specific projected outcomes on StrategyOutcomeBranch.

9. Teleology and game utility seam

The teleology seam is now explicit in the model layer through Goal and GoalDecompositionTree, while goal evaluation remains domain-neutral via GoalFeasibilityTool and GoalAdmissibilityChecker.

The game utility seam is explicit in UtilityFunction plus concrete game-layer combinators WeightedSumUtility and LexicographicUtility.

StrategyRanker evaluates terminal projected states and aggregates branch probabilities in a deterministic way, including directed acyclic strategy graphs with merged terminal paths.

Ometeotl

A Python library to build complex multi-agent simulations, wargames, and AI-driven strategies


Three-level walkthrough of how Ometeotl/ometeotl_core works internally