From f288dbb708e295baa21ccd3700e5d7426649a355 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 1 Jul 2026 13:02:16 +0800 Subject: [PATCH] fix(agent): align ssh offer timeout blocker --- ...est_ai_agent_autonomous_runtime_control.py | 10 ++++---- ...trolled_writeback_executor_readback_api.py | 10 ++++---- ..._controlled_writeback_plan_readback_api.py | 2 +- ...g_intelligence_integration_readback_api.py | 14 +++++++---- ...awoooi_priority_work_order_readback_api.py | 24 ++++++++++++------- docs/LOGBOOK.md | 15 ++++++++++++ ...ence-runtime-sample-readback.snapshot.json | 12 +++++----- 7 files changed, 57 insertions(+), 30 deletions(-) diff --git a/apps/api/tests/test_ai_agent_autonomous_runtime_control.py b/apps/api/tests/test_ai_agent_autonomous_runtime_control.py index 47ae09876..d91102e5c 100644 --- a/apps/api/tests/test_ai_agent_autonomous_runtime_control.py +++ b/apps/api/tests/test_ai_agent_autonomous_runtime_control.py @@ -37,7 +37,7 @@ def _assert_log_controlled_writeback_executor(payload: dict): assert payload["rollups"]["current_blocker_control_path_blocked_count"] == 1 assert ( payload["rollups"]["current_blocker_control_path_pressure_blocked_count"] - == 0 + == 1 ) assert payload["rollups"]["current_blocker_local_recovery_package_count"] == 1 assert payload["rollups"]["runtime_dispatch_performed"] is False @@ -75,11 +75,11 @@ def _assert_log_controlled_writeback_executor(payload: dict): "forbidden_runtime_actions" ] assert current_queue["external_control_path_blocker"] == ( - "remote_ssh_server_accepts_key_then_session_timeout" + "remote_ssh_publickey_offer_timeout" ) - assert current_queue["node_load_classifier"] == "load_not_high" - assert current_queue["node_load_high"] is False - assert current_queue["control_path_pressure_blocker"] == "" + assert current_queue["node_load_classifier"] == "high_load" + assert current_queue["node_load_high"] is True + assert current_queue["control_path_pressure_blocker"] == "node_load_high" assert context["raw_payload_required"] is False boundaries = payload["operation_boundaries"] 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 c8635b0d7..819629b32 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 @@ -67,7 +67,7 @@ def _assert_executor_readback(payload: dict, *, public_endpoint: bool = False): assert payload["rollups"]["current_blocker_control_path_blocked_count"] == 1 assert ( payload["rollups"]["current_blocker_control_path_pressure_blocked_count"] - == 0 + == 1 ) assert payload["rollups"]["current_blocker_local_recovery_package_count"] == 1 assert ( @@ -129,8 +129,8 @@ def _assert_executor_readback(payload: dict, *, public_endpoint: bool = False): "controlled_recovery_packaged_waiting_control_path_readback" ) assert current_queue[0]["runner_label"] == "awoooi-non110-host" - assert current_queue[0]["node_load_classifier"] == "load_not_high" - assert current_queue[0]["node_load_high"] is False + assert current_queue[0]["node_load_classifier"] == "high_load" + assert current_queue[0]["node_load_high"] is True assert current_queue[0]["registry_v2_status"] == 502 assert current_queue[0]["controlled_recovery_package"] == ( "recover-110-control-path-and-harbor-local.sh --check" @@ -239,9 +239,9 @@ def _assert_executor_readback(payload: dict, *, public_endpoint: bool = False): ) assert current_queue[0]["runtime_apply_required_on_110_local_console"] is True assert current_queue[0]["external_control_path_blocker"] == ( - "remote_ssh_server_accepts_key_then_session_timeout" + "remote_ssh_publickey_offer_timeout" ) - assert current_queue[0]["control_path_pressure_blocker"] == "" + assert current_queue[0]["control_path_pressure_blocker"] == "node_load_high" assert current_queue[0]["control_channel_readback_required"] is True assert set(current_queue[0]["learning_writeback_targets"]) == set(batches) assert len(current_queue[0]["target_batches"]) == 6 diff --git a/apps/api/tests/test_ai_agent_log_controlled_writeback_plan_readback_api.py b/apps/api/tests/test_ai_agent_log_controlled_writeback_plan_readback_api.py index 276c1486b..147756f17 100644 --- a/apps/api/tests/test_ai_agent_log_controlled_writeback_plan_readback_api.py +++ b/apps/api/tests/test_ai_agent_log_controlled_writeback_plan_readback_api.py @@ -167,7 +167,7 @@ def _assert_controlled_writeback_plan(payload: dict, *, public_endpoint: bool = assert { plan["current_blocker_recovery"]["external_control_path_blocker"] for plan in p0_plans - } == {"remote_ssh_server_accepts_key_then_session_timeout"} + } == {"remote_ssh_publickey_offer_timeout"} boundaries = payload["operation_boundaries"] assert boundaries["plan_readback_only"] is True diff --git a/apps/api/tests/test_ai_agent_log_intelligence_integration_readback_api.py b/apps/api/tests/test_ai_agent_log_intelligence_integration_readback_api.py index 853c734ed..1e423322b 100644 --- a/apps/api/tests/test_ai_agent_log_intelligence_integration_readback_api.py +++ b/apps/api/tests/test_ai_agent_log_intelligence_integration_readback_api.py @@ -107,17 +107,23 @@ def _assert_log_intelligence_payload(payload: dict): "harbor_110_remote_ssh_publickey_auth_stalled" ) assert p0_sample["classification"]["ssh_auth_classification"] == ( - "remote_ssh_server_accepts_key_then_session_timeout" + "remote_ssh_publickey_offer_timeout" ) assert p0_sample["classification"]["remote_control_channel"] == "unavailable" assert p0_sample["classification"]["bounded_ssh_timeout_seen"] is True assert p0_sample["classification"]["remote_ssh_publickey_auth_stalled"] is True assert ( p0_sample["classification"][ - "remote_ssh_server_accepts_key_then_session_timeout" + "remote_ssh_publickey_offer_timeout" ] is True ) + assert ( + p0_sample["classification"][ + "remote_ssh_server_accepts_key_then_session_timeout" + ] + is False + ) assert p0_sample["classification"]["remote_ssh_auth_permission_denied"] is False assert p0_sample["classification"]["remote_ssh_reachable"] is True assert p0_sample["classification"]["controlled_recovery_package"] == ( @@ -138,11 +144,11 @@ def _assert_log_intelligence_payload(payload: dict): ] assert recovery_plan[0]["mode"] == "read_only" assert recovery_plan[0]["expected_result"] == ( - "remote_ssh_server_accepts_key_then_session_timeout_classifier_without_secret_material" + "remote_ssh_publickey_offer_timeout_classifier_without_secret_material" ) assert recovery_plan[2]["mode"] == "controlled_apply" assert recovery_plan[2]["expected_result"] == ( - "ssh_session_pam_account_or_shell_path_repaired_without_key_material_read" + "ssh_authorized_keys_permissions_pam_or_account_lookup_path_repaired_without_key_material_read" ) assert recovery_plan[2]["runtime_write_allowed_only_on_110_local_console"] is True assert "read-public-gitea-actions-queue.py --json" in p0_sample[ 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 13457d132..c632859cf 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 @@ -261,10 +261,12 @@ def test_awoooi_priority_work_order_readback_overlays_ai_loop_current_blocker_qu "harbor_110_remote_ssh_publickey_auth_stalled" ) assert state["ai_loop_current_blocker_control_path_blocker"] == ( - "remote_ssh_server_accepts_key_then_session_timeout" + "remote_ssh_publickey_offer_timeout" ) - assert state["ai_loop_current_blocker_control_path_pressure_blocker"] == "" - assert state["ai_loop_current_blocker_node_load_classifier"] == "load_not_high" + assert state["ai_loop_current_blocker_control_path_pressure_blocker"] == ( + "node_load_high" + ) + assert state["ai_loop_current_blocker_node_load_classifier"] == "high_load" assert evidence["ai_loop_current_blocker_execution_queue_count"] == 1 assert evidence["ai_loop_current_blocker_id"] == ( "harbor_110_remote_ssh_publickey_auth_stalled" @@ -281,10 +283,12 @@ def test_awoooi_priority_work_order_readback_overlays_ai_loop_current_blocker_qu "controlled_after_110_local_console_preflight" ) assert evidence["ai_loop_current_blocker_control_path_blocker"] == ( - "remote_ssh_server_accepts_key_then_session_timeout" + "remote_ssh_publickey_offer_timeout" ) - assert evidence["ai_loop_current_blocker_control_path_pressure_blocker"] == "" - assert evidence["ai_loop_current_blocker_node_load_classifier"] == "load_not_high" + assert evidence["ai_loop_current_blocker_control_path_pressure_blocker"] == ( + "node_load_high" + ) + assert evidence["ai_loop_current_blocker_node_load_classifier"] == "high_load" assert set(evidence["ai_loop_current_blocker_learning_writeback_targets"]) == { "km", "rag", @@ -392,9 +396,11 @@ def test_awoooi_priority_work_order_readback_overlays_ai_loop_current_blocker_qu assert payload["summary"]["ai_loop_current_blocker_id"] == ( "harbor_110_remote_ssh_publickey_auth_stalled" ) - assert payload["summary"]["ai_loop_current_blocker_control_path_pressure_blocker"] == "" + assert payload["summary"]["ai_loop_current_blocker_control_path_pressure_blocker"] == ( + "node_load_high" + ) assert payload["summary"]["ai_loop_current_blocker_node_load_classifier"] == ( - "load_not_high" + "high_load" ) assert payload["summary"]["ai_loop_current_blocker_local_console_phase_count"] == 5 assert payload["summary"][ @@ -517,7 +523,7 @@ def test_awoooi_priority_work_order_ai_loop_overrides_stockplatform_drift_for_ha "harbor_110_remote_ssh_publickey_auth_stalled" ) assert state["ai_loop_current_blocker_control_path_blocker"] == ( - "remote_ssh_server_accepts_key_then_session_timeout" + "remote_ssh_publickey_offer_timeout" ) assert payload["summary"]["ai_loop_current_blocker_id"] == ( "harbor_110_remote_ssh_publickey_auth_stalled" diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index aef8ec276..3fff2b86b 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,18 @@ +## 2026-07-01 — 13:05 AI Loop current blocker 對齊 publickey offer timeout / high load + +**照主線修正的問題**: +- 最新 110 read-only SSH 診斷顯示 `SSH_AUTH user=wooo mode=publickey classification=publickey_offer_timeout`,且 `NODE_LOAD_CLASSIFIER=high_load`;AI Loop runtime sample 仍把當前主 classifier 留在 `remote_ssh_server_accepts_key_then_session_timeout` / `load_not_high`。 +- 本次把 AI Loop current blocker 的可執行子分類對齊為 `external_control_path_blocker=remote_ssh_publickey_offer_timeout`,並把 `control_path_pressure_blocker=node_load_high`、`node_load_classifier=high_load` 帶到 controlled writeback executor、autonomous runtime control、priority work order readback。 +- `remote_ssh_server_accepts_key_then_session_timeout` 仍保留在 queue normalizer contract,作為舊 Harbor repair log / CD marker 的相容解析能力;但不再當作目前 P0 blocker 的主分類。 +- current blocker container 仍維持 `harbor_110_remote_ssh_publickey_auth_stalled`,避免主線從 Harbor/110 deploy blocker 偏移;更細的 AI Agent next action 由 offer-timeout 與 high-load 兩個欄位決定。 + +**驗證**: +- `DATABASE_URL=... python3.11 -m pytest apps/api/tests/test_ai_agent_log_intelligence_integration_readback_api.py apps/api/tests/test_ai_agent_log_feedback_receipt_dry_run_api.py apps/api/tests/test_ai_agent_log_controlled_writeback_plan_readback_api.py apps/api/tests/test_ai_agent_log_controlled_writeback_executor_readback_api.py apps/api/tests/test_ai_agent_autonomous_runtime_control.py apps/api/tests/test_awoooi_priority_work_order_readback_api.py -q`:`30 passed`。 +- `python3.11 -m pytest ops/runner/test_read_public_gitea_actions_queue.py ops/runner/test_cd_controlled_runtime_profile.py -q`:`68 passed`。 +- `python3.11 -m json.tool --indent 2 docs/operations/ai-agent-log-intelligence-runtime-sample-readback.snapshot.json >/dev/null`、`python3.11 ops/runner/guard-gitea-runner-pressure.py --root .`、`git diff --check`:通過。 + +**邊界**:只改 AI Loop runtime sample、readback tests 與 LOGBOOK;未讀 secret / token / `.env` / raw sessions / SQLite / auth;未讀 authorized_keys 內容或 `.runner` 內容;未使用 GitHub / `gh` / GitHub API;未 workflow_dispatch;未重啟主機、未 restart Docker / Nginx / K3s / DB / firewall;未執行 110 runtime apply。 + ## 2026-07-01 — 12:50 Priority work order AI Loop blocker 優先權修正 **照主線修正的問題**: diff --git a/docs/operations/ai-agent-log-intelligence-runtime-sample-readback.snapshot.json b/docs/operations/ai-agent-log-intelligence-runtime-sample-readback.snapshot.json index e192c9d64..3d581e205 100644 --- a/docs/operations/ai-agent-log-intelligence-runtime-sample-readback.snapshot.json +++ b/docs/operations/ai-agent-log-intelligence-runtime-sample-readback.snapshot.json @@ -90,7 +90,7 @@ "harbor_110_repair_jobs_payload_stale_or_cross_workflow", "bounded_ssh_timeout_seen", "controlled_profile_no_matching_runner_cleared", - "node_load_not_high", + "node_load_high", "controlled_lane_verifier_packaged", "local_recovery_package_packaged" ], @@ -118,17 +118,17 @@ "risk_tier": "high", "runner_label": "awoooi-non110-host", "current_blocker": "harbor_110_remote_ssh_publickey_auth_stalled", - "ssh_auth_classification": "remote_ssh_server_accepts_key_then_session_timeout", + "ssh_auth_classification": "remote_ssh_publickey_offer_timeout", "remote_control_channel": "unavailable", "bounded_ssh_timeout_seen": true, "remote_ssh_reachable": true, "remote_ssh_publickey_auth_stalled": true, "remote_ssh_publickey_offer_timeout": true, - "remote_ssh_server_accepts_key_then_session_timeout": true, + "remote_ssh_server_accepts_key_then_session_timeout": false, "remote_ssh_auth_permission_denied": false, "harbor_110_repair_failure_classifier": "harbor_110_remote_ssh_publickey_auth_stalled", "harbor_110_repair_jobs_payload_stale_or_cross_workflow": true, - "node_load_classifier": "load_not_high", + "node_load_classifier": "high_load", "registry_v2_status": 502, "controlled_recovery_package": "recover-110-control-path-and-harbor-local.sh --check", "post_apply_verifier": "check-awoooi-110-controlled-cd-lane-readiness.sh", @@ -137,7 +137,7 @@ "phase_id": "diagnose_remote_control_channel", "mode": "read_only", "command": "read-public-gitea-actions-queue.py --json", - "expected_result": "remote_ssh_server_accepts_key_then_session_timeout_classifier_without_secret_material", + "expected_result": "remote_ssh_publickey_offer_timeout_classifier_without_secret_material", "runtime_write_allowed_only_on_110_local_console": false }, { @@ -151,7 +151,7 @@ "phase_id": "repair_ssh_service_or_metadata_if_check_confirms_drift", "mode": "controlled_apply", "command": "recover-110-control-path-and-harbor-local.sh --apply-ssh-control-path", - "expected_result": "ssh_session_pam_account_or_shell_path_repaired_without_key_material_read", + "expected_result": "ssh_authorized_keys_permissions_pam_or_account_lookup_path_repaired_without_key_material_read", "runtime_write_allowed_only_on_110_local_console": true }, {