from osint_core.scheduler import ( INVARIANT_CHECKS, DecisionPacket, ScheduleReason, ShortcutDebt, SystemState, fits_deadline, safe_utility, schedule_decision, total_required_time_ms, ) def make_packet(**overrides): data = { "intent_id": "intent_123", "action": "enrich_indicator", "risk_label": "low", "confidence": 0.90, "reversibility": 0.90, "deadline_ms": 1000, "verification_cost_ms": 100, "execution_cost_ms": 100, "rollback_cost_ms": 100, "expected_utility_decay": 0.10, "required_checks": INVARIANT_CHECKS, "rollback_plan": "observe_only", "uncertainty_notes": (), } data.update(overrides) return DecisionPacket(**data) def test_total_required_time_and_deadline_fit(): packet = make_packet() assert total_required_time_ms(packet) == 300 assert fits_deadline(packet) is True def test_fast_path_for_low_risk_reversible_action(): decision = schedule_decision(make_packet(risk_label="low")) assert decision.route == "FAST" assert decision.allowed is True assert decision.reason == ScheduleReason.FAST_PATH_AVAILABLE def test_deliberative_path_for_high_risk_action_that_fits_deadline(): packet = make_packet( risk_label="high", confidence=0.90, reversibility=0.70, rollback_plan="sandbox", rollback_cost_ms=200, deadline_ms=1000, ) decision = schedule_decision(packet) assert decision.route == "DELIBERATIVE" assert decision.allowed is True def test_invariant_checks_cannot_be_skipped(): packet = make_packet(required_checks=("scope_validated",)) decision = schedule_decision(packet) assert decision.route == "FAIL_CLOSED" assert decision.allowed is False assert decision.reason == ScheduleReason.INVARIANT_VIOLATION assert "hash_salt_present" in decision.skipped_checks def test_high_risk_without_rollback_fails_closed(): packet = make_packet( risk_label="critical", rollback_plan="", rollback_cost_ms=0, ) decision = schedule_decision(packet) assert decision.route == "FAIL_CLOSED" assert decision.reason == ScheduleReason.MISSING_ROLLBACK def test_deadline_too_tight_routes_to_containment_when_reversible(): packet = make_packet( deadline_ms=100, verification_cost_ms=100, execution_cost_ms=100, rollback_cost_ms=100, reversibility=0.90, ) decision = schedule_decision(packet) assert decision.route == "CONTAINMENT" assert decision.reason == ScheduleReason.DEADLINE_TOO_TIGHT assert decision.authority_scale == 0.25 def test_deadline_too_tight_and_not_reversible_fails_closed(): packet = make_packet( deadline_ms=100, reversibility=0.20, ) decision = schedule_decision(packet) assert decision.route == "FAIL_CLOSED" assert decision.reason == ScheduleReason.NO_SAFE_ACTION_FITS def test_shortcut_debt_forces_containment(): state = SystemState(shortcut_debt=ShortcutDebt(emergency_overrides=2), shortcut_debt_limit=0.70) decision = schedule_decision(make_packet(), state) assert decision.route == "CONTAINMENT" assert decision.reason == ScheduleReason.SHORTCUT_DEBT_TOO_HIGH def test_contested_trust_state_forces_containment(): state = SystemState(trust_state="contested") decision = schedule_decision(make_packet(), state) assert decision.route == "CONTAINMENT" assert decision.reason == ScheduleReason.TRUST_STATE_DEGRADED def test_low_confidence_high_risk_forces_containment(): packet = make_packet(risk_label="high", confidence=0.20, rollback_plan="sandbox") decision = schedule_decision(packet) assert decision.route == "CONTAINMENT" assert decision.reason == ScheduleReason.LOW_CONFIDENCE def test_safe_utility_is_bounded(): score = safe_utility(make_packet()) assert 0.0 <= score <= 1.0