From 9438cd0583db7829e97860164589424ab7efe3c0 Mon Sep 17 00:00:00 2001 From: ogt Date: Fri, 10 Jul 2026 12:54:46 +0800 Subject: [PATCH] fix(windows99): close scoped relink confirmation readback --- .../windows99_vmx_source_locator_readback.py | 19 +++++++++++++++++++ ...awoooi_priority_work_order_readback_api.py | 17 ++++++----------- ...ndows99_vmx_source_locator_readback_api.py | 14 +++++++++++++- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/apps/api/src/services/windows99_vmx_source_locator_readback.py b/apps/api/src/services/windows99_vmx_source_locator_readback.py index 2d68a67e2..fb8c7727e 100644 --- a/apps/api/src/services/windows99_vmx_source_locator_readback.py +++ b/apps/api/src/services/windows99_vmx_source_locator_readback.py @@ -1133,6 +1133,25 @@ def build_windows99_vmx_source_locator_readback( target_aliases=target_aliases, receipt_locate_status=receipt_locate_status, ) + if scoped_receipt_applies: + candidate_confirmation_gate = { + **candidate_confirmation_gate, + "status": "candidate_identity_confirmed_by_scoped_relink_dry_run_receipt", + "decision": "confirmed_for_dry_run", + "reason": ( + "scoped relink dry-run receipt already passed reviewer validation " + "with clean no-write operation boundaries" + ), + "confirmed_candidate_count": max( + _int(candidate_confirmation_gate.get("confirmed_candidate_count"), 0) + or 0, + 1, + ), + "identity_evidence_sufficient": True, + "can_prepare_scoped_relink_dry_run": True, + "safe_next_step": "rerun_no_secret_collector_and_scorecard_no_vm_power_change", + "missing_evidence": [], + } return { "schema_version": _SCHEMA_VERSION, diff --git a/apps/api/tests/test_awoooi_priority_work_order_readback_api.py b/apps/api/tests/test_awoooi_priority_work_order_readback_api.py index 6e0d9ef30..09704fd0e 100644 --- a/apps/api/tests/test_awoooi_priority_work_order_readback_api.py +++ b/apps/api/tests/test_awoooi_priority_work_order_readback_api.py @@ -1070,10 +1070,10 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a "windows99-vmx-source-relink-dry-run-111" ) assert state["windows99_vmx_source_locator_candidate_confirmation_status"] == ( - "blocked_single_unassigned_ubuntu_candidate_identity_not_confirmed" + "candidate_identity_confirmed_by_scoped_relink_dry_run_receipt" ) assert state["windows99_vmx_source_locator_candidate_identity_decision"] == ( - "blocked" + "confirmed_for_dry_run" ) assert ( state[ @@ -1084,12 +1084,7 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a assert state["windows99_vmx_source_locator_candidate_relink_dry_run_ready"] is True assert state[ "windows99_vmx_source_locator_candidate_confirmation_missing_evidence" - ] == [ - "target_alias_identity_hint", - "verified_backup_or_authorized_console_candidate_identity", - "pre_apply_backup_plan", - "scoped_relink_dry_run", - ] + ] == [] assert ( state[ "windows99_vmx_source_locator_apply_allowed_by_candidate_confirmation_gate" @@ -1262,10 +1257,10 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a ) assert payload["summary"][ "windows99_vmx_source_locator_candidate_confirmation_status" - ] == "blocked_single_unassigned_ubuntu_candidate_identity_not_confirmed" + ] == "candidate_identity_confirmed_by_scoped_relink_dry_run_receipt" assert payload["summary"][ "windows99_vmx_source_locator_candidate_identity_decision" - ] == "blocked" + ] == "confirmed_for_dry_run" assert ( payload["summary"][ "windows99_vmx_source_locator_candidate_identity_evidence_sufficient" @@ -1390,7 +1385,7 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a ) assert in_progress["evidence"][ "windows99_vmx_source_locator_candidate_confirmation_status" - ] == "blocked_single_unassigned_ubuntu_candidate_identity_not_confirmed" + ] == "candidate_identity_confirmed_by_scoped_relink_dry_run_receipt" assert ( in_progress["evidence"][ "windows99_vmx_source_locator_candidate_relink_dry_run_ready" diff --git a/apps/api/tests/test_windows99_vmx_source_locator_readback_api.py b/apps/api/tests/test_windows99_vmx_source_locator_readback_api.py index 548882e51..6dae7fad7 100644 --- a/apps/api/tests/test_windows99_vmx_source_locator_readback_api.py +++ b/apps/api/tests/test_windows99_vmx_source_locator_readback_api.py @@ -381,6 +381,16 @@ def test_windows99_vmx_source_locator_builder_projects_scoped_relink_receipt() - assert payload["verified_source_or_identity_evidence_required"] is False assert payload["candidate_relink_dry_run_ready"] is True assert payload["candidate_identity_evidence_sufficient"] is True + assert payload["candidate_confirmation_status"] == ( + "candidate_identity_confirmed_by_scoped_relink_dry_run_receipt" + ) + assert payload["candidate_identity_decision"] == "confirmed_for_dry_run" + assert payload["candidate_confirmation_missing_evidence"] == [] + assert payload["candidate_confirmation_gate"]["missing_evidence"] == [] + assert ( + payload["candidate_confirmation_gate"]["can_prepare_scoped_relink_dry_run"] + is True + ) plan = payload["controlled_relink_dry_run_plan"] assert plan["ready"] is True assert plan["reviewer_validation_passed"] is True @@ -823,10 +833,12 @@ def test_windows99_vmx_source_locator_endpoint_returns_public_safe_readback( assert plan["remote_write_performed"] is False assert plan["vm_power_change_performed"] is False assert payload["candidate_confirmation_status"] == ( - "blocked_single_unassigned_ubuntu_candidate_identity_not_confirmed" + "candidate_identity_confirmed_by_scoped_relink_dry_run_receipt" ) + assert payload["candidate_identity_decision"] == "confirmed_for_dry_run" assert payload["candidate_identity_evidence_sufficient"] is True assert payload["candidate_relink_dry_run_ready"] is True + assert payload["candidate_confirmation_missing_evidence"] == [] assert payload["apply_allowed_by_candidate_confirmation_gate"] is False assert payload["public_lan_topology_redacted"] is True assert payload["raw_path_output"] is False