State Apparatus AI (Feature 039)
Technical reference for the state apparatus AI subsystem: entity models, enums, decision functions, effect resolution, attention/intelligence modules, formulas, and configuration parameters.
Module Layout
src/babylon/
+-- config/defines.py StateApparatusAIDefines
+-- models/
| +-- enums.py StateFaction, StateActionType, ThreadPhase, SurveillanceMethod
| +-- entities/
| +-- state_apparatus_ai.py FactionBalance, StateBudget, StateAction, LegalFramework
| +-- attention_thread.py AttentionThread, SparrowAnalysis
+-- formulas/state_ai.py Faction shift, fascist convergence formulas
+-- ooda/
+-- state_ai/ Decision engine + effect resolution (11 modules)
| +-- protocols.py NPCDecisionStrategy protocol
| +-- decision.py RuleBasedStateAI class
| +-- escalation.py Escalation ladder ranking
| +-- faction_dynamics.py Faction weight shifts
| +-- territory_effects.py DEVELOP/WITHDRAW effects
| +-- co_opt_effects.py CO-OPT effects
| +-- repress_effects.py REPRESS pipeline
| +-- administer_effects.py ADMINISTER capacity
| +-- legislate_effects.py LEGISLATE consumption
| +-- observability.py Player-visible events + god mode
+-- attention/ Intelligence gathering (4 modules)
+-- observation.py G_observed construction
+-- sparrow.py Network vulnerability analysis
+-- thread_manager.py Thread lifecycle management
Enums
All state AI enums are StrEnum subclasses in
babylon.models.enums.
StateFaction
Ruling-class factions within the state coalition.
Member |
Value |
|---|---|
|
|
|
|
|
|
StateActionType
State verb taxonomy. Six top-level verbs and their sub-verbs.
Top-level verbs:
Member |
Value |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Sub-verbs by parent:
Parent |
Sub-verb |
Value |
|---|---|---|
ADMINISTER |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DEVELOP |
|
|
|
|
|
|
|
|
|
|
|
RESEARCH |
|
|
|
|
|
CO_OPT |
|
|
|
|
|
|
|
|
|
|
|
REPRESS |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
WITHDRAW |
|
|
|
|
|
|
|
ThreadPhase
Attention thread intelligence phase progression.
Member |
Value |
Intel threshold |
|---|---|---|
|
|
< 0.1 |
|
|
>= 0.1 |
|
|
>= 0.4 |
|
|
>= 0.7 |
SurveillanceMethod
Intelligence collection methods. Each reveals different network aspects.
Member |
Value |
|---|---|
|
|
|
|
|
|
|
|
|
|
Entity Models
All entity models use ConfigDict(frozen=True). Mutation via
model_copy(update={...}) only.
FactionBalance
babylon.models.entities.state_apparatus_ai
Three-faction weight vector. Weights must sum to 1.0 (within 0.01 tolerance, enforced by model validator).
Field |
Type |
Constraints |
Default |
|---|---|---|---|
|
|
|
required |
|
|
|
required |
|
|
|
required |
|
|
|
required |
|
|
|
required |
Computed property:
dominant_faction->StateFaction: faction with the highest weight.
StateBudget
babylon.models.entities.state_apparatus_ai
Field |
Type |
Constraints |
|---|---|---|
|
|
|
|
|
|
|
|
keys must be top-level verbs; values |
|
|
|
StateAction
babylon.models.entities.state_apparatus_ai
Model validator enforces sub_verb is a valid child of verb via
VERB_CHILDREN.
Field |
Type |
Constraints |
Default |
|---|---|---|---|
|
|
must be in |
required |
|
|
must be in |
required |
|
|
|
|
|
|
|
required |
|
|
|
required |
|
|
required |
|
|
|
required |
|
|
|
|
LegalFramework
babylon.models.entities.state_apparatus_ai
Model validator enforces law_type is in VALID_LAW_TYPES.
Field |
Type |
Constraints |
|---|---|---|
|
|
|
|
|
one of: |
|
|
JurisdictionLevel value |
|
|
|
|
|
|
|
|
|
|
|
|
AttentionThread
babylon.models.entities.attention_thread
Model validator enforces target_type is in VALID_TARGET_TYPES
("organization", "territory", "community").
Field |
Type |
Constraints |
Default |
|---|---|---|---|
|
|
|
required |
|
|
in |
required |
|
|
|
required |
|
|
required |
|
|
|
|
required |
|
|
|
required |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
required |
|
|
|
required |
|
|
|
required |
SparrowAnalysis
babylon.models.entities.attention_thread
Field |
Type |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Constants and Mappings
babylon.models.entities.state_apparatus_ai
VERB_CHILDREN: dict[StateActionType, frozenset[StateActionType]]– Authoritative parent-child verb hierarchy. Keys are the six top-level verbs; values are frozensets of valid sub-verbs.TOP_LEVEL_VERBS: frozenset[StateActionType]– The six keys ofVERB_CHILDREN.ALL_SUB_VERBS: frozenset[StateActionType]– Union of all values inVERB_CHILDREN.VALID_LAW_TYPES: frozenset[str]– The six permitted law type strings.get_parent_verb(sub_verb: StateActionType) -> StateActionType | None– Returns the parent verb of a sub-verb, orNoneif the input is itself top-level.
Event Types
Six EventType members added in babylon.models.enums:
EventType |
Value |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
Three EdgeType members for graph relationships:
TARGETS– AttentionThread -> target entityOWNED_BY– AttentionThread -> StateApparatusJURISDICTION– LegalFramework -> Territory
Note
These EventType members are declared in the enum but not yet emitted
by any system. They define the integration surface for downstream
consumers. The OODA dispatch path converts StateAction results
into legacy Action objects for the existing resolution pipeline.
Decision Engine
NPCDecisionStrategy Protocol
babylon.ooda.state_ai.protocols
@runtime_checkable protocol for state AI decision strategies.
def select_action(
self,
org_id: str,
org_attrs: dict[str, Any],
graph: Any,
context: dict[str, Any],
defines: StateApparatusAIDefines,
) -> list[StateAction]: ...
RuleBasedStateAI
babylon.ooda.state_ai.decision
Implements the faction-weighted OODA decision loop. The actual
select_action method signature differs from the protocol, using
fully-typed parameters:
def select_action(
self,
org_id: str,
faction_balance: FactionBalance,
budget: StateBudget,
heat: float,
defines: StateApparatusAIDefines,
rng_seed: int | None = None,
) -> list[StateAction]: ...
OODA cycle:
OBSERVE+ORIENT:
_generate_candidates()enumerates all sub-verbs whosebudget_cost <= budget.available.DECIDE: Each candidate scored via
score_action()(weighted dot product of faction objectives) pluscompute_heat_escalation_score()plus a small random tiebreaker.ACT: Top
defines.actions_per_tickcandidates selected within remaining budget.
def get_debug_state(
self,
defines: StateApparatusAIDefines,
faction_balance: FactionBalance | None = None,
budget: StateBudget | None = None,
last_actions: list[StateAction] | None = None,
) -> dict[str, Any] | None: ...
Returns None when defines.god_mode_enabled is False.
Scoring functions (module-level):
def finance_capital_objective(action: StateAction, heat: float) -> float: ...
def security_state_objective(action: StateAction, heat: float) -> float: ...
def settler_populist_objective(action: StateAction, heat: float) -> float: ...
def score_action(action: StateAction, balance: FactionBalance, heat: float) -> float: ...
Escalation
babylon.ooda.state_ai.escalation
def get_escalation_rank(
sub_verb: StateActionType,
defines: StateApparatusAIDefines,
) -> int: ...
Returns 0-based index in defines.escalation_ladder, or -1 if not
present.
def compute_heat_escalation_score(
heat: float,
escalation_rank: int,
max_rank: int,
) -> float: ...
Returns score in [0.0, 2.0]. Formula:
max(0, 1 - |heat - rank/max_rank|) * 2.0.
Faction Dynamics
babylon.ooda.state_ai.faction_dynamics
def apply_player_action_shift(
action_type: str,
outcome: str,
current_balance: FactionBalance,
defines: StateApparatusAIDefines,
) -> FactionBalance: ...
Valid action_type keys: "heat_generation",
"surviving_repression", "extraction_disruption",
"narrative_victory", "legitimacy_building". Outcome "success"
applies full magnitude; otherwise 0.5x.
def apply_repression_failure_shift(
current_balance: FactionBalance,
membership_retained_ratio: float,
defines: StateApparatusAIDefines,
) -> FactionBalance: ...
No-op if membership_retained_ratio <= 0.5. Otherwise shifts
Security-State weight down proportionally to (retained - 0.5) * 2.0.
def apply_material_condition_shift(
condition_type: str,
magnitude: float,
current_balance: FactionBalance,
defines: StateApparatusAIDefines,
) -> FactionBalance: ...
Valid condition_type keys: "profit_rate_decline",
"legitimacy_crisis", "imperial_rent_contraction",
"successful_co_opt".
def renormalize_faction_balance(
balance: FactionBalance,
max_shift: float,
previous_balance: FactionBalance,
) -> FactionBalance: ...
Iterative clamp-normalize (up to 5 iterations). No per-faction delta
exceeds max_shift.
def compute_stability(
shift_history: list[FactionBalance],
window: int,
) -> float: ...
Returns [0.0, 1.0]. Formula:
max(0, 1 - total_variance / 0.10).
def apply_fascist_overrides(
actions: list[StateAction],
balance: FactionBalance,
defines: StateApparatusAIDefines,
) -> list[StateAction]: ...
Active when is_fascist_convergence() conditions hold. Redirections:
CO_OPT -> REPRESS.RAID, DEVELOP -> DEVELOP.DISPLACE,
WITHDRAW -> WITHDRAW.SCORCHED_EARTH.
Effect Resolution
Territory Effects
babylon.ooda.state_ai.territory_effects
All functions accept dict[str, Any] territory representations and
return new dicts (no in-place mutation).
def resolve_invest(territory: dict[str, Any], defines: StateApparatusAIDefines) -> dict[str, Any]: ...
def resolve_neglect(territory: dict[str, Any], defines: StateApparatusAIDefines) -> dict[str, Any]: ...
def resolve_displace(
territory: dict[str, Any],
defines: StateApparatusAIDefines,
) -> tuple[dict[str, Any], int]: ...
Returns (updated_territory, displaced_count).
def resolve_strategic_withdrawal(
territory: dict[str, Any],
defines: StateApparatusAIDefines,
asset_extraction: bool = False,
) -> tuple[dict[str, Any], float]: ...
Returns (updated_territory, budget_recovered).
def resolve_scorched_earth(
territory: dict[str, Any],
defines: StateApparatusAIDefines,
) -> tuple[dict[str, Any], float]: ...
Returns (updated_territory, legitimacy_cost).
def compute_heat_accumulation(current_heat: float, high_profile_count: int, low_profile_count: int, defines: StateApparatusAIDefines) -> float: ...
def compute_heat_decay(current_heat: float, has_presence: bool, defines: StateApparatusAIDefines) -> float: ...
def compute_propagandize_effect(collective_identity: float, base_delta: float, defines: StateApparatusAIDefines) -> float: ...
def compute_scorched_earth_legitimacy(territory_type: str, defines: StateApparatusAIDefines) -> float: ...
def check_recruit_effectiveness(has_presence: bool, base_effectiveness: float, defines: StateApparatusAIDefines) -> float: ...
def assess_territory_threat(territory_ci: float, territory_heat: float, defines: StateApparatusAIDefines) -> float: ...
def resolve_eviction_cascade(
source_territory: dict[str, Any],
neighbor_territories: list[dict[str, Any]],
displaced_count: int,
defines: StateApparatusAIDefines,
) -> tuple[dict[str, Any], list[dict[str, Any]]]: ...
CO-OPT Effects
babylon.ooda.state_ai.co_opt_effects
def resolve_propagandize(
territory: dict[str, Any],
narrative: str,
intensity: float,
defines: StateApparatusAIDefines,
) -> dict[str, Any]: ...
Valid narratives: "we_are_all_americans" (1.0x), "reform_is_working"
(0.7x), "threat_narrative" (0.5x), "delegitimize_opposition" (0.3x).
"threat_narrative" increases settler CI instead of reducing target CI.
def compute_incorporate_probability(
coherence: float,
collective_identity: float,
offer_attractiveness: float,
defines: StateApparatusAIDefines,
) -> float: ...
Formula: (1 - coherence) * (1 - CI) * max(offer, base_attractiveness).
def resolve_divide(
current_edge_type: str,
has_prior_surveil: bool,
defines: StateApparatusAIDefines,
) -> str: ...
Degrades edges: solidaristic -> transactional -> antagonistic.
No-op when divide_requires_prior_surveil=True and no prior surveil.
def resolve_bribe(
target: dict[str, Any],
bribe_amount: float,
defines: StateApparatusAIDefines,
) -> dict[str, Any]: ...
Increases wealth, decreases r_tendency, increases l_tendency.
REPRESS Effects
babylon.ooda.state_ai.repress_effects
def resolve_infiltrate(
target_org: dict[str, Any],
thread: dict[str, Any],
agent_type: str,
defines: StateApparatusAIDefines,
rng_seed: int,
current_tick: int = 0,
) -> tuple[dict[str, Any], dict[str, Any], bool]: ...
Returns (updated_thread, infiltration_record, detected). Valid
agent_type: "INFORMANT", "PROVOCATEUR", "MOLE".
PROVOCATEUR has 1.5x detection chance. Raises ValueError for
invalid agent type.
def compute_raid_consciousness_effect(
ci: float,
defines: StateApparatusAIDefines,
) -> float: ...
Returns +raid_ci_radicalization_boost if
ci >= raid_ci_radicalization_threshold, else
-raid_ci_suppression_rate. This is the consciousness dialectic:
raids crush low-CI communities but radicalize high-CI ones.
def resolve_raid(
target_org: dict[str, Any],
territory: dict[str, Any],
scale: str,
force_level: str,
thread_intel: float,
key_figure_ids: list[str],
defines: StateApparatusAIDefines,
rng_seed: int,
) -> tuple[dict[str, Any], dict[str, Any], list[str], float]: ...
Returns (updated_org, updated_territory, captured_figure_ids,
legitimacy_cost). Valid scales: "TARGETED", "SWEEP",
"MASS". Valid force levels: "POLICE", "SWAT",
"MILITARY". MASS scale damages community_infrastructure_quality.
def resolve_prosecute(
target_org: dict[str, Any],
target_key_figure_id: str | None,
charge: str,
defines: StateApparatusAIDefines,
rng_seed: int,
current_tick: int = 0,
) -> tuple[dict[str, Any], dict[str, Any], float]: ...
Returns (updated_org, prosecution_record, legitimacy_delta). Valid
charges: "CONSPIRACY", "RACKETEERING", "TAX",
"CIVIL_RIGHTS_VIOLATION", "TERRORISM". Legitimacy delta is
positive on conviction, negative on acquittal.
def resolve_liquidate(
target_org: dict[str, Any],
target_key_figure_id: str,
method: str,
deniability: float,
territory_type: str,
liquidate_available_in_core: bool,
is_singleton: bool,
defines: StateApparatusAIDefines,
) -> tuple[dict[str, Any], float, bool]: ...
Returns (updated_org, legitimacy_cost, org_collapsed). Valid
methods: "ASSASSINATION", "DISAPPEARANCE", "RENDITION",
"PRISON_KILLING". Raises ValueError for CORE territory without
liquidate_available_in_core=True (requires EMERGENCY_POWERS).
ADMINISTER Effects
babylon.ooda.state_ai.administer_effects
def resolve_fund(
apparatus: dict[str, Any],
capacity_type: str,
defines: StateApparatusAIDefines,
) -> dict[str, Any]: ...
Valid capacity_type: "violence", "surveillance",
"service". Increments the corresponding capacity field by
fund_capacity_increment, capped at 1.0.
def resolve_staff(
apparatus: dict[str, Any],
current_pool_size: int,
count: int,
defines: StateApparatusAIDefines,
) -> tuple[dict[str, Any], int]: ...
Returns (updated_apparatus, new_pool_size). Capped by
staff_max_per_tick and thread_pool_max. No-op if
surveillance_capacity <= 0.0.
def resolve_audit(
apparatus: dict[str, Any],
active_infiltrations: list[dict[str, Any]],
depth: str,
defines: StateApparatusAIDefines,
rng_seed: int,
) -> tuple[dict[str, Any], list[dict[str, Any]]]: ...
Returns (updated_apparatus, detected_infiltrations). Valid depths:
"ROUTINE" (0.2 chance), "THOROUGH" (0.5 chance), "DEEP"
(0.8 chance).
LEGISLATE Effects
babylon.ooda.state_ai.legislate_effects
def consume_legal_framework_effects(
active_frameworks: list[dict[str, Any]],
baseline: dict[str, Any],
defines: StateApparatusAIDefines,
) -> dict[str, Any]: ...
Idempotent: each law_type applied at most once regardless of
framework count. Effects by law type:
EMERGENCY_POWERS: multipliesthread_pool_maxbyemergency_powers_thread_multiplier, setsliquidate_in_core=True.SURVEILLANCE_EXPANSION: addssurveillance_expansion_intel_bonustointel_bonus.
Observability
babylon.ooda.state_ai.observability
def create_observable_action(
action: StateAction,
territory_heat: float,
) -> dict[str, Any]: ...
Returns {verb, sub_verb, target_id, visible_intensity,
territory_heat}. Visible intensity formula:
min(1, budget_cost/20) * 0.7 + heat * 0.3.
def create_territory_observables(
territory: dict[str, Any],
) -> dict[str, Any]: ...
Returns {property_value_proxy, infrastructure_quality, heat,
population, collective_identity}.
def resolve_counter_intel(
intel_success: float,
faction_balance: FactionBalance,
last_actions: list[StateAction],
defines: StateApparatusAIDefines,
) -> dict[str, Any]: ...
Tiered disclosure by intel_success:
>= 0.0:intel_level,visible_actions(verb + target only)>= 0.3: addsfaction_balance(rounded to 2 decimals)>= 0.6: addsaction_details(verb, sub_verb, target, budget_cost, faction_alignment)>= 0.8: addsfull_state(dominant_faction, stability, legitimacy)
Attention / Intelligence
G_observed Construction
babylon.ooda.attention.observation
def build_g_observed(
thread: AttentionThread,
full_graph: nx.DiGraph[str],
) -> nx.DiGraph[str]: ...
Builds subgraph from thread.observed_node_ids and
thread.observed_edge_ids with method-specific distortions. Node cap:
1000. Edge cap: 5000.
Distortion rules:
SIGNALSonly: setsedge_type = "observed_connection"FINANCIALonly: non-monetary edges getdistorted=True, confidence=0.3
def compute_observation_ceiling(
base_ceiling: float,
compartmentalization_factor: float,
) -> float: ...
Formula: base_ceiling * (1 - compartmentalization_factor), clamped
to [0.0, 1.0].
Sparrow Analysis
babylon.ooda.attention.sparrow
def analyze_network(
thread_id: str,
tick: int,
g_observed: nx.DiGraph[str],
confidence: float = 0.8,
) -> SparrowAnalysis: ...
Computes degree, betweenness, and closeness centrality. Equivalence
classes by degree signature. Singletons: nodes with betweenness > 2x
mean. Cutsets: NetworkX articulation points (on undirected view).
Returns empty SparrowAnalysis for empty graphs.
Thread Lifecycle
babylon.ooda.attention.thread_manager
def allocate_threads(
existing_threads: list[AttentionThread],
target_scores: dict[str, float],
pool_size: int,
defines: StateApparatusAIDefines,
) -> list[AttentionThread]: ...
Greedy allocation. Stickiness bonus =
minimum_effect_floor * 5.0 * ticks_active, capped at 1.0.
def advance_thread_phase(
thread: AttentionThread,
defines: StateApparatusAIDefines,
) -> AttentionThread: ...
One-directional phase advancement (no regression). Thresholds from
defines.thread_escalation_thresholds.
Phase-to-methods mapping:
DORMANT->[]MONITORING->[SIGNALS]ACTIVE_INVESTIGATION->[SIGNALS, FINANCIAL]DISRUPTION->[SIGNALS, FINANCIAL, INFORMANT]
def update_thread_tick(
thread: AttentionThread,
intel_gain: float,
observation_ceiling: float,
) -> AttentionThread: ...
Increments ticks_active by 1. Increments intel_completeness by
intel_gain, capped at observation_ceiling and 1.0.
Formulas
def calculate_faction_shift(
heat: float,
current_balance: FactionBalance,
defines: StateApparatusAIDefines,
) -> FactionBalance: ...
Heat-driven Security-State weight adjustment:
heat > 0.5: SS gains up to(heat - 0.5) * 0.2, clamped tomax_shift. FC/SP absorb loss proportionally.heat < 0.3: SS loses(0.3 - heat) * 0.1 * 0.5. FC recovers 60%, SP 40%.0.3 <= heat <= 0.5: no change.
def is_fascist_convergence(
balance: FactionBalance,
settler_ci: float,
consecutive_ticks: int,
defines: StateApparatusAIDefines,
) -> bool: ...
Three-pillar check (all strict inequalities):
SS > fascist_security_threshold(default 0.4)settler_ci > fascist_settler_ci_threshold(default 0.6)FC < fascist_finance_ceiling(default 0.25)consecutive_ticks >= convergence_confirmation_ticks(default 2)
def check_fascist_reversion(
balance: FactionBalance,
settler_ci: float,
defines: StateApparatusAIDefines,
) -> bool: ...
Exit thresholds (asymmetrically harder than entry):
SS < reversion_ss_threshold(default 0.25)settler_ci < reversion_ci_threshold(default 0.30)
Configuration
StateApparatusAIDefines in babylon.config.defines.
Frozen BaseModel. All fields tagged [S] SYNTHETIC.
Faction Dynamics
Field |
Type |
Default |
Range |
|---|---|---|---|
|
float |
0.05 |
[0.0, 0.2] |
|
float |
0.02 |
[0.0, 0.1] |
|
float |
0.1 |
[0.0, 1.0] |
Fascist Convergence
Field |
Type |
Default |
Range |
|---|---|---|---|
|
float |
0.4 |
[0.0, 1.0] |
|
float |
0.6 |
[0.0, 1.0] |
|
float |
0.25 |
[0.0, 1.0] |
|
int |
2 |
[1, 10] |
|
float |
0.25 |
[0.0, 1.0] |
|
float |
0.30 |
[0.0, 1.0] |
Attention Threads
Field |
Type |
Default |
Range |
|---|---|---|---|
|
int |
5 |
[1, 50] |
|
int |
8 |
[1, 100] |
|
dict |
|
Budget
Field |
Type |
Default |
Range |
|---|---|---|---|
|
float |
100.0 |
ge=0.0 |
|
int |
1 |
[1, 10] |
Territory Effects
Field |
Type |
Default |
Range |
|---|---|---|---|
|
float |
0.1 |
[0.0, 1.0] |
|
float |
0.05 |
[0.0, 1.0] |
|
float |
0.1 |
[0.0, 1.0] |
|
float |
0.1 |
[0.0, 1.0] |
|
float |
0.5 |
[0.0, 1.0] |
|
float |
0.1 |
[0.0, 1.0] |
|
float |
0.02 |
[0.0, 1.0] |
|
float |
0.6 |
[0.0, 1.0] |
|
float |
0.15 |
[0.0, 1.0] |
|
float |
0.03 |
[0.0, 1.0] |
|
float |
2.0 |
[1.0, 10.0] |
|
float |
0.5 |
[0.0, 1.0] |
|
float |
0.2 |
[0.0, 1.0] |
|
float |
0.3 |
[0.0, 1.0] |
Spatial Dynamics
Field |
Type |
Default |
Range |
|---|---|---|---|
|
float |
0.05 |
[0.0, 1.0] |
|
float |
0.9 |
[0.0, 1.0] |
|
float |
0.15 |
[0.0, 1.0] |
CO-OPT Effects
Field |
Type |
Default |
Range |
|---|---|---|---|
|
float |
0.05 |
[0.0, 0.5] |
|
float |
0.3 |
[0.0, 1.0] |
|
float |
0.05 |
[0.0, 0.5] |
|
float |
0.03 |
[0.0, 0.5] |
|
bool |
True |
|
|
bool |
True |
ADMINISTER Effects
Field |
Type |
Default |
Range |
|---|---|---|---|
|
float |
0.05 |
[0.0, 0.5] |
|
float |
3.0 |
[0.0, 50.0] |
|
int |
2 |
[1, 10] |
|
float |
0.2 |
[0.0, 1.0] |
|
float |
0.5 |
[0.0, 1.0] |
|
float |
0.8 |
[0.0, 1.0] |
REPRESS Effects
Field |
Type |
Default |
Range |
|---|---|---|---|
|
float |
0.05 |
[0.0, 0.5] |
|
float |
0.03 |
[0.0, 0.5] |
|
float |
0.08 |
[0.0, 0.5] |
|
float |
0.1 |
[0.0, 1.0] |
|
float |
0.5 |
[0.0, 1.0] |
|
float |
0.1 |
[0.0, 0.5] |
|
float |
0.15 |
[0.0, 0.5] |
|
float |
0.2 |
[0.0, 1.0] |
|
float |
0.3 |
[0.0, 1.0] |
|
float |
1.5 |
[1.0, 5.0] |
|
float |
2.5 |
[1.0, 10.0] |
|
float |
0.1 |
[0.0, 0.5] |
|
float |
0.6 |
[0.0, 1.0] |
|
float |
1.5 |
[1.0, 5.0] |
|
float |
0.02 |
[0.0, 0.1] |
|
float |
0.7 |
[0.0, 1.0] |
|
float |
0.15 |
[0.0, 0.5] |
|
float |
0.03 |
[0.0, 0.5] |
|
float |
0.5 |
[0.0, 1.0] |
|
float |
0.3 |
[0.0, 1.0] |
LEGISLATE Consumption
Field |
Type |
Default |
Range |
|---|---|---|---|
|
float |
2.0 |
[1.0, 5.0] |
|
bool |
True |
|
|
float |
0.1 |
[0.0, 0.5] |
Debug
Field |
Type |
Default |
Range |
|---|---|---|---|
|
bool |
False |
OODA Dispatch Integration
The OODA system dispatches state apparatus decisions through the following path:
OODASystem.step()(engine/systems/ooda.py) iterates organizations by initiative.For
OrgType.STATE_APPARATUS, callsselect_npc_actions()(ooda/npc_stub.py)._try_state_ai_dispatch()checks forfaction_balanceon the graph node. If present, instantiatesRuleBasedStateAIand callsselect_action().Returned
list[StateAction]is converted to legacylist[Action]for the existing resolution pipeline.If
faction_balanceis absent, falls through to the legacy priority-queue stub (SURVEIL -> REPRESS -> INFILTRATE -> MAP_NETWORK -> COUNTER_INTEL).
FactionBalance and StateBudget are stored as graph node
attributes on the StateApparatus node, not as Pydantic model fields.
They do not survive WorldState.to_graph() / from_graph()
round-trips via the typed model path.
See Also
Organization Reference – Organization base model (Feature 031)
OODA Loop System Reference – OODA loop system (Feature 032)
About the State Apparatus AI – Design rationale and architecture
How to Work with the State Apparatus AI – Goal-oriented guides for working with the state AI