fix(windows99): accept bounded identity dry-run evidence
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 1m7s
CD Pipeline / build-and-deploy (push) Successful in 5m5s
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 1s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Successful in 1m0s
CD Pipeline / post-deploy-checks (push) Successful in 4m29s
All checks were successful
CD Pipeline / workflow-shape (push) Successful in 0s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 1m7s
CD Pipeline / build-and-deploy (push) Successful in 5m5s
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 1s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Successful in 1m0s
CD Pipeline / post-deploy-checks (push) Successful in 4m29s
This commit is contained in:
@@ -77,6 +77,7 @@ _CANDIDATE_CONFIRMATION_ALLOWED_KINDS = {
|
|||||||
"target_alias_hint",
|
"target_alias_hint",
|
||||||
"authorized_console_identity",
|
"authorized_console_identity",
|
||||||
"verified_backup_path_fingerprint",
|
"verified_backup_path_fingerprint",
|
||||||
|
"bounded_identity_metadata_single_unassigned_candidate",
|
||||||
}
|
}
|
||||||
_CANDIDATE_CONFIRMATION_FORBIDDEN_ACTIONS = [
|
_CANDIDATE_CONFIRMATION_FORBIDDEN_ACTIONS = [
|
||||||
"raw_vmx_path_output",
|
"raw_vmx_path_output",
|
||||||
@@ -495,6 +496,14 @@ def validate_windows99_vmx_source_candidate_confirmation_packet(
|
|||||||
_CANDIDATE_CONFIRMATION_ALLOWED_KINDS
|
_CANDIDATE_CONFIRMATION_ALLOWED_KINDS
|
||||||
):
|
):
|
||||||
rejected_fields.append("candidate_identity_kind")
|
rejected_fields.append("candidate_identity_kind")
|
||||||
|
if (
|
||||||
|
str(packet.get("candidate_identity_kind") or "")
|
||||||
|
== "bounded_identity_metadata_single_unassigned_candidate"
|
||||||
|
and _int(locator.get("identity_unassigned_ubuntu_candidate_count"), 0) != 1
|
||||||
|
):
|
||||||
|
rejected_fields.append(
|
||||||
|
"candidate_identity_kind.requires_single_unassigned_identity_candidate"
|
||||||
|
)
|
||||||
if str(packet.get("candidate_identity_evidence_ref") or "").strip() == "":
|
if str(packet.get("candidate_identity_evidence_ref") or "").strip() == "":
|
||||||
rejected_fields.append("candidate_identity_evidence_ref")
|
rejected_fields.append("candidate_identity_evidence_ref")
|
||||||
if _int(packet.get("candidate_match_count"), 0) != 1:
|
if _int(packet.get("candidate_match_count"), 0) != 1:
|
||||||
|
|||||||
@@ -828,7 +828,7 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
|
|||||||
is False
|
is False
|
||||||
)
|
)
|
||||||
assert state["windows99_vmx_source_locator_status"] == (
|
assert state["windows99_vmx_source_locator_status"] == (
|
||||||
"collector_readback_verified_source_required_before_relink_dry_run"
|
"collector_readback_scoped_relink_dry_run_ready"
|
||||||
)
|
)
|
||||||
assert state["windows99_vmx_source_locator_required"] is True
|
assert state["windows99_vmx_source_locator_required"] is True
|
||||||
assert state["windows99_vmx_source_locator_check_mode_ready"] is True
|
assert state["windows99_vmx_source_locator_check_mode_ready"] is True
|
||||||
@@ -842,7 +842,7 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
|
|||||||
)
|
)
|
||||||
assert state["windows99_vmx_source_locator_target_aliases"] == ["111"]
|
assert state["windows99_vmx_source_locator_target_aliases"] == ["111"]
|
||||||
assert state["windows99_vmx_source_locator_next_executable_step"] == (
|
assert state["windows99_vmx_source_locator_next_executable_step"] == (
|
||||||
"provide_verified_vmx_source_or_identity_evidence_then_scoped_relink_dry_run"
|
"rerun_no_secret_collector_and_scorecard"
|
||||||
)
|
)
|
||||||
assert state["windows99_vmx_source_locator_expected_vmx_path_count"] == 1
|
assert state["windows99_vmx_source_locator_expected_vmx_path_count"] == 1
|
||||||
assert state["windows99_vmx_source_locator_candidate_source_count"] == 8
|
assert state["windows99_vmx_source_locator_candidate_source_count"] == 8
|
||||||
@@ -865,15 +865,15 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
|
|||||||
state[
|
state[
|
||||||
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
|
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
|
||||||
]
|
]
|
||||||
is True
|
is False
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
state["windows99_vmx_source_locator_controlled_relink_dry_run_ready"]
|
state["windows99_vmx_source_locator_controlled_relink_dry_run_ready"]
|
||||||
is False
|
is True
|
||||||
)
|
)
|
||||||
assert state[
|
assert state[
|
||||||
"windows99_vmx_source_locator_controlled_relink_dry_run_blocker"
|
"windows99_vmx_source_locator_controlled_relink_dry_run_blocker"
|
||||||
] == "verified_vmx_source_or_identity_evidence_missing"
|
] == ""
|
||||||
assert state["windows99_vmx_source_locator_relink_dry_run_plan_id"] == (
|
assert state["windows99_vmx_source_locator_relink_dry_run_plan_id"] == (
|
||||||
"windows99-vmx-source-relink-dry-run-111"
|
"windows99-vmx-source-relink-dry-run-111"
|
||||||
)
|
)
|
||||||
@@ -887,9 +887,9 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
|
|||||||
state[
|
state[
|
||||||
"windows99_vmx_source_locator_candidate_identity_evidence_sufficient"
|
"windows99_vmx_source_locator_candidate_identity_evidence_sufficient"
|
||||||
]
|
]
|
||||||
is False
|
is True
|
||||||
)
|
)
|
||||||
assert state["windows99_vmx_source_locator_candidate_relink_dry_run_ready"] is False
|
assert state["windows99_vmx_source_locator_candidate_relink_dry_run_ready"] is True
|
||||||
assert state[
|
assert state[
|
||||||
"windows99_vmx_source_locator_candidate_confirmation_missing_evidence"
|
"windows99_vmx_source_locator_candidate_confirmation_missing_evidence"
|
||||||
] == [
|
] == [
|
||||||
@@ -1034,7 +1034,7 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
|
|||||||
"111"
|
"111"
|
||||||
]
|
]
|
||||||
assert payload["summary"]["windows99_vmx_source_locator_status"] == (
|
assert payload["summary"]["windows99_vmx_source_locator_status"] == (
|
||||||
"collector_readback_verified_source_required_before_relink_dry_run"
|
"collector_readback_scoped_relink_dry_run_ready"
|
||||||
)
|
)
|
||||||
assert payload["summary"]["windows99_vmx_source_locator_check_mode_ready"] is True
|
assert payload["summary"]["windows99_vmx_source_locator_check_mode_ready"] is True
|
||||||
assert payload["summary"]["windows99_vmx_source_locator_target_aliases"] == [
|
assert payload["summary"]["windows99_vmx_source_locator_target_aliases"] == [
|
||||||
@@ -1063,13 +1063,13 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
|
|||||||
payload["summary"][
|
payload["summary"][
|
||||||
"windows99_vmx_source_locator_candidate_identity_evidence_sufficient"
|
"windows99_vmx_source_locator_candidate_identity_evidence_sufficient"
|
||||||
]
|
]
|
||||||
is False
|
is True
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
payload["summary"][
|
payload["summary"][
|
||||||
"windows99_vmx_source_locator_candidate_relink_dry_run_ready"
|
"windows99_vmx_source_locator_candidate_relink_dry_run_ready"
|
||||||
]
|
]
|
||||||
is False
|
is True
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
payload["rollups"][
|
payload["rollups"][
|
||||||
@@ -1087,17 +1087,17 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
|
|||||||
payload["summary"][
|
payload["summary"][
|
||||||
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
|
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
|
||||||
]
|
]
|
||||||
is True
|
is False
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
payload["rollups"][
|
payload["rollups"][
|
||||||
"windows99_vmx_source_locator_controlled_relink_dry_run_ready"
|
"windows99_vmx_source_locator_controlled_relink_dry_run_ready"
|
||||||
]
|
]
|
||||||
is False
|
is True
|
||||||
)
|
)
|
||||||
assert payload["rollups"][
|
assert payload["rollups"][
|
||||||
"windows99_vmx_source_locator_controlled_relink_dry_run_blocker"
|
"windows99_vmx_source_locator_controlled_relink_dry_run_blocker"
|
||||||
] == "verified_vmx_source_or_identity_evidence_missing"
|
] == ""
|
||||||
assert (
|
assert (
|
||||||
payload["rollups"]["windows99_vmx_source_locator_remote_write_performed"]
|
payload["rollups"]["windows99_vmx_source_locator_remote_write_performed"]
|
||||||
is False
|
is False
|
||||||
@@ -1161,7 +1161,7 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
|
|||||||
"windows99_vmx_source_repair_playbook_trust_writeback_ref"
|
"windows99_vmx_source_repair_playbook_trust_writeback_ref"
|
||||||
].startswith("playbook://awoooi/windows99-vmx-source-repair/")
|
].startswith("playbook://awoooi/windows99-vmx-source-repair/")
|
||||||
assert in_progress["evidence"]["windows99_vmx_source_locator_status"] == (
|
assert in_progress["evidence"]["windows99_vmx_source_locator_status"] == (
|
||||||
"collector_readback_verified_source_required_before_relink_dry_run"
|
"collector_readback_scoped_relink_dry_run_ready"
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
in_progress["evidence"]["windows99_vmx_source_locator_check_mode_ready"]
|
in_progress["evidence"]["windows99_vmx_source_locator_check_mode_ready"]
|
||||||
@@ -1188,7 +1188,7 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
|
|||||||
in_progress["evidence"][
|
in_progress["evidence"][
|
||||||
"windows99_vmx_source_locator_candidate_relink_dry_run_ready"
|
"windows99_vmx_source_locator_candidate_relink_dry_run_ready"
|
||||||
]
|
]
|
||||||
is False
|
is True
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
in_progress["evidence"][
|
in_progress["evidence"][
|
||||||
@@ -1206,13 +1206,13 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
|
|||||||
in_progress["evidence"][
|
in_progress["evidence"][
|
||||||
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
|
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
|
||||||
]
|
]
|
||||||
is True
|
is False
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
in_progress["evidence"][
|
in_progress["evidence"][
|
||||||
"windows99_vmx_source_locator_controlled_relink_dry_run_ready"
|
"windows99_vmx_source_locator_controlled_relink_dry_run_ready"
|
||||||
]
|
]
|
||||||
is False
|
is True
|
||||||
)
|
)
|
||||||
assert (
|
assert (
|
||||||
in_progress["evidence"]["windows99_vmx_source_locator_remote_write_performed"]
|
in_progress["evidence"]["windows99_vmx_source_locator_remote_write_performed"]
|
||||||
|
|||||||
@@ -545,9 +545,11 @@ def test_windows99_candidate_confirmation_accepts_scoped_missing_alias_subset()
|
|||||||
"schema_version": "windows99_vmx_source_candidate_confirmation_packet_v1",
|
"schema_version": "windows99_vmx_source_candidate_confirmation_packet_v1",
|
||||||
"target_host_alias": "99",
|
"target_host_alias": "99",
|
||||||
"target_vm_aliases": ["111"],
|
"target_vm_aliases": ["111"],
|
||||||
"candidate_identity_kind": "verified_backup_path_fingerprint",
|
"candidate_identity_kind": (
|
||||||
|
"bounded_identity_metadata_single_unassigned_candidate"
|
||||||
|
),
|
||||||
"candidate_identity_evidence_ref": (
|
"candidate_identity_evidence_ref": (
|
||||||
"backup://awoooi/windows99/redacted-fingerprint-111"
|
"log://awoooi/windows99/redacted-identity-metadata-single-candidate-111"
|
||||||
),
|
),
|
||||||
"candidate_match_count": 1,
|
"candidate_match_count": 1,
|
||||||
"redacted_metadata_only": True,
|
"redacted_metadata_only": True,
|
||||||
@@ -582,6 +584,68 @@ def test_windows99_candidate_confirmation_accepts_scoped_missing_alias_subset()
|
|||||||
assert plan["vm_power_change_performed"] is False
|
assert plan["vm_power_change_performed"] is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_windows99_candidate_confirmation_rejects_unassigned_identity_without_single_candidate() -> None:
|
||||||
|
repair_package = build_windows99_vmx_source_repair_package(
|
||||||
|
_scorecard(),
|
||||||
|
generated_at="2026-07-03T11:21:00+08:00",
|
||||||
|
)
|
||||||
|
locator = build_windows99_vmx_source_locator_readback(
|
||||||
|
_scorecard(),
|
||||||
|
repair_package=repair_package,
|
||||||
|
collector_receipt={
|
||||||
|
"schema_version": "windows99_vmx_source_locator_receipt_v1",
|
||||||
|
"collector_readback_present": True,
|
||||||
|
"target_host_alias": "99",
|
||||||
|
"target_vm_aliases": ["111"],
|
||||||
|
"expected_vmx_path_present_count": 0,
|
||||||
|
"candidate_source_count": 8,
|
||||||
|
"candidate_source_fingerprint_count": 0,
|
||||||
|
"alias_hint_candidate_count": 0,
|
||||||
|
"identity_metadata_read": True,
|
||||||
|
"bounded_identity_metadata_only": True,
|
||||||
|
"identity_target_hint_count": 0,
|
||||||
|
"identity_unassigned_ubuntu_candidate_count": 2,
|
||||||
|
"locate_status": (
|
||||||
|
"multiple_identity_unassigned_ubuntu_candidates_requires_confirmation"
|
||||||
|
),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
payload = validate_windows99_vmx_source_candidate_confirmation_packet(
|
||||||
|
{
|
||||||
|
"schema_version": "windows99_vmx_source_candidate_confirmation_packet_v1",
|
||||||
|
"target_host_alias": "99",
|
||||||
|
"target_vm_aliases": ["111"],
|
||||||
|
"candidate_identity_kind": (
|
||||||
|
"bounded_identity_metadata_single_unassigned_candidate"
|
||||||
|
),
|
||||||
|
"candidate_identity_evidence_ref": (
|
||||||
|
"log://awoooi/windows99/redacted-identity-metadata-single-candidate-111"
|
||||||
|
),
|
||||||
|
"candidate_match_count": 1,
|
||||||
|
"redacted_metadata_only": True,
|
||||||
|
"bounded_identity_metadata_only": True,
|
||||||
|
"path_fingerprint_only": True,
|
||||||
|
"raw_path_output": False,
|
||||||
|
"secret_value_read": False,
|
||||||
|
"remote_write_performed": False,
|
||||||
|
"host_reboot_performed": False,
|
||||||
|
"vm_power_change_performed": False,
|
||||||
|
"windows_registry_apply_performed": False,
|
||||||
|
"scheduled_task_write_performed": False,
|
||||||
|
"apply_requested": False,
|
||||||
|
"vm_power_change_requested": False,
|
||||||
|
},
|
||||||
|
locator_readback=locator,
|
||||||
|
)
|
||||||
|
|
||||||
|
assert payload["accepted"] is False
|
||||||
|
assert (
|
||||||
|
"candidate_identity_kind.requires_single_unassigned_identity_candidate"
|
||||||
|
in payload["rejected_fields"]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_windows99_candidate_confirmation_validator_rejects_sensitive_payload() -> None:
|
def test_windows99_candidate_confirmation_validator_rejects_sensitive_payload() -> None:
|
||||||
locator = build_windows99_vmx_source_locator_readback(
|
locator = build_windows99_vmx_source_locator_readback(
|
||||||
_scorecard(),
|
_scorecard(),
|
||||||
|
|||||||
Reference in New Issue
Block a user