fix(reboot): surface vmx relink dry-run evidence gate
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 2m14s
CD Pipeline / build-and-deploy (push) Has started running
CD Pipeline / post-deploy-checks (push) Has been cancelled
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 1s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Successful in 40s
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 2m14s
CD Pipeline / build-and-deploy (push) Has started running
CD Pipeline / post-deploy-checks (push) Has been cancelled
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 1s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Successful in 40s
This commit is contained in:
@@ -3475,6 +3475,40 @@ def _enrich_from_current_readbacks(
|
||||
windows99_vmx_source_locator_readback.get("candidate_confirmation_required")
|
||||
is True
|
||||
)
|
||||
state[
|
||||
"windows99_vmx_source_locator_human_confirmation_required_for_dry_run"
|
||||
] = bool(
|
||||
windows99_vmx_source_locator_readback.get(
|
||||
"human_confirmation_required_for_dry_run"
|
||||
)
|
||||
is True
|
||||
)
|
||||
state[
|
||||
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
|
||||
] = bool(
|
||||
windows99_vmx_source_locator_readback.get(
|
||||
"verified_source_or_identity_evidence_required"
|
||||
)
|
||||
is True
|
||||
)
|
||||
state["windows99_vmx_source_locator_controlled_relink_dry_run_ready"] = bool(
|
||||
windows99_vmx_source_locator_readback.get(
|
||||
"controlled_relink_dry_run_ready"
|
||||
)
|
||||
is True
|
||||
)
|
||||
state["windows99_vmx_source_locator_controlled_relink_dry_run_blocker"] = str(
|
||||
windows99_vmx_source_locator_readback.get(
|
||||
"controlled_relink_dry_run_blocker"
|
||||
)
|
||||
or ""
|
||||
)
|
||||
locator_relink_plan = _dict(
|
||||
windows99_vmx_source_locator_readback.get("controlled_relink_dry_run_plan")
|
||||
)
|
||||
state["windows99_vmx_source_locator_relink_dry_run_plan_id"] = str(
|
||||
locator_relink_plan.get("plan_id") or ""
|
||||
)
|
||||
state["windows99_vmx_source_locator_candidate_source_count_known"] = bool(
|
||||
windows99_vmx_source_locator_readback.get("candidate_source_count_known")
|
||||
is True
|
||||
@@ -3891,6 +3925,29 @@ def _enrich_from_current_readbacks(
|
||||
evidence["windows99_vmx_source_locator_candidate_confirmation_required"] = state[
|
||||
"windows99_vmx_source_locator_candidate_confirmation_required"
|
||||
]
|
||||
evidence[
|
||||
"windows99_vmx_source_locator_human_confirmation_required_for_dry_run"
|
||||
] = state[
|
||||
"windows99_vmx_source_locator_human_confirmation_required_for_dry_run"
|
||||
]
|
||||
evidence[
|
||||
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
|
||||
] = state[
|
||||
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
|
||||
]
|
||||
evidence[
|
||||
"windows99_vmx_source_locator_controlled_relink_dry_run_ready"
|
||||
] = state[
|
||||
"windows99_vmx_source_locator_controlled_relink_dry_run_ready"
|
||||
]
|
||||
evidence[
|
||||
"windows99_vmx_source_locator_controlled_relink_dry_run_blocker"
|
||||
] = state[
|
||||
"windows99_vmx_source_locator_controlled_relink_dry_run_blocker"
|
||||
]
|
||||
evidence["windows99_vmx_source_locator_relink_dry_run_plan_id"] = state[
|
||||
"windows99_vmx_source_locator_relink_dry_run_plan_id"
|
||||
]
|
||||
evidence["windows99_vmx_source_locator_candidate_source_count_known"] = state[
|
||||
"windows99_vmx_source_locator_candidate_source_count_known"
|
||||
]
|
||||
@@ -4683,6 +4740,31 @@ def _set_rollups_and_summary(
|
||||
state.get("windows99_vmx_source_locator_candidate_confirmation_required")
|
||||
is True
|
||||
),
|
||||
"windows99_vmx_source_locator_human_confirmation_required_for_dry_run": (
|
||||
state.get(
|
||||
"windows99_vmx_source_locator_human_confirmation_required_for_dry_run"
|
||||
)
|
||||
is True
|
||||
),
|
||||
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required": (
|
||||
state.get(
|
||||
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
|
||||
)
|
||||
is True
|
||||
),
|
||||
"windows99_vmx_source_locator_controlled_relink_dry_run_ready": (
|
||||
state.get("windows99_vmx_source_locator_controlled_relink_dry_run_ready")
|
||||
is True
|
||||
),
|
||||
"windows99_vmx_source_locator_controlled_relink_dry_run_blocker": str(
|
||||
state.get(
|
||||
"windows99_vmx_source_locator_controlled_relink_dry_run_blocker"
|
||||
)
|
||||
or ""
|
||||
),
|
||||
"windows99_vmx_source_locator_relink_dry_run_plan_id": str(
|
||||
state.get("windows99_vmx_source_locator_relink_dry_run_plan_id") or ""
|
||||
),
|
||||
"windows99_vmx_source_locator_candidate_source_count_known": (
|
||||
state.get("windows99_vmx_source_locator_candidate_source_count_known")
|
||||
is True
|
||||
@@ -5005,6 +5087,31 @@ def _set_rollups_and_summary(
|
||||
state.get("windows99_vmx_source_locator_candidate_confirmation_required")
|
||||
is True
|
||||
),
|
||||
"windows99_vmx_source_locator_human_confirmation_required_for_dry_run": (
|
||||
state.get(
|
||||
"windows99_vmx_source_locator_human_confirmation_required_for_dry_run"
|
||||
)
|
||||
is True
|
||||
),
|
||||
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required": (
|
||||
state.get(
|
||||
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
|
||||
)
|
||||
is True
|
||||
),
|
||||
"windows99_vmx_source_locator_controlled_relink_dry_run_ready": (
|
||||
state.get("windows99_vmx_source_locator_controlled_relink_dry_run_ready")
|
||||
is True
|
||||
),
|
||||
"windows99_vmx_source_locator_controlled_relink_dry_run_blocker": str(
|
||||
state.get(
|
||||
"windows99_vmx_source_locator_controlled_relink_dry_run_blocker"
|
||||
)
|
||||
or ""
|
||||
),
|
||||
"windows99_vmx_source_locator_relink_dry_run_plan_id": str(
|
||||
state.get("windows99_vmx_source_locator_relink_dry_run_plan_id") or ""
|
||||
),
|
||||
"windows99_vmx_source_locator_candidate_source_count_known": (
|
||||
state.get("windows99_vmx_source_locator_candidate_source_count_known")
|
||||
is True
|
||||
|
||||
@@ -156,10 +156,131 @@ def build_windows99_vmx_source_locator_readback(
|
||||
and set(receipt_aliases).issubset(set(target_aliases or receipt_aliases))
|
||||
)
|
||||
receipt_locate_status = str(receipt.get("locate_status") or "")
|
||||
expected_vmx_path_present_count = (
|
||||
_int(receipt.get("expected_vmx_path_present_count"))
|
||||
if receipt_applies
|
||||
else None
|
||||
)
|
||||
candidate_source_count = (
|
||||
_int(receipt.get("candidate_source_count")) if receipt_applies else None
|
||||
)
|
||||
candidate_source_fingerprint_count = (
|
||||
_int(receipt.get("candidate_source_fingerprint_count"), 0)
|
||||
if receipt_applies
|
||||
else None
|
||||
)
|
||||
alias_hint_candidate_count = (
|
||||
_int(receipt.get("alias_hint_candidate_count"), 0)
|
||||
if receipt_applies
|
||||
else None
|
||||
)
|
||||
unassigned_ubuntu_candidate_count = (
|
||||
_int(receipt.get("unassigned_ubuntu_candidate_count"), 0)
|
||||
if receipt_applies
|
||||
else None
|
||||
)
|
||||
identity_target_hint_count = (
|
||||
_int(receipt.get("identity_target_hint_count"), 0)
|
||||
if receipt_applies
|
||||
else None
|
||||
)
|
||||
identity_unassigned_ubuntu_candidate_count = (
|
||||
_int(receipt.get("identity_unassigned_ubuntu_candidate_count"), 0)
|
||||
if receipt_applies
|
||||
else None
|
||||
)
|
||||
candidate_confirmation_required = bool(
|
||||
receipt_applies and "requires_confirmation" in receipt_locate_status
|
||||
)
|
||||
controlled_relink_dry_run_ready = bool(
|
||||
receipt_applies and receipt.get("controlled_relink_dry_run_ready") is True
|
||||
)
|
||||
verified_source_or_identity_evidence_required = bool(
|
||||
receipt_applies
|
||||
and candidate_confirmation_required
|
||||
and not controlled_relink_dry_run_ready
|
||||
)
|
||||
controlled_relink_dry_run_blocker = ""
|
||||
if receipt_applies:
|
||||
status = "collector_readback_single_identity_candidate_confirmation_required"
|
||||
next_step = "confirm_single_unassigned_ubuntu_candidate_before_scoped_relink_dry_run"
|
||||
safe_next_step = str(receipt.get("safe_next_step") or safe_next_step)
|
||||
if controlled_relink_dry_run_ready:
|
||||
status = "collector_readback_scoped_relink_dry_run_ready"
|
||||
next_step = "run_scoped_relink_dry_run_no_windows_or_vm_write"
|
||||
safe_next_step = (
|
||||
"run_scoped_relink_dry_run_no_windows_or_vm_write_then_post_verifier"
|
||||
)
|
||||
elif verified_source_or_identity_evidence_required:
|
||||
status = "collector_readback_verified_source_required_before_relink_dry_run"
|
||||
next_step = (
|
||||
"provide_verified_vmx_source_or_identity_evidence_then_"
|
||||
"scoped_relink_dry_run"
|
||||
)
|
||||
safe_next_step = (
|
||||
"provide_existing_vmx_source_or_verified_backup_path_then_build_"
|
||||
"scoped_relink_dry_run_no_write"
|
||||
)
|
||||
controlled_relink_dry_run_blocker = (
|
||||
"verified_vmx_source_or_identity_evidence_missing"
|
||||
)
|
||||
else:
|
||||
status = "collector_readback_no_scoped_relink_candidate"
|
||||
next_step = "provide_existing_vmx_source_or_backup_path"
|
||||
safe_next_step = (
|
||||
"provide_existing_vmx_source_or_verified_backup_path_then_rerun_"
|
||||
"locator_check_mode_no_write"
|
||||
)
|
||||
controlled_relink_dry_run_blocker = "scoped_relink_candidate_not_verified"
|
||||
|
||||
relink_dry_run_plan = {
|
||||
"plan_id": f"windows99-vmx-source-relink-dry-run-{','.join(missing_aliases) or 'none'}",
|
||||
"mode": "dry_run_no_windows_or_vm_write",
|
||||
"ready": controlled_relink_dry_run_ready,
|
||||
"blocker": controlled_relink_dry_run_blocker,
|
||||
"target_selector": {
|
||||
"host_alias": "99",
|
||||
"vm_aliases": target_aliases,
|
||||
"missing_vmx_aliases": missing_aliases,
|
||||
"candidate_requires_verified_identity": (
|
||||
verified_source_or_identity_evidence_required
|
||||
),
|
||||
},
|
||||
"source_diff": {
|
||||
"expected_vmx_path_count": expected_vmx_path_count,
|
||||
"expected_vmx_path_present_count": expected_vmx_path_present_count,
|
||||
"candidate_source_count": candidate_source_count,
|
||||
"candidate_source_fingerprint_count": (
|
||||
candidate_source_fingerprint_count
|
||||
),
|
||||
"alias_hint_candidate_count": alias_hint_candidate_count,
|
||||
"identity_target_hint_count": identity_target_hint_count,
|
||||
"identity_unassigned_ubuntu_candidate_count": (
|
||||
identity_unassigned_ubuntu_candidate_count
|
||||
),
|
||||
"raw_path_output": False,
|
||||
"path_fingerprint_only": True,
|
||||
"bounded_identity_metadata_only": bool(
|
||||
receipt_applies
|
||||
and receipt.get("bounded_identity_metadata_only") is True
|
||||
),
|
||||
},
|
||||
"rollback_ref": "rollback://awoooi/windows99-vmx-source-relink-dry-run",
|
||||
"post_verifier": [
|
||||
"bash scripts/reboot-recovery/collect-windows99-vmware-verify.sh --collect",
|
||||
"GET /api/v1/agents/reboot-auto-recovery-slo-scorecard",
|
||||
"GET /api/v1/agents/windows99-vmx-source-repair-package",
|
||||
"GET /api/v1/agents/windows99-vmx-source-locator-readback",
|
||||
],
|
||||
"km_writeback_ref": str(receipt.get("km_writeback_ref") or "")
|
||||
if receipt_applies
|
||||
else "",
|
||||
"playbook_trust_writeback_ref": str(
|
||||
receipt.get("playbook_trust_writeback_ref") or ""
|
||||
)
|
||||
if receipt_applies
|
||||
else "",
|
||||
"apply_allowed_by_this_plan": False,
|
||||
"remote_write_performed": False,
|
||||
"vm_power_change_performed": False,
|
||||
}
|
||||
|
||||
return {
|
||||
"schema_version": _SCHEMA_VERSION,
|
||||
@@ -199,47 +320,28 @@ def build_windows99_vmx_source_locator_readback(
|
||||
),
|
||||
"remote_locator_mode": "in_memory_stdin_scriptblock",
|
||||
"expected_vmx_path_count": expected_vmx_path_count,
|
||||
"expected_vmx_path_present_count": (
|
||||
_int(receipt.get("expected_vmx_path_present_count"))
|
||||
if receipt_applies
|
||||
else None
|
||||
),
|
||||
"candidate_source_count": (
|
||||
_int(receipt.get("candidate_source_count")) if receipt_applies else None
|
||||
),
|
||||
"expected_vmx_path_present_count": expected_vmx_path_present_count,
|
||||
"candidate_source_count": candidate_source_count,
|
||||
"candidate_source_count_known": bool(receipt_applies),
|
||||
"candidate_source_fingerprint_count": (
|
||||
_int(receipt.get("candidate_source_fingerprint_count"), 0)
|
||||
if receipt_applies
|
||||
else None
|
||||
),
|
||||
"alias_hint_candidate_count": (
|
||||
_int(receipt.get("alias_hint_candidate_count"), 0)
|
||||
if receipt_applies
|
||||
else None
|
||||
),
|
||||
"unassigned_ubuntu_candidate_count": (
|
||||
_int(receipt.get("unassigned_ubuntu_candidate_count"), 0)
|
||||
if receipt_applies
|
||||
else None
|
||||
),
|
||||
"candidate_source_fingerprint_count": candidate_source_fingerprint_count,
|
||||
"alias_hint_candidate_count": alias_hint_candidate_count,
|
||||
"unassigned_ubuntu_candidate_count": unassigned_ubuntu_candidate_count,
|
||||
"identity_metadata_read": bool(
|
||||
receipt_applies and receipt.get("identity_metadata_read") is True
|
||||
),
|
||||
"identity_target_hint_count": (
|
||||
_int(receipt.get("identity_target_hint_count"), 0)
|
||||
if receipt_applies
|
||||
else None
|
||||
),
|
||||
"identity_target_hint_count": identity_target_hint_count,
|
||||
"identity_unassigned_ubuntu_candidate_count": (
|
||||
_int(receipt.get("identity_unassigned_ubuntu_candidate_count"), 0)
|
||||
if receipt_applies
|
||||
else None
|
||||
identity_unassigned_ubuntu_candidate_count
|
||||
),
|
||||
"locate_status": receipt_locate_status if receipt_applies else "",
|
||||
"candidate_confirmation_required": bool(
|
||||
receipt_applies and "requires_confirmation" in receipt_locate_status
|
||||
"candidate_confirmation_required": candidate_confirmation_required,
|
||||
"human_confirmation_required_for_dry_run": False,
|
||||
"verified_source_or_identity_evidence_required": (
|
||||
verified_source_or_identity_evidence_required
|
||||
),
|
||||
"controlled_relink_dry_run_ready": controlled_relink_dry_run_ready,
|
||||
"controlled_relink_dry_run_blocker": controlled_relink_dry_run_blocker,
|
||||
"controlled_relink_dry_run_plan": relink_dry_run_plan,
|
||||
"public_lan_topology_redacted": True,
|
||||
"redacted_public_display_only": True,
|
||||
"raw_path_output": False,
|
||||
|
||||
@@ -738,7 +738,7 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
|
||||
"windows99_vmx_source_repair_playbook_trust_writeback_ref"
|
||||
].startswith("playbook://awoooi/windows99-vmx-source-repair/")
|
||||
assert state["windows99_vmx_source_locator_status"] == (
|
||||
"collector_readback_single_identity_candidate_confirmation_required"
|
||||
"collector_readback_verified_source_required_before_relink_dry_run"
|
||||
)
|
||||
assert state["windows99_vmx_source_locator_required"] is True
|
||||
assert state["windows99_vmx_source_locator_check_mode_ready"] is True
|
||||
@@ -752,7 +752,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_next_executable_step"] == (
|
||||
"confirm_single_unassigned_ubuntu_candidate_before_scoped_relink_dry_run"
|
||||
"provide_verified_vmx_source_or_identity_evidence_then_scoped_relink_dry_run"
|
||||
)
|
||||
assert state["windows99_vmx_source_locator_expected_vmx_path_count"] == 1
|
||||
assert state["windows99_vmx_source_locator_candidate_source_count"] == 6
|
||||
@@ -765,6 +765,28 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
|
||||
== 1
|
||||
)
|
||||
assert state["windows99_vmx_source_locator_candidate_confirmation_required"] is True
|
||||
assert (
|
||||
state[
|
||||
"windows99_vmx_source_locator_human_confirmation_required_for_dry_run"
|
||||
]
|
||||
is False
|
||||
)
|
||||
assert (
|
||||
state[
|
||||
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
|
||||
]
|
||||
is True
|
||||
)
|
||||
assert (
|
||||
state["windows99_vmx_source_locator_controlled_relink_dry_run_ready"]
|
||||
is False
|
||||
)
|
||||
assert state[
|
||||
"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"] == (
|
||||
"windows99-vmx-source-relink-dry-run-111"
|
||||
)
|
||||
assert state["windows99_vmx_source_locator_candidate_source_count_known"] is True
|
||||
assert state["windows99_vmx_source_locator_collector_readback_present"] is True
|
||||
assert state["windows99_vmx_source_locator_file_content_read"] is True
|
||||
@@ -848,7 +870,7 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
|
||||
"111"
|
||||
]
|
||||
assert payload["summary"]["windows99_vmx_source_locator_status"] == (
|
||||
"collector_readback_single_identity_candidate_confirmation_required"
|
||||
"collector_readback_verified_source_required_before_relink_dry_run"
|
||||
)
|
||||
assert payload["summary"]["windows99_vmx_source_locator_check_mode_ready"] is True
|
||||
assert payload["summary"]["windows99_vmx_source_locator_target_aliases"] == [
|
||||
@@ -867,6 +889,27 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
|
||||
]
|
||||
is True
|
||||
)
|
||||
assert (
|
||||
payload["summary"][
|
||||
"windows99_vmx_source_locator_human_confirmation_required_for_dry_run"
|
||||
]
|
||||
is False
|
||||
)
|
||||
assert (
|
||||
payload["summary"][
|
||||
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
|
||||
]
|
||||
is True
|
||||
)
|
||||
assert (
|
||||
payload["rollups"][
|
||||
"windows99_vmx_source_locator_controlled_relink_dry_run_ready"
|
||||
]
|
||||
is False
|
||||
)
|
||||
assert payload["rollups"][
|
||||
"windows99_vmx_source_locator_controlled_relink_dry_run_blocker"
|
||||
] == "verified_vmx_source_or_identity_evidence_missing"
|
||||
assert (
|
||||
payload["rollups"]["windows99_vmx_source_locator_remote_write_performed"]
|
||||
is False
|
||||
@@ -925,7 +968,7 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
|
||||
"windows99_vmx_source_repair_playbook_trust_writeback_ref"
|
||||
].startswith("playbook://awoooi/windows99-vmx-source-repair/")
|
||||
assert in_progress["evidence"]["windows99_vmx_source_locator_status"] == (
|
||||
"collector_readback_single_identity_candidate_confirmation_required"
|
||||
"collector_readback_verified_source_required_before_relink_dry_run"
|
||||
)
|
||||
assert (
|
||||
in_progress["evidence"]["windows99_vmx_source_locator_check_mode_ready"]
|
||||
@@ -945,6 +988,24 @@ def test_awoooi_priority_work_order_readback_routes_closed_backup_to_host_boot_a
|
||||
]
|
||||
is True
|
||||
)
|
||||
assert (
|
||||
in_progress["evidence"][
|
||||
"windows99_vmx_source_locator_human_confirmation_required_for_dry_run"
|
||||
]
|
||||
is False
|
||||
)
|
||||
assert (
|
||||
in_progress["evidence"][
|
||||
"windows99_vmx_source_locator_verified_source_or_identity_evidence_required"
|
||||
]
|
||||
is True
|
||||
)
|
||||
assert (
|
||||
in_progress["evidence"][
|
||||
"windows99_vmx_source_locator_controlled_relink_dry_run_ready"
|
||||
]
|
||||
is False
|
||||
)
|
||||
assert (
|
||||
in_progress["evidence"]["windows99_vmx_source_locator_remote_write_performed"]
|
||||
is False
|
||||
|
||||
@@ -146,7 +146,7 @@ def test_windows99_vmx_source_locator_builder_projects_redacted_receipt() -> Non
|
||||
)
|
||||
|
||||
assert payload["status"] == (
|
||||
"collector_readback_single_identity_candidate_confirmation_required"
|
||||
"collector_readback_verified_source_required_before_relink_dry_run"
|
||||
)
|
||||
assert payload["collector_readback_present"] is True
|
||||
assert payload["collector_collection_status"] == (
|
||||
@@ -161,8 +161,19 @@ def test_windows99_vmx_source_locator_builder_projects_redacted_receipt() -> Non
|
||||
assert payload["identity_target_hint_count"] == 0
|
||||
assert payload["identity_unassigned_ubuntu_candidate_count"] == 1
|
||||
assert payload["candidate_confirmation_required"] is True
|
||||
assert payload["human_confirmation_required_for_dry_run"] is False
|
||||
assert payload["verified_source_or_identity_evidence_required"] is True
|
||||
assert payload["controlled_relink_dry_run_ready"] is False
|
||||
assert payload["controlled_relink_dry_run_blocker"] == (
|
||||
"verified_vmx_source_or_identity_evidence_missing"
|
||||
)
|
||||
assert payload["controlled_relink_dry_run_plan"]["ready"] is False
|
||||
assert payload["controlled_relink_dry_run_plan"]["apply_allowed_by_this_plan"] is False
|
||||
assert payload["controlled_relink_dry_run_plan"]["source_diff"][
|
||||
"raw_path_output"
|
||||
] is False
|
||||
assert payload["next_executable_step"] == (
|
||||
"confirm_single_unassigned_ubuntu_candidate_before_scoped_relink_dry_run"
|
||||
"provide_verified_vmx_source_or_identity_evidence_then_scoped_relink_dry_run"
|
||||
)
|
||||
assert payload["raw_path_output"] is False
|
||||
assert payload["secret_value_read"] is False
|
||||
@@ -191,7 +202,7 @@ def test_windows99_vmx_source_locator_endpoint_returns_public_safe_readback(
|
||||
payload = response.json()
|
||||
assert payload["schema_version"] == "windows99_vmx_source_locator_readback_v1"
|
||||
assert payload["status"] == (
|
||||
"collector_readback_single_identity_candidate_confirmation_required"
|
||||
"collector_readback_verified_source_required_before_relink_dry_run"
|
||||
)
|
||||
assert payload["target_vm_aliases"] == ["111"]
|
||||
assert payload["locator_check_mode_ready"] is True
|
||||
@@ -200,6 +211,16 @@ def test_windows99_vmx_source_locator_endpoint_returns_public_safe_readback(
|
||||
assert payload["collector_readback_present"] is True
|
||||
assert payload["candidate_source_count"] == 6
|
||||
assert payload["candidate_confirmation_required"] is True
|
||||
assert payload["human_confirmation_required_for_dry_run"] is False
|
||||
assert payload["verified_source_or_identity_evidence_required"] is True
|
||||
assert payload["controlled_relink_dry_run_ready"] is False
|
||||
assert payload["controlled_relink_dry_run_blocker"] == (
|
||||
"verified_vmx_source_or_identity_evidence_missing"
|
||||
)
|
||||
assert payload["controlled_relink_dry_run_plan"]["plan_id"] == (
|
||||
"windows99-vmx-source-relink-dry-run-111"
|
||||
)
|
||||
assert payload["controlled_relink_dry_run_plan"]["remote_write_performed"] is False
|
||||
assert payload["public_lan_topology_redacted"] is True
|
||||
assert payload["raw_path_output"] is False
|
||||
assert payload["file_content_read"] is True
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
## 2026-07-03 — 13:12 Windows99 VMX relink dry-run evidence gate 上卷
|
||||
|
||||
**完成內容**:
|
||||
- Gitea CD `#4582` 已完成最新 main `ba0849f70` 部署,deploy marker 為 `558b9e916 chore(cd): deploy ba0849f [skip ci]`;job3 讀回 `ArgoCD: sync=Synced health=Healthy`、API/Web/Worker rollout completed、`Production deploy readback matches this build`、`Job succeeded`。
|
||||
- Production `/api/v1/agents/windows99-vmx-source-locator-readback` 已讀回 collector receipt:`collector_readback_present=true`、`candidate_source_count=6`、`identity_unassigned_ubuntu_candidate_count=1`、`raw_path_output=false`、`path_fingerprint_only=true`、`remote_write_performed=false`、`vm_power_change_performed=false`。
|
||||
- 本輪 verifier-only artifact:`/tmp/awoooi-p0-006-reboot-slo-20260703-130633`。host probe 顯示 99 reachable-unknown-boot、111 unreachable、112/120/121 reachable、188 reachable 但 `awoooi-startup.service failed/degraded`;本工作機對 99 的 no-secret SSH collector 固定 `ssh_batchmode_auth_ready=0`、`verify_collection_status=blocked_ssh_publickey_auth_missing`。
|
||||
- 將 VMX locator 的「confirmation」字眼改成 machine-readable evidence gate:`verified_source_or_identity_evidence_required=true`、`human_confirmation_required_for_dry_run=false`、`controlled_relink_dry_run_ready=false`、`controlled_relink_dry_run_blocker=verified_vmx_source_or_identity_evidence_missing`,並新增 `controlled_relink_dry_run_plan`。此 plan 只允許 dry-run evidence,不允許 apply / remote write / VM power change。
|
||||
- `awoooi-priority-work-order-readback` 同步投影上述 dry-run blocker 到 `mainline_execution_state`、in-progress evidence、`summary` 與 `rollups`,避免再把 P0-006 卡成模糊的人工確認。
|
||||
|
||||
**已跑驗證**:
|
||||
- `python3.11 -m py_compile apps/api/src/services/windows99_vmx_source_locator_readback.py apps/api/src/services/awoooi_priority_work_order_readback.py apps/api/tests/test_windows99_vmx_source_locator_readback_api.py apps/api/tests/test_awoooi_priority_work_order_readback_api.py`:通過。
|
||||
- `DATABASE_URL=postgresql+asyncpg://test:test@localhost/test PYTHONPATH=apps/api python3.11 -m pytest apps/api/tests/test_windows99_vmx_source_locator_readback_api.py apps/api/tests/test_awoooi_priority_work_order_readback_api.py -q -p no:cacheprovider`:`22 passed`。
|
||||
- `git diff --check`、`python3.11 ops/runner/guard-gitea-runner-pressure.py --root .`:通過。
|
||||
|
||||
**仍維持**:
|
||||
- P0-006 尚未完成:缺 verified 111 VMX source / backup path / stronger identity evidence,因此不得 relink generic Ubuntu candidate、不得 restore、不得 power on,也不得宣稱 10 分鐘 SLO 完成。
|
||||
- 未讀 secret / token / `.env` / raw sessions / SQLite / auth;未使用 GitHub / gh;未 workflow_dispatch;未啟動或關閉 VM;未重啟 host / service;未 Docker / Nginx / K3s / DB / firewall restart;未 DROP / TRUNCATE / restore / prune / delete / force push。
|
||||
|
||||
## 2026-07-03 — 12:47 Windows99 VMX locator receipt readback 上卷
|
||||
|
||||
**完成內容**:
|
||||
|
||||
Reference in New Issue
Block a user