From c70bcf481948c8bfad38c9118c34c9e94f005309 Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 29 Jun 2026 18:48:53 +0800 Subject: [PATCH] fix(api): expose credential escrow rollups at top level --- ...ential_escrow_evidence_intake_readiness.py | 48 ++++++++++--------- ...al_escrow_evidence_intake_readiness_api.py | 8 ++++ 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/apps/api/src/services/credential_escrow_evidence_intake_readiness.py b/apps/api/src/services/credential_escrow_evidence_intake_readiness.py index 6765c2d92..f7e1d9847 100644 --- a/apps/api/src/services/credential_escrow_evidence_intake_readiness.py +++ b/apps/api/src/services/credential_escrow_evidence_intake_readiness.py @@ -303,6 +303,29 @@ def _build_payload( if effective_missing == 0 and not blocked_items: status = "ready_for_escrow_marker_review" safe_next_step = "collect_redacted_non_secret_evidence_refs_then_rerun_preflight" + rollup_readback = { + "required_item_count": len(missing_items), + "missing_item_count": len(blocked_items), + "blocked_item_ids": blocked_items, + "effective_escrow_missing_count": effective_missing, + "owner_response_received_count": _int( + rollups.get("credential_escrow_owner_response_received_count") + ), + "owner_response_accepted_count": _int( + rollups.get("credential_escrow_owner_response_accepted_count") + ), + "runtime_gate_count": _int(rollups.get("credential_escrow_runtime_gate_count")), + "credential_marker_write_authorized_count": _int( + rollups.get("credential_marker_write_authorized_count") + ), + "secret_value_collection_allowed": bool( + rollups.get("credential_escrow_secret_value_collection_allowed") + ), + "forbidden_true_field_count": _int( + rollups.get("credential_escrow_forbidden_true_field_count") + ), + "forbidden_value_count": len(forbidden_values), + } payload = { "schema_version": _SCHEMA_VERSION, @@ -311,6 +334,7 @@ def _build_payload( "scope": "credential_escrow_evidence_intake", "status": status, "safe_next_step": safe_next_step, + **rollup_readback, "readback": { "workplan_id": "P0-005", "workplan_title": "產品資料與備份 contract", @@ -339,29 +363,7 @@ def _build_payload( "workflow_dispatch", "host_or_k8s_write", ], - "rollups": { - "required_item_count": len(missing_items), - "missing_item_count": len(blocked_items), - "blocked_item_ids": blocked_items, - "effective_escrow_missing_count": effective_missing, - "owner_response_received_count": _int( - rollups.get("credential_escrow_owner_response_received_count") - ), - "owner_response_accepted_count": _int( - rollups.get("credential_escrow_owner_response_accepted_count") - ), - "runtime_gate_count": _int(rollups.get("credential_escrow_runtime_gate_count")), - "credential_marker_write_authorized_count": _int( - rollups.get("credential_marker_write_authorized_count") - ), - "secret_value_collection_allowed": bool( - rollups.get("credential_escrow_secret_value_collection_allowed") - ), - "forbidden_true_field_count": _int( - rollups.get("credential_escrow_forbidden_true_field_count") - ), - "forbidden_value_count": len(forbidden_values), - }, + "rollups": rollup_readback, "operation_boundaries": { "read_only_api_allowed": True, "backup_execution_allowed": False, diff --git a/apps/api/tests/test_credential_escrow_evidence_intake_readiness_api.py b/apps/api/tests/test_credential_escrow_evidence_intake_readiness_api.py index e84ec29be..c31dbbc0c 100644 --- a/apps/api/tests/test_credential_escrow_evidence_intake_readiness_api.py +++ b/apps/api/tests/test_credential_escrow_evidence_intake_readiness_api.py @@ -31,6 +31,10 @@ def test_credential_escrow_evidence_intake_reports_p0_blocker(): "collect_redacted_non_secret_evidence_refs_then_rerun_preflight" ) assert payload["readback"]["safe_next_step"] == payload["safe_next_step"] + assert payload["missing_item_count"] == 5 + assert payload["owner_response_accepted_count"] == 0 + assert payload["runtime_gate_count"] == 0 + assert payload["secret_value_collection_allowed"] is False assert payload["rollups"]["required_item_count"] == 5 assert payload["rollups"]["missing_item_count"] == 5 assert payload["rollups"]["effective_escrow_missing_count"] == 5 @@ -63,6 +67,10 @@ def test_credential_escrow_evidence_intake_endpoint_returns_readiness(): assert data["safe_next_step"] == ( "collect_redacted_non_secret_evidence_refs_then_rerun_preflight" ) + assert data["missing_item_count"] == 5 + assert data["owner_response_accepted_count"] == 0 + assert data["runtime_gate_count"] == 0 + assert data["secret_value_collection_allowed"] is False assert data["rollups"]["missing_item_count"] == 5 assert data["operation_boundaries"]["restore_execution_allowed"] is False assert data["operation_boundaries"]["workflow_trigger_allowed"] is False