babylon.kernel
The kernel — Babylon’s bottom layer (Program 14, Constitution II.6).
Framework abstractions every layer may import and that import nothing above
themselves at runtime: the event bus, the system base class + protocol, the
graph substrate protocol, and the DI services protocol. These are exactly the
constructs whose former home inside babylon.engine forced economics,
persistence, and formulas to import the engine backward (the cycles broken in
Program 14 Phase 1).
Layering law (enforced by import-linter): kernel < models/formulas
< domain packages < engine. Annotations may reference upward under
TYPE_CHECKING; the runtime import graph may not.
- class babylon.kernel.BlockedEvent(event, interceptor_name, reason, blocked_at=datetime.datetime(1, 1, 1, 0, 0, tzinfo=datetime.timezone.utc))[source]
Bases:
objectAudit record for blocked events.
blocked_atdefaults to the deterministic sim-time of the wrapped event’s tick (Constitution III.7), never the wall clock.
- class babylon.kernel.Event(type, tick, payload, timestamp=datetime.datetime(1, 1, 1, 0, 0, tzinfo=datetime.timezone.utc))[source]
Bases:
objectImmutable event representing a simulation occurrence.
Events are frozen dataclasses to ensure they cannot be modified after creation, maintaining integrity of the event history.
- type
Event type identifier (e.g., “tick”, “rupture”, “synthesis”)
- tick
Simulation tick when the event occurred
- payload
Event-specific data dictionary
- timestamp
Deterministic sim-time derived from tick (Constitution III.7)
- class babylon.kernel.EventBus[source]
Bases:
objectPublish/subscribe event bus for simulation components.
The EventBus enables decoupled communication between systems. Components can subscribe to specific event types and will be notified when events of that type are published.
All published events are stored in history for replay/debugging.
Epoch 1→2 Bridge: Supports optional interceptor chain for adversarial mechanics. If no interceptors are registered, events flow through with zero overhead (backwards compatible).
The interceptor chain processes events before emission: - Interceptors are sorted by priority (higher runs first) - Each interceptor can ALLOW, BLOCK, or MODIFY the event - If blocked, the event is logged and not emitted - If modified, the modified event continues through the chain
Example
>>> bus = EventBus() >>> def on_tick(event: Event) -> None: ... print(f"Tick {event.tick}: {event.payload}") >>> bus.subscribe("tick", on_tick) >>> bus.publish(Event(type="tick", tick=1, payload={"value": 42})) Tick 1: {'value': 42}
- register_interceptor(interceptor)[source]
Register an interceptor to process events before emission.
Interceptors are sorted by priority (higher first) each time an event is published. Multiple interceptors with the same priority execute in registration order.
- Parameters:
interceptor (
EventInterceptor) – The interceptor to register.- Return type:
Example
>>> from babylon.kernel.interceptor import EventInterceptor >>> bus = EventBus() >>> bus.register_interceptor(my_security_interceptor)
- unregister_interceptor(interceptor)[source]
Remove an interceptor from the chain.
- Parameters:
interceptor (
EventInterceptor) – The interceptor to remove.- Raises:
ValueError – If the interceptor is not registered.
- Return type:
- publish(event, context=None)[source]
Publish an event to all subscribed handlers.
If interceptors are registered, the event passes through the interceptor chain first. If any interceptor blocks the event, it is logged to the blocked events audit channel and not emitted.
The event is stored in history only if it passes all interceptors.
- Parameters:
event (
Event) – The event to publish.context (
WorldContext|None) – Optional world context for interceptors. Required for Epoch 2 adversarial mechanics.
- Return type:
- class babylon.kernel.EventInterceptor[source]
Bases:
ABCAbstract base for event interceptors.
Priority ranges (higher runs first): - 90-100: Security/State (block first) - 50-89: Faction/adversarial - 10-49: Resource/validation - 1-9: Logging/audit (run last)
- abstractmethod intercept(event, context)[source]
Process event. Return allow/block/modify result.
- Return type:
- Parameters:
event (Event)
context (WorldContext | None)
- class babylon.kernel.GraphProtocol(*args, **kwargs)[source]
Bases:
ProtocolProtocol for backend-agnostic graph operations.
Systems interact with the simulation graph ONLY through this protocol. The concrete implementation (NetworkX, DuckDB) is hidden behind adapters.
This protocol is runtime_checkable, enabling isinstance() checks for protocol compliance.
Example
>>> class MyAdapter: ... def add_node(self, node_id: str, node_type: str, **attrs: Any) -> None: ... pass ... # ... implement all 16 methods >>> adapter = MyAdapter() >>> isinstance(adapter, GraphProtocol) True
- add_node(node_id, node_type, **attributes)[source]
Add a node with type marker and arbitrary attributes.
- add_edge(source, target, edge_type, weight=1.0, **attributes)[source]
Add directed edge with type, weight, and attributes.
- get_neighborhood(node_id, radius=1, edge_types=None, direction='out')[source]
Get all nodes within radius hops of the source node.
- Parameters:
- Return type:
- Returns:
SubgraphView or equivalent containing nodes in neighborhood.
- Raises:
KeyError – If node does not exist.
- execute_traversal(query)[source]
Execute a generic traversal query.
This is the hook for complex operations like percolation analysis, pathfinding, and component detection.
- Parameters:
query (
TraversalQuery) – TraversalQuery specifying the traversal.- Return type:
- Returns:
TraversalResult with nodes, edges, paths, or aggregates.
- Raises:
ValueError – If query_type is not supported.
- shortest_path(source, target, edge_types=None, weight_attr=None)[source]
Find shortest path between two nodes.
- query_nodes(node_type=None, predicate=None, attributes=None)[source]
Query nodes with optional filtering.
Returns an iterator for DuckDB compatibility (lazy evaluation).
- Parameters:
- Return type:
- Returns:
Iterator of matching GraphNode models.
- query_edges(edge_type=None, predicate=None, min_weight=None, max_weight=None)[source]
Query edges with optional filtering.
Returns an iterator for DuckDB compatibility (lazy evaluation).
- Parameters:
- Return type:
- Returns:
Iterator of matching GraphEdge models.
- aggregate(target, group_by=None, agg_func='count', agg_attr=None)[source]
Aggregate over nodes or edges.
- Parameters:
target (
Literal['nodes','edges']) – Whether to aggregate nodes or edges.group_by (
str|None) – Attribute to group by (e.g., ‘type’).agg_func (
Literal['count','sum','avg','min','max']) – Aggregation function to apply.agg_attr (
str|None) – Attribute to aggregate (required for sum/avg/min/max).
- Return type:
- Returns:
Dict mapping group keys to aggregated values.
Example
>>> graph.aggregate("nodes", group_by="type") {"social_class": 4, "territory": 2}
- get_graph_attr(key, default=None)[source]
Retrieve a graph-level attribute.
Graph attributes store global metadata (e.g., economy state, base_year, tick_dynamics). Maps to a metadata table in DuckDB.
- query_faction_influence_by_territory(territory_id)[source]
Return all INFLUENCES edges pointing at a Territory.
Spec-070 FR-021 winning-faction resolution. Each row is
(faction_id, influence_level, support_type). Sorted byinfluence_leveldescending, lex-ID ascending on ties.
- query_sovereign_claims(sovereign_id)[source]
Return all CLAIMS edges originating from a Sovereign.
Each row is
(territory_id, control_level, legal_status). Sorted bycontrol_leveldescending, lex-ID ascending on ties. Used by SovereigntySystem + CollapseTransitionSystem.
- query_territory_claims(territory_id)[source]
Return all CLAIMS edges pointing at a Territory.
Each row is
(sovereign_id, control_level, legal_status). Sorted bycontrol_leveldescending, lex-ID ascending on ties. Used by SovereigntySystem for dual-power detection (FR-035) and effective-controller resolution (FR-020).
- query_adjacent_territories(territory_id)[source]
Return sorted list of Territory IDs adjacent via
EdgeType.ADJACENCY.ADJACENCY edges are conceptually bidirectional; this method abstracts the in/out edge direction. Output is sorted lexicographically for determinism.
- bulk_partition_claims(from_sovereign_id, to_sovereign_id, territories)[source]
Atomically rewire CLAIMS edges from one Sovereign to another for the given Territory set (spec-070 FR-027).
Performance requirement (FR-018 / SC-004): MUST be implementable in
O(K)whereK = len(territories)— NOTO(N)in the unchanged-territory count.
- query_contiguous_component_under_predicate(territory_seed, predicate)[source]
BFS over
EdgeType.ADJACENCYfromterritory_seed, collecting Territories satisfyingpredicate.Bounded by the predicate-satisfying contiguous region size, not global graph size (per FR-018).
- Parameters:
- Return type:
- Returns:
Set of Territory IDs in the contiguous predicate-satisfying component containing
territory_seed(empty if the seed itself fails the predicate).
- __init__(*args, **kwargs)
- class babylon.kernel.InterceptResult(event, reason='')[source]
Bases:
objectImmutable result of interceptor processing.
- event
Event to continue with, or None if blocked.
- reason
Narrative explanation (required if blocked).
- classmethod block(reason)[source]
Block event with narrative reason.
- Return type:
- Parameters:
reason (str)
- class babylon.kernel.ServicesProtocol(*args, **kwargs)[source]
Bases:
ProtocolAttribute surface of the simulation service container.
- Variables:
config – Run-scoped
SimulationConfig(carriesrng_seed).database – Database connection satisfying the persistence protocol.
event_bus – Kernel publish/subscribe bus.
formulas –
FormulaRegistryof hot-swappable formulas.defines –
GameDefines— the moddable coefficient space.metrics – Telemetry collector.
- __init__(*args, **kwargs)
- class babylon.kernel.System(*args, **kwargs)[source]
Bases:
ProtocolProtocol defining a historical materialist system.
- step(graph, services, context)[source]
Apply system logic to the world graph.
- Parameters:
graph (
GraphProtocol) – Mutable NetworkX graph representing WorldState.services (
ServicesProtocol) – ServicesProtocol with config, formulas, event_bus, database.context (
Union[dict[str,Any],TickContext]) – TickContext or dict with ‘tick’ (int) and optional metadata. TickContext is the preferred type; dict is supported for backward compatibility with existing tests.
- Return type:
- __init__(*args, **kwargs)
- class babylon.kernel.SystemBase[source]
Bases:
ABCAbstract base for all simulation Systems.
Subclasses MUST set the
nameClassVar and implementstep().- Helpers:
_wrap_graph()— assert the graph satisfies GraphProtocol._read()— read a node attribute, raisingKeyErrorwhenrequired=Trueand the attribute is absent (surfaces schema bugs at the read site, per CLAUDE.md “Common Gotchas”)._publish()— publish an event via the service container’s bus.
- abstractmethod step(graph, services, context)[source]
Apply system logic to the world graph (in-place mutation).
The signature matches
babylon.kernel.system_protocol.Systemexactly. The engine (and all test fixtures) pass aBabylonGraph, which satisfiesGraphProtocol.- Return type:
None
- Parameters:
graph (GraphProtocol)
services (ServicesProtocol)
context (ContextType)
- babylon.kernel.resolve_rng(services, tick)[source]
Seed-deterministic RNG for stochastic System rolls (III.7).
Prefers
services.rngwhen a harness injects one; otherwise a freshrandom.Random(0xBA1AC1A + tick)— the spec-070 fallback previously duplicated byfaction_influenceandreactionary.- Parameters:
services (
ServicesProtocol) – Service container (checked for an injectedrng).tick (
int) – Current simulation tick, mixed into the fallback seed.
- Return type:
- Returns:
A
random.Randomwhose stream is a pure function oftick(fallback path) or the injected harness RNG.
Modules
Kernel protocol for the injectable database connection. |
|
Event system for decoupled communication in the simulation. |
|
Exception hierarchy for Babylon/Babylon. |
|
Graph Protocol definition for backend-agnostic graph operations. |
|
Event Interceptor pattern for Epoch 2 adversarial mechanics. |
|
Custom logging utilities for Babylon. |
|
Mathematical utilities for simulation precision. |
|
Metrics collector interfaces and protocols. |
|
Retry decorator for transient failure handling. |
|
Shared JSON Schema registry builder for |
|
Structural protocol for the simulation's DI service container. |
|
Deterministic simulation clock (Constitution III.7). |
|
SystemBase — abstract base class for simulation Systems (ADR-003). |
|
Protocol definition for simulation systems. |