From 90507c62343a9b1e238c4f42a8e2cef8019731f9 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 1 Jul 2026 16:09:32 +0800 Subject: [PATCH] fix(api): surface ssh local repair receipt contract --- ..._controlled_writeback_executor_readback.py | 20 +++++++++++++++++++ ...trolled_writeback_executor_readback_api.py | 10 ++++++---- ...awoooi_priority_work_order_readback_api.py | 10 ++++++---- 3 files changed, 32 insertions(+), 8 deletions(-) diff --git a/apps/api/src/services/ai_agent_log_controlled_writeback_executor_readback.py b/apps/api/src/services/ai_agent_log_controlled_writeback_executor_readback.py index 8d981c2f5..1472e95c6 100644 --- a/apps/api/src/services/ai_agent_log_controlled_writeback_executor_readback.py +++ b/apps/api/src/services/ai_agent_log_controlled_writeback_executor_readback.py @@ -558,6 +558,16 @@ def _harbor_recovery_receipt_inputs() -> list[dict[str, Any]]: ), **metadata_boundary, }, + { + "input_id": "ssh_local_repair_output", + "source": "repair-110-ssh-publickey-auth-local.sh --check/apply", + "required_when": "after_remote_control_channel_diagnosis_phase", + "purpose": ( + "prove non-secret 110 account, authorized_keys metadata, sshd " + "effective config, and SSH reload result before Harbor retry" + ), + **metadata_boundary, + }, { "input_id": "local_console_recovery_output", "source": "recover-110-control-path-and-harbor-local.sh --check/apply", @@ -646,6 +656,16 @@ def _harbor_recovery_receipt_output_contract() -> list[dict[str, Any]]: ), **metadata_boundary, }, + { + "output_id": "ssh_local_repair", + "source": "harbor-registry-controlled-recovery-receipt.readback.ssh_local_repair", + "required_when": "after_110_local_ssh_publickey_auth_repair_receipt", + "purpose": ( + "write back non-secret 110 target user, authorized_keys, sshd " + "publickey, AuthorizedKeysFile, and reload readiness signals" + ), + **metadata_boundary, + }, { "output_id": "controlled_cd_lane_readiness", "source": "harbor-registry-controlled-recovery-receipt.readback.controlled_cd_lane_readiness", diff --git a/apps/api/tests/test_ai_agent_log_controlled_writeback_executor_readback_api.py b/apps/api/tests/test_ai_agent_log_controlled_writeback_executor_readback_api.py index 68ba8b0cc..904211f74 100644 --- a/apps/api/tests/test_ai_agent_log_controlled_writeback_executor_readback_api.py +++ b/apps/api/tests/test_ai_agent_log_controlled_writeback_executor_readback_api.py @@ -75,13 +75,13 @@ def _assert_executor_readback(payload: dict, *, public_endpoint: bool = False): assert payload["rollups"]["current_blocker_local_recovery_package_count"] == 1 assert ( payload["rollups"]["current_blocker_harbor_recovery_receipt_input_count"] - == 10 + == 11 ) assert ( payload["rollups"][ "current_blocker_harbor_recovery_receipt_output_contract_count" ] - == 7 + == 8 ) assert payload["rollups"]["runtime_dispatch_performed"] is False @@ -183,13 +183,14 @@ def _assert_executor_readback(payload: dict, *, public_endpoint: bool = False): assert current_queue[0]["harbor_recovery_receipt_endpoint"] == ( "/api/v1/agents/harbor-registry-controlled-recovery-receipt" ) - assert current_queue[0]["harbor_recovery_receipt_input_count"] == 10 + assert current_queue[0]["harbor_recovery_receipt_input_count"] == 11 assert [ item["input_id"] for item in current_queue[0]["harbor_recovery_receipt_inputs"] ] == [ "gitea_actions_queue_readback", "remote_control_channel_readback", + "ssh_local_repair_output", "local_console_recovery_output", "watchdog_check_output", "watchdog_repair_output", @@ -202,12 +203,13 @@ def _assert_executor_readback(payload: dict, *, public_endpoint: bool = False): assert current_queue[0]["harbor_recovery_receipt_inputs"][-1][ "expected_schema" ] == "awoooi_production_deploy_readback_blocker_v1" - assert current_queue[0]["harbor_recovery_receipt_output_contract_count"] == 7 + assert current_queue[0]["harbor_recovery_receipt_output_contract_count"] == 8 assert [ item["output_id"] for item in current_queue[0]["harbor_recovery_receipt_output_contract"] ] == [ "control_path_readiness", + "ssh_local_repair", "controlled_cd_lane_readiness", "non110_runner_readiness", "gitea_actions_queue", 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 0d2ca5815..cacc6c34d 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 @@ -325,10 +325,11 @@ def test_awoooi_priority_work_order_readback_overlays_ai_loop_current_blocker_qu assert evidence["ai_loop_current_blocker_harbor_recovery_receipt_endpoint"] == ( "/api/v1/agents/harbor-registry-controlled-recovery-receipt" ) - assert evidence["ai_loop_current_blocker_harbor_recovery_receipt_input_count"] == 10 + assert evidence["ai_loop_current_blocker_harbor_recovery_receipt_input_count"] == 11 assert evidence["ai_loop_current_blocker_harbor_recovery_receipt_input_ids"] == [ "gitea_actions_queue_readback", "remote_control_channel_readback", + "ssh_local_repair_output", "local_console_recovery_output", "watchdog_check_output", "watchdog_repair_output", @@ -345,10 +346,11 @@ def test_awoooi_priority_work_order_readback_overlays_ai_loop_current_blocker_qu evidence[ "ai_loop_current_blocker_harbor_recovery_receipt_output_contract_count" ] - == 7 + == 8 ) assert evidence["ai_loop_current_blocker_harbor_recovery_receipt_output_ids"] == [ "control_path_readiness", + "ssh_local_repair", "controlled_cd_lane_readiness", "non110_runner_readiness", "gitea_actions_queue", @@ -443,7 +445,7 @@ def test_awoooi_priority_work_order_readback_overlays_ai_loop_current_blocker_qu payload["summary"][ "ai_loop_current_blocker_harbor_recovery_receipt_input_count" ] - == 10 + == 11 ) assert payload["summary"][ "ai_loop_current_blocker_harbor_recovery_receipt_input_ids" @@ -455,7 +457,7 @@ def test_awoooi_priority_work_order_readback_overlays_ai_loop_current_blocker_qu payload["summary"][ "ai_loop_current_blocker_harbor_recovery_receipt_output_contract_count" ] - == 7 + == 8 ) assert payload["summary"][ "ai_loop_current_blocker_harbor_recovery_receipt_output_ids"