feat(awooop): close ai automation node receipts with live readback
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 1m0s
CD Pipeline / build-and-deploy (push) Has started running
CD Pipeline / post-deploy-checks (push) Has been cancelled

This commit is contained in:
Your Name
2026-07-02 19:06:10 +08:00
parent 3cf54f3bf9
commit e2447d49a0
3 changed files with 407 additions and 18 deletions

View File

@@ -3528,6 +3528,144 @@ def apply_ai_automation_node_receipts(payload: dict[str, Any]) -> None:
_apply_ai_automation_node_receipts(payload)
def apply_ai_automation_live_closure_readbacks(
payload: dict[str, Any],
*,
executor_readback: dict[str, Any] | None = None,
verifier_readback: dict[str, Any] | None = None,
consumer_readback: dict[str, Any] | None = None,
) -> None:
"""Overlay live AI-loop executor/verifier/consumer readbacks onto receipts."""
summary = _dict(payload.setdefault("summary", {}))
rollups = _dict(payload.setdefault("rollups", {}))
state = _dict(payload.setdefault("mainline_execution_state", {}))
executor = _dict(executor_readback)
executor_rollups = _dict(executor.get("rollups"))
executor_active_blockers = _strings(executor.get("active_blockers"))
if executor:
summary["ai_automation_executor_status"] = str(executor.get("status") or "")
summary["ai_automation_executor_ready_execution_batch_count"] = _int(
executor_rollups.get("ready_execution_batch_count")
)
summary["ai_automation_executor_post_apply_verifier_ready_count"] = _int(
executor_rollups.get("post_apply_verifier_ready_count")
)
summary["ai_automation_executor_log_source_grouping_key_count"] = _int(
executor_rollups.get("log_source_grouping_key_count")
)
summary["ai_automation_executor_metadata_only_log_source_tagging_ready"] = bool(
executor_rollups.get("metadata_only_log_source_tagging_ready") is True
)
summary["ai_automation_executor_controlled_dispatch_ready"] = bool(
executor_rollups.get("controlled_executor_dispatch_ready") is True
)
summary["ai_automation_executor_runtime_dispatch_performed"] = bool(
executor_rollups.get("runtime_dispatch_performed") is True
)
summary["ai_automation_executor_active_blockers"] = executor_active_blockers
rollups["ai_automation_executor_active_blocker_count"] = len(
executor_active_blockers
)
state["ai_automation_executor_controlled_dispatch_ready"] = summary[
"ai_automation_executor_controlled_dispatch_ready"
]
verifier = _dict(verifier_readback)
verifier_rollups = _dict(verifier.get("rollups"))
verifier_active_blockers = _strings(verifier.get("active_blockers"))
if verifier:
summary["ai_automation_post_write_verifier_status"] = str(
verifier.get("status") or ""
)
summary["ai_automation_post_write_verifier_dry_run_ready"] = bool(
verifier_rollups.get("dry_run_ready") is True
)
summary["ai_automation_post_write_verifier_passed_node_count"] = _int(
verifier_rollups.get("passed_verifier_node_count")
)
summary["ai_automation_post_write_verifier_verified_target_count"] = _int(
verifier_rollups.get("verified_target_count")
)
summary["ai_automation_post_write_verifier_verified_candidate_receipt_count"] = (
_int(verifier_rollups.get("verified_candidate_receipt_count"))
)
summary["ai_automation_post_write_verifier_active_blockers"] = (
verifier_active_blockers
)
rollups["ai_automation_post_write_verifier_active_blocker_count"] = len(
verifier_active_blockers
)
state["ai_automation_post_write_verifier_dry_run_ready"] = summary[
"ai_automation_post_write_verifier_dry_run_ready"
]
consumer = _dict(consumer_readback)
consumer_rollups = _dict(consumer.get("rollups"))
consumer_control = _dict(consumer.get("controlled_consume"))
consumer_active_blockers = _strings(consumer.get("active_blockers"))
if consumer:
context_receipt_counts = {
"km": _int(consumer_rollups.get("km_context_receipt_write_count")),
"rag": _int(consumer_rollups.get("rag_context_receipt_write_count")),
"playbook": _int(
consumer_rollups.get("playbook_context_receipt_write_count")
),
"mcp": _int(consumer_rollups.get("mcp_context_receipt_write_count")),
"verifier": _int(
consumer_rollups.get("verifier_context_receipt_write_count")
),
"ai_agent": _int(
consumer_rollups.get("ai_agent_context_receipt_write_count")
),
}
summary["ai_automation_consumer_status"] = str(consumer.get("status") or "")
summary["ai_automation_consumer_readback_ready"] = bool(
consumer_rollups.get("controlled_consumer_readback_ready") is True
)
summary["ai_automation_consumer_controlled_consume_allowed"] = bool(
consumer_control.get("controlled_consume_allowed") is True
)
summary["ai_automation_consumer_runtime_target_write_performed"] = bool(
consumer_rollups.get("runtime_target_write_performed") is True
or consumer_control.get("runtime_target_write_performed") is True
)
summary["ai_automation_consumer_ready_target_count"] = _int(
consumer_rollups.get("ready_target_count")
)
summary["ai_automation_consumer_target_context_receipt_write_count"] = _int(
consumer_rollups.get("target_context_receipt_write_count")
)
summary["ai_automation_consumer_post_apply_verifier_ref_count"] = _int(
consumer_rollups.get("post_apply_verifier_ref_count")
)
summary["ai_automation_consumer_context_receipt_counts"] = (
context_receipt_counts
)
summary["ai_automation_consumer_apply_route"] = str(
consumer_control.get("consumer_apply_route") or ""
)
summary["ai_automation_consumer_active_blockers"] = consumer_active_blockers
rollups["ai_automation_consumer_active_blocker_count"] = len(
consumer_active_blockers
)
rollups["ai_automation_consumer_ready_target_count"] = summary[
"ai_automation_consumer_ready_target_count"
]
rollups["ai_automation_consumer_target_context_receipt_write_count"] = (
summary["ai_automation_consumer_target_context_receipt_write_count"]
)
state["ai_automation_consumer_readback_ready"] = summary[
"ai_automation_consumer_readback_ready"
]
state["ai_automation_consumer_runtime_target_write_performed"] = summary[
"ai_automation_consumer_runtime_target_write_performed"
]
apply_ai_automation_node_receipts(payload)
def _apply_ai_automation_node_receipts(payload: dict[str, Any]) -> None:
summary = _dict(payload.setdefault("summary", {}))
rollups = _dict(payload.setdefault("rollups", {}))
@@ -3559,6 +3697,66 @@ def _apply_ai_automation_node_receipts(payload: dict[str, Any]) -> None:
summary.get("ai_loop_current_blocker_queue_readback_normalizer_field_ids")
)
log_grouping_keys = _strings(summary.get("ai_loop_log_source_grouping_keys"))
executor_metadata_tagging_ready = bool(
summary.get("ai_automation_executor_metadata_only_log_source_tagging_ready")
is True
)
executor_log_grouping_key_count = _int(
summary.get("ai_automation_executor_log_source_grouping_key_count")
)
executor_dispatch_ready = bool(
summary.get("ai_automation_executor_controlled_dispatch_ready") is True
)
executor_runtime_dispatch_performed = bool(
summary.get("ai_automation_executor_runtime_dispatch_performed") is True
)
verifier_dry_run_ready = bool(
summary.get("ai_automation_post_write_verifier_dry_run_ready") is True
)
verifier_passed_node_count = _int(
summary.get("ai_automation_post_write_verifier_passed_node_count")
)
consumer_readback_ready = bool(
summary.get("ai_automation_consumer_readback_ready") is True
)
consumer_runtime_target_write_performed = bool(
summary.get("ai_automation_consumer_runtime_target_write_performed") is True
)
consumer_ready_target_count = _int(
summary.get("ai_automation_consumer_ready_target_count")
)
consumer_context_receipt_write_count = _int(
summary.get("ai_automation_consumer_target_context_receipt_write_count")
)
consumer_post_apply_verifier_ref_count = _int(
summary.get("ai_automation_consumer_post_apply_verifier_ref_count")
)
consumer_context_counts = _dict(
summary.get("ai_automation_consumer_context_receipt_counts")
)
consumer_apply_route = str(summary.get("ai_automation_consumer_apply_route") or "")
normalizer_ready = bool(
queue_fields
or log_grouping_keys
or executor_metadata_tagging_ready
or executor_log_grouping_key_count > 0
)
candidate_ready = bool(safe_next_action_id or executor_dispatch_ready)
execution_boundary_ready = bool(
consumer_runtime_target_write_performed
or executor_runtime_dispatch_performed
or executor_dispatch_ready
)
post_verifier_ready = bool(
receipt_outputs
or verifier_dry_run_ready
or consumer_post_apply_verifier_ref_count > 0
)
learning_writeback_ready = bool(
consumer_readback_ready
and consumer_context_receipt_write_count >= consumer_ready_target_count
and consumer_ready_target_count > 0
)
base_refs = [
"awoooi-priority-work-order-readback",
@@ -3583,13 +3781,22 @@ def _apply_ai_automation_node_receipts(payload: dict[str, Any]) -> None:
{
"node_id": "normalizer_log_tags",
"node_label": "Normalizer / LOG tags",
"node_status": "ready" if queue_fields or log_grouping_keys else "queued",
"node_status": "ready" if normalizer_ready else "queued",
"work_item_id": "CIR-P0-LOG-002",
"lane_id": "log_tagging_classification_clustering",
"evidence_refs": [*queue_fields[:4], *log_grouping_keys[:4]],
"evidence_refs": [
*queue_fields[:4],
*log_grouping_keys[:4],
f"executor_log_grouping_keys:{executor_log_grouping_key_count}",
f"metadata_only_tagging_ready:{executor_metadata_tagging_ready}",
],
"verifier_result": "queue_normalizer_fields_readback"
if queue_fields
else "normalizer_contract_required",
else (
"executor_log_source_tagging_readback"
if normalizer_ready
else "normalizer_contract_required"
),
"next_action": "extend tag taxonomy to Telegram, CPU, backup, freshness",
},
{
@@ -3605,13 +3812,21 @@ def _apply_ai_automation_node_receipts(payload: dict[str, Any]) -> None:
{
"node_id": "candidate_action",
"node_label": "Candidate",
"node_status": "ready" if safe_next_action_id else "queued",
"node_status": "ready" if candidate_ready else "queued",
"work_item_id": "CIR-P0-AILOOP-002",
"lane_id": "p0_runtime_lane",
"evidence_refs": [safe_next_action_id, safe_next_action_stage],
"evidence_refs": [
safe_next_action_id,
safe_next_action_stage,
f"controlled_executor_dispatch_ready:{executor_dispatch_ready}",
],
"verifier_result": "safe_next_action_readback"
if safe_next_action_id
else "candidate_action_required",
else (
"controlled_executor_dispatch_ready"
if executor_dispatch_ready
else "candidate_action_required"
),
"next_action": "emit candidate action with target selector and dry-run",
},
{
@@ -3627,34 +3842,78 @@ def _apply_ai_automation_node_receipts(payload: dict[str, Any]) -> None:
{
"node_id": "execution_boundary",
"node_label": "Execution Boundary",
"node_status": "queued",
"node_status": "ready" if execution_boundary_ready else "queued",
"work_item_id": "CIR-P0-AILOOP-002",
"lane_id": "telegram_alert_ai_automation",
"evidence_refs": ["metadata_only", "no_secret_no_runtime_write"],
"verifier_result": "execution_receipt_required",
"evidence_refs": [
"metadata_only",
"no_secret_no_runtime_secret",
f"consumer_ready_targets:{consumer_ready_target_count}",
f"context_receipts:{consumer_context_receipt_write_count}",
f"consumer_apply_route:{consumer_apply_route}",
],
"verifier_result": "controlled_consumer_context_receipt_readback"
if consumer_runtime_target_write_performed
else (
"controlled_executor_dispatch_ready"
if executor_dispatch_ready
else "execution_receipt_required"
),
"next_action": "attach Telegram alert receipt and controlled executor result",
"telegram_receipt_ref": (
f"controlled_consumer_readback:{consumer_context_receipt_write_count}"
if consumer_runtime_target_write_performed
else "metadata_only"
),
},
{
"node_id": "post_verifier",
"node_label": "Verifier",
"node_status": "ready" if receipt_outputs else "queued",
"node_status": "ready" if post_verifier_ready else "queued",
"work_item_id": "CIR-P0-AILOOP-002",
"lane_id": "p0_runtime_lane",
"evidence_refs": receipt_outputs[:4],
"evidence_refs": [
*receipt_outputs[:4],
f"post_write_verifier_nodes:{verifier_passed_node_count}",
f"consumer_post_apply_verifier_refs:{consumer_post_apply_verifier_ref_count}",
],
"verifier_result": "post_verifier_receipt_readback"
if receipt_outputs
else "post_verifier_required",
else (
"post_write_verifier_dry_run_ready"
if verifier_dry_run_ready
else "post_verifier_required"
),
"next_action": "read back route/API/UI/verifier output before closing",
},
{
"node_id": "learning_writeback",
"node_label": "Learning / Writeback",
"node_status": "queued",
"node_status": "ready" if learning_writeback_ready else "queued",
"work_item_id": "CIR-P1-KM-002",
"lane_id": "km_rag_mcp_playbook_integration",
"evidence_refs": ["KM", "RAG", "MCP", "PlayBook trust"],
"verifier_result": "writeback_receipt_required",
"evidence_refs": [
f"context_receipts:{consumer_context_receipt_write_count}",
f"km_context_receipt:{_int(consumer_context_counts.get('km'))}",
f"rag_context_receipt:{_int(consumer_context_counts.get('rag'))}",
f"playbook_context_receipt:{_int(consumer_context_counts.get('playbook'))}",
f"mcp_context_receipt:{_int(consumer_context_counts.get('mcp'))}",
],
"verifier_result": "consumer_context_receipt_writeback_ready"
if learning_writeback_ready
else "writeback_receipt_required",
"next_action": "write KM/RAG/MCP/PlayBook trust refs after verifier",
"km_writeback_ref": (
f"context_receipt:km={_int(consumer_context_counts.get('km'))}"
if learning_writeback_ready
else "queued"
),
"playbook_trust_writeback_ref": (
"context_receipt:playbook="
f"{_int(consumer_context_counts.get('playbook'))}"
if learning_writeback_ready
else "queued"
),
},
]