test_phase_two_contracts.py 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. from __future__ import annotations
  2. from datetime import UTC, datetime, timedelta
  3. from types import SimpleNamespace
  4. import pytest
  5. from script_build_host.application.phase_two_planning import (
  6. PHASE_ONE_CAPABILITY_BOUNDARY,
  7. PhasePolicyGuard,
  8. _execution_seconds,
  9. )
  10. from script_build_host.domain.task_capabilities import (
  11. LegacyTaskCapabilityCatalog,
  12. TaskCapabilityCatalog,
  13. )
  14. from script_build_host.domain.task_contracts import ScriptTaskKind, TaskContractError
  15. def test_execution_budget_counts_runtime_intervals_not_planner_idle_time() -> None:
  16. now = datetime.now(UTC)
  17. stages = (
  18. SimpleNamespace(
  19. started_at=(now - timedelta(hours=2)).isoformat(),
  20. completed_at=(now - timedelta(hours=2) + timedelta(seconds=12)).isoformat(),
  21. ),
  22. SimpleNamespace(
  23. started_at=(now - timedelta(minutes=1)).isoformat(),
  24. completed_at=(now - timedelta(minutes=1) + timedelta(seconds=8)).isoformat(),
  25. ),
  26. )
  27. assert _execution_seconds(stages) == pytest.approx(20.0)
  28. def test_phase_policy_dispatches_only_v2_logical_evidence() -> None:
  29. guard = PhasePolicyGuard()
  30. guard.dispatch(context={"phase": 1}, kind=ScriptTaskKind.DIRECTION)
  31. guard.dispatch(context={"phase": 1}, kind=ScriptTaskKind.EVIDENCE_RETRIEVAL)
  32. with pytest.raises(TaskContractError, match="PHASE_POLICY_VIOLATION"):
  33. guard.dispatch(
  34. context={"phase": 1},
  35. kind=ScriptTaskKind.KNOWLEDGE_RETRIEVAL,
  36. )
  37. def test_phase_boundary_reason_is_host_owned() -> None:
  38. guard = PhasePolicyGuard()
  39. guard.boundary(
  40. context={"phase": 1},
  41. reason=PHASE_ONE_CAPABILITY_BOUNDARY,
  42. )
  43. with pytest.raises(TaskContractError, match="PHASE_POLICY_VIOLATION"):
  44. guard.boundary(context={"phase": 1}, reason="model-invented-boundary")
  45. def test_legacy_catalog_is_readable_but_physical_retrieval_is_not_v2_executable() -> None:
  46. assert (
  47. LegacyTaskCapabilityCatalog()
  48. .get(ScriptTaskKind.KNOWLEDGE_RETRIEVAL)
  49. .worker_preset
  50. == "script_knowledge_retrieval_worker"
  51. )
  52. with pytest.raises(TaskContractError, match="TASK_CAPABILITY_MISMATCH"):
  53. TaskCapabilityCatalog().get(ScriptTaskKind.KNOWLEDGE_RETRIEVAL)