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
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:
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user