From 5862b485712edcad61153187deca7c9d6c2b3fec Mon Sep 17 00:00:00 2001 From: Your Name Date: Mon, 29 Jun 2026 18:44:36 +0800 Subject: [PATCH] feat(api): expose credential escrow reviewer readiness --- ...ential_escrow_evidence_intake_readiness.py | 50 ++++++++++++++++++- ...al_escrow_evidence_intake_readiness_api.py | 21 +++++++- 2 files changed, 69 insertions(+), 2 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 95e0d18a0..6765c2d92 100644 --- a/apps/api/src/services/credential_escrow_evidence_intake_readiness.py +++ b/apps/api/src/services/credential_escrow_evidence_intake_readiness.py @@ -187,6 +187,14 @@ def validate_credential_escrow_evidence_owner_response( owner_response_accepted_count = ( 1 if status == "accepted_for_independent_reviewer_readiness_only" else 0 ) + current_rollups = _dict(current.get("rollups")) + accepted_item_count = len(set(accepted_item_ids)) + projected_effective_missing = ( + 0 + if status == "accepted_for_independent_reviewer_readiness_only" + and accepted_item_count == len(_REQUIRED_ITEM_IDS) + else _int(current_rollups.get("effective_escrow_missing_count")) + ) return { "schema_version": _VALIDATION_SCHEMA_VERSION, "status": status, @@ -198,7 +206,11 @@ def validate_credential_escrow_evidence_owner_response( "owner_response_accepted_count": owner_response_accepted_count, "required_item_count": len(_REQUIRED_ITEM_IDS), "provided_item_count": len(seen_item_ids & _REQUIRED_ITEM_IDS), - "accepted_item_count": len(set(accepted_item_ids)), + "accepted_item_count": accepted_item_count, + "current_effective_escrow_missing_count": _int( + current_rollups.get("effective_escrow_missing_count") + ), + "projected_effective_escrow_missing_count": projected_effective_missing, "missing_item_ids": missing_item_ids, "unknown_item_ids": unknown_item_ids, "redacted_evidence_ref_count": len(evidence_refs), @@ -226,6 +238,42 @@ def validate_credential_escrow_evidence_owner_response( "raw_session_or_sqlite_read_performed": False, "runtime_action_performed": False, }, + "reviewer_readiness": { + "schema_version": "credential_escrow_reviewer_readiness_v1", + "status": ( + "ready_for_reviewer_acceptance_writeback" + if status == "accepted_for_independent_reviewer_readiness_only" + else "not_ready_for_reviewer_acceptance_writeback" + ), + "accepted_required_item_ids": sorted(set(accepted_item_ids)), + "missing_required_item_ids": missing_item_ids, + "current_effective_escrow_missing_count": _int( + current_rollups.get("effective_escrow_missing_count") + ), + "projected_effective_escrow_missing_count": projected_effective_missing, + "redacted_receipt_writeback_ready_count": ( + 1 if status == "accepted_for_independent_reviewer_readiness_only" else 0 + ), + "credential_marker_write_authorized_count": 0, + "runtime_gate_count": 0, + "secret_value_collection_allowed": False, + "payload_persisted": False, + "safe_next_step": ( + "write_redacted_reviewer_receipt_snapshot_without_secret_values" + if status == "accepted_for_independent_reviewer_readiness_only" + else "supplement_redacted_non_secret_evidence_refs_without_secret_values" + ), + "blocked_operations": [ + "credential_marker_write", + "credential_read", + "secret_plaintext_export", + "backup_execution", + "restore_execution", + "offsite_sync_execution", + "workflow_dispatch", + "host_or_k8s_write", + ], + }, "safe_next_step": ( "independent_reviewer_acceptance_then_marker_dry_run" if status == "accepted_for_independent_reviewer_readiness_only" 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 cfda109a7..e84ec29be 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 @@ -71,7 +71,10 @@ def test_credential_escrow_evidence_intake_endpoint_returns_readiness(): def test_credential_escrow_evidence_owner_response_validator_accepts_redacted_refs_only(): payload = validate_credential_escrow_evidence_owner_response( _valid_redacted_owner_response(), - readiness={"status": "blocked_waiting_non_secret_credential_escrow_evidence"}, + readiness={ + "status": "blocked_waiting_non_secret_credential_escrow_evidence", + "rollups": {"effective_escrow_missing_count": 5}, + }, ) assert payload["schema_version"] == "credential_escrow_evidence_owner_response_validation_v1" @@ -80,6 +83,8 @@ def test_credential_escrow_evidence_owner_response_validator_accepts_redacted_re assert payload["result"]["owner_response_accepted_count"] == 1 assert payload["result"]["required_item_count"] == 5 assert payload["result"]["accepted_item_count"] == 5 + assert payload["result"]["current_effective_escrow_missing_count"] == 5 + assert payload["result"]["projected_effective_escrow_missing_count"] == 0 assert payload["result"]["runtime_gate_count"] == 0 assert payload["result"]["credential_marker_write_authorized_count"] == 0 assert payload["result"]["secret_value_collection_allowed"] is False @@ -87,6 +92,14 @@ def test_credential_escrow_evidence_owner_response_validator_accepts_redacted_re assert payload["operation_boundaries"]["credential_read_performed"] is False assert payload["operation_boundaries"]["credential_marker_write_performed"] is False assert payload["operation_boundaries"]["runtime_action_performed"] is False + assert ( + payload["reviewer_readiness"]["status"] + == "ready_for_reviewer_acceptance_writeback" + ) + assert payload["reviewer_readiness"]["projected_effective_escrow_missing_count"] == 0 + assert payload["reviewer_readiness"]["redacted_receipt_writeback_ready_count"] == 1 + assert payload["reviewer_readiness"]["credential_marker_write_authorized_count"] == 0 + assert payload["reviewer_readiness"]["secret_value_collection_allowed"] is False def test_credential_escrow_evidence_owner_response_validator_quarantines_secret_payload(): @@ -136,6 +149,12 @@ def test_credential_escrow_evidence_owner_response_endpoint_validates_without_pe data = response.json() assert data["status"] == "accepted_for_independent_reviewer_readiness_only" assert data["result"]["owner_response_accepted_count"] == 1 + assert data["result"]["projected_effective_escrow_missing_count"] == 0 + assert ( + data["reviewer_readiness"]["status"] + == "ready_for_reviewer_acceptance_writeback" + ) + assert data["reviewer_readiness"]["redacted_receipt_writeback_ready_count"] == 1 assert data["operation_boundaries"]["payload_persisted"] is False assert data["operation_boundaries"]["secret_plaintext_read"] is False assert data["operation_boundaries"]["host_or_k8s_write_performed"] is False