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
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:
@@ -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"
|
||||
),
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user