system-prompts-and-models-o.../dealix/tests/integration/test_governed_pipeline.py
2026-05-01 14:03:52 +03:00

87 lines
3.1 KiB
Python

"""Integration test for the GovernedPipeline (Phase 8 + Trust Plane)."""
from __future__ import annotations
import pytest
from dealix.execution import GovernedPipeline
from dealix.trust.policy import PolicyDecision
@pytest.mark.asyncio
async def test_governed_pipeline_emits_decisions(sample_lead_payload, mock_router):
"""The governed pipeline must produce DecisionOutputs from the underlying run."""
mock_router.run.return_value.content = (
'{"pain_points":[{"text":"slow","category":"performance","severity":0.8}],'
'"urgency_score":0.9,"likely_offer":"X","recommended_next_step":"call","key_phrases":[]}'
)
governed = GovernedPipeline()
result = await governed.run(
payload=sample_lead_payload,
auto_book=False,
auto_proposal=False,
)
assert result.underlying.lead.id
# At minimum we expect pain + icp + qualification decisions
assert len(result.decisions) >= 2
# Every decision must carry classifications
for d in result.decisions:
assert d.approval_class is not None
assert d.reversibility_class is not None
assert d.sensitivity_class is not None
@pytest.mark.asyncio
async def test_governed_pipeline_audits_every_step(sample_lead_payload, mock_router):
mock_router.run.return_value.content = '{"ok": true}'
governed = GovernedPipeline()
result = await governed.run(
payload=sample_lead_payload,
auto_book=False,
)
# Every emitted decision produces an audit entry
assert len(result.audit_trail) >= len(result.decisions)
@pytest.mark.asyncio
async def test_governed_pipeline_escalates_high_stakes_actions(sample_lead_payload, mock_router):
"""When a tier-A lead is detected and a proposal is auto-generated,
the proposal-send NextAction should be ESCALATED (never auto-allowed)."""
mock_router.run.return_value.content = '{"ok": true}'
governed = GovernedPipeline()
result = await governed.run(
payload=sample_lead_payload,
auto_book=False,
auto_proposal=True, # force proposal generation
)
# Find any proposal_send action in the policy results
proposal_sends = [(d, a, r) for d, a, r in result.policy_results if a == "proposal_send"]
# If a proposal was generated, its send action must not be ALLOW
if proposal_sends:
for _d, _a, r in proposal_sends:
assert (
r.decision != PolicyDecision.ALLOW
), f"proposal_send was {r.decision.value} — should be ESCALATE"
@pytest.mark.asyncio
async def test_governed_pipeline_creates_approval_requests(sample_lead_payload, mock_router):
"""Escalated actions must yield pending approval requests."""
mock_router.run.return_value.content = '{"ok": true}'
governed = GovernedPipeline()
result = await governed.run(
payload=sample_lead_payload,
auto_book=False,
auto_proposal=True,
)
# Count escalations vs approval requests — they should roughly match
n_escalations = sum(
1 for _, _, r in result.policy_results if r.decision == PolicyDecision.ESCALATE
)
assert len(result.approval_requests) == n_escalations