| """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) |
|
|
| |
| 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) |
| |
| 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) |
|
|