Topology System Reference
This reference documents the topology monitoring system that tracks revolutionary organization via percolation theory. For conceptual background, see Percolation Theory & Phase Transitions.
Overview
The topology system analyzes the solidarity subgraph to detect phase transitions
in organizational structure. It is implemented as a SimulationObserver
that receives state change notifications and computes topological metrics.
Key Components:
babylon.engine.topology_monitor- Observer and helper functionsbabylon.models.topology_metrics- Data models for metrics
Constants & Thresholds
Phase Detection
Constant |
Value |
Purpose |
|---|---|---|
|
0.1 |
Percolation ratio below this indicates atomized movement |
|
0.5 |
Crossing this threshold triggers phase shift detection |
|
2 |
If potential > actual × this, movement is brittle |
Liquidity Classification
Constant |
Value |
Purpose |
|---|---|---|
|
0.1 |
Minimum solidarity strength for sympathizer classification |
|
0.5 |
Minimum solidarity strength for cadre classification |
Resilience Testing
Constant |
Value |
Purpose |
|---|---|---|
|
0.2 |
Fraction of nodes removed in purge simulation (20%) |
|
0.4 |
Giant component must survive at 40% of original size |
Metrics
TopologySnapshot
The TopologySnapshot model captures metrics at each tick:
Field |
Type |
Description |
|---|---|---|
|
|
Simulation tick number |
|
|
Number of disconnected solidarity cells |
|
|
Size of largest connected component (L_max) |
|
|
Total social_class nodes in system |
|
|
L_max / total_nodes (range [0, 1]) |
|
|
Count of SOLIDARITY edges > 0.1 strength |
|
|
Count of SOLIDARITY edges > 0.5 strength |
|
|
actual/potential liquidity ratio [0, 1] (Sprint 3.3) |
|
|
Whether network survives purge test (None if not tested) |
ResilienceResult
The ResilienceResult model captures purge simulation output:
Field |
Type |
Description |
|---|---|---|
|
|
True if network survives simulated purge |
|
|
L_max before node removal |
|
|
L_max after removing nodes |
|
|
Fraction of nodes removed |
|
|
Required survival fraction |
|
|
RNG seed for reproducibility |
Functions
extract_solidarity_subgraph
- extract_solidarity_subgraph(G, min_strength=0.0)
Extract undirected solidarity network from WorldState graph.
- Parameters:
- Returns:
Undirected graph with only SOLIDARITY edges above threshold
- Return type:
nx.Graph[str]
Example:
from babylon.engine.topology_monitor import extract_solidarity_subgraph graph = state.to_graph() solidarity_graph = extract_solidarity_subgraph(graph, min_strength=0.1)
calculate_component_metrics
- calculate_component_metrics(solidarity_graph, total_social_classes)
Calculate connected component metrics for percolation analysis.
- Parameters:
- Returns:
Tuple of (num_components, max_component_size, percolation_ratio)
- Return type:
Example:
from babylon.engine.topology_monitor import ( extract_solidarity_subgraph, calculate_component_metrics, ) solidarity_graph = extract_solidarity_subgraph(graph) num_comp, l_max, ratio = calculate_component_metrics( solidarity_graph, total_social_classes=20 )
calculate_liquidity
- calculate_liquidity(G)
Calculate potential vs actual solidarity metrics.
- Parameters:
G (nx.DiGraph[str]) – Directed graph from
WorldState.to_graph()- Returns:
Tuple of (potential_liquidity, actual_liquidity)
- Return type:
Interpretation:
potential: Sympathizer network (edges > 0.1)actual: Cadre network (edges > 0.5)If
potential > actual * 2: Movement is broad but brittle
check_resilience
- check_resilience(G, removal_rate=0.2, survival_threshold=0.4, seed=None)
Test if solidarity network survives targeted node removal.
Simulates a “purge” scenario by removing a percentage of nodes and checking if the giant component survives.
- Parameters:
- Returns:
Result with is_resilient flag and metrics
- Return type:
Example:
from babylon.engine.topology_monitor import check_resilience result = check_resilience(graph, removal_rate=0.2, seed=42) if not result.is_resilient: print("Sword of Damocles: Network is fragile!")
TopologyMonitor Class
- class TopologyMonitor(resilience_test_interval=5, resilience_removal_rate=0.2, logger=None)
Observer tracking solidarity network condensation via percolation theory.
Implements
SimulationObserverprotocol.- Parameters:
resilience_test_interval (int) – Run resilience test every N ticks (0 = disabled)
resilience_removal_rate (float) – Fraction of nodes to remove in test
logger (logging.Logger | None) – Logger instance (default: module logger)
Configuration
Parameter |
Default |
Description |
|---|---|---|
|
5 |
Test resilience every N ticks (0 disables) |
|
0.2 |
Fraction of nodes removed in purge test |
Properties
- history: list[TopologySnapshot]
Returns copy of recorded snapshots (one per tick)
Lifecycle Hooks
- on_simulation_start(initial_state, config)
Called when simulation begins. Clears history and records initial snapshot.
- on_tick(previous_state, new_state)
Called after each tick. Records snapshot and logs narrative states.
- on_simulation_end(final_state)
Called when simulation ends. Logs summary statistics.
Event Emission (Sprint 3.3)
The TopologyMonitor emits PhaseTransitionEvent when percolation ratio
crosses threshold boundaries. Events are collected and injected into the next
tick’s WorldState.
Internal State:
Attribute |
Type |
Description |
|---|---|---|
|
|
Last known phase state |
|
|
Events awaiting collection |
Methods:
- _classify_phase(percolation_ratio, cadre_density=0.0)
Classify current phase state from percolation ratio and cadre density.
- get_pending_events()
Return and clear pending events list.
- Returns:
List of events awaiting injection
- Return type:
Phase States (4-Phase Model - Sprint 3.3):
State |
Threshold |
Political Meaning |
|---|---|---|
Gaseous |
|
Atomized leftism, no coordination capacity |
Transitional |
|
Emerging structure, vulnerable to disruption |
Liquid |
|
Mass movement formed, broad but lacks discipline |
Solid |
|
Vanguard party crystallized, iron discipline |
Narrative States
The monitor logs these narrative states based on metrics:
State |
Condition |
Log Message |
|---|---|---|
Gaseous |
|
“Movement is atomized” |
Liquid |
|
“Mass movement formed, lacks cadre discipline” |
Solid |
|
“Vanguard Party crystallized, iron discipline” |
Crystallization |
|
“Mass movement hardened into disciplined vanguard” |
Brittle |
|
“Movement is broad but brittle” |
Sword of Damocles |
|
“A purge would destroy the movement” |
Usage Example
from babylon.engine.simulation import Simulation
from babylon.engine.topology_monitor import TopologyMonitor
from babylon.models import WorldState, SimulationConfig
# Create initial state
state = WorldState(entities={...}, relationships=[...])
config = SimulationConfig()
# Create monitor
monitor = TopologyMonitor(resilience_test_interval=5)
# Create simulation with observer
sim = Simulation(state, config, observers=[monitor])
# Run simulation
for _ in range(10):
sim.step()
# Access metrics
for snapshot in monitor.history:
print(f"Tick {snapshot.tick}: p={snapshot.percolation_ratio:.2f}")
sim.end()
See Also
Percolation Theory & Phase Transitions - Conceptual explanation of percolation theory
Event System Architecture - Event system architecture
Event System Reference - Complete event type reference (includes PhaseTransitionEvent)
Imperial Rent - Related economic mechanics
babylon.engine.systems.solidarity- Solidarity transmission systembabylon.formulas- Mathematical formulas
Bifurcation Topology Analysis
Consciousness-weighted analysis predicting whether crisis routes to fascism or revolution. For conceptual background, see George Jackson Bifurcation Model.
Key Modules:
babylon.bifurcation- Package with all analysis functionsbabylon.bifurcation.analysis- Full orchestratorbabylon.bifurcation.consciousness- Sigmoid weightingbabylon.bifurcation.axis- Per-axis contradiction analysisbabylon.bifurcation.bridges- Community bridge detectionbabylon.bifurcation.resilience- Topological resilience metricsbabylon.bifurcation.ceiling- Material solidarity ceilingbabylon.bifurcation.legitimation- Legitimation crisis amplifierbabylon.bifurcation.types- Result typesbabylon.engine.bifurcation_monitor- Tick-level observerbabylon.engine.community_state_store- Community state protocol
BifurcationDefines
Configurable parameters in GameDefines.bifurcation.
Consciousness Sigmoid (US1)
Parameter |
Default |
Description |
|---|---|---|
|
0.4 |
CI value at sigmoid inflection. Below-center so breakage cliff catches assimilated communities. |
|
10.0 |
Slope at inflection point. Higher values produce a sharper cliff. |
|
0.2 |
Minimum sigmoid output to include edge in filtered subgraph. |
Classification (US5)
Parameter |
Default |
Description |
|---|---|---|
|
0.2 |
Score within +/-0.2 of 1.0 threshold classifies as “indeterminate”. |
|
0.001 |
Division guard for cross-solidarity / lateral-antagonism ratio. |
Legitimation Amplifier (US7)
Parameter |
Default |
Description |
|---|---|---|
|
2.0 |
At zero legitimation, crisis intensity multiplied by this factor. |
Solidarity Ceiling (US6)
Parameter |
Default |
Description |
|---|---|---|
|
10.0 |
Wage gap ratio at which ceiling reaches its minimum. |
|
2.0 |
Wage gap ratio at which ceiling reaches its maximum. |
|
0.3 |
Minimum solidarity ceiling (at extreme wage gaps). |
|
0.9 |
Maximum solidarity ceiling (at similar wages). |
|
0.2 |
Ceiling bonus when agents share an exploitation source. |
Purge Resilience (US4)
Parameter |
Default |
Description |
|---|---|---|
|
0.2 |
Fraction of high-degree nodes removed in purge resilience test. |
Result Types
BifurcationResult
Frozen Pydantic model produced by bifurcation_tendency().
One instance per analysis call.
Field |
Type |
Description |
|---|---|---|
|
|
|
|
|
Axis ID to tendency ratio (all axes, including inactive) |
|
|
Raw SOLIDARITY edges crossing any contradiction axis |
|
|
Raw SOLIDARITY edges within the same side of an axis |
|
|
Antagonistic edges within same side (lateral conflict) |
|
|
Antagonistic edges from marginalized toward hegemonic |
|
|
Sum of consciousness-weighted cross-line solidarity values |
|
|
Mean CI across marginalized communities [0, 1] |
|
|
ConsciousnessTendency fractions across marginalized communities |
|
|
Number of communities spanning contradiction axes |
|
|
Sum of infrastructure * sigmoid(CI) for bridge communities |
|
|
Population-weighted mean legitimation [0, 1] |
|
|
Connected components (all SOLIDARITY edges) |
|
|
Cycle rank (all SOLIDARITY edges) |
|
|
Connected components (consciousness-filtered edges only) |
|
|
Cycle rank (consciousness-filtered edges only) |
|
|
Post-purge L_max / pre-purge L_max on filtered subgraph [0, 1] |
|
|
Maps class size to count of structurally equivalent groups |
|
|
Articulation point node IDs on filtered subgraph |
|
|
Minimum edge cuts on filtered subgraph (bounded by max_cutset_size=3) |
|
|
Mean |
|
|
Solidarity edges where effective CI < 0.3 (crisis-fragile). Default: 0. (Feature 034) |
BifurcationSnapshot
Wraps BifurcationResult with tick metadata.
Stored in BifurcationMonitor._bifurcation_history.
Field |
Type |
Description |
|---|---|---|
|
|
Simulation tick when computed (>= 0) |
|
|
Full analysis result for this tick |
AxisTendency
Per-contradiction-axis analysis result.
Field |
Type |
Description |
|---|---|---|
|
|
Matches |
|
|
Sum of consciousness-weighted cross-line solidarity (>= 0) |
|
|
Sum of antagonistic edge weights on same side (>= 0) |
|
|
cross / (lateral + epsilon); > 1.0 = solidarity-dominant |
|
|
Raw count of cross-line solidarity edges |
|
|
Raw count of lateral antagonism edges |
|
|
Raw count of upward antagonism edges |
BridgeInfo
Community spanning a contradiction axis with weighted potential.
Field |
Type |
Description |
|---|---|---|
|
|
Which community (e.g. |
|
|
ContradictionAxis IDs this community bridges (min length 1) |
|
|
Raw CI from CommunityConsciousness [0, 1] |
|
|
Sigmoid-transformed CI [0, 1] |
|
|
Community infrastructure from CommunityState [0, 1] |
|
|
infrastructure * sigmoid_ci |
|
|
Number of agents in this community |
SolidarityCeiling
Material constraints on solidarity between two agents.
Field |
Type |
Description |
|---|---|---|
|
|
From wage gap ratio interpolation [0, 1] |
|
|
+0.2 if shared exploitation source [0, 0.2] |
|
|
Bonus from shared community membership (>= 0) |
|
|
Clamped sum of all components [0, 1] |
|
|
max(w_a, w_b) / min(w_a, w_b) |
|
|
Whether agents share ADJACENCY-linked territories |
Analysis Functions
bifurcation_tendency
- bifurcation_tendency(graph, H, community_states, agent_memberships, defines)
Compute full bifurcation analysis.
Combines per-axis contradiction tendency (weakest-link), community bridge potential (consciousness-weighted), legitimation crisis amplifier, and topological resilience (two-pass Betti numbers).
- Parameters:
graph (nx.DiGraph) – Simulation DiGraph with
social_classandterritorynodesH (xgi.Hypergraph) – XGI hypergraph for community membership lookup
community_states (dict[CommunityType, CommunityState]) – Community consciousness data
agent_memberships (dict[str, set[CommunityType]]) – Agent ID to community memberships mapping
defines (BifurcationDefines) – Configurable parameters
- Returns:
Frozen result with all analysis fields populated
- Return type:
BifurcationResult
Example:
from babylon.bifurcation import bifurcation_tendency from babylon.config.defines import BifurcationDefines result = bifurcation_tendency( graph=sim_graph, H=hypergraph, community_states=states, agent_memberships=memberships, defines=BifurcationDefines(), ) print(result.overall_tendency) # "revolutionary", "fascist", or "indeterminate"
consciousness_sigmoid
- consciousness_sigmoid(collective_identity, midpoint, steepness)
Nonlinear transform with breakage cliff for consciousness weighting.
Logistic sigmoid:
1 / (1 + exp(-steepness * (ci - midpoint))). Exponent clamped to [-500, +500] to prevent overflow.
WeightedSolidarityResult
Result of consciousness-weighted solidarity computation (Feature 034). Extends the original float return with a crisis-fragile marker.
Field |
Type |
Description |
|---|---|---|
|
|
Consciousness-weighted solidarity value (>= 0) |
|
|
|
Defined in WeightedSolidarityResult.
See Ternary Consciousness Reference for full details.
consciousness_weighted_solidarity
- consciousness_weighted_solidarity(source_id, target_id, graph, H, community_states, defines)
Weight a solidarity edge by consciousness of connected communities.
For each agent, finds marginalized community memberships via the hypergraph, computes mean CI, then weights the edge by
sigmoid(min(source_ci, target_ci)).Edges where the effective CI (min of both endpoints) falls below the crisis-fragile threshold (0.3) are marked as crisis-fragile (Feature 034).
- Parameters:
source_id (str) – Source agent node ID
target_id (str) – Target agent node ID
graph (nx.DiGraph) – The simulation DiGraph (for edge attribute access)
H (xgi.Hypergraph) – XGI hypergraph (for community membership lookup)
community_states (dict[CommunityType, CommunityState]) – Current community consciousness data
defines (BifurcationDefines) – Configurable parameters (sigmoid midpoint/steepness)
- Returns:
Weighted solidarity with crisis-fragile flag
- Return type:
crosses_contradiction_axis
- crosses_contradiction_axis(source_id, target_id, axis, agent_memberships)
Check if an edge crosses the given contradiction axis.
An edge crosses when one endpoint is on the hegemonic side and the other is on the marginalized side.
- Parameters:
- Returns:
True if the edge spans hegemonic and marginalized sides
- Return type:
classify_edge_antagonism
- classify_edge_antagonism(source_id, target_id, graph, axis, agent_memberships)
Classify antagonistic direction of an edge along a contradiction axis.
Only EXPLOITATION, REPRESSION, and COMPETITION edges are classified.
- Parameters:
- Returns:
"lateral"(same side),"upward"(marginalized toward hegemonic),"downward"(hegemonic toward marginalized), or"none"- Return type:
compute_axis_tendency
- compute_axis_tendency(graph, H, axis, community_states, agent_memberships, defines)
Compute solidarity vs antagonism balance along a single contradiction axis.
Sums consciousness-weighted cross-line solidarity and lateral antagonism. Returns
tendency_ratio = cross / (lateral + epsilon).- Parameters:
graph (nx.DiGraph) – The simulation DiGraph
H (xgi.Hypergraph) – XGI hypergraph for community membership lookup
axis (ContradictionAxis) – The contradiction axis to analyze
community_states (dict[CommunityType, CommunityState]) – Current community consciousness data
agent_memberships (dict[str, set[CommunityType]]) – Agent ID to community memberships mapping
defines (BifurcationDefines) – Configurable parameters
- Returns:
AxisTendency with all counts and weighted totals
- Return type:
AxisTendency
detect_bridges
- detect_bridges(H, community_states, axes, agent_memberships, defines)
Detect communities spanning contradiction axes, weighted by consciousness.
Iterates INSTITUTIONAL_EXCLUSION communities in the hypergraph. For each, checks if members span both sides of any contradiction axis. Returns weighted bridge potential = infrastructure * sigmoid(CI).
- Parameters:
H (xgi.Hypergraph) – XGI hypergraph with communities as hyperedges
community_states (dict[CommunityType, CommunityState]) – Current community consciousness and infrastructure
axes (list[ContradictionAxis]) – Contradiction axes to check spanning against
agent_memberships (dict[str, set[CommunityType]]) – Agent ID to community memberships mapping
defines (BifurcationDefines) – Configurable parameters (sigmoid midpoint/steepness)
- Returns:
List of BridgeInfo for each community spanning at least one axis
- Return type:
list[BridgeInfo]
compute_solidarity_ceiling
- compute_solidarity_ceiling(node_a_id, node_b_id, graph, agent_memberships, defines)
Compute material solidarity ceiling between two agents.
The ceiling is the maximum achievable solidarity given material conditions (wage gap, shared exploitation, shared community membership, geography).
- Parameters:
node_a_id (str) – First agent node ID
node_b_id (str) – Second agent node ID
graph (nx.DiGraph) – Simulation graph with wealth and edge attributes
agent_memberships (dict[str, set[CommunityType]]) – Agent ID to community memberships mapping
defines (BifurcationDefines) – Bifurcation coefficient configuration
- Returns:
SolidarityCeiling with all computed components
- Return type:
SolidarityCeiling
compute_legitimation_amplifier
- compute_legitimation_amplifier(graph, defines)
Compute crisis amplifier from population-weighted mean legitimation.
- Parameters:
graph (nx.DiGraph) – Simulation graph with territory nodes carrying
legitimation_indexandpopulationdefines (BifurcationDefines) – Provides
legitimation_amplifier_scale
- Returns:
Crisis amplifier in [1.0, legitimation_amplifier_scale]. Returns 1.0 if no territories.
- Return type:
Resilience Functions
compute_betti_numbers
compute_equivalence_classes
find_critical_singletons
find_critical_cutsets
- find_critical_cutsets(subgraph, max_cutset_size=3)
Find minimum edge cuts per connected component, bounded by size.
compute_purge_resilience
- compute_purge_resilience(subgraph, removal_rate, seed=None)
Measure resilience to targeted removal of high-degree nodes.
Removes top-degree nodes at the given rate and compares post-purge to pre-purge largest component size.
BifurcationMonitor
- class BifurcationMonitor(community_state_store, defines=None, logger=None)
Monitor tracking bifurcation tendency across simulation ticks.
Records
BifurcationSnapshotper tick and emitsBifurcationTendencyEventwhen the overall tendency changes.Accepts a
CommunityStateStorevia dependency injection for community consciousness access.- Parameters:
community_state_store (CommunityStateStore) – Protocol-based access to community states
defines (BifurcationDefines | None) – Configurable bifurcation parameters (default: BifurcationDefines())
logger (logging.Logger | None) – Logger instance (default: module logger)
Properties
Methods
- record_bifurcation(graph, H, agent_memberships, tick)
Run bifurcation analysis and record snapshot.
Calls
bifurcation_tendency()with community states from the injected store, records the resultingBifurcationSnapshot, and emits aBifurcationTendencyEventif the overall tendency changed since the previous tick.- Parameters:
graph (nx.DiGraph) – Simulation DiGraph with social_class and territory nodes
H (xgi.Hypergraph) – XGI hypergraph for community membership lookup
agent_memberships (dict[str, set[CommunityType]]) – Agent ID to community memberships mapping
tick (int) – Current simulation tick
- get_pending_events()
Return and clear pending events. Same pattern as
TopologyMonitor.get_pending_events().- Returns:
List of pending events (cleared after return)
- Return type:
BifurcationTendencyEvent
Emitted when overall_tendency changes between ticks. Inherits
TopologyEvent.
Field |
Type |
Description |
|---|---|---|
|
|
Always |
|
|
Set to 0.0 (not tracked by bifurcation monitor) |
|
|
|
|
|
Overall tendency before change |
|
|
Overall tendency after change |
|
|
Sum of consciousness-weighted cross-line solidarity |
|
|
Mean CI across marginalized communities |
|
|
Sum of infrastructure * sigmoid(CI) for bridges |
|
|
Population-weighted mean legitimation |
CommunityStateStore Protocol
- class CommunityStateStore
Protocol for accessing community consciousness state. Enables dependency injection so
BifurcationMonitoris decoupled from concrete state storage.- get_all()
- Returns:
Mapping of community type to current community state
- Return type:
- class InMemoryCommunityStateStore(states)
Default implementation wrapping a dict.
- Parameters:
states (dict[CommunityType, CommunityState]) – Initial community states
Usage Example
from babylon.bifurcation import bifurcation_tendency
from babylon.config.defines import BifurcationDefines
from babylon.engine.bifurcation_monitor import BifurcationMonitor
from babylon.engine.community_state_store import InMemoryCommunityStateStore
# Set up community state store
store = InMemoryCommunityStateStore(community_states)
# Create monitor
monitor = BifurcationMonitor(
community_state_store=store,
defines=BifurcationDefines(),
)
# Record each tick
monitor.record_bifurcation(
graph=sim_graph,
H=hypergraph,
agent_memberships=memberships,
tick=current_tick,
)
# Check for tendency changes
events = monitor.get_pending_events()
for event in events:
print(f"Tendency changed: {event.previous_tendency} -> {event.new_tendency}")
# Access history
for snapshot in monitor.bifurcation_history:
result = snapshot.result
print(f"Tick {snapshot.tick}: {result.overall_tendency}")