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 e3a14c3a1..013c1119a 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 @@ -639,6 +639,28 @@ def _queue_readback_normalizer_contract() -> list[dict[str, Any]]: ], "learning_targets": ["km", "rag", "playbook", "mcp", "verifier"], }, + { + "field_id": "harbor_110_repair_visible_running_jobs_api_stale", + "purpose": ( + "classify when the visible Harbor repair run is still Running " + "but the jobs API payload belongs to another workflow or stale run" + ), + "writes_blockers": [ + "gitea_queue_harbor_110_repair_visible_running_jobs_api_stale", + ], + "learning_targets": ["km", "rag", "playbook", "mcp", "verifier", "ai_agent"], + }, + { + "field_id": "current_cd_waiting_behind_harbor_110_repair_running", + "purpose": ( + "classify when current CD is waiting behind an in-flight or " + "stale Harbor 110 repair readback" + ), + "writes_blockers": [ + "gitea_queue_current_cd_waiting_behind_harbor_110_repair_running", + ], + "learning_targets": ["km", "rag", "playbook", "mcp", "verifier", "ai_agent"], + }, { "field_id": "controlled_profile_no_matching_runner_labels", "purpose": ( 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 5cf5e6761..f79890283 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 @@ -187,7 +187,7 @@ def _assert_executor_readback(payload: dict, *, public_endpoint: bool = False): ] for item in current_queue[0]["harbor_recovery_receipt_output_contract"] ) - assert current_queue[0]["queue_readback_normalizer_contract_count"] == 9 + assert current_queue[0]["queue_readback_normalizer_contract_count"] == 11 assert [ item["field_id"] for item in current_queue[0]["queue_readback_normalizer_contract"] @@ -200,6 +200,8 @@ def _assert_executor_readback(payload: dict, *, public_endpoint: bool = False): "latest_visible_harbor_110_repair_remote_ssh_publickey_offer_timeout", "latest_visible_harbor_110_repair_remote_ssh_server_accepts_key_then_session_timeout", "current_cd_workflow_runner_readiness", + "harbor_110_repair_visible_running_jobs_api_stale", + "current_cd_waiting_behind_harbor_110_repair_running", "controlled_profile_no_matching_runner_labels", ] assert "gitea_queue_cd_jobs_stale_or_mismatched" in current_queue[0][ 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 e7ce42508..1b6ad03ac 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 @@ -368,6 +368,8 @@ def test_awoooi_priority_work_order_readback_overlays_ai_loop_current_blocker_qu "latest_visible_harbor_110_repair_remote_ssh_publickey_offer_timeout", "latest_visible_harbor_110_repair_remote_ssh_server_accepts_key_then_session_timeout", "current_cd_workflow_runner_readiness", + "harbor_110_repair_visible_running_jobs_api_stale", + "current_cd_waiting_behind_harbor_110_repair_running", "controlled_profile_no_matching_runner_labels", ] assert evidence["ai_loop_current_blocker_queue_readback_normalizer_contract"][0][ @@ -425,7 +427,7 @@ def test_awoooi_priority_work_order_readback_overlays_ai_loop_current_blocker_qu payload["summary"][ "ai_loop_current_blocker_queue_readback_normalizer_contract_count" ] - == 9 + == 11 ) assert payload["summary"][ "ai_loop_current_blocker_queue_readback_normalizer_field_ids" diff --git a/docs/LOGBOOK.md b/docs/LOGBOOK.md index d73e9bc5b..fffacc90b 100644 --- a/docs/LOGBOOK.md +++ b/docs/LOGBOOK.md @@ -1,3 +1,16 @@ +## 2026-07-01 — 14:05 AI Agent normalizer 納入 stale Harbor repair readback + +**照主線修正的問題**: +- `a5481429d` 已讓 public Gitea queue / closure verifier 可分類 `blocked_current_cd_waiting_behind_stale_harbor_110_repair_readback`,但 AI Agent controlled writeback executor 的 queue normalizer contract 尚未列入這兩個新欄位。 +- 本次把 `harbor_110_repair_visible_running_jobs_api_stale` 與 `current_cd_waiting_behind_harbor_110_repair_running` 加進 `queue_readback_normalizer_contract`,並讓 priority work order summary / evidence 顯示 contract count `11`。 +- 這讓 KM / RAG / PlayBook / MCP / verifier / AI Agent 能把「CD 正等待 stale Harbor 110 repair running readback」當成可學習、可回寫、可排隊的 blocker,而不是只看見泛稱 SSH auth stalled。 + +**驗證**: +- `DATABASE_URL=... python3.11 -m pytest 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`:`23 passed`。 +- `python3.11 -m pytest ops/runner/test_read_public_gitea_actions_queue.py ops/runner/test_verify_awoooi_non110_cd_closure.py -q`:`45 passed`。 + +**邊界**:只改 AI Agent executor normalizer contract、priority work order tests 與 LOGBOOK;未使用 GitHub / `gh` / GitHub API;未 workflow_dispatch;未讀 secret / token / `.env` / raw sessions / SQLite / auth;未讀 authorized_keys 內容或 `.runner` 內容;未執行 110 runtime apply。 + ## 2026-07-01 — 13:55 CD waiting behind stale Harbor 110 repair readback **照主線修正的問題**: