feat(agent): bind context and timeline receipts
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 1m12s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled

This commit is contained in:
ogt
2026-07-10 20:00:32 +08:00
parent bfdc2658bd
commit 43ceb3b259
2 changed files with 332 additions and 1 deletions

View File

@@ -19,20 +19,24 @@ from src.services.awooop_ansible_check_mode_service import (
_build_auto_repair_execution_receipt,
_claim_from_apply_operation_row,
_claim_from_stale_check_mode_row,
_load_pre_decision_context_runtime_stage_receipts,
_post_apply_km_path_type,
_post_apply_verification_result,
_record_auto_repair_execution_receipt,
_record_learning_writeback_receipt,
_record_retry_runtime_stage_receipt,
_record_runtime_stage_receipts,
_record_timeline_projection_receipt,
_run_ansible_command,
_send_controlled_apply_telegram_receipt,
backfill_missing_auto_repair_execution_receipts_once,
build_ansible_apply_command,
build_ansible_check_mode_claim_input,
build_ansible_check_mode_command,
build_ansible_context_runtime_stage_receipts,
build_ansible_post_apply_runtime_stage_receipts,
build_ansible_pre_apply_runtime_stage_receipts,
build_ansible_timeline_runtime_stage_receipt,
claim_pending_check_modes,
claim_stale_pending_check_modes,
detect_ansible_transport_blockers,
@@ -1885,6 +1889,85 @@ def test_ansible_runtime_stage_receipts_are_same_run_and_public_safe() -> None:
assert inspect.iscoroutinefunction(_record_runtime_stage_receipts)
def test_ansible_context_receipts_reference_pre_decision_evidence_without_content() -> None:
claim = AnsibleCheckModeClaim(
op_id="00000000-0000-0000-0000-000000000112",
source_candidate_op_id="00000000-0000-0000-0000-000000000111",
incident_id="INC-RUNTIME-CONTEXT",
catalog_id="ansible:188-ai-web",
playbook_path="infra/ansible/playbooks/188-ai-web-readonly.yml",
apply_playbook_path="infra/ansible/playbooks/188-ai-web.yml",
inventory_hosts=("host_188",),
risk_level="medium",
input_payload={
"automation_run_id": "00000000-0000-0000-0000-000000000111",
},
)
receipts = build_ansible_context_runtime_stage_receipts(
claim,
{
"id": "evidence-111",
"recent_logs": "sanitized service log summary",
"mcp_health": {"prometheus": True, "kubernetes": False},
"sensors_attempted": 2,
"sensors_succeeded": 1,
},
)
assert {receipt["stage_id"] for receipt in receipts} == {
"mcp_context",
"service_log_evidence",
}
assert all(receipt["automation_run_id"] == claim.source_candidate_op_id for receipt in receipts)
assert all(receipt["raw_log_payload_stored"] is False for receipt in receipts)
service_log = next(
receipt for receipt in receipts if receipt["stage_id"] == "service_log_evidence"
)
assert service_log["detail"]["content_in_receipt"] is False
assert "sanitized service log summary" not in str(service_log)
loader_source = inspect.getsource(_load_pre_decision_context_runtime_stage_receipts)
assert "evidence.collected_at <= candidate.created_at" in loader_source
assert "evidence.post_execution_state IS NULL" in loader_source
def test_ansible_timeline_projection_receipt_is_same_run_and_idempotent() -> None:
claim = AnsibleCheckModeClaim(
op_id="00000000-0000-0000-0000-000000000122",
source_candidate_op_id="00000000-0000-0000-0000-000000000121",
incident_id="INC-RUNTIME-TIMELINE",
catalog_id="ansible:188-ai-web",
playbook_path="infra/ansible/playbooks/188-ai-web-readonly.yml",
apply_playbook_path="infra/ansible/playbooks/188-ai-web.yml",
inventory_hosts=("host_188",),
risk_level="medium",
input_payload={
"automation_run_id": "00000000-0000-0000-0000-000000000121",
},
)
result = AnsibleRunResult(
returncode=2,
stdout="",
stderr="apply failed",
duration_ms=42,
)
receipt = build_ansible_timeline_runtime_stage_receipt(
claim,
result,
apply_op_id="00000000-0000-0000-0000-000000000123",
timeline_event_id="timeline-123",
)
assert receipt["stage_id"] == "timeline_projection"
assert receipt["automation_run_id"] == claim.source_candidate_op_id
assert receipt["evidence_ref"] == "timeline_events:timeline-123"
assert receipt["detail"]["projection_status"] == "error"
writer_source = inspect.getsource(_record_timeline_projection_receipt)
assert "WITH existing AS" in writer_source
assert "WHERE NOT EXISTS (SELECT 1 FROM existing)" in writer_source
assert inspect.iscoroutinefunction(_record_timeline_projection_receipt)
def test_ansible_claim_query_limits_recent_candidate_backlog() -> None:
source = inspect.getsource(claim_pending_check_modes)