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
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:
@@ -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 [
|
||||
{
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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"]
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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 queue;runtime 若仍卡 Harbor 502 與 `awoooi-host` no matching,下一個主線仍是 110 controlled lane verifier / registration receipt,不恢復 generic runner。
|
||||
|
||||
Reference in New Issue
Block a user