mud_server.axis.engine
Axis resolution engine.
AxisEngine is the orchestrator that ties together the resolution
grammar, the resolver functions, the JSONL ledger, and the SQLite materialized
view. One instance is created per World at
startup and remains live for the server’s lifetime.
Resolution sequence (resolve_chat_interaction):
Resolve character IDs from names (world-scoped, raises
CharacterNotFoundErroron miss).Acquire per-character threading locks in ascending ID order (deadlock prevention).
Read current axis scores from the SQLite DB.
Compute ipc_hash via
compute_payload_hash()over the pre-interaction snapshot.Compute axis deltas for every axis in the chat grammar.
Write
chat.mechanical_resolutionto the JSONL ledger — the authoritative act that makes the interaction permanent.Clamp deltas to
[0.0, 1.0]and apply to the DB viaapply_axis_event().Release locks.
Return
AxisResolutionResult.
- Locking strategy:
Each character has a
threading.Lockstored in a dict keyed bycharacter_id. Locks are always acquired in ascending ID order to prevent deadlocks when two interactions share a character. The dict itself is protected by a separate_locks_mutex.- Note on ipc_hash computation (deviation from plan):
compute_ipc_id()requiressystem_prompt_hash: str— a concept that has no meaning in a purely mechanical resolution (no LLM call).compute_payload_hash()is used directly on the resolution payload dict instead. When the translation service subsequently uses thisipc_hashfor deterministic Ollama seeding it callscompute_ipc_id()with this hash asinput_hash, which is the intended design.
Attributes
Exceptions
Raised when a character name cannot be resolved within a world. |
Classes
General-purpose resolver registry for axis mutations. |
Module Contents
- mud_server.axis.engine.logger
- exception mud_server.axis.engine.CharacterNotFoundError(character_name, world_id)[source]
Bases:
ExceptionRaised when a character name cannot be resolved within a world.
- character_name
The name that could not be resolved.
- world_id
The world in which the lookup was attempted.
Initialize self. See help(type(self)) for accurate signature.
- character_name
- world_id
- class mud_server.axis.engine.AxisEngine(*, world_id, grammar)[source]
General-purpose resolver registry for axis mutations.
Instantiated once per
World(same lifecycle as the translation service). The chat resolver is the first concrete implementation; future stimulus types (environmental, physical, economic) will add newresolve_*methods following the same pattern.- Parameters:
world_id (str) – The world this engine is scoped to. Used when reading and writing the JSONL ledger and the DB.
grammar (mud_server.axis.grammar.ResolutionGrammar) – The parsed
ResolutionGrammarfor this world. Immutable for the engine’s lifetime.
- resolve_chat_interaction(*, speaker_name, listener_name, channel, world_id)[source]
Resolve a chat interaction between two characters.
This is the primary entry point. All ten steps of the resolution sequence (see module docstring) are executed here atomically under per-character locks.
- Parameters:
speaker_name (str) – Display name of the character who sent the message.
listener_name (str) – Display name of the character who received it.
channel (str) – Chat channel —
"say","yell", or"whisper". Governs the channel multiplier applied to every axis delta.world_id (str) – World in which the interaction occurs. Must match
self._world_id(passed explicitly to make the call site readable).
- Returns:
AxisResolutionResultcontaining the ipc_hash, per-character deltas (only axes with non-zero actual change), and the pre-interaction axis snapshot.- Raises:
CharacterNotFoundError – If either speaker_name or listener_name is not registered in world_id.
- Return type: