"""Integration tests for the ExperimentationOS orchestrator.""" from __future__ import annotations import pytest from spinor_os.config import AttributionMethod, Direction, EventType, LoopStage from spinor_os.engine import ExperimentationOS from spinor_os.workflow import WorkflowTransitionError def make_os() -> ExperimentationOS: os = ExperimentationOS(config={"min_replications": 1}) os.register_employee("emp-001", "rep", "northeast", {"enterprise": 0.8}) return os def test_health_check_empty(): os = ExperimentationOS() health = os.health_check() assert health["status"] == "healthy" def test_full_experiment_loop(): os = make_os() hypothesis = os.propose_hypothesis( statement="X increases Y", causal_claim="X causes Y to increase.", predicted_effect={ "metric": "y_rate", "direction": Direction.INCREASE.value, "magnitude": 0.1, "unit": "pp", "timing": "7d", }, employee_owner="emp-001", falsification_criteria=["Y does not increase"], customer_segment="enterprise", territory="northeast", modification="mod-a", ) exp = os.start_experiment(hypothesis.hypothesis_id) assert exp.current_stage == LoopStage.RESEARCH candidates = [ { "hypothesis_id": hypothesis.hypothesis_id, "modification": "mod-a", "customer_segment": "enterprise", "territory": "northeast", "timing": "2026-W31", "resource_allocation": 1.0, } ] mission = os.allocate_mission(exp.experiment_id, "emp-001", candidates) assert mission.mission_id in os.missions os.record_event( exp.experiment_id, mission.mission_id, EventType.MISSION_EXECUTED, actor_id="emp-001", execution_quality=0.85, ) os.record_event( exp.experiment_id, mission.mission_id, EventType.OUTCOME_OBSERVED, actor_id="emp-001", outcome_value=0.2, metric="y_rate", execution_quality=0.85, ) claim = os.attribute( exp.experiment_id, outcome_metric="y_rate", outcome_value=0.2, counterfactual_estimate=0.05, method=AttributionMethod.RCT, confidence=0.95, falsification_survived=True, ) assert claim.is_significant() os.advance(exp.experiment_id, LoopStage.OBSERVE) os.advance(exp.experiment_id, LoopStage.ATTRIBUTE) os.advance(exp.experiment_id, LoopStage.FALSIFY) assert exp.current_stage == LoopStage.FALSIFY os.ingest_to_causal_graph(exp.experiment_id) os.update_policy(exp.experiment_id) # Engine can produce top causal graph candidates. top = os.causal_graph.next_experiments() assert len(top) == 1 def test_promotion_requires_replications(): os = make_os() hypothesis = os.propose_hypothesis( statement="X increases Y", causal_claim="X causes Y to increase.", predicted_effect={ "metric": "y_rate", "direction": Direction.INCREASE.value, "magnitude": 0.1, "unit": "pp", "timing": "7d", }, employee_owner="emp-001", falsification_criteria=["Y does not increase"], customer_segment="enterprise", territory="northeast", modification="mod-a", ) exp = os.start_experiment(hypothesis.hypothesis_id) candidates = [ { "hypothesis_id": hypothesis.hypothesis_id, "modification": "mod-a", "customer_segment": "enterprise", "territory": "northeast", "timing": "2026-W31", "resource_allocation": 1.0, } ] mission = os.allocate_mission(exp.experiment_id, "emp-001", candidates) os.record_event( exp.experiment_id, mission.mission_id, EventType.OUTCOME_OBSERVED, actor_id="emp-001", outcome_value=0.2, metric="y_rate", execution_quality=0.85, ) os.attribute( exp.experiment_id, outcome_metric="y_rate", outcome_value=0.2, counterfactual_estimate=0.05, method=AttributionMethod.RCT, confidence=0.95, falsification_survived=True, ) os.advance(exp.experiment_id, LoopStage.OBSERVE) os.advance(exp.experiment_id, LoopStage.ATTRIBUTE) os.advance(exp.experiment_id, LoopStage.FALSIFY) os.advance(exp.experiment_id, LoopStage.REPLICATE) os.advance(exp.experiment_id, LoopStage.SYSTEMIZE) strategy = os.systemize_strategy(exp.experiment_id, "S", "D", automation_ready=True) # Promotion should fail because the registry requires 3 replications and this experiment has only 1. os.golden_registry.rules.required_replications = 3 os.golden_registry.rules.required_adversarial_retests = 0 result = os.promote_to_golden(strategy.strategy_id, "Mechanism", "auto-1") assert not result.success assert any("replications" in r.lower() for r in result.reasons)