feat(agent): expose harbor receipt output contract
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 41s
CD Pipeline / build-and-deploy (push) Failing after 2m35s
CD Pipeline / post-deploy-checks (push) Has been skipped
AWOOOI Harbor 110 Local Repair / workflow-shape (push) Successful in 0s
AWOOOI Harbor 110 Local Repair / harbor-110-local-repair (push) Has been cancelled

This commit is contained in:
Your Name
2026-07-01 08:13:39 +08:00
parent f3a29b4818
commit 693a31343b
5 changed files with 189 additions and 2 deletions

View File

@@ -115,6 +115,10 @@ def load_latest_ai_agent_log_controlled_writeback_executor_readback() -> dict[st
item["harbor_recovery_receipt_input_count"]
for item in current_blocker_queue
),
"current_blocker_harbor_recovery_receipt_output_contract_count": sum(
item["harbor_recovery_receipt_output_contract_count"]
for item in current_blocker_queue
),
"runtime_dispatch_performed": False,
},
"active_blockers": active_blockers,
@@ -353,6 +357,12 @@ def _current_blocker_queue_item(recovery: dict[str, Any]) -> dict[str, Any]:
"harbor_recovery_receipt_input_count": len(
_harbor_recovery_receipt_inputs()
),
"harbor_recovery_receipt_output_contract": (
_harbor_recovery_receipt_output_contract()
),
"harbor_recovery_receipt_output_contract_count": len(
_harbor_recovery_receipt_output_contract()
),
"queue_readback_normalizer_contract": _queue_readback_normalizer_contract(),
"queue_readback_normalizer_contract_count": len(
_queue_readback_normalizer_contract()
@@ -468,6 +478,74 @@ def _harbor_recovery_receipt_inputs() -> list[dict[str, Any]]:
]
def _harbor_recovery_receipt_output_contract() -> list[dict[str, Any]]:
metadata_boundary = {
"metadata_only": True,
"raw_output_allowed": False,
"secret_value_allowed": False,
"writeback_targets": ["km", "rag", "playbook", "mcp", "verifier", "ai_agent"],
}
return [
{
"output_id": "control_path_readiness",
"source": "harbor-registry-controlled-recovery-receipt.readback.control_path_readiness",
"required_when": "after_receipt_validation_before_km_rag_mcp_playbook_writeback",
"purpose": (
"normalize 110 SSH, node load, awoooi-host queue, registry, "
"and safe-next-action signals into AI learning evidence"
),
**metadata_boundary,
},
{
"output_id": "controlled_cd_lane_readiness",
"source": "harbor-registry-controlled-recovery-receipt.readback.controlled_cd_lane_readiness",
"required_when": "before_retrying_harbor_110_local_repair_queue",
"purpose": (
"write back controlled lane registration, service, fail-closed, "
"blocker count, and safe-next-step readiness"
),
**metadata_boundary,
},
{
"output_id": "gitea_actions_queue",
"source": "harbor-registry-controlled-recovery-receipt.readback.gitea_actions_queue",
"required_when": "after_public_gitea_queue_readback",
"purpose": (
"write back normalized CD job, Harbor repair job, and "
"awoooi-host no-matching runner classifiers"
),
**metadata_boundary,
},
{
"output_id": "local_console_phase_readback",
"source": "harbor-registry-controlled-recovery-receipt.local_console_phase_readback",
"required_when": "after_receipt_validation",
"purpose": (
"write back ordered diagnose, preflight, repair, verifier phase "
"status without raw console output"
),
**metadata_boundary,
},
{
"output_id": "post_apply_verifier",
"source": "harbor-registry-controlled-recovery-receipt.readback.post_apply_verifier",
"required_when": "after_registry_v2_verifier",
"purpose": "write back public and internal registry /v2/ readiness",
**metadata_boundary,
},
{
"output_id": "deploy_marker",
"source": "harbor-registry-controlled-recovery-receipt.readback.deploy_marker",
"required_when": "after_registry_v2_ready_and_cd_retry",
"purpose": (
"write back deploy marker, production image match, and latest "
"CD status before closing the P0 blocker"
),
**metadata_boundary,
},
]
def _queue_readback_normalizer_contract() -> list[dict[str, Any]]:
return [
{

View File

@@ -542,6 +542,15 @@ def apply_ai_loop_current_blocker_execution_queue(
for item in harbor_recovery_receipt_inputs
if item.get("input_id")
]
harbor_recovery_receipt_output_contract = [
_dict(item)
for item in _list(first_item.get("harbor_recovery_receipt_output_contract"))
]
harbor_recovery_receipt_output_ids = [
str(item.get("output_id") or "")
for item in harbor_recovery_receipt_output_contract
if item.get("output_id")
]
queue_readback_normalizer_contract = [
_dict(item)
for item in _list(first_item.get("queue_readback_normalizer_contract"))
@@ -589,6 +598,12 @@ def apply_ai_loop_current_blocker_execution_queue(
state["ai_loop_current_blocker_harbor_recovery_receipt_input_ids"] = (
harbor_recovery_receipt_input_ids
)
state["ai_loop_current_blocker_harbor_recovery_receipt_output_contract_count"] = (
len(harbor_recovery_receipt_output_contract)
)
state["ai_loop_current_blocker_harbor_recovery_receipt_output_ids"] = (
harbor_recovery_receipt_output_ids
)
state["ai_loop_current_blocker_queue_readback_normalizer_contract_count"] = len(
queue_readback_normalizer_contract
)
@@ -665,6 +680,15 @@ def apply_ai_loop_current_blocker_execution_queue(
evidence["ai_loop_current_blocker_harbor_recovery_receipt_inputs"] = (
harbor_recovery_receipt_inputs
)
evidence[
"ai_loop_current_blocker_harbor_recovery_receipt_output_contract_count"
] = len(harbor_recovery_receipt_output_contract)
evidence["ai_loop_current_blocker_harbor_recovery_receipt_output_ids"] = (
harbor_recovery_receipt_output_ids
)
evidence["ai_loop_current_blocker_harbor_recovery_receipt_output_contract"] = (
harbor_recovery_receipt_output_contract
)
evidence["ai_loop_current_blocker_queue_readback_normalizer_contract"] = (
queue_readback_normalizer_contract
)
@@ -715,8 +739,9 @@ def apply_ai_loop_current_blocker_execution_queue(
"P0-006-AI-LOOP-CURRENT-BLOCKER-EXECUTION-QUEUE: execute the "
f"{blocker_id} queue item through 110 control-path readback, "
f"{len(local_console_plan)} ordered local-console phases, post-recovery "
"readback commands, Harbor receipt inputs, and metadata-only "
"KM/RAG/MCP/PlayBook writeback from normalized queue classifiers."
"readback commands, Harbor receipt inputs and outputs, and "
"metadata-only KM/RAG/MCP/PlayBook writeback from normalized queue "
"classifiers and control-path readiness classifiers."
),
(
"P0-006-HARBOR-REGISTRY-CONTROLLED-RECOVERY-PREFLIGHT: after the "
@@ -759,6 +784,12 @@ def apply_ai_loop_current_blocker_execution_queue(
summary["ai_loop_current_blocker_harbor_recovery_receipt_input_ids"] = (
harbor_recovery_receipt_input_ids
)
summary["ai_loop_current_blocker_harbor_recovery_receipt_output_contract_count"] = (
len(harbor_recovery_receipt_output_contract)
)
summary["ai_loop_current_blocker_harbor_recovery_receipt_output_ids"] = (
harbor_recovery_receipt_output_ids
)
summary["ai_loop_current_blocker_queue_readback_normalizer_contract_count"] = len(
queue_readback_normalizer_contract
)

View File

@@ -74,6 +74,12 @@ def _assert_executor_readback(payload: dict, *, public_endpoint: bool = False):
payload["rollups"]["current_blocker_harbor_recovery_receipt_input_count"]
== 9
)
assert (
payload["rollups"][
"current_blocker_harbor_recovery_receipt_output_contract_count"
]
== 6
)
assert payload["rollups"]["runtime_dispatch_performed"] is False
batches = {batch["target"]: batch for batch in payload["execution_batches"]}
@@ -151,6 +157,32 @@ 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"] == 6
assert [
item["output_id"]
for item in current_queue[0]["harbor_recovery_receipt_output_contract"]
] == [
"control_path_readiness",
"controlled_cd_lane_readiness",
"gitea_actions_queue",
"local_console_phase_readback",
"post_apply_verifier",
"deploy_marker",
]
assert all(
item["metadata_only"] is True
and item["raw_output_allowed"] is False
and item["secret_value_allowed"] is False
and item["writeback_targets"] == [
"km",
"rag",
"playbook",
"mcp",
"verifier",
"ai_agent",
]
for item in current_queue[0]["harbor_recovery_receipt_output_contract"]
)
assert current_queue[0]["queue_readback_normalizer_contract_count"] == 3
assert [
item["field_id"]

View File

@@ -344,6 +344,23 @@ def test_awoooi_priority_work_order_readback_overlays_ai_loop_current_blocker_qu
assert evidence["ai_loop_current_blocker_harbor_recovery_receipt_inputs"][-1][
"expected_schema"
] == "awoooi_production_deploy_readback_blocker_v1"
assert (
evidence[
"ai_loop_current_blocker_harbor_recovery_receipt_output_contract_count"
]
== 6
)
assert evidence["ai_loop_current_blocker_harbor_recovery_receipt_output_ids"] == [
"control_path_readiness",
"controlled_cd_lane_readiness",
"gitea_actions_queue",
"local_console_phase_readback",
"post_apply_verifier",
"deploy_marker",
]
assert evidence["ai_loop_current_blocker_harbor_recovery_receipt_output_contract"][
0
]["writeback_targets"] == ["km", "rag", "playbook", "mcp", "verifier", "ai_agent"]
assert evidence["ai_loop_current_blocker_queue_readback_normalizer_field_ids"] == [
"cd_run_jobs_payload_classifier",
"harbor_110_repair_jobs_payload_classifier",
@@ -393,6 +410,15 @@ def test_awoooi_priority_work_order_readback_overlays_ai_loop_current_blocker_qu
assert payload["summary"][
"ai_loop_current_blocker_harbor_recovery_receipt_input_ids"
][-1] == "deploy_marker_readback"
assert (
payload["summary"][
"ai_loop_current_blocker_harbor_recovery_receipt_output_contract_count"
]
== 6
)
assert payload["summary"][
"ai_loop_current_blocker_harbor_recovery_receipt_output_ids"
][0] == "control_path_readiness"
assert (
payload["summary"][
"ai_loop_current_blocker_queue_readback_normalizer_contract_count"

View File

@@ -51054,3 +51054,23 @@ production browser smoke:
**下一步**
- commit / push 後讀回 Gitea queue、registry `/v2/`、Harbor health 與 priority work-order API若仍卡 `awoooi-host` no matching下一步維持 110 local console / controlled lane restore-registration verifier不恢復 generic runner。
## 2026-07-01 — 08:12 AI Loop Harbor receipt output writeback contract
**完成內容**
- `agent-log-controlled-writeback-executor-readback` 新增 `harbor_recovery_receipt_output_contract`,把 Harbor receipt 產出的 `control_path_readiness``controlled_cd_lane_readiness``gitea_actions_queue``local_console_phase_readback``post_apply_verifier``deploy_marker` 6 個 metadata-only output 明確列為 KM / RAG / PlayBook / MCP / Verifier / AI Agent writeback 目標。
- `awoooi-priority-work-order-readback` 同步投影 output contract count / ids / contract讓主工作順序頁不只知道要收哪些 receipt input也知道 receipt output 要沉澱到哪些學習節點。
- next execution order 保留 `normalized queue classifiers` 相容字串,並新增 `control-path readiness classifiers`,避免舊下游判讀斷裂。
**本地驗證結果**
- Focused suite`74 passed`
- `ruff check``py_compile``ops/runner/guard-gitea-runner-pressure.py --root .``scripts/ci/check-gitea-step-env-secrets.js``git diff --check`:通過。
- runner pressure guard 仍讀回 `auto_branch_events_on_110=0``generic_runner_labels=0`
**仍維持**
- 沒有讀 secret / token / `.env` / raw sessions / SQLite / auth沒有讀 `.runner` 內容。
- 沒有使用 GitHub / gh / GitHub API / GitHub Actions。
- 沒有重啟主機,沒有 Docker / Nginx / K3s / DB restart沒有 workflow_dispatch沒有 runtime write。
**下一步**
- commit / push 後讀回 Gitea queueruntime 若仍卡 Harbor 502 與 `awoooi-host` no matching下一個主線仍是 110 controlled lane verifier / registration receipt不恢復 generic runner。