feat(api): roll up log writeback executor readiness
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 20s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
Some checks failed
CD Pipeline / workflow-shape (push) Successful in 1s
CD Pipeline / cancel-stale-cd (push) Has been skipped
CD Pipeline / tests (push) Successful in 20s
CD Pipeline / post-deploy-checks (push) Has been cancelled
CD Pipeline / build-and-deploy (push) Has been cancelled
This commit is contained in:
@@ -18,6 +18,9 @@ from sqlalchemy import text
|
||||
from src.core.config import settings
|
||||
from src.core.logging import get_logger
|
||||
from src.db.base import get_db_context
|
||||
from src.services.ai_agent_log_controlled_writeback_executor_readback import (
|
||||
load_latest_ai_agent_log_controlled_writeback_executor_readback,
|
||||
)
|
||||
from src.services.report_generation_service import (
|
||||
DAILY_REPORT_HOUR_TAIPEI,
|
||||
MONTHLY_REPORT_DAY_TAIPEI,
|
||||
@@ -178,6 +181,90 @@ def _status_recent(summary: Mapping[str, Any] | None, *statuses: str) -> int:
|
||||
return sum(_int_value(by_status.get(status)) for status in statuses)
|
||||
|
||||
|
||||
def _load_log_controlled_writeback_executor_readback() -> dict[str, Any]:
|
||||
"""Attach the LOG/KM/RAG/MCP/PlayBook executor queue without dispatching it."""
|
||||
|
||||
try:
|
||||
return load_latest_ai_agent_log_controlled_writeback_executor_readback()
|
||||
except Exception as exc: # pragma: no cover - keeps runtime control API visible
|
||||
logger.warning(
|
||||
"log_controlled_writeback_executor_readback_failed",
|
||||
error_type=type(exc).__name__,
|
||||
)
|
||||
return {
|
||||
"schema_version": "ai_agent_log_controlled_writeback_executor_readback_v1",
|
||||
"priority": "P1-LOG-KM-RAG-MCP-PLAYBOOK",
|
||||
"scope": "ai_agent_log_controlled_writeback_executor",
|
||||
"status": "blocked_waiting_log_controlled_writeback_executor_readback",
|
||||
"readback": {
|
||||
"workplan_id": "P1-LOG-CONTROLLED-WRITEBACK-EXECUTOR",
|
||||
"workplan_title": "LOG feedback controlled writeback executor and AI Agent consumption readback",
|
||||
"safe_next_step": "repair_log_controlled_writeback_executor_readback_then_retry",
|
||||
"error_type": type(exc).__name__,
|
||||
},
|
||||
"executor_policy": {
|
||||
"executor_route": "ai_agent_metadata_writeback_executor",
|
||||
"low_medium_high_controlled_apply_enabled": True,
|
||||
"owner_review_required_for_low_medium_high": False,
|
||||
"critical_break_glass_required": True,
|
||||
"target_selector_required": True,
|
||||
"source_of_truth_diff_required": True,
|
||||
"check_mode_required": True,
|
||||
"rollback_required": True,
|
||||
"post_apply_verifier_required": True,
|
||||
},
|
||||
"execution_batches": [],
|
||||
"agent_consumption_context": {
|
||||
"context_id": "ai-agent-log-controlled-writeback-consumption-v1",
|
||||
"consumable_by": [
|
||||
"ai_agent_autonomous_runtime_control",
|
||||
"awooop_work_items",
|
||||
"alert_triage_loop",
|
||||
"km_rag_playbook_learning_loop",
|
||||
"mcp_audit_context_loop",
|
||||
],
|
||||
"evidence_chain": [
|
||||
"/api/v1/agents/agent-log-intelligence-integration-readback",
|
||||
"/api/v1/agents/agent-log-feedback-receipt-dry-run",
|
||||
"/api/v1/agents/agent-log-post-write-verifier-dry-run",
|
||||
"/api/v1/agents/agent-log-controlled-writeback-plan-readback",
|
||||
],
|
||||
"next_action_queue": [],
|
||||
"learning_feedback_targets": [],
|
||||
"raw_payload_required": False,
|
||||
},
|
||||
"rollups": {
|
||||
"source_writeback_plan_count": 0,
|
||||
"execution_batch_count": 0,
|
||||
"ready_execution_batch_count": 0,
|
||||
"target_count": 0,
|
||||
"target_selector_count": 0,
|
||||
"source_of_truth_diff_count": 0,
|
||||
"check_mode_ready_count": 0,
|
||||
"rollback_ready_count": 0,
|
||||
"post_apply_verifier_ready_count": 0,
|
||||
"controlled_executor_dispatch_ready": False,
|
||||
"controlled_apply_enabled_by_policy": True,
|
||||
"runtime_dispatch_performed": False,
|
||||
},
|
||||
"active_blockers": ["log_controlled_writeback_executor_readback_unavailable"],
|
||||
"operation_boundaries": {
|
||||
"executor_readback_only": True,
|
||||
"controlled_apply_enabled_by_policy": True,
|
||||
"executor_dispatch_performed": False,
|
||||
"km_write_performed": False,
|
||||
"rag_index_write_performed": False,
|
||||
"playbook_trust_write_performed": False,
|
||||
"mcp_tool_call_performed": False,
|
||||
"agent_runtime_action_performed": False,
|
||||
"workflow_trigger_performed": False,
|
||||
"raw_log_payload_persisted": False,
|
||||
"secret_value_collection_allowed": False,
|
||||
"github_api_used": False,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
def _trace_stage(
|
||||
*,
|
||||
stage_id: str,
|
||||
@@ -1533,6 +1620,7 @@ def _build_work_item_progress(
|
||||
*,
|
||||
trace_ledger: Mapping[str, Any],
|
||||
log_integration_taxonomy: Mapping[str, Any],
|
||||
log_controlled_writeback_executor: Mapping[str, Any],
|
||||
agent_decision_wiring: Mapping[str, Any],
|
||||
learning_loop: Mapping[str, Any],
|
||||
alert_noise_reduction: Mapping[str, Any],
|
||||
@@ -1581,6 +1669,20 @@ def _build_work_item_progress(
|
||||
and alert_noise_reduction.get("status") == "completed"
|
||||
and alert_noise_missing == 0
|
||||
)
|
||||
log_executor_rollups = log_controlled_writeback_executor.get("rollups")
|
||||
if not isinstance(log_executor_rollups, Mapping):
|
||||
log_executor_rollups = {}
|
||||
log_executor_blockers = log_controlled_writeback_executor.get("active_blockers")
|
||||
if not isinstance(log_executor_blockers, list):
|
||||
log_executor_blockers = []
|
||||
log_executor_ready = (
|
||||
log_controlled_writeback_executor.get("schema_version")
|
||||
== "ai_agent_log_controlled_writeback_executor_readback_v1"
|
||||
and log_controlled_writeback_executor.get("status")
|
||||
== "controlled_writeback_executor_ready"
|
||||
and log_executor_rollups.get("controlled_executor_dispatch_ready") is True
|
||||
and not log_executor_blockers
|
||||
)
|
||||
ui_rollups = ui_productization.get("rollups")
|
||||
if not isinstance(ui_rollups, Mapping):
|
||||
ui_rollups = {}
|
||||
@@ -1680,11 +1782,24 @@ def _build_work_item_progress(
|
||||
"exit_criteria": "repeated alerts are clustered, deduped, routed to controlled automation, and no longer default to manual handling",
|
||||
"remaining_alert_noise_stage_count": alert_noise_missing,
|
||||
},
|
||||
{
|
||||
"work_item_id": "P1-E-log-controlled-writeback-executor",
|
||||
"priority": "P1-E",
|
||||
"title": "LOG feedback executor queue for KM / RAG / MCP / PlayBook",
|
||||
"status": "completed" if log_executor_ready else "in_progress" if p1d_completed else "pending",
|
||||
"exit_criteria": "executor readback exposes ready batches, target selectors, source diffs, rollback, verifier, and next-action queue",
|
||||
"remaining_executor_batch_count": max(
|
||||
0,
|
||||
_int_value(log_executor_rollups.get("execution_batch_count"))
|
||||
- _int_value(log_executor_rollups.get("ready_execution_batch_count")),
|
||||
),
|
||||
"active_blocker_count": len(log_executor_blockers),
|
||||
},
|
||||
{
|
||||
"work_item_id": "P2-A-ui-ux-productization",
|
||||
"priority": "P2-A",
|
||||
"title": "Professional product UI replacing text-heavy surfaces",
|
||||
"status": "completed" if p2a_completed else "in_progress" if p1d_completed else "pending",
|
||||
"status": "completed" if p2a_completed else "in_progress" if log_executor_ready else "pending",
|
||||
"exit_criteria": "AI automation status is shown as dense dashboard controls, filters, counters, and action rails",
|
||||
"remaining_ui_surface_count": ui_surface_missing,
|
||||
},
|
||||
@@ -2589,9 +2704,11 @@ def build_runtime_receipt_readback_from_rows(
|
||||
)
|
||||
ui_productization = _build_ui_productization_readback()
|
||||
multi_product_taxonomy = _build_multi_product_taxonomy_contract(log_integration_taxonomy)
|
||||
log_controlled_writeback_executor = _load_log_controlled_writeback_executor_readback()
|
||||
work_item_progress = _build_work_item_progress(
|
||||
trace_ledger=trace_ledger,
|
||||
log_integration_taxonomy=log_integration_taxonomy,
|
||||
log_controlled_writeback_executor=log_controlled_writeback_executor,
|
||||
agent_decision_wiring=agent_decision_wiring,
|
||||
learning_loop=learning_loop,
|
||||
alert_noise_reduction=alert_noise_reduction,
|
||||
@@ -2718,6 +2835,7 @@ def build_runtime_receipt_readback_from_rows(
|
||||
"autonomous_execution_loop_ledger": loop_ledger,
|
||||
"trace_ledger": trace_ledger,
|
||||
"log_integration_taxonomy": log_integration_taxonomy,
|
||||
"log_controlled_writeback_executor": log_controlled_writeback_executor,
|
||||
"agent_decision_wiring": agent_decision_wiring,
|
||||
"learning_loop": learning_loop,
|
||||
"alert_noise_reduction": alert_noise_reduction,
|
||||
@@ -2739,6 +2857,21 @@ def _attach_runtime_receipt_readback(
|
||||
) -> dict[str, Any]:
|
||||
payload["runtime_receipt_readback"] = readback
|
||||
rollups = payload.setdefault("rollups", {})
|
||||
log_executor = readback.get("log_controlled_writeback_executor")
|
||||
if not isinstance(log_executor, Mapping):
|
||||
log_executor = {}
|
||||
log_executor_rollups = log_executor.get("rollups")
|
||||
if not isinstance(log_executor_rollups, Mapping):
|
||||
log_executor_rollups = {}
|
||||
log_executor_context = log_executor.get("agent_consumption_context")
|
||||
if not isinstance(log_executor_context, Mapping):
|
||||
log_executor_context = {}
|
||||
log_executor_queue = log_executor_context.get("next_action_queue")
|
||||
if not isinstance(log_executor_queue, list):
|
||||
log_executor_queue = []
|
||||
log_executor_blockers = log_executor.get("active_blockers")
|
||||
if not isinstance(log_executor_blockers, list):
|
||||
log_executor_blockers = []
|
||||
rollups.update({
|
||||
"live_ansible_apply_executed_count": _int_value(
|
||||
readback.get("ansible_apply_executed", {}).get("total")
|
||||
@@ -2826,6 +2959,23 @@ def _attach_runtime_receipt_readback(
|
||||
"recent_classified_event_total"
|
||||
)
|
||||
),
|
||||
"live_log_controlled_writeback_executor_batch_count": _int_value(
|
||||
log_executor_rollups.get("execution_batch_count")
|
||||
),
|
||||
"live_log_controlled_writeback_executor_ready_batch_count": _int_value(
|
||||
log_executor_rollups.get("ready_execution_batch_count")
|
||||
),
|
||||
"live_log_controlled_writeback_executor_ready_count": (
|
||||
1
|
||||
if log_executor.get("status") == "controlled_writeback_executor_ready"
|
||||
else 0
|
||||
),
|
||||
"live_log_controlled_writeback_executor_blocker_count": len(
|
||||
log_executor_blockers
|
||||
),
|
||||
"live_log_controlled_writeback_next_action_queue_count": len(
|
||||
log_executor_queue
|
||||
),
|
||||
"live_agent_decision_wiring_stage_count": _int_value(
|
||||
((readback.get("agent_decision_wiring") or {}).get("rollups") or {}).get(
|
||||
"stage_count"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from src.services.ai_agent_autonomous_runtime_control import (
|
||||
_RUNTIME_ALERTMANAGER_EVENT_COUNTS_SQL,
|
||||
_RUNTIME_ALERT_OPERATION_COUNTS_SQL,
|
||||
_RUNTIME_ALERTMANAGER_EVENT_COUNTS_SQL,
|
||||
_RUNTIME_GROUPED_ALERT_EVENT_COUNTS_SQL,
|
||||
_RUNTIME_PLAYBOOK_TRUST_COUNTS_FALLBACK_SQL,
|
||||
_RUNTIME_TIMELINE_COUNTS_SQL,
|
||||
@@ -10,6 +10,50 @@ from src.services.ai_agent_autonomous_runtime_control import (
|
||||
)
|
||||
|
||||
|
||||
def _assert_log_controlled_writeback_executor(payload: dict):
|
||||
assert payload["schema_version"] == "ai_agent_log_controlled_writeback_executor_readback_v1"
|
||||
assert payload["priority"] == "P1-LOG-KM-RAG-MCP-PLAYBOOK"
|
||||
assert payload["status"] == "controlled_writeback_executor_ready"
|
||||
assert payload["active_blockers"] == []
|
||||
|
||||
policy = payload["executor_policy"]
|
||||
assert policy["low_medium_high_controlled_apply_enabled"] is True
|
||||
assert policy["owner_review_required_for_low_medium_high"] is False
|
||||
assert policy["critical_break_glass_required"] is True
|
||||
assert policy["target_selector_required"] is True
|
||||
assert policy["source_of_truth_diff_required"] is True
|
||||
assert policy["check_mode_required"] is True
|
||||
assert policy["rollback_required"] is True
|
||||
assert policy["post_apply_verifier_required"] is True
|
||||
|
||||
assert payload["rollups"]["source_writeback_plan_count"] == 12
|
||||
assert payload["rollups"]["execution_batch_count"] == 6
|
||||
assert payload["rollups"]["ready_execution_batch_count"] == 6
|
||||
assert payload["rollups"]["target_selector_count"] == 12
|
||||
assert payload["rollups"]["source_of_truth_diff_count"] == 12
|
||||
assert payload["rollups"]["controlled_executor_dispatch_ready"] is True
|
||||
assert payload["rollups"]["controlled_apply_enabled_by_policy"] is True
|
||||
assert payload["rollups"]["runtime_dispatch_performed"] is False
|
||||
|
||||
context = payload["agent_consumption_context"]
|
||||
assert "ai_agent_autonomous_runtime_control" in context["consumable_by"]
|
||||
assert "km_rag_playbook_learning_loop" in context["consumable_by"]
|
||||
assert len(context["next_action_queue"]) == 6
|
||||
assert context["raw_payload_required"] is False
|
||||
|
||||
boundaries = payload["operation_boundaries"]
|
||||
assert boundaries["executor_readback_only"] is True
|
||||
assert boundaries["executor_dispatch_performed"] is False
|
||||
assert boundaries["km_write_performed"] is False
|
||||
assert boundaries["rag_index_write_performed"] is False
|
||||
assert boundaries["playbook_trust_write_performed"] is False
|
||||
assert boundaries["mcp_tool_call_performed"] is False
|
||||
assert boundaries["agent_runtime_action_performed"] is False
|
||||
assert boundaries["raw_log_payload_persisted"] is False
|
||||
assert boundaries["secret_value_collection_allowed"] is False
|
||||
assert boundaries["github_api_used"] is False
|
||||
|
||||
|
||||
def test_runtime_receipt_auxiliary_sql_keeps_source_family_counts_schema_safe():
|
||||
assert "GROUP BY coalesce(status, 'unknown')" in _RUNTIME_TIMELINE_COUNTS_SQL
|
||||
assert "FROM timeline_events" in _RUNTIME_TIMELINE_COUNTS_SQL
|
||||
@@ -76,6 +120,14 @@ def test_ai_agent_autonomous_runtime_control_exposes_reports_and_executor_receip
|
||||
assert data["rollups"]["direct_bot_api_allowed_count"] == 0
|
||||
assert data["rollups"]["legacy_policy_overridden_count"] >= 4
|
||||
assert data["runtime_receipt_readback"]["db_read_status"] == "not_queried"
|
||||
_assert_log_controlled_writeback_executor(
|
||||
data["runtime_receipt_readback"]["log_controlled_writeback_executor"]
|
||||
)
|
||||
assert data["rollups"]["live_log_controlled_writeback_executor_batch_count"] == 6
|
||||
assert data["rollups"]["live_log_controlled_writeback_executor_ready_batch_count"] == 6
|
||||
assert data["rollups"]["live_log_controlled_writeback_executor_ready_count"] == 1
|
||||
assert data["rollups"]["live_log_controlled_writeback_executor_blocker_count"] == 0
|
||||
assert data["rollups"]["live_log_controlled_writeback_next_action_queue_count"] == 6
|
||||
assert data["runtime_receipt_readback"]["learning_loop"]["status"] == "in_progress"
|
||||
assert (
|
||||
data["runtime_receipt_readback"]["learning_loop"]["rollups"][
|
||||
@@ -453,6 +505,9 @@ def test_runtime_receipt_readback_summarizes_live_executor_closure_rows():
|
||||
}.issubset(set(taxonomy["required_label_dimensions"]))
|
||||
assert taxonomy["public_safety"]["raw_secret_collection_allowed"] is False
|
||||
assert taxonomy["public_safety"]["unredacted_payload_storage_allowed"] is False
|
||||
_assert_log_controlled_writeback_executor(
|
||||
readback["log_controlled_writeback_executor"]
|
||||
)
|
||||
decision_wiring = readback["agent_decision_wiring"]
|
||||
assert decision_wiring["schema_version"] == "ai_agent_decision_wiring_readback_v1"
|
||||
assert decision_wiring["status"] == "completed"
|
||||
@@ -561,6 +616,7 @@ def test_runtime_receipt_readback_summarizes_live_executor_closure_rows():
|
||||
"P1-B-agent-decision-wiring",
|
||||
"P1-C-learning-loop",
|
||||
"P1-D-alert-noise-reduction",
|
||||
"P1-E-log-controlled-writeback-executor",
|
||||
"P2-A-ui-ux-productization",
|
||||
"P2-B-multi-product-expansion",
|
||||
]
|
||||
@@ -572,13 +628,16 @@ def test_runtime_receipt_readback_summarizes_live_executor_closure_rows():
|
||||
assert progress["ordered_items"][8]["status"] == "completed"
|
||||
assert progress["ordered_items"][8]["remaining_alert_noise_stage_count"] == 0
|
||||
assert progress["ordered_items"][9]["status"] == "completed"
|
||||
assert progress["ordered_items"][9]["remaining_ui_surface_count"] == 0
|
||||
assert progress["ordered_items"][9]["remaining_executor_batch_count"] == 0
|
||||
assert progress["ordered_items"][9]["active_blocker_count"] == 0
|
||||
assert progress["ordered_items"][10]["status"] == "completed"
|
||||
assert progress["ordered_items"][10]["remaining_product_scope_count"] == 0
|
||||
assert progress["ordered_items"][10]["remaining_ui_surface_count"] == 0
|
||||
assert progress["ordered_items"][11]["status"] == "completed"
|
||||
assert progress["ordered_items"][11]["remaining_product_scope_count"] == 0
|
||||
assert progress["source_family_items"]
|
||||
assert {item["status"] for item in progress["source_family_items"]} == {"completed"}
|
||||
assert progress["rollups"]["source_family_work_item_count"] == 10
|
||||
assert progress["rollups"]["completed_count"] == 21
|
||||
assert progress["rollups"]["completed_count"] == 22
|
||||
assert progress["rollups"]["pending_count"] == 0
|
||||
|
||||
|
||||
@@ -763,10 +822,11 @@ def test_runtime_receipt_work_items_use_learning_receipts_without_latest_telegra
|
||||
}
|
||||
assert statuses["P1-C-learning-loop"] == "completed"
|
||||
assert statuses["P1-D-alert-noise-reduction"] == "completed"
|
||||
assert statuses["P1-E-log-controlled-writeback-executor"] == "completed"
|
||||
assert statuses["P2-A-ui-ux-productization"] == "completed"
|
||||
assert statuses["P2-B-multi-product-expansion"] == "completed"
|
||||
assert {item["status"] for item in progress["source_family_items"]} == {"completed"}
|
||||
assert progress["rollups"]["completed_count"] == 21
|
||||
assert progress["rollups"]["completed_count"] == 22
|
||||
assert progress["rollups"]["pending_count"] == 0
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user